From c6d566627d9277d072b22011babac2ded18e9818 Mon Sep 17 00:00:00 2001 From: Serghei Motpan Date: Tue, 6 Aug 2024 18:37:45 +0300 Subject: [PATCH] Expose Account query API --- .../adapter/persistence/JpaAccountQuery.java | 37 +++++++++++ .../adapter/web/AccountController.java | 25 +++++++- .../account/adapter/web/AccountsApi.java | 23 ++++++- .../account/application/AccountQuery.java | 21 +++++++ .../application/CreateAccountService.java | 4 +- .../io/myfinbox/account/domain/Account.java | 11 ++-- .../myfinbox/account/domain/EmailAddress.java | 14 ++--- .../db/migration/V1_01__accounts_schema.sql | 10 +-- server/src/main/resources/openapi.yml | 7 ++- .../io/myfinbox/account/DataSamples.groovy | 14 ++++- .../adapter/web/AccountControllerSpec.groovy | 62 +++++++++++++++++-- .../CreateAccountServiceSpec.groovy | 8 +-- .../resources/account/web/create-account.sql | 3 + 13 files changed, 201 insertions(+), 38 deletions(-) create mode 100644 server/src/main/java/io/myfinbox/account/adapter/persistence/JpaAccountQuery.java create mode 100644 server/src/main/java/io/myfinbox/account/application/AccountQuery.java create mode 100644 server/src/test/resources/account/web/create-account.sql diff --git a/server/src/main/java/io/myfinbox/account/adapter/persistence/JpaAccountQuery.java b/server/src/main/java/io/myfinbox/account/adapter/persistence/JpaAccountQuery.java new file mode 100644 index 0000000..ce864b5 --- /dev/null +++ b/server/src/main/java/io/myfinbox/account/adapter/persistence/JpaAccountQuery.java @@ -0,0 +1,37 @@ +package io.myfinbox.account.adapter.persistence; + +import io.myfinbox.account.application.AccountQuery; +import io.myfinbox.account.domain.Account; +import io.myfinbox.account.domain.Accounts; +import io.myfinbox.shared.Failure; +import io.vavr.control.Either; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import java.util.UUID; + +import static io.myfinbox.account.domain.Account.AccountIdentifier; +import static io.myfinbox.shared.Failure.ofNotFound; +import static java.util.Objects.isNull; + +@Repository +@RequiredArgsConstructor +class JpaAccountQuery implements AccountQuery { + + static final String ACCOUNT_NOT_FOUND = "Account '%s' not found."; + + private final Accounts accounts; + + @Override + @Transactional(readOnly = true) + public Either findOne(UUID accountId) { + if (isNull(accountId)) { + return Either.left(ofNotFound(ACCOUNT_NOT_FOUND.formatted(accountId))); + } + + return accounts.findById(new AccountIdentifier(accountId)) + .>map(Either::right) + .orElseGet(() -> Either.left(ofNotFound(ACCOUNT_NOT_FOUND.formatted(accountId)))); + } +} diff --git a/server/src/main/java/io/myfinbox/account/adapter/web/AccountController.java b/server/src/main/java/io/myfinbox/account/adapter/web/AccountController.java index 840dbab..11a64b2 100644 --- a/server/src/main/java/io/myfinbox/account/adapter/web/AccountController.java +++ b/server/src/main/java/io/myfinbox/account/adapter/web/AccountController.java @@ -1,8 +1,10 @@ package io.myfinbox.account.adapter.web; +import io.myfinbox.account.application.AccountQuery; import io.myfinbox.account.application.CreateAccountUseCase; import io.myfinbox.account.application.CreateAccountUseCase.CreateAccountCommand; -import io.myfinbox.rest.AccountCreateResource; +import io.myfinbox.account.domain.Account; +import io.myfinbox.rest.AccountResource; import io.myfinbox.shared.ApiFailureHandler; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -10,6 +12,7 @@ import java.util.Currency; import java.util.Locale; +import java.util.UUID; import static java.util.Objects.isNull; import static org.springframework.http.HttpHeaders.ACCEPT_LANGUAGE; @@ -25,11 +28,12 @@ final class AccountController implements AccountsApi { static final Locale defaultLocale = Locale.of("en", "MD"); private final CreateAccountUseCase createAccountUseCase; + private final AccountQuery accountQuery; private final ApiFailureHandler apiFailureHandler; @PostMapping(consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) public ResponseEntity create(@RequestHeader(name = ACCEPT_LANGUAGE, required = false) Locale locale, - @RequestBody AccountCreateResource resource) { + @RequestBody AccountResource resource) { var command = CreateAccountCommand.builder() .firstName(resource.getFirstName()) .lastName(resource.getLastName()) @@ -46,6 +50,12 @@ public ResponseEntity create(@RequestHeader(name = ACCEPT_LANGUAGE, required )); } + @GetMapping(path = "/{accountId}", produces = APPLICATION_JSON_VALUE) + public ResponseEntity one(@PathVariable UUID accountId) { + return accountQuery.findOne(accountId) + .fold(apiFailureHandler::handle, account -> ResponseEntity.ok(toResource(account))); + } + private Locale resolve(Locale locale) { try { if (isNull(Currency.getInstance(locale).getCurrencyCode())) { @@ -57,4 +67,15 @@ private Locale resolve(Locale locale) { return locale; } + + private AccountResource toResource(Account account) { + return new AccountResource() + .accountId(account.getId().id()) + .creationTimestamp(account.getCreationTimestamp().toString()) + .firstName(account.getAccountDetails().firstName()) + .lastName(account.getAccountDetails().lastName()) + .emailAddress(account.getEmailAddress().value()) + .zoneId(account.getPreference().zoneId().getId()) + .currency(account.getPreference().currency().getCurrencyCode()); + } } diff --git a/server/src/main/java/io/myfinbox/account/adapter/web/AccountsApi.java b/server/src/main/java/io/myfinbox/account/adapter/web/AccountsApi.java index b7294ff..99f837c 100644 --- a/server/src/main/java/io/myfinbox/account/adapter/web/AccountsApi.java +++ b/server/src/main/java/io/myfinbox/account/adapter/web/AccountsApi.java @@ -1,6 +1,6 @@ package io.myfinbox.account.adapter.web; -import io.myfinbox.rest.AccountCreateResource; +import io.myfinbox.rest.AccountResource; import io.myfinbox.shared.ApiErrorResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -15,8 +15,10 @@ import java.net.URI; import java.util.Locale; +import java.util.UUID; import static io.swagger.v3.oas.annotations.enums.ParameterIn.HEADER; +import static io.swagger.v3.oas.annotations.enums.ParameterIn.PATH; import static org.springframework.http.HttpHeaders.LOCATION; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; @@ -30,7 +32,7 @@ public interface AccountsApi { @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "Successful Operation", headers = @Header(name = LOCATION, description = "Created account URI location", schema = @Schema(implementation = URI.class)), - content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = AccountCreateResource.class))), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = AccountResource.class))), @ApiResponse(responseCode = "400", description = "Malformed or Type Mismatch Failure", content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ApiErrorResponse.class))), @ApiResponse(responseCode = "409", description = "Email Address already exists", @@ -41,6 +43,21 @@ public interface AccountsApi { content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ApiErrorResponse.class))) }) ResponseEntity create(@Parameter(in = HEADER) Locale locale, - @RequestBody(description = "AccountResource to be created", required = true) AccountCreateResource resource); + @RequestBody(description = "AccountResource to be created", required = true) AccountResource resource); + + @Operation(summary = "Get one account in the MyFinBox", description = "Get one account in the MyFinBox", + security = {@SecurityRequirement(name = "openId")}, + tags = {TAGS}) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Get one existing account", + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = AccountResource.class))), + @ApiResponse(responseCode = "400", description = "Malformed or Type Mismatch Failure", + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ApiErrorResponse.class))), + @ApiResponse(responseCode = "404", description = "Account not found", + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ApiErrorResponse.class))), + @ApiResponse(responseCode = "500", description = "Internal Server Error", + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ApiErrorResponse.class))) + }) + ResponseEntity one(@Parameter(in = PATH, description = "Account ID to be found") UUID accountId); } diff --git a/server/src/main/java/io/myfinbox/account/application/AccountQuery.java b/server/src/main/java/io/myfinbox/account/application/AccountQuery.java new file mode 100644 index 0000000..094c1ec --- /dev/null +++ b/server/src/main/java/io/myfinbox/account/application/AccountQuery.java @@ -0,0 +1,21 @@ +package io.myfinbox.account.application; + +import io.myfinbox.account.domain.Account; +import io.myfinbox.shared.Failure; +import io.vavr.control.Either; + +import java.util.UUID; + +/** + * Interface for querying account information. + */ +public interface AccountQuery { + + /** + * Finds an account by its unique identifier. + * + * @param accountId the unique identifier of the account to find + * @return an {@link Either} instance containing either a {@link Failure} or the {@link Account} found + */ + Either findOne(UUID accountId); +} diff --git a/server/src/main/java/io/myfinbox/account/application/CreateAccountService.java b/server/src/main/java/io/myfinbox/account/application/CreateAccountService.java index db56026..58b1f51 100644 --- a/server/src/main/java/io/myfinbox/account/application/CreateAccountService.java +++ b/server/src/main/java/io/myfinbox/account/application/CreateAccountService.java @@ -100,7 +100,7 @@ private Validation validateEmailAddress(String emailAddr .build()); } - if (Account.MAX_LENGTH < emailAddress.length()) { + if (EmailAddress.MAX_LENGTH < emailAddress.length()) { return Invalid(FieldViolation.builder() .field(FIELD_EMAIL_ADDRESS) .message("Email address length cannot exceed '%d' characters.".formatted(Account.MAX_LENGTH)) @@ -108,7 +108,7 @@ private Validation validateEmailAddress(String emailAddr .build()); } - if (!Pattern.compile(Account.patternRFC5322).matcher(emailAddress).matches()) { + if (!Pattern.compile(EmailAddress.patternRFC5322).matcher(emailAddress).matches()) { return Invalid(FieldViolation.builder() .field(FIELD_EMAIL_ADDRESS) .message("Email address must follow RFC 5322 standard.") diff --git a/server/src/main/java/io/myfinbox/account/domain/Account.java b/server/src/main/java/io/myfinbox/account/domain/Account.java index 8d71bcd..ae4f919 100644 --- a/server/src/main/java/io/myfinbox/account/domain/Account.java +++ b/server/src/main/java/io/myfinbox/account/domain/Account.java @@ -8,7 +8,6 @@ import java.io.Serializable; import java.time.Instant; import java.util.UUID; -import java.util.regex.Pattern; import static io.myfinbox.shared.Guards.notNull; import static lombok.AccessLevel.PRIVATE; @@ -23,14 +22,12 @@ public class Account extends AbstractAggregateRoot { public static final int MAX_LENGTH = 255; - public static final String patternRFC5322 = "^[\\w!#$%&'*+/=?`{|}~^-]+(?:\\.[\\w!#$%&'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$"; - static final Pattern pattern = Pattern.compile(patternRFC5322); - @EmbeddedId private final AccountIdentifier id; - private final Instant creationDate; + private final Instant creationTimestamp; @Embedded + @AttributeOverride(name = "value", column = @Column(name = "email_address")) private EmailAddress emailAddress; @Embedded @@ -48,11 +45,11 @@ public Account(AccountDetails accountDetails, this.preference = notNull(preference, "preference cannot be null"); this.id = new AccountIdentifier(UUID.randomUUID()); - this.creationDate = Instant.now(); + this.creationTimestamp = Instant.now(); registerEvent(AccountCreated.builder() .accountId(this.id.id()) - .emailAddress(this.emailAddress.emailAddress()) + .emailAddress(this.emailAddress.value()) .firstName(this.accountDetails.firstName()) .lastName(this.accountDetails.lastName()) .currency(this.preference.currency()) diff --git a/server/src/main/java/io/myfinbox/account/domain/EmailAddress.java b/server/src/main/java/io/myfinbox/account/domain/EmailAddress.java index 1f944c7..e47e6fc 100644 --- a/server/src/main/java/io/myfinbox/account/domain/EmailAddress.java +++ b/server/src/main/java/io/myfinbox/account/domain/EmailAddress.java @@ -8,20 +8,20 @@ import static io.myfinbox.shared.Guards.*; @Embeddable -public record EmailAddress(String emailAddress) implements Serializable { +public record EmailAddress(String value) implements Serializable { - static final String patternRFC5322 = "^[\\w!#$%&'*+/=?`{|}~^-]+(?:\\.[\\w!#$%&'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$"; + public static final String patternRFC5322 = "^[\\w!#$%&'*+/=?`{|}~^-]+(?:\\.[\\w!#$%&'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$"; static final Pattern pattern = Pattern.compile(patternRFC5322); - static final int MAX_LENGTH = 255; + public static final int MAX_LENGTH = 255; public EmailAddress { - notBlank(emailAddress, "emailAddress cannot be blank"); - doesNotOverflow(emailAddress.trim(), MAX_LENGTH, "emailAddress max length must be '%d'".formatted(MAX_LENGTH)); - matches(emailAddress, pattern, "emailAddress must match '%s'".formatted(patternRFC5322)); + notBlank(value, "value cannot be blank"); + doesNotOverflow(value.trim(), MAX_LENGTH, "value max length must be '%d'".formatted(MAX_LENGTH)); + matches(value, pattern, "value must match '%s'".formatted(patternRFC5322)); } @Override public String toString() { - return emailAddress; + return value; } } diff --git a/server/src/main/resources/db/migration/V1_01__accounts_schema.sql b/server/src/main/resources/db/migration/V1_01__accounts_schema.sql index a46de06..7e25043 100644 --- a/server/src/main/resources/db/migration/V1_01__accounts_schema.sql +++ b/server/src/main/resources/db/migration/V1_01__accounts_schema.sql @@ -1,9 +1,9 @@ CREATE TABLE IF NOT EXISTS accounts ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - creation_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - email_address VARCHAR(256) NOT NULL UNIQUE, - first_name VARCHAR(255), - last_name VARCHAR(255) + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + creation_timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + email_address VARCHAR(256) NOT NULL UNIQUE, + first_name VARCHAR(255), + last_name VARCHAR(255) ) ; diff --git a/server/src/main/resources/openapi.yml b/server/src/main/resources/openapi.yml index 6080ea3..16fc5ff 100644 --- a/server/src/main/resources/openapi.yml +++ b/server/src/main/resources/openapi.yml @@ -21,7 +21,7 @@ paths: components: schemas: # Request Objects - AccountCreateResource: + AccountResource: type: object properties: accountId: @@ -37,6 +37,11 @@ components: type: string example: Doe description: The last name of the account holder. + creationTimestamp: + type: string + readOnly: true + example: 2024-03-23T10:00:04.224870Z + description: The timestamp when the expense was created (read-only). zoneId: type: string example: Europe/Paris diff --git a/server/src/test/groovy/io/myfinbox/account/DataSamples.groovy b/server/src/test/groovy/io/myfinbox/account/DataSamples.groovy index 4f25b09..71e4834 100644 --- a/server/src/test/groovy/io/myfinbox/account/DataSamples.groovy +++ b/server/src/test/groovy/io/myfinbox/account/DataSamples.groovy @@ -11,7 +11,17 @@ class DataSamples { .findAndAddModules() .build() - static CREATE_ACCOUNT_RESOURCE = [ + static ACCOUNT_RESOURCE = [ + accountId : "e2709aa2-7907-4f78-98b6-0f36a0c1b5ca", + firstName : "Jon", + lastName : "Snow", + emailAddress : "jonsnow@gmail.com", + zoneId : "Europe/Chisinau", + currency : "MDL", + creationTimestamp: "2024-03-23T10:00:04.224870Z" + ] + + static ACCOUNT_CREATE_COMMAND = [ firstName : "Jon", lastName : "Snow", emailAddress: "jonsnow@gmail.com", @@ -29,7 +39,7 @@ class DataSamples { ] static newSampleCreateAccountCommand(map = [:]) { - MAPPER.readValue(JsonOutput.toJson(CREATE_ACCOUNT_RESOURCE + map) as String, CreateAccountCommand.class) + MAPPER.readValue(JsonOutput.toJson(ACCOUNT_CREATE_COMMAND + map) as String, CreateAccountCommand.class) } static newSampleAccountEvent(map = [:]) { diff --git a/server/src/test/groovy/io/myfinbox/account/adapter/web/AccountControllerSpec.groovy b/server/src/test/groovy/io/myfinbox/account/adapter/web/AccountControllerSpec.groovy index 252b9f6..21221dc 100644 --- a/server/src/test/groovy/io/myfinbox/account/adapter/web/AccountControllerSpec.groovy +++ b/server/src/test/groovy/io/myfinbox/account/adapter/web/AccountControllerSpec.groovy @@ -11,20 +11,22 @@ import org.springframework.boot.test.web.client.TestRestTemplate import org.springframework.core.io.ClassPathResource import org.springframework.http.HttpEntity import org.springframework.http.HttpHeaders +import org.springframework.http.HttpMethod import org.springframework.jdbc.core.JdbcTemplate import org.springframework.modulith.test.ApplicationModuleTest import org.springframework.modulith.test.PublishedEvents import org.springframework.test.context.TestPropertySource +import org.springframework.test.context.jdbc.Sql import org.springframework.test.jdbc.JdbcTestUtils +import org.springframework.web.util.UriComponentsBuilder import spock.lang.Specification import spock.lang.Tag -import static io.myfinbox.account.DataSamples.CREATE_ACCOUNT_RESOURCE +import static io.myfinbox.account.DataSamples.ACCOUNT_RESOURCE import static io.myfinbox.account.DataSamples.newSampleAccountEvent import static org.skyscreamer.jsonassert.JSONCompareMode.LENIENT import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT -import static org.springframework.http.HttpStatus.CREATED -import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY +import static org.springframework.http.HttpStatus.* import static org.springframework.http.MediaType.APPLICATION_JSON @Tag("integration") @@ -48,7 +50,7 @@ class AccountControllerSpec extends Specification { def "should create an new account with default locale"() { given: 'user wants to create an account' - var request = JsonOutput.toJson(CREATE_ACCOUNT_RESOURCE) + var request = JsonOutput.toJson(ACCOUNT_RESOURCE) when: 'account is created' var response = postNewAccount(request) @@ -82,10 +84,52 @@ class AccountControllerSpec extends Specification { JSONAssert.assertEquals(expectedCreationFailure(), response.getBody(), LENIENT) } + @Sql('/account/web/create-account.sql') + def "should gen one account when exits"() { + given: 'an exiting account' + var accountId = UUID.fromString("e2709aa2-7907-4f78-98b6-0f36a0c1b5ca") + + when: 'account is resource is received' + var response = getOneAccount(accountId) + + then: 'response has status code OK' + assert response.getStatusCode() == OK + + and: 'response body contains exiting account' + JSONAssert.assertEquals(JsonOutput.toJson(ACCOUNT_RESOURCE), response.getBody(), LENIENT) + } + + def "should get not found when account doesn't exit"() { + given: 'a non exiting account' + var accountId = UUID.fromString("e2709aa2-7907-4f78-98b6-0f36a0c1b5ca") + + when: 'account is not found' + var response = getOneAccount(accountId) + + then: 'response has status code NOT_FOUND' + assert response.getStatusCode() == NOT_FOUND + + and: 'response body contains not found failure' + JSONAssert.assertEquals(expectAccountNotFoundFailure(accountId), response.getBody(), LENIENT) + } + def postNewAccount(String req) { restTemplate.postForEntity('/v1/accounts', entityRequest(req), String.class) } + def getOneAccount(UUID accountId) { + def uri = UriComponentsBuilder.fromUriString("${restTemplate.getRootUri()}/v1/accounts/${accountId}") + .build() + .toUri() + + restTemplate.exchange( + uri, + HttpMethod.GET, + null, + String.class + ) + } + def entityRequest(String req) { var headers = new HttpHeaders() headers.setContentType(APPLICATION_JSON) @@ -105,6 +149,14 @@ class AccountControllerSpec extends Specification { } def accountResource(UUID id) { - JsonOutput.toJson(CREATE_ACCOUNT_RESOURCE + [accountId: id.toString()]) + JsonOutput.toJson(ACCOUNT_RESOURCE + [accountId: id.toString()]) + } + + def expectAccountNotFoundFailure(UUID accountId) { + JsonOutput.toJson([ + status : 404, + errorCode: 'NOT_FOUND', + message : "Account '${accountId}' not found." + ]) } } diff --git a/server/src/test/groovy/io/myfinbox/account/application/CreateAccountServiceSpec.groovy b/server/src/test/groovy/io/myfinbox/account/application/CreateAccountServiceSpec.groovy index 947b914..56a4ae5 100644 --- a/server/src/test/groovy/io/myfinbox/account/application/CreateAccountServiceSpec.groovy +++ b/server/src/test/groovy/io/myfinbox/account/application/CreateAccountServiceSpec.groovy @@ -9,7 +9,7 @@ import java.time.Instant import java.time.ZoneId import static io.myfinbox.account.DataSamples.newSampleCreateAccountCommand -import static io.myfinbox.account.application.CreateAccountService.* +import static io.myfinbox.account.application.CreateAccountService.ERROR_MESSAGE import static org.apache.commons.lang3.RandomStringUtils.random @Tag("unit") @@ -107,7 +107,7 @@ class CreateAccountServiceSpec extends Specification { "a\"b(c)d,e:f;gi[j\\k]l@example.com" | RFC_EMAIL_FIELD_ERROR "this is\"not\\allowed@example.com" | RFC_EMAIL_FIELD_ERROR "this\\ still\\\"not\\\\allowed@example.com" | RFC_EMAIL_FIELD_ERROR - "%s@gmail.com".formatted(randomString(256)) | "Email address length cannot exceed '${Account.MAX_LENGTH}' characters." + "%s@gmail.com".formatted(randomString(256)) | "Email address length cannot exceed '${EmailAddress.MAX_LENGTH}' characters." } def "should fail account creation when currency is invalid with message: '#errorMessage'"() { @@ -177,8 +177,8 @@ class CreateAccountServiceSpec extends Specification { and: 'ensure account is build as expected' assert either.get().getId().id() != null assert either.get().getId().id() instanceof UUID - assert either.get().getCreationDate() != null - assert either.get().getCreationDate() instanceof Instant + assert either.get().getCreationTimestamp() != null + assert either.get().getCreationTimestamp() instanceof Instant assert either.get().getAccountDetails() == new AccountDetails("Jon", "Snow") assert either.get().getEmailAddress() == new EmailAddress("jonsnow@gmail.com") assert either.get().getPreference() == new Preference(Currency.getInstance("MDL"), ZoneId.of("Europe/Chisinau")) diff --git a/server/src/test/resources/account/web/create-account.sql b/server/src/test/resources/account/web/create-account.sql new file mode 100644 index 0000000..986936c --- /dev/null +++ b/server/src/test/resources/account/web/create-account.sql @@ -0,0 +1,3 @@ +INSERT INTO server.accounts(id, creation_timestamp, email_address, first_name, last_name, zone_id, currency) +VALUES ('e2709aa2-7907-4f78-98b6-0f36a0c1b5ca', '2024-03-23T10:00:04.224870Z', 'jonsnow@gmail.com', 'Jon', 'Snow', + 'Europe/Chisinau', 'MDL');