From 750835e39e06ab23ddd5d444fe039244cfddcc98 Mon Sep 17 00:00:00 2001 From: Paulo Gomes da Cruz Junior Date: Wed, 2 Oct 2024 15:40:25 -0700 Subject: [PATCH] chore: small code cleanup --- .../client/ClientCodesController.java | 30 +- .../app/service/client/ClientCodeService.java | 159 +++++++ .../client/ClientCountryProvinceService.java | 155 ++++++ .../service/client/ClientDistrictService.java | 94 ++++ .../gov/app/service/client/ClientService.java | 449 ++++-------------- .../client/ClientSubmissionService.java | 55 +-- .../ClientCodeServiceIntegrationTest.java | 54 +++ ...CountryProvinceServiceIntegrationTest.java | 31 ++ .../ClientDistrictServiceIntegrationTest.java | 33 ++ .../client/ClientServiceIntegrationTest.java | 117 ----- 10 files changed, 653 insertions(+), 524 deletions(-) create mode 100644 backend/src/main/java/ca/bc/gov/app/service/client/ClientCodeService.java create mode 100644 backend/src/main/java/ca/bc/gov/app/service/client/ClientCountryProvinceService.java create mode 100644 backend/src/main/java/ca/bc/gov/app/service/client/ClientDistrictService.java create mode 100644 backend/src/test/java/ca/bc/gov/app/service/client/ClientCodeServiceIntegrationTest.java create mode 100644 backend/src/test/java/ca/bc/gov/app/service/client/ClientCountryProvinceServiceIntegrationTest.java create mode 100644 backend/src/test/java/ca/bc/gov/app/service/client/ClientDistrictServiceIntegrationTest.java delete mode 100644 backend/src/test/java/ca/bc/gov/app/service/client/ClientServiceIntegrationTest.java diff --git a/backend/src/main/java/ca/bc/gov/app/controller/client/ClientCodesController.java b/backend/src/main/java/ca/bc/gov/app/controller/client/ClientCodesController.java index 3a90411328..bcd64e8113 100644 --- a/backend/src/main/java/ca/bc/gov/app/controller/client/ClientCodesController.java +++ b/backend/src/main/java/ca/bc/gov/app/controller/client/ClientCodesController.java @@ -3,9 +3,13 @@ import ca.bc.gov.app.dto.client.CodeNameDto; import ca.bc.gov.app.dto.client.DistrictDto; import ca.bc.gov.app.dto.client.IdentificationTypeDto; +import ca.bc.gov.app.service.client.ClientCodeService; +import ca.bc.gov.app.service.client.ClientCountryProvinceService; +import ca.bc.gov.app.service.client.ClientDistrictService; import ca.bc.gov.app.service.client.ClientService; import io.micrometer.observation.annotation.Observed; import java.time.LocalDate; +import java.time.LocalDateTime; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.MediaType; @@ -25,11 +29,14 @@ public class ClientCodesController { private final ClientService clientService; + private final ClientDistrictService clientDistrictService; + private final ClientCountryProvinceService clientCountryProvinceService; + private final ClientCodeService clientCodeService; @GetMapping("/client-types") public Flux findActiveClientTypeCodes() { log.info("Requesting a list of active client type codes from the client service."); - return clientService + return clientCodeService .findActiveClientTypeCodes(LocalDate.now()); } @@ -37,7 +44,7 @@ public Flux findActiveClientTypeCodes() { public Mono getClientTypeByCode( @PathVariable String code) { log.info("Requesting a client type by code {} from the client service.", code); - return clientService.getClientTypeByCode(code); + return clientCodeService.getClientTypeByCode(code); } @GetMapping("/contact-types") @@ -48,7 +55,7 @@ public Flux listClientContactTypeCodes( Integer size ) { log.info("Requesting a list of active client contact type codes from the client service."); - return clientService + return clientCodeService .listClientContactTypeCodes(LocalDate.now(), page, size); } @@ -59,13 +66,13 @@ public Flux getActiveDistrictCodes( @RequestParam(value = "size", required = false, defaultValue = "10") Integer size) { log.info("Requesting a list of districts from the client service."); - return clientService.getActiveDistrictCodes(page, size); + return clientDistrictService.getActiveDistrictCodes(page, size, LocalDate.now()); } @GetMapping("/districts/{districtCode}") public Mono getDistrictByCode(@PathVariable String districtCode) { log.info("Requesting a district by code {} from the client service.", districtCode); - return clientService.getDistrictByCode(districtCode); + return clientDistrictService.getDistrictByCode(districtCode); } @GetMapping("/countries") @@ -75,14 +82,14 @@ public Flux countries( @RequestParam(value = "size", required = false, defaultValue = "10") Integer size) { log.info("Requesting a list of countries from the client service."); - return clientService.listCountries(page, size); + return clientCountryProvinceService.listCountries(page, size, LocalDate.now()); } @GetMapping("/countries/{countryCode}") public Mono getCountryByCode( @PathVariable String countryCode) { log.info("Requesting a country by code {} from the client service.", countryCode); - return clientService.getCountryByCode(countryCode); + return clientCountryProvinceService.getCountryByCode(countryCode); } @GetMapping("/countries/{countryCode}/provinces") @@ -94,7 +101,7 @@ public Flux listProvinces( Integer size) { log.info("Requesting a list of provinces by country code {} from the client service.", countryCode); - return clientService + return clientCountryProvinceService .listProvinces(countryCode, page, size); } @@ -105,20 +112,21 @@ public Mono getProvinceByCountryAndProvinceCode( log.info("Requesting a province by country and province code {} {} from the client service.", countryCode, provinceCode); - return clientService.getProvinceByCountryAndProvinceCode(countryCode, provinceCode); + return clientCountryProvinceService.getProvinceByCountryAndProvinceCode(countryCode, provinceCode); } @GetMapping("/identification-types") public Flux identificationTypes() { log.info("Requesting a list of identification type codes."); - return clientService.getAllActiveIdentificationTypes(LocalDate.now()); + return clientCodeService.getAllActiveIdentificationTypes(LocalDate.now()); } + //TODO: This endpoint needs to be updated to properly reflect what code is returning @GetMapping("{idCode}") public Mono getIdentificationTypeByCode( @PathVariable String idCode) { log.info("Requesting an identification type by code {}.", idCode); - return clientService.getIdentificationTypeByCode(idCode); + return clientCodeService.getIdentificationTypeByCode(idCode); } } diff --git a/backend/src/main/java/ca/bc/gov/app/service/client/ClientCodeService.java b/backend/src/main/java/ca/bc/gov/app/service/client/ClientCodeService.java new file mode 100644 index 0000000000..442d86cebf --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/service/client/ClientCodeService.java @@ -0,0 +1,159 @@ +package ca.bc.gov.app.service.client; + +import static org.springframework.data.relational.core.query.Query.query; + +import ca.bc.gov.app.dto.client.CodeNameDto; +import ca.bc.gov.app.dto.client.IdentificationTypeDto; +import ca.bc.gov.app.entity.client.ClientTypeCodeEntity; +import ca.bc.gov.app.predicates.QueryPredicates; +import ca.bc.gov.app.repository.client.ClientTypeCodeRepository; +import ca.bc.gov.app.repository.client.ContactTypeCodeRepository; +import ca.bc.gov.app.repository.client.IdentificationTypeCodeRepository; +import io.micrometer.observation.annotation.Observed; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.r2dbc.core.R2dbcEntityTemplate; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Service +@RequiredArgsConstructor +@Slf4j +@Observed +public class ClientCodeService { + + private final ClientTypeCodeRepository clientTypeCodeRepository; + private final ContactTypeCodeRepository contactTypeCodeRepository; + private final IdentificationTypeCodeRepository identificationTypeCodeRepository; + private final R2dbcEntityTemplate template; + + /** + *

Find Active Client Type Codes

+ *

List client type code based on it's effective and expiration date. + * The rule used for it is the expiration date must not be set or should be bigger than provided + * date and the effective date bust be before or equal to the provided date.

+ *

The order is by description.

+ * + * @param targetDate The date to be used as reference. + * @return A list of {@link CodeNameDto} + */ + public Flux findActiveClientTypeCodes(LocalDate targetDate) { + log.info("Loading active client type codes for {}", targetDate); + return + clientTypeCodeRepository + .findActiveAt(targetDate) + .map(entity -> new CodeNameDto( + entity.getCode(), + entity.getDescription() + ) + ); + } + + + /** + * Retrieves a client type by its unique code. This method queries the clientTypeCodeRepository to + * find a client type entity with the specified code. If a matching entity is found, it is + * converted to a {@code CodeNameDto} object containing the code and description, and wrapped in a + * Mono. If no matching entity is found, the Mono will complete without emitting any items. + * + * @param code The unique code of the client type to retrieve. + * @return A Mono emitting a {@code CodeNameDto} if a matching client type is found, or an empty + * result if no match is found. + * @see CodeNameDto + */ + public Mono getClientTypeByCode(String code) { + log.info("Loading client type for {}", code); + return clientTypeCodeRepository + .findByCode(code) + .map(entity -> new CodeNameDto(entity.getCode(), + entity.getDescription())); + } + + /** + * Retrieves a map of client types that are currently active. + * This method queries the database for client type entities that are effective as of now and not expired. + * The results are collected into a list and then converted into a map where the keys are the client type codes + * and the values are the descriptions. + * + * @return A Mono emitting a map with client type codes as keys and their descriptions as values. + */ +public Mono> getClientTypes() { + return template + .select( + query( + QueryPredicates.isBefore(LocalDateTime.now(), "effectiveAt") + .and( + QueryPredicates.isAfter(LocalDateTime.now(), "expiredAt") + .or(QueryPredicates.isNull("expiredAt")) + ) + ), + ClientTypeCodeEntity.class + ) + .collectList() + // Convert the list into a map using code as the key and description as value + .map(clientTypeCodeEntities -> + clientTypeCodeEntities + .stream() + .collect(Collectors.toMap(ClientTypeCodeEntity::getCode, + ClientTypeCodeEntity::getDescription)) + ); +} + + + /** + *

List contact types

+ * List contact type codes by page with a defined size. + * + * @param page The page number, it is a 0-index base. + * @param size The amount of entries per page. + * @return A list of {@link CodeNameDto} entries. + */ + public Flux listClientContactTypeCodes(LocalDate activeDate, int page, int size) { + log.info("Loading contact types for page {} with size {}", page, size); + return contactTypeCodeRepository + .findActiveAt(activeDate, PageRequest.of(page, size)) + .map(entity -> new CodeNameDto( + entity.getContactTypeCode(), + entity.getDescription())); + } + + /** + * Retrieves all active identification types as of the specified target date. + * + * @param targetDate the date to check for active identification types. + * @return a Flux stream of IdentificationTypeDto containing the code, description, and country + * code of each active identification type. + */ + public Flux getAllActiveIdentificationTypes(LocalDate targetDate) { + log.info("Loading active identification type codes by {}", targetDate); + return identificationTypeCodeRepository + .findActiveAt(targetDate) + .map(entity -> new IdentificationTypeDto( + entity.getCode(), + entity.getDescription(), + entity.getCountryCode())); + } + + /** + * Retrieves an identification type by its code. + * + * @param idCode the code of the identification type to retrieve. + * @return a Mono containing a CodeNameDto with the code and description of the identification + * type, or an empty Mono if not found. + */ + public Mono getIdentificationTypeByCode(String idCode) { + log.info("Loading identification type by {}", idCode); + return identificationTypeCodeRepository + .findByCode(idCode) + .map(entity -> new CodeNameDto(entity.getCode(), + entity.getDescription())); + } + + +} diff --git a/backend/src/main/java/ca/bc/gov/app/service/client/ClientCountryProvinceService.java b/backend/src/main/java/ca/bc/gov/app/service/client/ClientCountryProvinceService.java new file mode 100644 index 0000000000..421bb18232 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/service/client/ClientCountryProvinceService.java @@ -0,0 +1,155 @@ +package ca.bc.gov.app.service.client; + +import ca.bc.gov.app.dto.client.ClientValueTextDto; +import ca.bc.gov.app.dto.client.CodeNameDto; +import ca.bc.gov.app.repository.client.CountryCodeRepository; +import ca.bc.gov.app.repository.client.ProvinceCodeRepository; +import io.micrometer.observation.annotation.Observed; +import java.time.LocalDate; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Service +@RequiredArgsConstructor +@Slf4j +@Observed +public class ClientCountryProvinceService { + + private final CountryCodeRepository countryCodeRepository; + private final ProvinceCodeRepository provinceCodeRepository; + + /** + *

List countries

+ *

List countries by page with a defined size. + * The list will be sorted by order and country name.

List countries by page with a defined + * size. The list will be sorted by order and country name. + * + * @param page The page number, it is a 0-index base. + * @param size The amount of entries per page. + * @return A list of {@link CodeNameDto} entries. + */ + public Flux listCountries( + int page, + int size, + LocalDate currentDate + ) { + log.info("Loading countries for page {} with size {}", page, size); + return countryCodeRepository + .findAllBy(PageRequest.of(page, size, Sort.by("order", "description"))) + .filter(entity -> (currentDate.isBefore(entity.getExpiredAt()) + || currentDate.isEqual(entity.getExpiredAt())) + && + (currentDate.isAfter(entity.getEffectiveAt()) + || currentDate.isEqual(entity.getEffectiveAt()))) + .map(entity -> new CodeNameDto(entity.getCountryCode(), entity.getDescription())); + } + + /** + *

List Provinces

+ *

List provinces by country (which include states) by page with a defined size. + * The list will be sorted by province name.

+ * + * @param countryCode The code of the country to list provinces from. + * @param page The page number, it is a 0-index base. + * @param size The amount of entries per page. + * @return A list of {@link CodeNameDto} entries. + */ + public Flux listProvinces(String countryCode, int page, int size) { + log.info("Loading provinces for {} with page {} and size {}", countryCode, page, size); + return provinceCodeRepository + .findByCountryCode(countryCode, PageRequest.of(page, size, Sort.by("description"))) + .map(entity -> new CodeNameDto(entity.getProvinceCode(), entity.getDescription())); + } + + /** + * Retrieves country information by its country code. This method queries the + * {@code countryCodeRepository} to find a country entity with the specified country code. If a + * matching entity is found, it is mapped to a {@code CodeNameDto} object, which encapsulates the + * country code and description. The resulting data is wrapped in a Mono, which represents the + * asynchronous result of the operation. + * + * @param countryCode The code of the country to retrieve information for. + * @return A Mono that emits the {@code CodeNameDto} object if a matching country is found, or an + * empty result if no match is found. + * @see CodeNameDto + */ + public Mono getCountryByCode(String countryCode) { + log.info("Loading country for {}", countryCode); + return countryCodeRepository + .findByCountryCode(countryCode) + .map(entity -> new CodeNameDto(entity.getCountryCode(), + entity.getDescription())); + } + + /** + * Loads country information based on the provided country description. + * This method queries the {@code countryCodeRepository} to find a country entity with the specified description. + * If a matching entity is found, it is mapped to a {@code ClientValueTextDto} object, which encapsulates the country code and description. + * If no matching entity is found, a default {@code ClientValueTextDto} object with an empty country code and the provided description is returned. + * + * @param countryCode The description of the country to retrieve information for. + * @return A Mono that emits the {@code ClientValueTextDto} object if a matching country is found, or a default object if no match is found. + * @see ClientValueTextDto + */ +public Mono loadCountry(String countryCode) { + return + countryCodeRepository + .findByDescription(countryCode) + .map( + entity -> new ClientValueTextDto(entity.getCountryCode(), entity.getDescription()) + ) + .defaultIfEmpty(new ClientValueTextDto(StringUtils.EMPTY, countryCode)); +} + + /** + * Retrieves province information by its country code and province code. This method queries the + * {@code provinceCodeRepository} to find a province entity with the specified country code and + * province code. If a matching entity is found, it is mapped to a {@code CodeNameDto} object, + * which encapsulates the province code and description. The resulting data is wrapped in a Mono, + * which represents the asynchronous result of the operation. + * + * @param countryCode The code of the country to retrieve the province from. + * @param provinceCode The code of the province to retrieve information for. + * @return A Mono that emits the {@code CodeNameDto} object if a matching province is found, or an + * empty result if no match is found. + * @see CodeNameDto + */ + public Mono getProvinceByCountryAndProvinceCode( + String countryCode, + String provinceCode) { + log.info("Loading province by country and province code {} {}", countryCode, provinceCode); + return provinceCodeRepository + .findByCountryCodeAndProvinceCode(countryCode, provinceCode) + .map(entity -> new CodeNameDto(entity.getProvinceCode(), + entity.getDescription())); + } + + /** + * Loads province information based on the provided country code and province code. + * This method queries the {@code provinceCodeRepository} to find a province entity with the specified country code and province code. + * If a matching entity is found, it is mapped to a {@code ClientValueTextDto} object, which encapsulates the province code and description. + * If no matching entity is found, a default {@code ClientValueTextDto} object with the provided province code and description is returned. + * + * @param countryCode The code of the country to retrieve the province from. + * @param provinceCode The code of the province to retrieve information for. + * @return A Mono that emits the {@code ClientValueTextDto} object if a matching province is found, or a default object if no match is found. + * @see ClientValueTextDto + */ +public Mono loadProvince(String countryCode, String provinceCode) { + return + provinceCodeRepository + .findByCountryCodeAndProvinceCode(countryCode, provinceCode) + .map( + entity -> new ClientValueTextDto(entity.getProvinceCode(), entity.getDescription()) + ) + .defaultIfEmpty(new ClientValueTextDto(provinceCode, provinceCode)); +} + + +} diff --git a/backend/src/main/java/ca/bc/gov/app/service/client/ClientDistrictService.java b/backend/src/main/java/ca/bc/gov/app/service/client/ClientDistrictService.java new file mode 100644 index 0000000000..dfaea02cd9 --- /dev/null +++ b/backend/src/main/java/ca/bc/gov/app/service/client/ClientDistrictService.java @@ -0,0 +1,94 @@ +package ca.bc.gov.app.service.client; + +import ca.bc.gov.app.dto.client.CodeNameDto; +import ca.bc.gov.app.dto.client.DistrictDto; +import ca.bc.gov.app.repository.client.DistrictCodeRepository; +import io.micrometer.observation.annotation.Observed; +import java.time.LocalDate; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@Service +@RequiredArgsConstructor +@Slf4j +@Observed +public class ClientDistrictService { + + private final DistrictCodeRepository districtCodeRepository; + + /** + *

List natural resource districts

+ *

List natural resource districts by page with a defined size.

+ * List natural resource districts by page with a defined size. The list will be sorted by + * district name. + * + * @param page The page number, it is a 0-index base. + * @param size The amount of entries per page. + * @param currentDate The date to be used as reference. + * @return A list of {@link CodeNameDto} entries. + */ + public Flux getActiveDistrictCodes( + int page, + int size, + LocalDate currentDate + ) { + log.info("Loading natural resource districts for page {} with size {}", page, size); + return districtCodeRepository + .findAllBy(PageRequest.of(page, size, Sort.by("description"))) + .filter(entity -> (currentDate.isBefore(entity.getExpiredAt()) + || currentDate.isEqual(entity.getExpiredAt())) + && + (currentDate.isAfter(entity.getEffectiveAt()) + || currentDate.isEqual(entity.getEffectiveAt()))) + .map(entity -> new CodeNameDto(entity.getCode(), entity.getDescription())); + } + + + /** + * Retrieves natural resource district information by its district code. This method queries the + * {@code districtCodeRepository} to find a district entity with the specified district code. If a + * matching entity is found, it is mapped to a {@code DistrictDto} object, which encapsulates the + * district code, description and email. The resulting data is wrapped in a Mono, which represents + * the asynchronous result of the operation. + * + * @param districtCode The code of the district to retrieve information for. + * @return A Mono that emits the {@code DistrictDto} object if a matching district is found, or an + * empty result if no match is found. + * @see DistrictDto + */ + public Mono getDistrictByCode(String districtCode) { + log.info("Loading district for {}", districtCode); + return districtCodeRepository + .findByCode(districtCode) + .map(entity -> new DistrictDto( + entity.getCode(), + entity.getDescription(), + entity.getEmailAddress() + ) + ); + } + + /** + * Retrieves the full description of a natural resource district by its district code. + * This method queries the {@code districtCodeRepository} to find a district entity with the specified district code. + * If a matching entity is found, it constructs a string combining the district code and description. + * If no matching entity is found, an empty string is returned. + * + * @param districtCode The code of the district to retrieve the full description for. + * @return A Mono that emits the full description string if a matching district is found, or an empty string if no match is found. + */ +public Mono getDistrictFullDescByCode(String districtCode) { + return Mono.justOrEmpty(districtCode) + .flatMap(districtCodeRepository::findByCode) + .map(districtCodeEntity -> districtCodeEntity.getCode() + " - " + + districtCodeEntity.getDescription()) + .defaultIfEmpty(""); +} + + +} diff --git a/backend/src/main/java/ca/bc/gov/app/service/client/ClientService.java b/backend/src/main/java/ca/bc/gov/app/service/client/ClientService.java index c8cd00f010..0766b36644 100644 --- a/backend/src/main/java/ca/bc/gov/app/service/client/ClientService.java +++ b/backend/src/main/java/ca/bc/gov/app/service/client/ClientService.java @@ -11,10 +11,7 @@ import ca.bc.gov.app.dto.client.ClientContactDto; import ca.bc.gov.app.dto.client.ClientLookUpDto; import ca.bc.gov.app.dto.client.ClientValueTextDto; -import ca.bc.gov.app.dto.client.CodeNameDto; -import ca.bc.gov.app.dto.client.DistrictDto; import ca.bc.gov.app.dto.client.EmailRequestDto; -import ca.bc.gov.app.dto.client.IdentificationTypeDto; import ca.bc.gov.app.dto.client.LegalTypeEnum; import ca.bc.gov.app.dto.legacy.ForestClientDto; import ca.bc.gov.app.exception.ClientAlreadyExistException; @@ -23,17 +20,10 @@ import ca.bc.gov.app.exception.UnableToProcessRequestException; import ca.bc.gov.app.exception.UnsupportedClientTypeException; import ca.bc.gov.app.exception.UnsupportedLegalTypeException; -import ca.bc.gov.app.repository.client.ClientTypeCodeRepository; -import ca.bc.gov.app.repository.client.ContactTypeCodeRepository; -import ca.bc.gov.app.repository.client.CountryCodeRepository; -import ca.bc.gov.app.repository.client.DistrictCodeRepository; -import ca.bc.gov.app.repository.client.IdentificationTypeCodeRepository; -import ca.bc.gov.app.repository.client.ProvinceCodeRepository; import ca.bc.gov.app.service.bcregistry.BcRegistryService; import ca.bc.gov.app.service.ches.ChesService; import ca.bc.gov.app.util.ClientValidationUtils; import io.micrometer.observation.annotation.Observed; -import java.time.LocalDate; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -44,8 +34,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -56,157 +44,12 @@ @Observed public class ClientService { - private final ClientTypeCodeRepository clientTypeCodeRepository; - private final DistrictCodeRepository districtCodeRepository; - private final CountryCodeRepository countryCodeRepository; - private final ProvinceCodeRepository provinceCodeRepository; - private final ContactTypeCodeRepository contactTypeCodeRepository; - private final IdentificationTypeCodeRepository identificationTypeCodeRepository; + private final ClientCountryProvinceService countryProvinceService; private final BcRegistryService bcRegistryService; private final ChesService chesService; private final ClientLegacyService legacyService; private final Predicate isMultiAddressEnabled; - LocalDate currentDate = LocalDate.now(); - - /** - *

Find Active Client Type Codes

- *

List client type code based on it's effective and expiration date. - * The rule used for it is the expiration date must not be set or should be bigger than provided - * date and the effective date bust be before or equal to the provided date.

- *

The order is by description.

- * - * @param targetDate The date to be used as reference. - * @return A list of {@link CodeNameDto} - */ - public Flux findActiveClientTypeCodes(LocalDate targetDate) { - log.info("Loading active client type codes for {}", targetDate); - return - clientTypeCodeRepository - .findActiveAt(targetDate) - .map(entity -> new CodeNameDto( - entity.getCode(), - entity.getDescription() - ) - ); - } - - /** - *

List natural resource districts

- *

List natural resource districts by page with a defined size.

- * List natural resource districts by page with a defined size. The list will be sorted by - * district name. - * - * @param page The page number, it is a 0-index base. - * @param size The amount of entries per page. - * @return A list of {@link CodeNameDto} entries. - */ - public Flux getActiveDistrictCodes(int page, int size) { - log.info("Loading natural resource districts for page {} with size {}", page, size); - return districtCodeRepository - .findAllBy(PageRequest.of(page, size, Sort.by("description"))) - .filter(entity -> (currentDate.isBefore(entity.getExpiredAt()) - || currentDate.isEqual(entity.getExpiredAt())) - && - (currentDate.isAfter(entity.getEffectiveAt()) - || currentDate.isEqual(entity.getEffectiveAt()))) - .map(entity -> new CodeNameDto(entity.getCode(), entity.getDescription())); - } - - /** - *

List countries

- *

List countries by page with a defined size. - * The list will be sorted by order and country name.

List countries by page with a defined - * size. The list will be sorted by order and country name. - * - * @param page The page number, it is a 0-index base. - * @param size The amount of entries per page. - * @return A list of {@link CodeNameDto} entries. - */ - public Flux listCountries(int page, int size) { - log.info("Loading countries for page {} with size {}", page, size); - return countryCodeRepository - .findAllBy(PageRequest.of(page, size, Sort.by("order", "description"))) - .filter(entity -> (currentDate.isBefore(entity.getExpiredAt()) - || currentDate.isEqual(entity.getExpiredAt())) - && - (currentDate.isAfter(entity.getEffectiveAt()) - || currentDate.isEqual(entity.getEffectiveAt()))) - .map(entity -> new CodeNameDto(entity.getCountryCode(), entity.getDescription())); - } - - /** - * Retrieves country information by its country code. This method queries the - * {@code countryCodeRepository} to find a country entity with the specified country code. If a - * matching entity is found, it is mapped to a {@code CodeNameDto} object, which encapsulates the - * country code and description. The resulting data is wrapped in a Mono, which represents the - * asynchronous result of the operation. - * - * @param countryCode The code of the country to retrieve information for. - * @return A Mono that emits the {@code CodeNameDto} object if a matching country is found, or an - * empty result if no match is found. - * @see CodeNameDto - */ - public Mono getCountryByCode(String countryCode) { - log.info("Loading country for {}", countryCode); - return countryCodeRepository - .findByCountryCode(countryCode) - .map(entity -> new CodeNameDto(entity.getCountryCode(), - entity.getDescription())); - } - - /** - * Retrieves a client type by its unique code. This method queries the clientTypeCodeRepository to - * find a client type entity with the specified code. If a matching entity is found, it is - * converted to a {@code CodeNameDto} object containing the code and description, and wrapped in a - * Mono. If no matching entity is found, the Mono will complete without emitting any items. - * - * @param code The unique code of the client type to retrieve. - * @return A Mono emitting a {@code CodeNameDto} if a matching client type is found, or an empty - * result if no match is found. - * @see CodeNameDto - */ - public Mono getClientTypeByCode(String code) { - log.info("Loading client type for {}", code); - return clientTypeCodeRepository - .findByCode(code) - .map(entity -> new CodeNameDto(entity.getCode(), - entity.getDescription())); - } - - /** - *

List Provinces

- *

List provinces by country (which include states) by page with a defined size. - * The list will be sorted by province name.

- * - * @param countryCode The code of the country to list provinces from. - * @param page The page number, it is a 0-index base. - * @param size The amount of entries per page. - * @return A list of {@link CodeNameDto} entries. - */ - public Flux listProvinces(String countryCode, int page, int size) { - log.info("Loading provinces for {} with page {} and size {}", countryCode, page, size); - return provinceCodeRepository - .findByCountryCode(countryCode, PageRequest.of(page, size, Sort.by("description"))) - .map(entity -> new CodeNameDto(entity.getProvinceCode(), entity.getDescription())); - } - - /** - *

List contact types

- * List contact type codes by page with a defined size. - * - * @param page The page number, it is a 0-index base. - * @param size The amount of entries per page. - * @return A list of {@link CodeNameDto} entries. - */ - public Flux listClientContactTypeCodes(LocalDate activeDate, int page, int size) { - log.info("Loading contact types for page {} with size {}", page, size); - return contactTypeCodeRepository - .findActiveAt(activeDate, PageRequest.of(page, size)) - .map(entity -> new CodeNameDto( - entity.getContactTypeCode(), - entity.getDescription())); - } /** * Retrieves the client details for a given client number by making calls to BC Registry service. @@ -221,82 +64,82 @@ public Mono getClientDetails( String businessId, String provider ) { - log.info("Loading details for {}", clientNumber); - return bcRegistryService - .requestDocumentData(clientNumber) - .next() - .doOnNext(document -> - log.info("Searching on Oracle legacy db for {} {}", - document.business().identifier(), - document.business().getResolvedLegalName() - ) - ) - .flatMap(document -> legacyService - .searchLegacy( - document.business().identifier(), - document.business().getResolvedLegalName(), - userId, - businessId - ) - .next() - .filter(isMatchWith(document)) - .doOnNext(legacy -> - log.info("Found legacy entry for {} {}", - document.business().identifier(), - document.business().getResolvedLegalName() - ) - ) - .flatMap(legacy -> Mono.error( - new ClientAlreadyExistException( - legacy.clientNumber(), - document.business().identifier(), - document.business().getResolvedLegalName()) - )) - .defaultIfEmpty(document) - .doOnNext(value -> - log.info("No entry found on legacy for {} {}", - document.business().identifier(), - document.business().getResolvedLegalName() - ) - ) - ) - .map(BcRegistryDocumentDto.class::cast) - - .flatMap(client -> { - // Check for unsupported legal type - LegalTypeEnum legalType = LegalTypeEnum.fromValue(client.business().legalType()); - if (legalType == null) { - return Mono.error( - new UnsupportedLegalTypeException(client.business().legalType()) - ); - } - - // FSADT1-1388: Allow IDIR users to search for any client type - if (provider.equalsIgnoreCase("idir")) { - return Mono.just(client); - } - - if (ApplicationConstant.AVAILABLE_CLIENT_TYPES.contains( - ClientValidationUtils.getClientType(legalType).toString() - )) { - return Mono.just(client); - } - - return Mono.error(new UnsupportedClientTypeException( - ClientValidationUtils.getClientType(legalType).toString() - )); - }) - - // If document type is SP and party contains only one entry that is not a person, fail - .filter(document -> provider.equalsIgnoreCase("idir") || - !("SP".equalsIgnoreCase(document.business().legalType()) && - document.parties().size() == 1 && - !document.parties().get(0).isPerson()) - ) - .flatMap(buildDetails()) - .switchIfEmpty(Mono.error(new UnableToProcessRequestException( - "Unable to process request. This sole proprietor is not owned by a person" - ))); + log.info("Loading details for {}", clientNumber); + return bcRegistryService + .requestDocumentData(clientNumber) + .next() + .doOnNext(document -> + log.info("Searching on Oracle legacy db for {} {}", + document.business().identifier(), + document.business().getResolvedLegalName() + ) + ) + .flatMap(document -> legacyService + .searchLegacy( + document.business().identifier(), + document.business().getResolvedLegalName(), + userId, + businessId + ) + .next() + .filter(isMatchWith(document)) + .doOnNext(legacy -> + log.info("Found legacy entry for {} {}", + document.business().identifier(), + document.business().getResolvedLegalName() + ) + ) + .flatMap(legacy -> Mono.error( + new ClientAlreadyExistException( + legacy.clientNumber(), + document.business().identifier(), + document.business().getResolvedLegalName()) + )) + .defaultIfEmpty(document) + .doOnNext(value -> + log.info("No entry found on legacy for {} {}", + document.business().identifier(), + document.business().getResolvedLegalName() + ) + ) + ) + .map(BcRegistryDocumentDto.class::cast) + + .flatMap(client -> { + // Check for unsupported legal type + LegalTypeEnum legalType = LegalTypeEnum.fromValue(client.business().legalType()); + if (legalType == null) { + return Mono.error( + new UnsupportedLegalTypeException(client.business().legalType()) + ); + } + + // FSADT1-1388: Allow IDIR users to search for any client type + if (provider.equalsIgnoreCase("idir")) { + return Mono.just(client); + } + + if (ApplicationConstant.AVAILABLE_CLIENT_TYPES.contains( + ClientValidationUtils.getClientType(legalType).toString() + )) { + return Mono.just(client); + } + + return Mono.error(new UnsupportedClientTypeException( + ClientValidationUtils.getClientType(legalType).toString() + )); + }) + + // If document type is SP and party contains only one entry that is not a person, fail + .filter(document -> provider.equalsIgnoreCase("idir") || + !("SP".equalsIgnoreCase(document.business().legalType()) && + document.parties().size() == 1 && + !document.parties().get(0).isPerson()) + ) + .flatMap(buildDetails()) + .switchIfEmpty(Mono.error(new UnableToProcessRequestException( + "Unable to process request. This sole proprietor is not owned by a person" + ))); } /** @@ -323,6 +166,17 @@ public Flux findByClientNameOrIncorporation(String value) { .sort(Comparator.comparing(ClientLookUpDto::name)); } + public Mono findByIndividual(String userId, String lastName) { + return legacyService + .searchIdAndLastName(userId, lastName) + .doOnNext(legacy -> log.info("Found legacy entry for {} {}", userId, lastName)) + //If we have result, we return a Mono.error with the exception, otherwise return a Mono.empty + .next() + .flatMap(legacy -> Mono + .error(new ClientAlreadyExistException(legacy.clientNumber())) + ); + } + /** *

Send Email

*

Send email to a client.

@@ -331,7 +185,12 @@ public Flux findByClientNameOrIncorporation(String value) { * @return A {@link Mono} of {@link String}. */ public Mono sendEmail(EmailRequestDto emailRequestDto) { - return triggerEmail(emailRequestDto); + return chesService.sendEmail( + emailRequestDto.templateName(), + emailRequestDto.email(), + emailRequestDto.subject(), + emailRequestDto.variables(), + null); } /** @@ -360,25 +219,6 @@ public Mono triggerEmailDuplicatedClient( .then(); } - public Mono findByIndividual(String userId, String lastName) { - return legacyService - .searchIdAndLastName(userId, lastName) - .doOnNext(legacy -> log.info("Found legacy entry for {} {}", userId, lastName)) - //If we have result, we return a Mono.error with the exception, otherwise return a Mono.empty - .next() - .flatMap(legacy -> Mono - .error(new ClientAlreadyExistException(legacy.clientNumber())) - ); - } - - public Mono findByUserIdAndLastName(String userId, String lastName) { - return legacyService - .searchIdAndLastName(userId, lastName) - .doOnNext(legacy -> log.info("Found legacy entry for {} {}", userId, lastName)) - .next() - .map(ForestClientDto::clientNumber); - } - private Function> buildDetails() { return document -> buildAddress( @@ -454,9 +294,11 @@ private Mono buildAddress( " address").toUpperCase() ) ) - .flatMap(address -> loadCountry(address.country().text()).map(address::withCountry)) + .flatMap(address -> countryProvinceService.loadCountry(address.country().text()) + .map(address::withCountry)) .flatMap(address -> - loadProvince(address.country().value(), address.province().value()) + countryProvinceService. + loadProvince(address.country().value(), address.province().value()) .map(address::withProvince) ) .sort(Comparator.comparing(ClientAddressDto::locationName).reversed()) @@ -509,26 +351,6 @@ private static List matchAddress(List addr .toList(); } - private Mono loadCountry(String countryCode) { - return - countryCodeRepository - .findByDescription(countryCode) - .map( - entity -> new ClientValueTextDto(entity.getCountryCode(), entity.getDescription()) - ) - .defaultIfEmpty(new ClientValueTextDto(StringUtils.EMPTY, countryCode)); - } - - private Mono loadProvince(String countryCode, String provinceCode) { - return - provinceCodeRepository - .findByCountryCodeAndProvinceCode(countryCode, provinceCode) - .map( - entity -> new ClientValueTextDto(entity.getProvinceCode(), entity.getDescription()) - ) - .defaultIfEmpty(new ClientValueTextDto(provinceCode, provinceCode)); - } - private Predicate isMatchWith(BcRegistryDocumentDto document) { return legacy -> StringUtils.equals( @@ -554,79 +376,4 @@ private Function> triggerEmailDuplicatedC .thenReturn(legacy); } - private Mono triggerEmail(EmailRequestDto emailRequestDto) { - return chesService.sendEmail( - emailRequestDto.templateName(), - emailRequestDto.email(), - emailRequestDto.subject(), - emailRequestDto.variables(), - null); - } - - /** - * Retrieves natural resource district information by its district code. This method queries the - * {@code districtCodeRepository} to find a district entity with the specified district code. If a - * matching entity is found, it is mapped to a {@code DistrictDto} object, which encapsulates the - * district code, description and email. The resulting data is wrapped in a Mono, which represents - * the asynchronous result of the operation. - * - * @param districtCode The code of the district to retrieve information for. - * @return A Mono that emits the {@code DistrictDto} object if a matching district is found, or an - * empty result if no match is found. - * @see DistrictDto - */ - public Mono getDistrictByCode(String districtCode) { - log.info("Loading district for {}", districtCode); - return districtCodeRepository - .findByCode(districtCode) - .map(entity -> new DistrictDto( - entity.getCode(), - entity.getDescription(), - entity.getEmailAddress() - ) - ); - } - - /** - * Retrieves all active identification types as of the specified target date. - * - * @param targetDate the date to check for active identification types. - * @return a Flux stream of IdentificationTypeDto containing the code, description, and country - * code of each active identification type. - */ - public Flux getAllActiveIdentificationTypes(LocalDate targetDate) { - log.info("Loading active identification type codes by {}", targetDate); - return identificationTypeCodeRepository - .findActiveAt(targetDate) - .map(entity -> new IdentificationTypeDto( - entity.getCode(), - entity.getDescription(), - entity.getCountryCode())); - } - - /** - * Retrieves an identification type by its code. - * - * @param idCode the code of the identification type to retrieve. - * @return a Mono containing a CodeNameDto with the code and description of the identification - * type, or an empty Mono if not found. - */ - public Mono getIdentificationTypeByCode(String idCode) { - log.info("Loading identification type by {}", idCode); - return identificationTypeCodeRepository - .findByCode(idCode) - .map(entity -> new CodeNameDto(entity.getCode(), - entity.getDescription())); - } - - public Mono getProvinceByCountryAndProvinceCode( - String countryCode, - String provinceCode) { - log.info("Loading province by country and province code {} {}", countryCode, provinceCode); - return provinceCodeRepository - .findByCountryCodeAndProvinceCode(countryCode, provinceCode) - .map(entity -> new CodeNameDto(entity.getProvinceCode(), - entity.getDescription())); - } - } diff --git a/backend/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionService.java b/backend/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionService.java index 1336afb80d..00c905e202 100644 --- a/backend/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionService.java +++ b/backend/src/main/java/ca/bc/gov/app/service/client/ClientSubmissionService.java @@ -75,38 +75,41 @@ @Observed public class ClientSubmissionService { + private final ClientCodeService codeService; + private final ClientDistrictService districtService; private final SubmissionRepository submissionRepository; private final SubmissionDetailRepository submissionDetailRepository; private final SubmissionLocationRepository submissionLocationRepository; private final SubmissionContactRepository submissionContactRepository; private final SubmissionLocationContactRepository submissionLocationContactRepository; private final SubmissionMatchDetailRepository submissionMatchDetailRepository; - private final DistrictCodeRepository districtCodeRepository; private final ChesService chesService; private final R2dbcEntityTemplate template; private final ForestClientConfiguration configuration; private final WebClient processorApi; public ClientSubmissionService( + ClientCodeService codeService, + ClientDistrictService districtService, SubmissionRepository submissionRepository, SubmissionDetailRepository submissionDetailRepository, SubmissionLocationRepository submissionLocationRepository, SubmissionContactRepository submissionContactRepository, SubmissionLocationContactRepository submissionLocationContactRepository, SubmissionMatchDetailRepository submissionMatchDetailRepository, - DistrictCodeRepository districtCodeRepository, ChesService chesService, R2dbcEntityTemplate template, ForestClientConfiguration configuration, @Qualifier("processorApi") WebClient processorApi ) { + this.codeService = codeService; + this.districtService = districtService; this.submissionRepository = submissionRepository; this.submissionDetailRepository = submissionDetailRepository; this.submissionLocationRepository = submissionLocationRepository; this.submissionContactRepository = submissionContactRepository; this.submissionLocationContactRepository = submissionLocationContactRepository; this.submissionMatchDetailRepository = submissionMatchDetailRepository; - this.districtCodeRepository = districtCodeRepository; this.chesService = chesService; this.template = template; this.configuration = configuration; @@ -135,13 +138,14 @@ public Flux listSubmissions( submittedAt ); - return getClientTypes() + return + codeService.getClientTypes() .flatMapMany(clientTypes -> loadSubmissions(page, size, requestStatus, submittedAt) .flatMapSequential(submissionPair -> loadSubmissionDetail(clientType, name, submissionPair.getRight()) .flatMap(submissionDetail -> - getDistrictFullDescByCode(submissionDetail.getDistrictCode()) + districtService.getDistrictFullDescByCode(submissionDetail.getDistrictCode()) .map(districtFullDesc -> new ClientListSubmissionDto( submissionPair.getRight().getSubmissionId(), @@ -520,22 +524,6 @@ private Mono saveSubmission( ); } - private Mono getDistrictFullDescByCode(String districtCode) { - return Mono.justOrEmpty(districtCode) - .flatMap(districtCodeRepository::findByCode) - .map(districtCodeEntity -> districtCodeEntity.getCode() + " - " - + districtCodeEntity.getDescription()) - .defaultIfEmpty(""); - } - - private Mono getDistrictByCode(String districtCode) { - return Mono.justOrEmpty(districtCode).flatMap(districtCodeRepository::findByCode) - .map(districtCodeEntity -> new DistrictDto( - districtCodeEntity.getCode(), - districtCodeEntity.getDescription(), - districtCodeEntity.getEmailAddress())); - } - private void cleanMatchers(SubmissionMatchDetailEntity entity) { entity.getMatchers().entrySet().forEach(entry -> { if (entry.getValue() instanceof String value) { @@ -588,7 +576,7 @@ private Mono sendEmail( String userName ) { return - getDistrictByCode(clientSubmissionDto.businessInformation().district()) + districtService.getDistrictByCode(clientSubmissionDto.businessInformation().district()) .map(district -> registrationParameters( clientSubmissionDto.description(userName), district.description(), @@ -620,29 +608,6 @@ private Map registrationParameters( return descMap; } - private Mono> getClientTypes() { - return template - .select( - query( - QueryPredicates.isBefore(LocalDateTime.now(), "effectiveAt") - .and( - QueryPredicates.isAfter(LocalDateTime.now(), "expiredAt") - .or(QueryPredicates.isNull("expiredAt")) - ) - ), - ClientTypeCodeEntity.class - ) - .collectList() - //Convert the list into a map using code as the key and description as value - .map(clientTypeCodeEntities -> - clientTypeCodeEntities - .stream() - .collect(Collectors.toMap(ClientTypeCodeEntity::getCode, - ClientTypeCodeEntity::getDescription)) - ); - } - - private Mono loadSubmissionDetail(String[] clientType, String[] name, SubmissionEntity submission) { return template diff --git a/backend/src/test/java/ca/bc/gov/app/service/client/ClientCodeServiceIntegrationTest.java b/backend/src/test/java/ca/bc/gov/app/service/client/ClientCodeServiceIntegrationTest.java new file mode 100644 index 0000000000..55ec8e697d --- /dev/null +++ b/backend/src/test/java/ca/bc/gov/app/service/client/ClientCodeServiceIntegrationTest.java @@ -0,0 +1,54 @@ +package ca.bc.gov.app.service.client; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import ca.bc.gov.app.dto.client.CodeNameDto; +import ca.bc.gov.app.extensions.AbstractTestContainerIntegrationTest; +import java.time.LocalDate; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import reactor.test.StepVerifier; + +@Slf4j +@DisplayName("Integrated Test | FSA Client Code Service") +public class ClientCodeServiceIntegrationTest extends AbstractTestContainerIntegrationTest { + + @Autowired + private ClientCodeService service; + + @ParameterizedTest + @MethodSource("date") + @DisplayName("Return code as long as the date allows it") + void shouldListCodeAsExpected(LocalDate date) { + StepVerifier + .create(service.findActiveClientTypeCodes(date)) + .assertNext(results -> assertEquals("A", results.code())) + .expectNextCount(13) + .verifyComplete(); + } + + @Test + void testGetClientTypeByCode() { + + CodeNameDto expectedDto = new CodeNameDto("RSP", "Registered sole proprietorship"); + + service + .getClientTypeByCode("RSP") + .as(StepVerifier::create) + .expectNext(expectedDto) + .verifyComplete(); + } + + private static Stream date() { + return + Stream.of( + LocalDate.now(), + LocalDate.now().plusDays(1) + ); + } +} diff --git a/backend/src/test/java/ca/bc/gov/app/service/client/ClientCountryProvinceServiceIntegrationTest.java b/backend/src/test/java/ca/bc/gov/app/service/client/ClientCountryProvinceServiceIntegrationTest.java new file mode 100644 index 0000000000..b24d2f29e8 --- /dev/null +++ b/backend/src/test/java/ca/bc/gov/app/service/client/ClientCountryProvinceServiceIntegrationTest.java @@ -0,0 +1,31 @@ +package ca.bc.gov.app.service.client; + +import ca.bc.gov.app.dto.client.CodeNameDto; +import ca.bc.gov.app.extensions.AbstractTestContainerIntegrationTest; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import reactor.test.StepVerifier; + +@Slf4j +@DisplayName("Integrated Test | FSA Client Country and District Service") +class ClientCountryProvinceServiceIntegrationTest extends AbstractTestContainerIntegrationTest { + + @Autowired + private ClientCountryProvinceService service; + + @Test + void testGetCountryByCode() { + + CodeNameDto expectedDto = new CodeNameDto("CA", "Canada"); + + service + .getCountryByCode("CA") + .as(StepVerifier::create) + .expectNext(expectedDto) + .verifyComplete(); + } + + +} \ No newline at end of file diff --git a/backend/src/test/java/ca/bc/gov/app/service/client/ClientDistrictServiceIntegrationTest.java b/backend/src/test/java/ca/bc/gov/app/service/client/ClientDistrictServiceIntegrationTest.java new file mode 100644 index 0000000000..a39f17f6e1 --- /dev/null +++ b/backend/src/test/java/ca/bc/gov/app/service/client/ClientDistrictServiceIntegrationTest.java @@ -0,0 +1,33 @@ +package ca.bc.gov.app.service.client; + +import ca.bc.gov.app.dto.client.DistrictDto; +import ca.bc.gov.app.extensions.AbstractTestContainerIntegrationTest; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import reactor.test.StepVerifier; + +@Slf4j +@DisplayName("Integrated Test | FSA Client District Service") +public class ClientDistrictServiceIntegrationTest extends AbstractTestContainerIntegrationTest { + + @Autowired + private ClientDistrictService service; + + @Test + @DisplayName("Return district by code") + void testGetDistrictByCode() { + + DistrictDto expectedDto = + new DistrictDto("DMH", "100 Mile House Natural Resource District", + "mail@mail.ca"); + + service + .getDistrictByCode("DMH") + .as(StepVerifier::create) + .expectNext(expectedDto) + .verifyComplete(); + } + +} diff --git a/backend/src/test/java/ca/bc/gov/app/service/client/ClientServiceIntegrationTest.java b/backend/src/test/java/ca/bc/gov/app/service/client/ClientServiceIntegrationTest.java deleted file mode 100644 index bcb7581130..0000000000 --- a/backend/src/test/java/ca/bc/gov/app/service/client/ClientServiceIntegrationTest.java +++ /dev/null @@ -1,117 +0,0 @@ -package ca.bc.gov.app.service.client; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; - -import ca.bc.gov.app.dto.client.DistrictDto; -import ca.bc.gov.app.extensions.AbstractTestContainerIntegrationTest; -import ca.bc.gov.app.dto.client.CodeNameDto; -import ca.bc.gov.app.entity.client.ClientTypeCodeEntity; -import ca.bc.gov.app.entity.client.CountryCodeEntity; -import ca.bc.gov.app.entity.client.DistrictCodeEntity; -import ca.bc.gov.app.repository.client.ClientTypeCodeRepository; -import ca.bc.gov.app.repository.client.CountryCodeRepository; -import ca.bc.gov.app.repository.client.DistrictCodeRepository; -import java.time.LocalDate; -import java.util.stream.Stream; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.Mock; -import org.springframework.beans.factory.annotation.Autowired; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -@Slf4j -@DisplayName("Integrated Test | FSA Client Service") -class ClientServiceIntegrationTest extends AbstractTestContainerIntegrationTest { - - @Autowired - private ClientService service; - - @Mock - private CountryCodeRepository countryCodeRepository; - - @Mock - private DistrictCodeRepository districtCodeRepository; - - @Mock - private ClientTypeCodeRepository clientTypeCodeRepository; - - @ParameterizedTest - @MethodSource("date") - @DisplayName("Return code as long as the date allows it") - void shouldListCodeAsExpected(LocalDate date) { - StepVerifier - .create(service.findActiveClientTypeCodes(date)) - .assertNext(results -> assertEquals("A", results.code())) - .expectNextCount(13) - .verifyComplete(); - } - - @Test - @DisplayName("Return district by code") - void testGetDistrictByCode() { - - DistrictCodeEntity districtCodeEntity = - new DistrictCodeEntity("DMH", "100 Mile House Natural Resource District"); - - DistrictDto expectedDto = - new DistrictDto("DMH", "100 Mile House Natural Resource District", - "mail@mail.ca"); - - when(districtCodeRepository - .findByCode("DMH")) - .thenReturn(Mono.just(districtCodeEntity)); - - service - .getDistrictByCode("DMH") - .as(StepVerifier::create) - .expectNext(expectedDto) - .verifyComplete(); - } - - @Test - void testGetCountryByCode() { - - CountryCodeEntity countryCodeEntity = CountryCodeEntity.builder().countryCode("CA") - .description("Canada").build(); - CodeNameDto expectedDto = new CodeNameDto("CA", "Canada"); - - when(countryCodeRepository.findByCountryCode("CA")).thenReturn(Mono.just(countryCodeEntity)); - - service - .getCountryByCode("CA") - .as(StepVerifier::create) - .expectNext(expectedDto) - .verifyComplete(); - } - - @Test - void testGetClientTypeByCode() { - - ClientTypeCodeEntity clientTypeCodeEntity = new ClientTypeCodeEntity("CA", "Canada"); - CodeNameDto expectedDto = new CodeNameDto("RSP", "Registered sole proprietorship"); - - when(clientTypeCodeRepository - .findByCode("RSP")) - .thenReturn(Mono.just(clientTypeCodeEntity)); - - service - .getClientTypeByCode("RSP") - .as(StepVerifier::create) - .expectNext(expectedDto) - .verifyComplete(); - } - - private static Stream date() { - return - Stream.of( - LocalDate.now(), - LocalDate.now().plusDays(1) - ); - } - -} \ No newline at end of file