IdUCmdAbstractContract.java
/*
* Copyright © 2023 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package com.io7m.idstore.tests.server.controller.user;
import com.io7m.idstore.database.api.IdDatabaseTransactionType;
import com.io7m.idstore.model.IdEmail;
import com.io7m.idstore.model.IdName;
import com.io7m.idstore.model.IdNonEmptyList;
import com.io7m.idstore.model.IdPassword;
import com.io7m.idstore.model.IdPasswordAlgorithmPBKDF2HmacSHA256;
import com.io7m.idstore.model.IdPasswordException;
import com.io7m.idstore.model.IdRealName;
import com.io7m.idstore.model.IdUser;
import com.io7m.idstore.server.api.IdServerConfigurations;
import com.io7m.idstore.server.controller.user.IdUCommandContext;
import com.io7m.idstore.server.service.branding.IdServerBrandingServiceType;
import com.io7m.idstore.server.service.clock.IdServerClock;
import com.io7m.idstore.server.service.configuration.IdServerConfigurationFiles;
import com.io7m.idstore.server.service.configuration.IdServerConfigurationService;
import com.io7m.idstore.server.service.mail.IdServerMailServiceType;
import com.io7m.idstore.server.service.ratelimit.IdRateLimitEmailVerificationServiceType;
import com.io7m.idstore.server.service.sessions.IdSessionSecretIdentifier;
import com.io7m.idstore.server.service.sessions.IdSessionUser;
import com.io7m.idstore.server.service.telemetry.api.IdEventServiceType;
import com.io7m.idstore.server.service.telemetry.api.IdMetricsServiceType;
import com.io7m.idstore.server.service.telemetry.api.IdServerTelemetryNoOp;
import com.io7m.idstore.server.service.telemetry.api.IdServerTelemetryServiceType;
import com.io7m.idstore.server.service.templating.IdFMTemplateServiceType;
import com.io7m.idstore.strings.IdStrings;
import com.io7m.idstore.tests.IdFakeClock;
import com.io7m.idstore.tests.IdTestDirectories;
import com.io7m.idstore.tests.server.api.IdServerConfigurationsTest;
import com.io7m.repetoir.core.RPServiceDirectory;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.mockito.internal.verification.Times;
import java.nio.file.Path;
import java.time.Clock;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import static org.mockito.Mockito.mock;
public abstract class IdUCmdAbstractContract
{
private RPServiceDirectory services;
private IdDatabaseTransactionType transaction;
private IdFakeClock clock;
private IdServerClock serverClock;
private IdStrings strings;
private OffsetDateTime timeStart;
private IdFMTemplateServiceType templates;
private Path directory;
private IdServerConfigurationService configurations;
private IdServerMailServiceType mail;
private IdServerBrandingServiceType branding;
private IdRateLimitEmailVerificationServiceType rateLimit;
private IdEventServiceType eventService;
private IdMetricsServiceType metrics;
protected final Times once()
{
return new Times(1);
}
protected final Times twice()
{
return new Times(2);
}
protected final IdPassword password()
{
try {
return IdPasswordAlgorithmPBKDF2HmacSHA256.create().createHashed("x");
} catch (final IdPasswordException e) {
throw new IllegalStateException(e);
}
}
protected final OffsetDateTime timeStart()
{
return this.timeStart;
}
protected final IdUser createUser(
final String name)
{
return new IdUser(
UUID.randomUUID(),
new IdName(name),
new IdRealName("User " + name),
IdNonEmptyList.single(new IdEmail(name + "@example.com")),
OffsetDateTime.now(),
OffsetDateTime.now(),
this.password()
);
}
protected final IdEventServiceType events()
{
return this.eventService;
}
@BeforeEach
protected final void commandSetup()
throws Exception
{
this.directory =
IdTestDirectories.createTempDirectory();
final var file =
IdTestDirectories.resourceOf(
IdServerConfigurationsTest.class,
this.directory,
"server-config-0.xml"
);
final var configFile =
new IdServerConfigurationFiles()
.parse(file);
final var configuration =
IdServerConfigurations.ofFile(
Locale.getDefault(),
Clock.systemUTC(),
configFile
);
this.services =
new RPServiceDirectory();
this.transaction =
mock(IdDatabaseTransactionType.class);
this.clock =
new IdFakeClock();
this.serverClock =
new IdServerClock(this.clock);
this.timeStart =
this.serverClock.now();
this.strings =
IdStrings.create(Locale.ROOT);
this.templates =
mock(IdFMTemplateServiceType.class);
this.metrics =
mock(IdMetricsServiceType.class);
this.configurations =
new IdServerConfigurationService(this.metrics, configuration);
this.mail =
mock(IdServerMailServiceType.class);
this.branding =
mock(IdServerBrandingServiceType.class);
this.rateLimit =
mock(IdRateLimitEmailVerificationServiceType.class);
this.eventService =
mock(IdEventServiceType.class);
this.services.register(
IdServerClock.class,
this.serverClock
);
this.services.register(
IdEventServiceType.class,
this.eventService
);
this.services.register(
IdStrings.class,
this.strings
);
this.services.register(
IdServerTelemetryServiceType.class,
IdServerTelemetryNoOp.noop()
);
this.services.register(
IdFMTemplateServiceType.class,
this.templates
);
this.services.register(
IdServerConfigurationService.class,
this.configurations
);
this.services.register(
IdServerMailServiceType.class,
this.mail
);
this.services.register(
IdServerBrandingServiceType.class,
this.branding
);
this.services.register(
IdRateLimitEmailVerificationServiceType.class,
this.rateLimit
);
}
@AfterEach
protected final void commandTearDown()
throws Exception
{
this.services.close();
}
protected final RPServiceDirectory services()
{
return this.services;
}
protected final IdDatabaseTransactionType transaction()
{
return this.transaction;
}
protected final IdUCommandContext createContextAndSession(
final IdUser user)
{
return this.createContext(
new IdSessionUser(user.id(), IdSessionSecretIdentifier.generate()),
user
);
}
protected final IdFMTemplateServiceType templates()
{
return this.templates;
}
protected final IdServerConfigurationService configurations()
{
return this.configurations;
}
protected final IdServerMailServiceType mail()
{
return this.mail;
}
protected final IdServerBrandingServiceType branding()
{
return this.branding;
}
protected final IdRateLimitEmailVerificationServiceType rateLimit()
{
return this.rateLimit;
}
protected final IdUCommandContext createContext(
final IdSessionUser session,
final IdUser user)
{
return new IdUCommandContext(
this.services,
UUID.randomUUID(),
this.transaction,
session,
user,
"localhost",
"NCSA Mosaic"
);
}
protected final IdUser createUserAndSessionWithEmails(
final String name)
{
final var user0 = this.createUser(name);
return new IdUser(
user0.id(),
user0.idName(),
user0.realName(),
IdNonEmptyList.ofList(
List.of(
user0.emails().first(),
new IdEmail(name + "-e1@example.com"),
new IdEmail(name + "-e2@example.com"),
new IdEmail(name + "-e3@example.com"),
new IdEmail(name + "-e4@example.com")
)
),
user0.timeCreated(),
user0.timeUpdated(),
user0.password()
);
}
}