From ef13faff2f8ca7a70aa22820ea071aab34f52682 Mon Sep 17 00:00:00 2001 From: armin isenring Date: Tue, 21 Jun 2022 14:51:44 +0200 Subject: [PATCH 01/23] changed authorization uri for report a7 --- src/main/resources/application-authorization.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-authorization.yml b/src/main/resources/application-authorization.yml index d7a66119..ba3a26d9 100644 --- a/src/main/resources/application-authorization.yml +++ b/src/main/resources/application-authorization.yml @@ -866,7 +866,7 @@ services: from: 2022-01-01T00:00:00 until: 2099-12-31T23:59:59 mandatory: ${roles.id.report.agg} - uri: "/api/v2/report/fraud/a7/(Aggregated Rep, URL TBD)" #TODO + uri: "/api/v2/report/fraud/a7" report-a8: identifier: "report-a8" From 32ad30caad5e1edae24a12649dc44ceb5ab842dd Mon Sep 17 00:00:00 2001 From: Nino Di Natale Date: Wed, 29 Jun 2022 16:55:03 +0200 Subject: [PATCH 02/23] release 4.4.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3be9c8c4..0bc75395 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ ch.admin.bag.covidcertificate cc-management-service - 4.3.3 + 4.4.0 cc-management-service Service for generating Covid Certificates From c17677ce2ef48e9bc032eb8a88ed6bf258539d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20L=C3=B6sing?= Date: Fri, 1 Jul 2022 15:45:32 +0200 Subject: [PATCH 03/23] sampleDateTime gets now parsed with and without time to map RecoveryRatCertificateCsvBean to a valid RecoveryRatCertificateDataDto. --- .../RecoveryRatCertificateCsvBean.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java b/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java index c33b3814..59ee1382 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java +++ b/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java @@ -7,9 +7,12 @@ import lombok.NoArgsConstructor; import lombok.ToString; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.ZonedDateTime; import static ch.admin.bag.covidcertificate.api.Constants.INVALID_SAMPLE_DATE_TIME; +import static ch.admin.bag.covidcertificate.api.Constants.SWISS_TIMEZONE; @Getter @ToString @@ -17,6 +20,8 @@ @AllArgsConstructor public class RecoveryRatCertificateCsvBean extends CertificateCreateCsvBean { + public static final String TIME = "T"; + @CsvBindByName(column = "sampleDateTime") private String sampleDateTime; @CsvBindByName(column = "memberStateOfTest") @@ -26,7 +31,20 @@ public class RecoveryRatCertificateCsvBean extends CertificateCreateCsvBean { public RecoveryRatCertificateCreateDto mapToCreateDto() { ZonedDateTime sampleDateTimeParsed; try { - sampleDateTimeParsed = ZonedDateTime.parse(this.sampleDateTime); + if (this.sampleDateTime.contains(TIME)) { + // it contains a time + if (this.sampleDateTime.contains("Z")) { + // it is UTC zoned + ZonedDateTime utcZoned = ZonedDateTime.parse(this.sampleDateTime); + sampleDateTimeParsed = utcZoned.withZoneSameInstant(SWISS_TIMEZONE); + } else { + // it is un zoned and we interpret it as SWISS_TIMEZONE + sampleDateTimeParsed = LocalDateTime.parse(this.sampleDateTime).atZone(SWISS_TIMEZONE); + } + } else { + // it is without time and we take start of day with SWISS_TIMEZONE + sampleDateTimeParsed = LocalDate.parse(sampleDateTime).atStartOfDay(SWISS_TIMEZONE); + } } catch (Exception e) { throw new CreateCertificateException(INVALID_SAMPLE_DATE_TIME); } From 239efeee16abaaa85b012083c03847fe7118112d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20L=C3=B6sing?= Date: Mon, 4 Jul 2022 08:20:30 +0200 Subject: [PATCH 04/23] define zoned marker Z as a constant. --- .../api/request/RecoveryRatCertificateCsvBean.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java b/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java index 59ee1382..98188782 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java +++ b/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java @@ -21,6 +21,7 @@ public class RecoveryRatCertificateCsvBean extends CertificateCreateCsvBean { public static final String TIME = "T"; + public static final String ZONED_MARKER = "Z"; @CsvBindByName(column = "sampleDateTime") private String sampleDateTime; @@ -33,7 +34,7 @@ public RecoveryRatCertificateCreateDto mapToCreateDto() { try { if (this.sampleDateTime.contains(TIME)) { // it contains a time - if (this.sampleDateTime.contains("Z")) { + if (this.sampleDateTime.contains(ZONED_MARKER)) { // it is UTC zoned ZonedDateTime utcZoned = ZonedDateTime.parse(this.sampleDateTime); sampleDateTimeParsed = utcZoned.withZoneSameInstant(SWISS_TIMEZONE); From f0d4b47ffe3a2d61674f5dccf836cda58d795c91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20L=C3=B6sing?= Date: Mon, 4 Jul 2022 12:25:11 +0200 Subject: [PATCH 05/23] added test cases and named zonedDateTime variable correct as it parses other zoned date time instances like 2022-07-04T00:00+02:00[Europe/Zurich] correctly. --- .../RecoveryRatCertificateCsvBean.java | 6 +- .../RecoveryRatCertificateCsvBeanTest.java | 91 +++++++++++++++++++ 2 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 src/test/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBeanTest.java diff --git a/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java b/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java index 98188782..ed67c34c 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java +++ b/src/main/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBean.java @@ -35,9 +35,9 @@ public RecoveryRatCertificateCreateDto mapToCreateDto() { if (this.sampleDateTime.contains(TIME)) { // it contains a time if (this.sampleDateTime.contains(ZONED_MARKER)) { - // it is UTC zoned - ZonedDateTime utcZoned = ZonedDateTime.parse(this.sampleDateTime); - sampleDateTimeParsed = utcZoned.withZoneSameInstant(SWISS_TIMEZONE); + // it is zoned + ZonedDateTime zonedDateTime = ZonedDateTime.parse(this.sampleDateTime); + sampleDateTimeParsed = zonedDateTime.withZoneSameInstant(SWISS_TIMEZONE); } else { // it is un zoned and we interpret it as SWISS_TIMEZONE sampleDateTimeParsed = LocalDateTime.parse(this.sampleDateTime).atZone(SWISS_TIMEZONE); diff --git a/src/test/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBeanTest.java b/src/test/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBeanTest.java new file mode 100644 index 00000000..0d43f670 --- /dev/null +++ b/src/test/java/ch/admin/bag/covidcertificate/api/request/RecoveryRatCertificateCsvBeanTest.java @@ -0,0 +1,91 @@ +package ch.admin.bag.covidcertificate.api.request; + +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; + +import static ch.admin.bag.covidcertificate.api.Constants.SWISS_TIMEZONE; +import static java.time.format.DateTimeFormatter.ISO_INSTANT; +import static java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME; +import static org.assertj.core.api.Assertions.assertThat; + +class RecoveryRatCertificateCsvBeanTest { + + @Test + void mapToCreateDto_sampleDateTime_without_time_and_zone() { + ZonedDateTime sampleDate = LocalDate.now().atStartOfDay(SWISS_TIMEZONE); + String sampleDateString = sampleDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); + RecoveryRatCertificateCsvBean recoveryRatCertificateCsvBean = new RecoveryRatCertificateCsvBean( + sampleDateString, "CH"); + setOtherFields(recoveryRatCertificateCsvBean); + + RecoveryRatCertificateCreateDto result = recoveryRatCertificateCsvBean.mapToCreateDto(); + + doAssertions(sampleDate, result); + } + + @Test + void mapToCreateDto_sampleDateTime_with_time_and_zone_utc() { + ZonedDateTime sampleDate = LocalDate.now().atStartOfDay(ZoneId.of("UTC")); + String sampleDateString = sampleDate.format(ISO_INSTANT); + RecoveryRatCertificateCsvBean recoveryRatCertificateCsvBean = new RecoveryRatCertificateCsvBean( + sampleDateString, "CH"); + setOtherFields(recoveryRatCertificateCsvBean); + + RecoveryRatCertificateCreateDto result = recoveryRatCertificateCsvBean.mapToCreateDto(); + + doAssertions(sampleDate, result); + } + + @Test + void mapToCreateDto_sampleDateTime_with_time_and_zone_zurich() { + ZoneId zone_zurich = ZoneId.of("Europe/Zurich"); + ZonedDateTime sampleDate = LocalDate.now().atStartOfDay(zone_zurich); + String sampleDateString = sampleDate.format(ISO_ZONED_DATE_TIME); + RecoveryRatCertificateCsvBean recoveryRatCertificateCsvBean = new RecoveryRatCertificateCsvBean( + sampleDateString, "CH"); + setOtherFields(recoveryRatCertificateCsvBean); + + RecoveryRatCertificateCreateDto result = recoveryRatCertificateCsvBean.mapToCreateDto(); + + doAssertions(sampleDate, result); + } + + @Test + void mapToCreateDto_sampleDateTime_with_time_only() { + ZonedDateTime sampleDate = LocalDate.now().atStartOfDay(SWISS_TIMEZONE); + DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder() + .appendPattern("yyyy-MM-dd") + .appendLiteral("T") + .appendPattern("HH:mm:ss") + .toFormatter(); + String sampleDateString = sampleDate.format(dateTimeFormatter); + RecoveryRatCertificateCsvBean recoveryRatCertificateCsvBean = new RecoveryRatCertificateCsvBean( + sampleDateString, "CH"); + setOtherFields(recoveryRatCertificateCsvBean); + + RecoveryRatCertificateCreateDto result = recoveryRatCertificateCsvBean.mapToCreateDto(); + + doAssertions(sampleDate, result); + } + + private void doAssertions(ZonedDateTime sampleDate, RecoveryRatCertificateCreateDto result) { + assertThat(result).isNotNull(); + assertThat(result.getTestInfo().size()).isEqualTo(1); + RecoveryRatCertificateDataDto resultData = result.getTestInfo().get(0); + assertThat(resultData).isNotNull(); + assertThat(resultData.getSampleDateTime()).isEqualTo(sampleDate); + } + + private void setOtherFields(RecoveryRatCertificateCsvBean recoveryRatCertificateCsvBean) { + ReflectionTestUtils.setField(recoveryRatCertificateCsvBean, "familyName", "test"); + ReflectionTestUtils.setField(recoveryRatCertificateCsvBean, "givenName", "test"); + ReflectionTestUtils.setField(recoveryRatCertificateCsvBean, "dateOfBirth", "01.01.2000"); + ReflectionTestUtils.setField(recoveryRatCertificateCsvBean, "language", "fr"); + } +} From 8f9672e4e625d220f1707cf76b025cd0b0e54c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20L=C3=B6sing?= Date: Mon, 4 Jul 2022 13:23:36 +0200 Subject: [PATCH 06/23] prepare next release. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0bc75395..0cffabf4 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ ch.admin.bag.covidcertificate cc-management-service - 4.4.0 + 4.4.1 cc-management-service Service for generating Covid Certificates From a1e8ec494328aa204bed10e21bc511993638b961 Mon Sep 17 00:00:00 2001 From: armin isenring Date: Mon, 4 Jul 2022 20:35:33 +0200 Subject: [PATCH 07/23] changed feature-toggle- and authorization-exception from error to warning --- .../web/controller/ResponseStatusExceptionHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/admin/bag/covidcertificate/web/controller/ResponseStatusExceptionHandler.java b/src/main/java/ch/admin/bag/covidcertificate/web/controller/ResponseStatusExceptionHandler.java index fb4db279..f3d0a38d 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/web/controller/ResponseStatusExceptionHandler.java +++ b/src/main/java/ch/admin/bag/covidcertificate/web/controller/ResponseStatusExceptionHandler.java @@ -91,13 +91,13 @@ protected ResponseEntity handleCacheNotFoundException(CacheNotFoundExcep @ExceptionHandler(value = {FeatureToggleException.class}) protected ResponseEntity handleFeatureToggleException(FeatureToggleException e) { - log.error(e.getMessage()); + log.warn(e.getMessage()); return new ResponseEntity<>(e.getError(), HttpStatus.FORBIDDEN); } @ExceptionHandler(value = {AuthorizationException.class}) protected ResponseEntity handleAuthorizationException(AuthorizationException e) { - log.error(e.getMessage()); + log.warn(e.getMessage()); return new ResponseEntity<>(e.getMessage(), HttpStatus.FORBIDDEN); } From 75002780929cc35ab16a50bd6e8ce86c9e6b9a51 Mon Sep 17 00:00:00 2001 From: Iris Hunkeler Date: Thu, 7 Jul 2022 13:42:34 +0200 Subject: [PATCH 08/23] VACCINECER-2259 add partition to signing information and use when calling signing-service --- .../api/mapper/SigningInformationMapper.java | 17 ++-- .../client/signing/SigningClient.java | 2 +- .../client/signing/SigningInformationDto.java | 87 +++---------------- .../client/signing/SigningRequestDto.java | 3 + .../signing/VerifySignatureRequestDto.java | 3 + .../internal/DefaultSigningClient.java | 55 ++++++++---- .../signing/internal/MockSigningClient.java | 2 +- .../domain/SigningInformation.java | 3 + .../covidcertificate/service/COSEService.java | 5 +- .../test/SigningInformationStatus.java | 9 ++ .../web/controller/test/TestController.java | 47 ++++++---- ..._0_56__add_slot_to_signing_information.sql | 2 + ...aultSigningClientCacheIntegrationTest.java | 10 ++- .../internal/DefaultSigningClientTest.java | 50 ++++++----- .../service/COSEServiceTest.java | 4 +- ...nformationCacheServiceIntegrationTest.java | 32 ++++--- 16 files changed, 164 insertions(+), 167 deletions(-) create mode 100644 src/main/java/ch/admin/bag/covidcertificate/web/controller/test/SigningInformationStatus.java create mode 100644 src/main/resources/db/migration/common/V1_0_56__add_slot_to_signing_information.sql diff --git a/src/main/java/ch/admin/bag/covidcertificate/api/mapper/SigningInformationMapper.java b/src/main/java/ch/admin/bag/covidcertificate/api/mapper/SigningInformationMapper.java index 625cd685..6e7138e6 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/api/mapper/SigningInformationMapper.java +++ b/src/main/java/ch/admin/bag/covidcertificate/api/mapper/SigningInformationMapper.java @@ -9,17 +9,18 @@ public class SigningInformationMapper { public static SigningInformationDto fromEntity(SigningInformation signingInformation) { - return new SigningInformationDto.SigningInformationDtoBuilder() - .withCertificateType(signingInformation.getCertificateType()) - .withCode(signingInformation.getCode()) - .withAlias(signingInformation.getAlias()) - .withCertificateAlias(signingInformation.getCertificateAlias()) - .withValidFrom(signingInformation.getValidFrom()) - .withValidTo(signingInformation.getValidTo()) + return SigningInformationDto.builder() + .certificateType(signingInformation.getCertificateType()) + .code(signingInformation.getCode()) + .alias(signingInformation.getAlias()) + .certificateAlias(signingInformation.getCertificateAlias()) + .slotNumber(signingInformation.getSlotNumber()) + .validFrom(signingInformation.getValidFrom()) + .validTo(signingInformation.getValidTo()) .build(); } public static List fromEntityList(List signingInformationList) { - return signingInformationList.stream().map(one -> fromEntity(one)).collect(Collectors.toList()); + return signingInformationList.stream().map(SigningInformationMapper::fromEntity).collect(Collectors.toList()); } } diff --git a/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningClient.java b/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningClient.java index c0f0b09d..609cdbdb 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningClient.java +++ b/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningClient.java @@ -6,7 +6,7 @@ public interface SigningClient { boolean verifySignature(VerifySignatureRequestDto verifySignatureRequestDto); - String getKeyIdentifier(String certificateAlias); + String getKeyIdentifier(Integer slotNumber, String certificateAlias); void cleanKeyIdentifierCache(); diff --git a/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningInformationDto.java b/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningInformationDto.java index a262a976..208f7952 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningInformationDto.java +++ b/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningInformationDto.java @@ -1,5 +1,7 @@ package ch.admin.bag.covidcertificate.client.signing; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -9,84 +11,17 @@ @Getter @EqualsAndHashCode +@AllArgsConstructor @ToString +@Builder public class SigningInformationDto { - private String certificateType; - private String code; - private String alias; - private String certificateAlias; - private LocalDate validFrom; - private LocalDate validTo; + private final String certificateType; + private final String code; + private final String alias; + private final String certificateAlias; + private final Integer slotNumber; + private final LocalDate validFrom; + private final LocalDate validTo; @Setter private String calculatedKeyIdentifier; - - public SigningInformationDto( - String certificateType, - String code, - String alias, - String certificateAlias, - LocalDate validFrom, - LocalDate validTo - ) { - this.certificateType = certificateType; - this.code = code; - this.alias = alias; - this.certificateAlias = certificateAlias; - this.validFrom = validFrom; - this.validTo = validTo; - } - - public static class SigningInformationDtoBuilder { - - private String certificateType; - private String code; - private String alias; - private String certificateAlias; - private LocalDate validFrom; - private LocalDate validTo; - - public SigningInformationDtoBuilder() { - super(); - } - - public SigningInformationDtoBuilder withCertificateType(String certificateType) { - this.certificateType = certificateType; - return this; - } - - public SigningInformationDtoBuilder withCode(String code) { - this.code = code; - return this; - } - - public SigningInformationDtoBuilder withAlias(String alias) { - this.alias = alias; - return this; - } - - public SigningInformationDtoBuilder withCertificateAlias(String certificateAlias) { - this.certificateAlias = certificateAlias; - return this; - } - - public SigningInformationDtoBuilder withValidFrom(LocalDate validFrom) { - this.validFrom = validFrom; - return this; - } - - public SigningInformationDtoBuilder withValidTo(LocalDate validTo) { - this.validTo = validTo; - return this; - } - - public SigningInformationDto build() { - return new SigningInformationDto( - this.certificateType, - this.code, - this.alias, - this.certificateAlias, - this.validFrom, - this.validTo); - } - } } diff --git a/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningRequestDto.java b/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningRequestDto.java index 7ffa86a0..9eb8ff7d 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningRequestDto.java +++ b/src/main/java/ch/admin/bag/covidcertificate/client/signing/SigningRequestDto.java @@ -1,5 +1,6 @@ package ch.admin.bag.covidcertificate.client.signing; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -10,4 +11,6 @@ public class SigningRequestDto { private String dataToSign; private String signingKeyAlias; + @JsonProperty("keyStoreSlot") + private Integer slotNumber; } \ No newline at end of file diff --git a/src/main/java/ch/admin/bag/covidcertificate/client/signing/VerifySignatureRequestDto.java b/src/main/java/ch/admin/bag/covidcertificate/client/signing/VerifySignatureRequestDto.java index ccc5c431..79099ff1 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/client/signing/VerifySignatureRequestDto.java +++ b/src/main/java/ch/admin/bag/covidcertificate/client/signing/VerifySignatureRequestDto.java @@ -1,5 +1,6 @@ package ch.admin.bag.covidcertificate.client.signing; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -11,4 +12,6 @@ public class VerifySignatureRequestDto { private final String dataToSign; private final String signature; private final String certificateAlias; + @JsonProperty("keyStoreSlot") + private Integer slotNumber; } \ No newline at end of file diff --git a/src/main/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClient.java b/src/main/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClient.java index 587e67fa..eea17ebb 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClient.java +++ b/src/main/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClient.java @@ -35,7 +35,7 @@ public class DefaultSigningClient implements SigningClient { private final RestTemplate restTemplate; @Value("${cc-signing-service.url}") - private String url; + private String signUrl; @Value("${cc-signing-service.verify-url}") private String verifyUrl; @@ -48,22 +48,30 @@ public DefaultSigningClient(@Qualifier("signingServiceRestTemplate") RestTemplat } public byte[] createSignature(byte[] cosePayload, SigningInformationDto signingInformation) { - var signingRequestDto = new SigningRequestDto(Base64.getEncoder().encodeToString(cosePayload), - signingInformation.getAlias()); + var signingRequestDto = new SigningRequestDto( + Base64.getEncoder().encodeToString(cosePayload), + signingInformation.getAlias(), + signingInformation.getSlotNumber() + ); long start = System.currentTimeMillis(); - log.info("Call signing service with url {}", url); + log.info("Call signing service with url {}", signUrl); HttpHeaders headers = new HttpHeaders(); headers.put("Content-Type", Collections.singletonList(MediaType.APPLICATION_JSON_VALUE)); try { - ResponseEntity result = restTemplate.exchange(url, HttpMethod.POST, + ResponseEntity result = restTemplate.exchange( + signUrl, + HttpMethod.POST, new HttpEntity<>(signingRequestDto, headers), - byte[].class); + byte[].class + ); long end = System.currentTimeMillis(); - log.info("Call of signing service finished with result {} within {} ms.", result.getStatusCode(), + log.info("Call of signing service url {} finished with result {} within {} ms.", + signUrl, + result.getStatusCode(), end - start); return result.getBody(); } catch (RestClientException e) { - log.error("Connection with signing service {} could not be established.", url, e); + log.error("Connection with signing service {} could not be established.", signUrl, e); throw e; } } @@ -73,7 +81,12 @@ public boolean verifySignature(VerifySignatureRequestDto verifySignatureRequestD HttpHeaders headers = new HttpHeaders(); headers.put("Content-Type", Collections.singletonList(MediaType.APPLICATION_JSON_VALUE)); try { - ResponseEntity result = restTemplate.exchange(verifyUrl, HttpMethod.POST, new HttpEntity<>(verifySignatureRequestDto, headers), boolean.class); + ResponseEntity result = restTemplate.exchange( + verifyUrl, + HttpMethod.POST, + new HttpEntity<>(verifySignatureRequestDto, headers), + boolean.class + ); return result.getBody(); } catch (RestClientException e) { log.error("Connection with signing service {} could not be established.", verifyUrl, e); @@ -82,20 +95,26 @@ public boolean verifySignature(VerifySignatureRequestDto verifySignatureRequestD } @Cacheable(KEY_IDENTIFIER_CACHE) - public String getKeyIdentifier(String certificateAlias) { - var getKeyUrl = buildSigningUrl(kidUrl, certificateAlias); + public String getKeyIdentifier(Integer slotNumber, String certificateAlias) { + var specificKidUrl = buildKidUrl(this.kidUrl, slotNumber, certificateAlias); long start = System.currentTimeMillis(); - log.info("Call signing service to retrieve key identifier for certificate {}.", certificateAlias); + log.info("Call signing service with url {}", specificKidUrl); try { - ResponseEntity result = restTemplate.exchange(getKeyUrl, HttpMethod.GET, - new HttpEntity<>(new HttpHeaders()), String.class); + ResponseEntity result = restTemplate.exchange( + specificKidUrl, + HttpMethod.GET, + new HttpEntity<>(new HttpHeaders()), + String.class + ); long end = System.currentTimeMillis(); - log.info("Call of signing service finished with result {} within {} ms.", result.getStatusCode(), + log.info("Call of signing service url {} finished with result {} within {} ms.", + specificKidUrl, + result.getStatusCode(), end - start); return result.getBody(); } catch (RestClientException e) { - log.error("Connection with signing service {} could not be established.", url, e); + log.error("Connection with signing service {} could not be established.", specificKidUrl, e); throw e; } } @@ -106,10 +125,10 @@ public void cleanKeyIdentifierCache() { log.info("Cleaning cache of key identifier"); } - private String buildSigningUrl(String url, String pathSegment) { + private String buildKidUrl(String url, Integer slotNumber, String kid) { return new DefaultUriBuilderFactory() .uriString(url) - .pathSegment(pathSegment) + .pathSegment(slotNumber.toString(), kid) .build().toString(); } } diff --git a/src/main/java/ch/admin/bag/covidcertificate/client/signing/internal/MockSigningClient.java b/src/main/java/ch/admin/bag/covidcertificate/client/signing/internal/MockSigningClient.java index b1ad6053..5b2292f6 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/client/signing/internal/MockSigningClient.java +++ b/src/main/java/ch/admin/bag/covidcertificate/client/signing/internal/MockSigningClient.java @@ -30,7 +30,7 @@ public boolean verifySignature(VerifySignatureRequestDto verifySignatureRequestD } @SneakyThrows - public String getKeyIdentifier(String certificateAlias){ + public String getKeyIdentifier(Integer slotNumber, String certificateAlias){ var outputStream = new ByteArrayOutputStream(); new HexEncoder().encode(UUID.randomUUID().toString().getBytes(), 0, 8, outputStream); return outputStream.toString(); diff --git a/src/main/java/ch/admin/bag/covidcertificate/domain/SigningInformation.java b/src/main/java/ch/admin/bag/covidcertificate/domain/SigningInformation.java index 8d59b6b4..58f66f24 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/domain/SigningInformation.java +++ b/src/main/java/ch/admin/bag/covidcertificate/domain/SigningInformation.java @@ -29,6 +29,7 @@ public class SigningInformation { private String code; private String alias; private String certificateAlias; + private Integer slotNumber; private LocalDate validFrom; private LocalDate validTo; @@ -37,6 +38,7 @@ public SigningInformation( String code, String alias, String certificateAlias, + Integer slotNumber, LocalDate validFrom, LocalDate validTo) { @@ -44,6 +46,7 @@ public SigningInformation( this.code = code; this.alias = alias; this.certificateAlias = certificateAlias; + this.slotNumber = slotNumber; this.validFrom = validFrom; this.validTo = validTo; } diff --git a/src/main/java/ch/admin/bag/covidcertificate/service/COSEService.java b/src/main/java/ch/admin/bag/covidcertificate/service/COSEService.java index 66e71493..5e7be2d6 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/service/COSEService.java +++ b/src/main/java/ch/admin/bag/covidcertificate/service/COSEService.java @@ -34,7 +34,10 @@ public byte[] getCOSESign1(byte[] dgcCBOR, SigningInformationDto signingInformat private byte[] getProtectedHeader(SigningInformationDto signingInformation) { try { if (StringUtils.isNotBlank(signingInformation.getCertificateAlias())) { - var keyIdentifier = signingClient.getKeyIdentifier(signingInformation.getCertificateAlias()); + var keyIdentifier = signingClient.getKeyIdentifier( + signingInformation.getSlotNumber(), + signingInformation.getCertificateAlias() + ); signingInformation.setCalculatedKeyIdentifier(keyIdentifier); return cborService.getProtectedHeader(keyIdentifier); } diff --git a/src/main/java/ch/admin/bag/covidcertificate/web/controller/test/SigningInformationStatus.java b/src/main/java/ch/admin/bag/covidcertificate/web/controller/test/SigningInformationStatus.java new file mode 100644 index 00000000..6407c9da --- /dev/null +++ b/src/main/java/ch/admin/bag/covidcertificate/web/controller/test/SigningInformationStatus.java @@ -0,0 +1,9 @@ +package ch.admin.bag.covidcertificate.web.controller.test; + +public enum SigningInformationStatus { + OK, + WARN_NOT_PRESENT, + ERROR_INVALID, + ERROR + ; +} diff --git a/src/main/java/ch/admin/bag/covidcertificate/web/controller/test/TestController.java b/src/main/java/ch/admin/bag/covidcertificate/web/controller/test/TestController.java index 9421b185..3d17cc19 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/web/controller/test/TestController.java +++ b/src/main/java/ch/admin/bag/covidcertificate/web/controller/test/TestController.java @@ -32,11 +32,16 @@ import javax.validation.Valid; import java.io.IOException; import java.time.LocalDate; -import java.util.ArrayList; import java.util.Base64; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import java.util.UUID; +/** + * /internal routes are not allowed to be whitelisted! + * + * The TestController can be used to verify current and future signing_information configuration. + */ @RestController @RequestMapping("/internal/api/v1/test") @RequiredArgsConstructor @@ -48,19 +53,23 @@ public class TestController { private final TestCovidCertificateGenerationService testCovidCertificateGenerationService; @GetMapping("/{validAt}") - public List testSigningInformationConfiguration( + public Map testSigningInformationConfiguration( @PathVariable @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate validAt) { - List errors = new ArrayList<>(); + Map checkedSigningInformationToStatus = new HashMap<>(); for (SigningCertificateCategory signingCertificateCategory : SigningCertificateCategory.values()) { - var signingInformationList = signingInformationRepository - .findSigningInformation(signingCertificateCategory.value, validAt); + var signingInformationList = signingInformationRepository.findSigningInformation( + signingCertificateCategory.value, + validAt + ); for (SigningInformation signingInformation : signingInformationList) { try { var messageBytes = UUID.randomUUID().toString().getBytes(); - var signatureBytes = signingClient - .createSignature(messageBytes, SigningInformationMapper.fromEntity(signingInformation)); + var signatureBytes = signingClient.createSignature( + messageBytes, + SigningInformationMapper.fromEntity(signingInformation) + ); if (StringUtils.isNotBlank(signingInformation.getCertificateAlias())) { var message = Base64.getEncoder().encodeToString(messageBytes); @@ -69,21 +78,25 @@ public List testSigningInformationConfiguration( var verifySignatureDto = new VerifySignatureRequestDto( message, signature, - signingInformation.getCertificateAlias() + signingInformation.getCertificateAlias(), + signingInformation.getSlotNumber() ); var validSignature = signingClient.verifySignature(verifySignatureDto); - if (!validSignature) { - errors.add(signingInformation); + + if (validSignature) { + checkedSigningInformationToStatus.put(signingInformation, SigningInformationStatus.OK); + } else { + checkedSigningInformationToStatus.put(signingInformation, SigningInformationStatus.ERROR_INVALID); } } else { - log.warn("No certificate alias found for signing information {}", signingInformation.getId().toString()); + checkedSigningInformationToStatus.put(signingInformation, SigningInformationStatus.WARN_NOT_PRESENT); } } catch (Exception e) { - errors.add(signingInformation); + checkedSigningInformationToStatus.put(signingInformation, SigningInformationStatus.ERROR); } } } - return errors; + return checkedSigningInformationToStatus; } @PostMapping("/vaccination/{validAt}") @@ -156,8 +169,10 @@ public ConvertedCertificateResponseDto convertVaccinationCertificate( conversionRequestDto.validate(); ConvertedCertificateResponseEnvelope convertedCertificateResponseEnvelope = - testCovidCertificateGenerationService.convertFromExistingCovidCertificate(conversionRequestDto, - validAt); + testCovidCertificateGenerationService.convertFromExistingCovidCertificate( + conversionRequestDto, + validAt + ); log.info("Used key-id for conversion/vaccination: {}", convertedCertificateResponseEnvelope.getUsedKeyIdentifier()); return convertedCertificateResponseEnvelope.getResponseDto(); diff --git a/src/main/resources/db/migration/common/V1_0_56__add_slot_to_signing_information.sql b/src/main/resources/db/migration/common/V1_0_56__add_slot_to_signing_information.sql new file mode 100644 index 00000000..bb8a6dd0 --- /dev/null +++ b/src/main/resources/db/migration/common/V1_0_56__add_slot_to_signing_information.sql @@ -0,0 +1,2 @@ +alter table signing_information + add column if not exists slot_number integer not null default 0; \ No newline at end of file diff --git a/src/test/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClientCacheIntegrationTest.java b/src/test/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClientCacheIntegrationTest.java index cb722b2e..1c3b0af2 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClientCacheIntegrationTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClientCacheIntegrationTest.java @@ -75,14 +75,15 @@ class GetKeyIdentifier { @Test void shouldCallSigningServiceAndWriteResultInCache_whenNotAlreadyInCache(){ var certificateAlias = fixture.create(String.class); + Integer slot = fixture.create(Integer.class); ResponseEntity responseEntity = mock(ResponseEntity.class); lenient().when(responseEntity.getBody()).thenReturn(fixture.create(String.class)); lenient().when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), eq(String.class))).thenReturn(responseEntity); - signingClient.getKeyIdentifier(certificateAlias); + signingClient.getKeyIdentifier(slot, certificateAlias); verify(restTemplate).exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), eq(String.class)); - assertEquals(responseEntity.getBody(), Objects.requireNonNull(getCache().get(certificateAlias)).get()); + assertEquals(responseEntity.getBody(), Objects.requireNonNull(getCache().get(new SimpleKey(slot, certificateAlias))).get()); } @Test @@ -92,11 +93,12 @@ void shouldNotCallSigningService_whenAlreadyInCache(){ lenient().when(responseEntity.getBody()).thenReturn(fixture.create(String.class)); lenient().when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), eq(String.class))).thenReturn(responseEntity); - signingClient.getKeyIdentifier(certificateAlias); + Integer slot = fixture.create(Integer.class); + signingClient.getKeyIdentifier(slot, certificateAlias); verify(restTemplate, times(1)).exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), eq(String.class)); clearInvocations(restTemplate); - signingClient.getKeyIdentifier(certificateAlias); + signingClient.getKeyIdentifier(slot, certificateAlias); verifyNoInteractions(restTemplate); } diff --git a/src/test/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClientTest.java b/src/test/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClientTest.java index 5778bba3..86d9ca26 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClientTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/client/signing/internal/DefaultSigningClientTest.java @@ -46,9 +46,9 @@ class DefaultSigningClientTest { private final JFixture fixture = new JFixture(); @BeforeEach - public void init(){ - String url = fixture.create(String.class); - ReflectionTestUtils.setField(signingClient, "url", url); + public void init() { + String signUrl = fixture.create(String.class); + ReflectionTestUtils.setField(signingClient, "signUrl", signUrl); String verifyUrl = fixture.create(String.class); ReflectionTestUtils.setField(signingClient, "verifyUrl", verifyUrl); String kidUrl = fixture.create(String.class); @@ -65,16 +65,16 @@ public void init(){ } @Nested - class CreateSignature{ + class CreateSignature { @Test void makesRequestToCorrectUrl() { - var url = fixture.create(String.class); - ReflectionTestUtils.setField(signingClient, "url", url); + var signUrl = fixture.create(String.class); + ReflectionTestUtils.setField(signingClient, "signUrl", signUrl); var signingInformation = fixture.create(SigningInformationDto.class); signingClient.createSignature(fixture.create(byte[].class), signingInformation); - verify(restTemplate).exchange(eq(url), any(HttpMethod.class), any(HttpEntity.class), any(Class.class)); + verify(restTemplate).exchange(eq(signUrl), any(HttpMethod.class), any(HttpEntity.class), any(Class.class)); } @Test @@ -88,14 +88,17 @@ void makesPostRequest() { void makesRequestWithCorrectBody() { var body = fixture.create(byte[].class); var signingInformation = fixture.create(SigningInformationDto.class); - var signingRequestDto = new SigningRequestDto(Base64.getEncoder().encodeToString(body), - signingInformation.getAlias()); + var signingRequestDto = new SigningRequestDto( + Base64.getEncoder().encodeToString(body), + signingInformation.getAlias(), + signingInformation.getSlotNumber() + ); signingClient.createSignature(body, signingInformation); verify(restTemplate).exchange(anyString(), any(HttpMethod.class), - argThat(argument -> Objects.equals(argument.getBody(), signingRequestDto)), - any(Class.class)); + argThat(argument -> Objects.equals(argument.getBody(), signingRequestDto)), + any(Class.class)); } @Test @@ -103,10 +106,10 @@ void returnsResponseBody() { ResponseEntity responseEntity = mock(ResponseEntity.class); when(responseEntity.getBody()).thenReturn(fixture.create(byte[].class)); when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), - any(Class.class))).thenReturn(responseEntity); + any(Class.class))).thenReturn(responseEntity); var actual = signingClient.createSignature(fixture.create(byte[].class), - fixture.create(SigningInformationDto.class)); + fixture.create(SigningInformationDto.class)); assertEquals(responseEntity.getBody(), actual); } @@ -125,7 +128,7 @@ void throwsExceptionIfRequestThrowsException() { } @Nested - class VerifySignature{ + class VerifySignature { @Test void makesRequestToCorrectUrl() { var verifyUrl = fixture.create(String.class); @@ -145,11 +148,11 @@ void makesPostRequest() { @Test void makesRequestWithCorrectBody() { - var verifySignatureRequestDto = fixture.create(VerifySignatureRequestDto.class); + var verifySignatureRequestDto = fixture.create(VerifySignatureRequestDto.class); signingClient.verifySignature(verifySignatureRequestDto); - verify(restTemplate).exchange(anyString(), any(HttpMethod.class), argThat(argument -> Objects.equals(argument.getBody(), verifySignatureRequestDto)) , any(Class.class)); + verify(restTemplate).exchange(anyString(), any(HttpMethod.class), argThat(argument -> Objects.equals(argument.getBody(), verifySignatureRequestDto)), any(Class.class)); } @Test @@ -176,22 +179,23 @@ void throwsExceptionIfRequestThrowsException() { } @Nested - class GetKeyIdentifier{ + class GetKeyIdentifier { @Test void makesRequestToCorrectUrl() { var url = UUID.randomUUID().toString(); - var certificateAlias = fixture.create(String.class); - var fullUrl = url+"/"+certificateAlias; + var slotNumber = fixture.create(Integer.class); + var certificateAlias = fixture.create(String.class); + var fullUrl = url + "/" + slotNumber + "/" + certificateAlias; ReflectionTestUtils.setField(signingClient, "kidUrl", url); - signingClient.getKeyIdentifier(certificateAlias); + signingClient.getKeyIdentifier(slotNumber, certificateAlias); verify(restTemplate).exchange(eq(fullUrl), any(HttpMethod.class), any(HttpEntity.class), any(Class.class)); } @Test void makesGetRequest() { - signingClient.getKeyIdentifier(fixture.create(String.class)); + signingClient.getKeyIdentifier(fixture.create(Integer.class), fixture.create(String.class)); verify(restTemplate).exchange(anyString(), eq(HttpMethod.GET), any(HttpEntity.class), any(Class.class)); } @@ -202,7 +206,7 @@ void returnsResponseBody() { when(responseEntity.getBody()).thenReturn(fixture.create(String.class)); when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))).thenReturn(responseEntity); - var actual = signingClient.getKeyIdentifier(fixture.create(String.class)); + var actual = signingClient.getKeyIdentifier(fixture.create(Integer.class), fixture.create(String.class)); assertEquals(responseEntity.getBody(), actual); } @@ -213,7 +217,7 @@ void throwsExceptionIfRequestThrowsException() { var signingInformation = fixture.create(String.class); when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))).thenThrow(exception); - var actual = assertThrows(RestClientException.class, () -> signingClient.getKeyIdentifier(signingInformation)); + var actual = assertThrows(RestClientException.class, () -> signingClient.getKeyIdentifier(fixture.create(Integer.class), signingInformation)); assertEquals(exception, actual); } diff --git a/src/test/java/ch/admin/bag/covidcertificate/service/COSEServiceTest.java b/src/test/java/ch/admin/bag/covidcertificate/service/COSEServiceTest.java index d82761ef..3343c4e2 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/service/COSEServiceTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/service/COSEServiceTest.java @@ -61,14 +61,14 @@ void callsSigningService_toGetKeyIdentifier_whenCertificateAliasIsPresent() { var signingInformation = fixture.create(SigningInformationDto.class); coseService.getCOSESign1(fixture.create(byte[].class), signingInformation, fixture.create(Instant.class)); // then - verify(signingClient).getKeyIdentifier(signingInformation.getCertificateAlias()); + verify(signingClient).getKeyIdentifier(signingInformation.getSlotNumber(), signingInformation.getCertificateAlias()); } @Test void callsCBORServiceGetProtectedHeader_withIdentifierFromSigningService_whenCertificateAliasIsPresent() throws Exception { var signingInformation = fixture.create(SigningInformationDto.class); var keyIdentifier = fixture.create(String.class); - when(signingClient.getKeyIdentifier(any())).thenReturn(keyIdentifier); + when(signingClient.getKeyIdentifier(any(), any())).thenReturn(keyIdentifier); coseService.getCOSESign1(fixture.create(byte[].class), signingInformation, fixture.create(Instant.class)); // then verify(cborService).getProtectedHeader(keyIdentifier); diff --git a/src/test/java/ch/admin/bag/covidcertificate/service/SigningInformationCacheServiceIntegrationTest.java b/src/test/java/ch/admin/bag/covidcertificate/service/SigningInformationCacheServiceIntegrationTest.java index 7c54df03..4e479634 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/service/SigningInformationCacheServiceIntegrationTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/service/SigningInformationCacheServiceIntegrationTest.java @@ -58,20 +58,18 @@ class SigningInformationCacheServiceIntegrationTest { @BeforeEach private void setup() { getCache().clear(); - lenient().when(signingInformationRepository - .findSigningInformation(any(), any(), any())).thenReturn( - fixture.create(SigningInformation.class)); - lenient().when(signingInformationRepository - .findSigningInformation(any(), any())).thenReturn(Collections.singletonList( - fixture.create(SigningInformation.class))); + lenient().when(signingInformationRepository.findSigningInformation(any(), any(), any())) + .thenReturn(fixture.create(SigningInformation.class)); + lenient().when(signingInformationRepository.findSigningInformation(any(), any())) + .thenReturn(Collections.singletonList(fixture.create(SigningInformation.class))); } - private Cache getCache(){ + private Cache getCache() { return Objects.requireNonNull(cacheManager.getCache("signingInformationCache")); } @Nested - class FindSigningInformationOnlyByCertificateType{ + class FindSigningInformationOnlyByCertificateType { @Test void shouldCallRepositoryAndWriteResultInCache_ifNotInCache() { var certificateType = fixture.create(String.class); @@ -90,7 +88,7 @@ void shouldCallRepositoryAndWriteResultInCache_ifNotInCache() { } @Test - void shouldNotCallRepositoryIfSigningInformationAreInCache(){ + void shouldNotCallRepositoryIfSigningInformationAreInCache() { var certificateType = fixture.create(String.class); var validAt = fixture.create(LocalDate.class); var signingInformationList = Collections.singletonList(fixture.create(SigningInformation.class)); @@ -107,9 +105,9 @@ void shouldNotCallRepositoryIfSigningInformationAreInCache(){ } @Nested - class FindSigningInformation{ + class FindSigningInformation { @Test - void shouldCallRepositoryAndWriteResultInCache_ifNotInCache(){ + void shouldCallRepositoryAndWriteResultInCache_ifNotInCache() { var certificateType = fixture.create(String.class); var code = fixture.create(String.class); var validAt = fixture.create(LocalDate.class); @@ -122,11 +120,11 @@ void shouldCallRepositoryAndWriteResultInCache_ifNotInCache(){ verify(signingInformationRepository).findSigningInformation(eq(certificateType), eq(code), any()); assertEquals(expectedDto, - Objects.requireNonNull(getCache().get(new SimpleKey(certificateType, code, validAt))).get()); + Objects.requireNonNull(getCache().get(new SimpleKey(certificateType, code, validAt))).get()); } @Test - void shouldNotCallRepositoryIfSigningInformationAreInCache(){ + void shouldNotCallRepositoryIfSigningInformationAreInCache() { var certificateType = fixture.create(String.class); var code = fixture.create(String.class); var validAt = fixture.create(LocalDate.class); @@ -144,13 +142,13 @@ void shouldNotCallRepositoryIfSigningInformationAreInCache(){ } @Nested - class CleanSigningInformationCache{ + class CleanSigningInformationCache { @Test - void shouldRemoveAllEntriesFromTheCache(){ + void shouldRemoveAllEntriesFromTheCache() { var simpleKeys = new ArrayList<>(fixture.collections().createCollection(SimpleKey.class, 3)); var values = new ArrayList<>(fixture.collections().createCollection(String.class, 3)); //setup cache - for(int i=0; i<3; i++){ + for (int i = 0; i < 3; i++) { getCache().put(simpleKeys.get(i), values.get(i)); assertNotNull(getCache().get(simpleKeys.get(i))); } @@ -158,7 +156,7 @@ void shouldRemoveAllEntriesFromTheCache(){ //Clean Cache signingInformationCacheService.cleanSigningInformationCache(); - for(int i=0; i<3; i++){ + for (int i = 0; i < 3; i++) { assertNull(getCache().get(simpleKeys.get(i))); } } From 35bbc647265c554817a4905ad704e238b8afd13c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20L=C3=B6sing?= Date: Thu, 7 Jul 2022 16:30:30 +0200 Subject: [PATCH 09/23] separated generation and pdf service and completed test cases for alle certificate types. --- .../bag/covidcertificate/api/Constants.java | 7 +- .../CovidCertificateGenerationService.java | 136 +- .../CovidCertificatePdfGenerationService.java | 150 ++ .../util/DateDeserializer.java | 26 +- .../util/ZonedDateTimeDeserializer.java | 5 +- .../CovidCertificateGenerationController.java | 11 + ...CovidCertificatePdfGenerateController.java | 25 +- .../FixtureCustomization.java | 13 +- .../covidcertificate/TestModelProvider.java | 199 ++- .../AntibodyCertificateQrCodeMapperTest.java | 16 +- ...CovidCertificateGenerationServiceTest.java | 1577 ++++++++++++----- ...idCertificatePdfGenerationServiceTest.java | 726 ++++++++ ...icateGenerationControllerSecurityTest.java | 182 +- ...idCertificateGenerationControllerTest.java | 276 ++- ...tePdfGenerationControllerSecurityTest.java | 51 +- ...ertificatePdfGenerationControllerTest.java | 16 +- .../controller/RevocationControllerTest.java | 104 -- .../RevocationListControllerTest.java | 1 + 18 files changed, 2732 insertions(+), 789 deletions(-) create mode 100644 src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationService.java create mode 100644 src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationServiceTest.java diff --git a/src/main/java/ch/admin/bag/covidcertificate/api/Constants.java b/src/main/java/ch/admin/bag/covidcertificate/api/Constants.java index eceb6833..d1ecf3b5 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/api/Constants.java +++ b/src/main/java/ch/admin/bag/covidcertificate/api/Constants.java @@ -114,7 +114,12 @@ public class Constants { public static final CreateCertificateError INVALID_DATE_OF_BIRTH_IN_FUTURE = new CreateCertificateError(489, "Invalid dateOfBirth! Date cannot be in the future", HttpStatus.BAD_REQUEST); public static final CreateCertificateError NO_ANTIBODY_DATA = new CreateCertificateError(490, "No antibody data specified", HttpStatus.BAD_REQUEST); public static final CreateCertificateError INVALID_ANTIBODY_SAMPLE_DATE_TIME = new CreateCertificateError(491, "Date of sample collection must not be before 16.11.2021", HttpStatus.BAD_REQUEST); - public static final CreateCertificateError NO_EXCEPTIONAL_INFO = new CreateCertificateError(492, "No exceptional data specified", HttpStatus.BAD_REQUEST); + public static final CreateCertificateError NO_EXCEPTIONAL_INFO = new CreateCertificateError(492, + "No exceptional data specified", + HttpStatus.BAD_REQUEST); + public static final CreateCertificateError INVALID_EXCEPTIONAL_VALID_FROM_DATE = new CreateCertificateError(493, + "Invalid date for valid from field", + HttpStatus.BAD_REQUEST); public static final CreateCertificateError DATE_CANT_BE_BEFORE = new CreateCertificateError(494, "Date can't be before %s!", HttpStatus.BAD_REQUEST); public static final CreateCertificateError DATE_CANT_BE_AFTER = new CreateCertificateError(495, "Date can't be after %s!", HttpStatus.BAD_REQUEST); diff --git a/src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificateGenerationService.java b/src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificateGenerationService.java index f029de2c..efda079c 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificateGenerationService.java +++ b/src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificateGenerationService.java @@ -1,7 +1,6 @@ package ch.admin.bag.covidcertificate.service; import ch.admin.bag.covidcertificate.api.Constants; -import ch.admin.bag.covidcertificate.api.exception.CreateCertificateException; import ch.admin.bag.covidcertificate.api.mapper.CertificatePrintRequestDtoMapper; import ch.admin.bag.covidcertificate.api.request.AntibodyCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.CertificateCreateDto; @@ -11,13 +10,6 @@ import ch.admin.bag.covidcertificate.api.request.TestCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.VaccinationCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.VaccinationTouristCertificateCreateDto; -import ch.admin.bag.covidcertificate.api.request.pdfgeneration.AntibodyCertificatePdfGenerateRequestDto; -import ch.admin.bag.covidcertificate.api.request.pdfgeneration.ExceptionalCertificatePdfGenerateRequestDto; -import ch.admin.bag.covidcertificate.api.request.pdfgeneration.RecoveryCertificatePdfGenerateRequestDto; -import ch.admin.bag.covidcertificate.api.request.pdfgeneration.RecoveryRatCertificatePdfGenerateRequestDto; -import ch.admin.bag.covidcertificate.api.request.pdfgeneration.TestCertificatePdfGenerateRequestDto; -import ch.admin.bag.covidcertificate.api.request.pdfgeneration.VaccinationCertificatePdfGenerateRequestDto; -import ch.admin.bag.covidcertificate.api.request.pdfgeneration.VaccinationTouristCertificatePdfGenerateRequestDto; import ch.admin.bag.covidcertificate.api.response.CovidCertificateCreateResponseDto; import ch.admin.bag.covidcertificate.api.response.CovidCertificateResponseEnvelope; import ch.admin.bag.covidcertificate.client.inapp_delivery.InAppDeliveryClient; @@ -32,147 +24,26 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import se.digg.dgc.encoding.BarcodeException; -import se.digg.dgc.encoding.impl.DefaultBarcodeCreator; -import java.nio.charset.StandardCharsets; import java.time.Instant; import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.ZonedDateTime; import java.util.Base64; -import static ch.admin.bag.covidcertificate.api.Constants.CREATE_BARCODE_FAILED; - @Service @Slf4j @RequiredArgsConstructor public class CovidCertificateGenerationService { + private final BarcodeService barcodeService; private final PrintQueueClient printQueueClient; private final InAppDeliveryClient inAppDeliveryClient; private final ObjectMapper objectMapper; private final PdfCertificateGenerationService pdfCertificateGenerationService; private final CovidCertificateDtoMapperService ccDtoMapperService; - private final CovidCertificatePdfGenerateRequestDtoMapperService pdfDtoMapperService; private final CertificatePrintRequestDtoMapper certificatePrintRequestDtoMapper; private final SigningInformationService signingInformationService; private final COSETime coseTime; - public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( - VaccinationCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { - - var pdfData = pdfDtoMapperService.toVaccinationCertificatePdf(pdfGenerateRequestDto); - return generateFromExistingCovidCertificate(pdfData, - pdfGenerateRequestDto.getHcert(), - pdfGenerateRequestDto.getIssuedAt(), - pdfGenerateRequestDto.getDecodedCert() - .getVaccinationInfo() - .get(0) - .getIdentifier()); - } - - public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( - VaccinationTouristCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { - - var pdfData = pdfDtoMapperService - .toVaccinationTouristCertificatePdf(pdfGenerateRequestDto); - return generateFromExistingCovidCertificate(pdfData, - pdfGenerateRequestDto.getHcert(), - pdfGenerateRequestDto.getIssuedAt(), - pdfGenerateRequestDto.getDecodedCert() - .getVaccinationTouristInfo() - .get(0) - .getIdentifier()); - } - - public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( - TestCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { - - var pdfData = pdfDtoMapperService.toTestCertificatePdf(pdfGenerateRequestDto); - return generateFromExistingCovidCertificate(pdfData, - pdfGenerateRequestDto.getHcert(), - pdfGenerateRequestDto.getIssuedAt(), - pdfGenerateRequestDto.getDecodedCert() - .getTestInfo() - .get(0) - .getIdentifier()); - } - - public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( - RecoveryCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { - - var pdfData = pdfDtoMapperService.toRecoveryCertificatePdf(pdfGenerateRequestDto); - return generateFromExistingCovidCertificate(pdfData, - pdfGenerateRequestDto.getHcert(), - pdfGenerateRequestDto.getIssuedAt(), - pdfGenerateRequestDto.getDecodedCert() - .getRecoveryInfo() - .get(0) - .getIdentifier()); - } - - public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( - RecoveryRatCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { - - var pdfData = pdfDtoMapperService.toRecoveryRatCertificatePdf(pdfGenerateRequestDto); - return generateFromExistingCovidCertificate(pdfData, - pdfGenerateRequestDto.getHcert(), - pdfGenerateRequestDto.getIssuedAt(), - pdfGenerateRequestDto.getDecodedCert() - .getTestInfo() - .get(0) - .getIdentifier()); - } - - public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( - AntibodyCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { - - var pdfData = pdfDtoMapperService.toAntibodyCertificatePdf(pdfGenerateRequestDto); - return generateFromExistingCovidCertificate(pdfData, - pdfGenerateRequestDto.getHcert(), - pdfGenerateRequestDto.getIssuedAt(), - pdfGenerateRequestDto.getDecodedCert() - .getAntibodyInfo() - .get(0) - .getIdentifier()); - } - - public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( - ExceptionalCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { - - var pdfData = pdfDtoMapperService.toExceptionalCertificatePdf(pdfGenerateRequestDto); - return generateFromExistingCovidCertificate(pdfData, - pdfGenerateRequestDto.getHcert(), - pdfGenerateRequestDto.getIssuedAt(), - pdfGenerateRequestDto.getDecodedCert() - .getExceptionalInfo() - .get(0) - .getIdentifier()); - } - - private CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( - AbstractCertificatePdf pdfData, - String hcert, - long issuedAtMillis, - String uvci) { - - try { - var issuedAt = getLocalDateTimeFromEpochMillis(issuedAtMillis); - var barcode = new DefaultBarcodeCreator().create(hcert, StandardCharsets.US_ASCII); - var pdf = pdfCertificateGenerationService.generateCovidCertificate(pdfData, hcert, issuedAt); - var responseDto = new CovidCertificateCreateResponseDto(pdf, barcode.getImage(), uvci); - return new CovidCertificateResponseEnvelope(responseDto, null); - } catch (BarcodeException e) { - throw new CreateCertificateException(CREATE_BARCODE_FAILED); - } - } - - private LocalDateTime getLocalDateTimeFromEpochMillis(long millis) { - var instant = Instant.ofEpochMilli(millis); - return ZonedDateTime.from(instant.atZone(ZoneId.systemDefault())).toLocalDateTime(); - } - public CovidCertificateResponseEnvelope generateCovidCertificate(VaccinationCertificateCreateDto createDto) throws JsonProcessingException { @@ -323,8 +194,7 @@ private CovidCertificateResponseEnvelope generateCovidCertificate( var createError = this.inAppDeliveryClient.deliverToApp(uvci, inAppDeliveryDto); // null if no error responseDto.setAppDeliveryError(createError); } - var envelope = new CovidCertificateResponseEnvelope(responseDto, - signingInformation.getCalculatedKeyIdentifier()); - return envelope; + return new CovidCertificateResponseEnvelope(responseDto, + signingInformation.getCalculatedKeyIdentifier()); } } diff --git a/src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationService.java b/src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationService.java new file mode 100644 index 00000000..03d775c9 --- /dev/null +++ b/src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationService.java @@ -0,0 +1,150 @@ +package ch.admin.bag.covidcertificate.service; + +import ch.admin.bag.covidcertificate.api.exception.CreateCertificateException; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.AntibodyCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.ExceptionalCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.RecoveryCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.RecoveryRatCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.TestCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.VaccinationCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.VaccinationTouristCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.response.CovidCertificateCreateResponseDto; +import ch.admin.bag.covidcertificate.api.response.CovidCertificateResponseEnvelope; +import ch.admin.bag.covidcertificate.service.document.PdfCertificateGenerationService; +import ch.admin.bag.covidcertificate.service.domain.AbstractCertificatePdf; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import se.digg.dgc.encoding.BarcodeException; +import se.digg.dgc.encoding.impl.DefaultBarcodeCreator; + +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import static ch.admin.bag.covidcertificate.api.Constants.CREATE_BARCODE_FAILED; + +@Service +@Slf4j +@RequiredArgsConstructor +public class CovidCertificatePdfGenerationService { + + private final CovidCertificatePdfGenerateRequestDtoMapperService pdfDtoMapperService; + private final PdfCertificateGenerationService pdfCertificateGenerationService; + + public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( + VaccinationCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { + + var pdfData = pdfDtoMapperService.toVaccinationCertificatePdf(pdfGenerateRequestDto); + return generateFromExistingCovidCertificate(pdfData, + pdfGenerateRequestDto.getHcert(), + pdfGenerateRequestDto.getIssuedAt(), + pdfGenerateRequestDto.getDecodedCert() + .getVaccinationInfo() + .get(0) + .getIdentifier()); + } + + public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( + VaccinationTouristCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { + + var pdfData = pdfDtoMapperService + .toVaccinationTouristCertificatePdf(pdfGenerateRequestDto); + return generateFromExistingCovidCertificate(pdfData, + pdfGenerateRequestDto.getHcert(), + pdfGenerateRequestDto.getIssuedAt(), + pdfGenerateRequestDto.getDecodedCert() + .getVaccinationTouristInfo() + .get(0) + .getIdentifier()); + } + + public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( + TestCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { + + var pdfData = pdfDtoMapperService.toTestCertificatePdf(pdfGenerateRequestDto); + return generateFromExistingCovidCertificate(pdfData, + pdfGenerateRequestDto.getHcert(), + pdfGenerateRequestDto.getIssuedAt(), + pdfGenerateRequestDto.getDecodedCert() + .getTestInfo() + .get(0) + .getIdentifier()); + } + + public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( + RecoveryCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { + + var pdfData = pdfDtoMapperService.toRecoveryCertificatePdf(pdfGenerateRequestDto); + return generateFromExistingCovidCertificate(pdfData, + pdfGenerateRequestDto.getHcert(), + pdfGenerateRequestDto.getIssuedAt(), + pdfGenerateRequestDto.getDecodedCert() + .getRecoveryInfo() + .get(0) + .getIdentifier()); + } + + public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( + RecoveryRatCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { + + var pdfData = pdfDtoMapperService.toRecoveryRatCertificatePdf(pdfGenerateRequestDto); + return generateFromExistingCovidCertificate(pdfData, + pdfGenerateRequestDto.getHcert(), + pdfGenerateRequestDto.getIssuedAt(), + pdfGenerateRequestDto.getDecodedCert() + .getTestInfo() + .get(0) + .getIdentifier()); + } + + public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( + AntibodyCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { + + var pdfData = pdfDtoMapperService.toAntibodyCertificatePdf(pdfGenerateRequestDto); + return generateFromExistingCovidCertificate(pdfData, + pdfGenerateRequestDto.getHcert(), + pdfGenerateRequestDto.getIssuedAt(), + pdfGenerateRequestDto.getDecodedCert() + .getAntibodyInfo() + .get(0) + .getIdentifier()); + } + + public CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( + ExceptionalCertificatePdfGenerateRequestDto pdfGenerateRequestDto) { + + var pdfData = pdfDtoMapperService.toExceptionalCertificatePdf(pdfGenerateRequestDto); + return generateFromExistingCovidCertificate(pdfData, + pdfGenerateRequestDto.getHcert(), + pdfGenerateRequestDto.getIssuedAt(), + pdfGenerateRequestDto.getDecodedCert() + .getExceptionalInfo() + .get(0) + .getIdentifier()); + } + + private CovidCertificateResponseEnvelope generateFromExistingCovidCertificate( + AbstractCertificatePdf pdfData, + String hcert, + long issuedAtMillis, + String uvci) { + + try { + var issuedAt = getLocalDateTimeFromEpochMillis(issuedAtMillis); + var barcode = new DefaultBarcodeCreator().create(hcert, StandardCharsets.US_ASCII); + var pdf = pdfCertificateGenerationService.generateCovidCertificate(pdfData, hcert, issuedAt); + var responseDto = new CovidCertificateCreateResponseDto(pdf, barcode.getImage(), uvci); + return new CovidCertificateResponseEnvelope(responseDto, null); + } catch (BarcodeException e) { + throw new CreateCertificateException(CREATE_BARCODE_FAILED); + } + } + + private LocalDateTime getLocalDateTimeFromEpochMillis(long millis) { + var instant = Instant.ofEpochMilli(millis); + return ZonedDateTime.from(instant.atZone(ZoneId.systemDefault())).toLocalDateTime(); + } +} diff --git a/src/main/java/ch/admin/bag/covidcertificate/util/DateDeserializer.java b/src/main/java/ch/admin/bag/covidcertificate/util/DateDeserializer.java index d9080132..393ad43f 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/util/DateDeserializer.java +++ b/src/main/java/ch/admin/bag/covidcertificate/util/DateDeserializer.java @@ -1,9 +1,12 @@ package ch.admin.bag.covidcertificate.util; import ch.admin.bag.covidcertificate.api.exception.CreateCertificateException; +import ch.admin.bag.covidcertificate.api.request.AntibodyCertificateDataDto; +import ch.admin.bag.covidcertificate.api.request.ExceptionalCertificateDataDto; import ch.admin.bag.covidcertificate.api.request.RecoveryCertificateDataDto; import ch.admin.bag.covidcertificate.api.request.TestCertificateDataDto; import ch.admin.bag.covidcertificate.api.request.VaccinationCertificateDataDto; +import ch.admin.bag.covidcertificate.api.request.VaccinationTouristCertificateDataDto; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; @@ -13,13 +16,19 @@ import java.time.LocalDate; import java.time.format.DateTimeParseException; -import static ch.admin.bag.covidcertificate.api.Constants.*; +import static ch.admin.bag.covidcertificate.api.Constants.INVALID_DATE_OF_FIRST_POSITIVE_TEST_RESULT; +import static ch.admin.bag.covidcertificate.api.Constants.INVALID_EXCEPTIONAL_VALID_FROM_DATE; +import static ch.admin.bag.covidcertificate.api.Constants.INVALID_SAMPLE_DATE_TIME; +import static ch.admin.bag.covidcertificate.api.Constants.INVALID_VACCINATION_DATE; public class DateDeserializer extends JsonDeserializer { + static final String vaccinationTouristCertificate = VaccinationTouristCertificateDataDto.class.getSimpleName(); static final String vaccinationCertificate = VaccinationCertificateDataDto.class.getSimpleName(); static final String recoveryCertificate = RecoveryCertificateDataDto.class.getSimpleName(); + static final String antibodyCertificate = AntibodyCertificateDataDto.class.getSimpleName(); static final String testCertificate = TestCertificateDataDto.class.getSimpleName(); + static final String exceptionalCertificate = ExceptionalCertificateDataDto.class.getSimpleName(); @Override public LocalDate deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException { @@ -29,15 +38,18 @@ public LocalDate deserialize(JsonParser jsonparser, DeserializationContext conte try { String dateAsString = jsonparser.getText(); return LocalDate.parse(dateAsString); - } catch(DateTimeParseException dateTimeParseException) { + } catch (DateTimeParseException dateTimeParseException) { String origin = jsonparser.getParsingContext().getCurrentValue().getClass().getSimpleName(); - - if (vaccinationCertificate.equals(origin)) { - throw new CreateCertificateException(INVALID_VACCINATION_DATE); - } else if(recoveryCertificate.equals(origin)) { + if (vaccinationCertificate.equals(origin) || + vaccinationTouristCertificate.equals(origin)) { + throw new CreateCertificateException(INVALID_VACCINATION_DATE); + } else if (recoveryCertificate.equals(origin) || + antibodyCertificate.equals(origin)) { throw new CreateCertificateException(INVALID_DATE_OF_FIRST_POSITIVE_TEST_RESULT); - } else if(testCertificate.equals(origin)) { + } else if (testCertificate.equals(origin)) { throw new CreateCertificateException(INVALID_SAMPLE_DATE_TIME); + } else if (exceptionalCertificate.equals(origin)) { + throw new CreateCertificateException(INVALID_EXCEPTIONAL_VALID_FROM_DATE); } else { throw dateTimeParseException; } diff --git a/src/main/java/ch/admin/bag/covidcertificate/util/ZonedDateTimeDeserializer.java b/src/main/java/ch/admin/bag/covidcertificate/util/ZonedDateTimeDeserializer.java index 40bf83a7..463d0e91 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/util/ZonedDateTimeDeserializer.java +++ b/src/main/java/ch/admin/bag/covidcertificate/util/ZonedDateTimeDeserializer.java @@ -1,21 +1,18 @@ package ch.admin.bag.covidcertificate.util; import ch.admin.bag.covidcertificate.api.exception.CreateCertificateException; -import ch.admin.bag.covidcertificate.api.request.TestCertificateDataDto; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; -import java.io.IOException; import java.time.ZonedDateTime; -import java.time.format.DateTimeParseException; import static ch.admin.bag.covidcertificate.api.Constants.INVALID_SAMPLE_DATE_TIME; public class ZonedDateTimeDeserializer extends JsonDeserializer { @Override - public ZonedDateTime deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException { + public ZonedDateTime deserialize(JsonParser jsonparser, DeserializationContext context) { try { return jsonparser.getCodec().readValue(jsonparser, ZonedDateTime.class); } catch (Exception e) { diff --git a/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationController.java b/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationController.java index 00cd0159..d1e56400 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationController.java +++ b/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationController.java @@ -12,6 +12,8 @@ import ch.admin.bag.covidcertificate.service.CovidCertificateGenerationService; import ch.admin.bag.covidcertificate.service.CovidCertificateVaccinationValidationService; import ch.admin.bag.covidcertificate.service.KpiDataService; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; @@ -158,6 +160,15 @@ public CovidCertificateCreateResponseDto createMedicalExemptionCertificate( log.info("Call of create for exceptional certificate"); createDto.validate(); + try { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.findAndRegisterModules(); + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + String demo = objectMapper.writeValueAsString(createDto); + log.info("Moinsen demo is: {}", demo); + } catch (Exception ex) { + log.error("Moinsen writing failed: ", ex); + } CovidCertificateResponseEnvelope responseEnvelope = covidCertificateGenerationService .generateCovidCertificate(createDto); CovidCertificateCreateResponseDto responseDto = responseEnvelope.getResponseDto(); diff --git a/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerateController.java b/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerateController.java index 8e991bea..01be224d 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerateController.java +++ b/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerateController.java @@ -9,7 +9,7 @@ import ch.admin.bag.covidcertificate.api.request.pdfgeneration.VaccinationTouristCertificatePdfGenerateRequestDto; import ch.admin.bag.covidcertificate.api.response.CovidCertificateCreateResponseDto; import ch.admin.bag.covidcertificate.api.response.CovidCertificateResponseEnvelope; -import ch.admin.bag.covidcertificate.service.CovidCertificateGenerationService; +import ch.admin.bag.covidcertificate.service.CovidCertificatePdfGenerationService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; @@ -25,7 +25,7 @@ @Slf4j public class CovidCertificatePdfGenerateController { - private final CovidCertificateGenerationService covidCertificateGenerationService; + private final CovidCertificatePdfGenerationService covidCertificateGenerationService; @PostMapping("/vaccination") public CovidCertificateCreateResponseDto generateVaccinationPdfFromExistingCertificate( @@ -34,8 +34,7 @@ public CovidCertificateCreateResponseDto generateVaccinationPdfFromExistingCerti log.info("Call of create PDF for vaccination certificate"); CovidCertificateResponseEnvelope responseEnvelope = covidCertificateGenerationService .generateFromExistingCovidCertificate(pdfGenerateRequestDto); - CovidCertificateCreateResponseDto responseDto = responseEnvelope.getResponseDto(); - return responseDto; + return responseEnvelope.getResponseDto(); } @PostMapping("/vaccination-tourist") @@ -45,8 +44,7 @@ public CovidCertificateCreateResponseDto generateVaccinationTouristPdfFromExisti log.info("Call of create PDF for vaccination-tourist certificate"); CovidCertificateResponseEnvelope responseEnvelope = covidCertificateGenerationService .generateFromExistingCovidCertificate(pdfGenerateRequestDto); - CovidCertificateCreateResponseDto responseDto = responseEnvelope.getResponseDto(); - return responseDto; + return responseEnvelope.getResponseDto(); } @PostMapping("/test") @@ -56,8 +54,7 @@ public CovidCertificateCreateResponseDto generateTestPdfFromExistingCertificate( log.info("Call of create PDF for test certificate"); CovidCertificateResponseEnvelope responseEnvelope = covidCertificateGenerationService .generateFromExistingCovidCertificate(pdfGenerateRequestDto); - CovidCertificateCreateResponseDto responseDto = responseEnvelope.getResponseDto(); - return responseDto; + return responseEnvelope.getResponseDto(); } @PostMapping("/recovery") @@ -67,8 +64,7 @@ public CovidCertificateCreateResponseDto generateRecoveryPdfFromExistingCertific log.info("Call of create PDF for recovery certificate"); CovidCertificateResponseEnvelope responseEnvelope = covidCertificateGenerationService .generateFromExistingCovidCertificate(pdfGenerateRequestDto); - CovidCertificateCreateResponseDto responseDto = responseEnvelope.getResponseDto(); - return responseDto; + return responseEnvelope.getResponseDto(); } @PostMapping("/recovery-rat") @@ -78,8 +74,7 @@ public CovidCertificateCreateResponseDto generateRecoveryRatPdfFromExistingCerti log.info("Call of create PDF for recovery-rat certificate"); CovidCertificateResponseEnvelope responseEnvelope = covidCertificateGenerationService .generateFromExistingCovidCertificate(pdfGenerateRequestDto); - CovidCertificateCreateResponseDto responseDto = responseEnvelope.getResponseDto(); - return responseDto; + return responseEnvelope.getResponseDto(); } @PostMapping("/antibody") @@ -89,8 +84,7 @@ public CovidCertificateCreateResponseDto generateAntibodyPdfFromExistingCertific log.info("Call of create PDF for antibody certificate"); CovidCertificateResponseEnvelope responseEnvelope = covidCertificateGenerationService .generateFromExistingCovidCertificate(pdfGenerateRequestDto); - CovidCertificateCreateResponseDto responseDto = responseEnvelope.getResponseDto(); - return responseDto; + return responseEnvelope.getResponseDto(); } @PostMapping("/exceptional") @@ -100,7 +94,6 @@ public CovidCertificateCreateResponseDto generateExceptionalPdfFromExistingCerti log.info("Call of create PDF for exceptional certificate"); CovidCertificateResponseEnvelope responseEnvelope = covidCertificateGenerationService .generateFromExistingCovidCertificate(pdfGenerateRequestDto); - CovidCertificateCreateResponseDto responseDto = responseEnvelope.getResponseDto(); - return responseDto; + return responseEnvelope.getResponseDto(); } } diff --git a/src/test/java/ch/admin/bag/covidcertificate/FixtureCustomization.java b/src/test/java/ch/admin/bag/covidcertificate/FixtureCustomization.java index 63b6c762..0a235231 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/FixtureCustomization.java +++ b/src/test/java/ch/admin/bag/covidcertificate/FixtureCustomization.java @@ -8,6 +8,7 @@ import ch.admin.bag.covidcertificate.api.request.ExceptionalCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.Issuable; import ch.admin.bag.covidcertificate.api.request.RecoveryCertificateCreateDto; +import ch.admin.bag.covidcertificate.api.request.RecoveryRatCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.RevocationDto; import ch.admin.bag.covidcertificate.api.request.RevocationListDto; import ch.admin.bag.covidcertificate.api.request.SystemSource; @@ -145,11 +146,21 @@ public static void customizeRecoveryCertificateCreateDto(JFixture fixture) { }); } + public static void customizeRecoveryRatCertificateCreateDto(JFixture fixture) { + fixture.customise().lazyInstance(RecoveryRatCertificateCreateDto.class, () -> { + var helperFixture = new JFixture(); + var recoveryRatCertificateCreateDto = helperFixture.create(RecoveryRatCertificateCreateDto.class); + ReflectionTestUtils.setField(recoveryRatCertificateCreateDto, "language", DE); + return recoveryRatCertificateCreateDto; + }); + } + public static void customizeVaccinationTouristCertificateCreateDto(JFixture fixture) { fixture.customise().lazyInstance(VaccinationTouristCertificateCreateDto.class, () -> { var helperFixture = new JFixture(); customizeVaccinationTouristCertificateDataDto(helperFixture); - var vaccinationTouristCertificateCreateDto = helperFixture.create(VaccinationTouristCertificateCreateDto.class); + var vaccinationTouristCertificateCreateDto = helperFixture.create( + VaccinationTouristCertificateCreateDto.class); ReflectionTestUtils.setField(vaccinationTouristCertificateCreateDto, "language", DE); return vaccinationTouristCertificateCreateDto; }); diff --git a/src/test/java/ch/admin/bag/covidcertificate/TestModelProvider.java b/src/test/java/ch/admin/bag/covidcertificate/TestModelProvider.java index b473df95..37f752c4 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/TestModelProvider.java +++ b/src/test/java/ch/admin/bag/covidcertificate/TestModelProvider.java @@ -9,6 +9,8 @@ import ch.admin.bag.covidcertificate.api.request.ExceptionalCertificateDataDto; import ch.admin.bag.covidcertificate.api.request.RecoveryCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.RecoveryCertificateDataDto; +import ch.admin.bag.covidcertificate.api.request.RecoveryRatCertificateCreateDto; +import ch.admin.bag.covidcertificate.api.request.RecoveryRatCertificateDataDto; import ch.admin.bag.covidcertificate.api.request.SystemSource; import ch.admin.bag.covidcertificate.api.request.TestCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.TestCertificateDataDto; @@ -25,6 +27,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.Month; import java.time.ZonedDateTime; import java.util.List; @@ -45,6 +48,18 @@ public static VaccinationCertificateCreateDto getVaccinationCertificateCreateDto ); } + public static VaccinationCertificateCreateDto getVaccinationCertificateCreateDtoWithInvalidVaccinationDate( + String medicalProductCode, String language) { + return new VaccinationCertificateCreateDto( + getCovidCertificatePersonDto(), + List.of(getVaccinationCertificateDataDtoWithInvalidVaccinationDate(medicalProductCode)), + language, + getCovidCertificateAddressDto(), + null, + SystemSource.WebUI + ); + } + public static VaccinationCertificateCreateDto getVaccinationCertificateCreateDto( String familyName, String givenName, @@ -94,6 +109,79 @@ public static VaccinationCertificateCreateDto getVaccinationCertificateCreateDto ); } + public static VaccinationTouristCertificateCreateDto getVaccinationTouristCertificateCreateDto( + String medicalProductCode, String language) { + return new VaccinationTouristCertificateCreateDto( + getCovidCertificatePersonDto(), + List.of(getVaccinationTouristCertificateDataDto(medicalProductCode)), + language, + getCovidCertificateAddressDto(), + null, + SystemSource.WebUI + ); + } + + public static VaccinationTouristCertificateCreateDto getVaccinationTouristCertificateCreateDtoWithoutAddress( + String medicalProductCode, String language) { + return new VaccinationTouristCertificateCreateDto( + getCovidCertificatePersonDto(), + List.of(getVaccinationTouristCertificateDataDto(medicalProductCode)), + language, + null, + null, + SystemSource.WebUI + ); + } + + public static VaccinationTouristCertificateCreateDto getVaccinationTouristCertificateCreateDto( + String familyName, + String givenName, + LocalDate birthDate, + String medicalProductCode, + int numberOfDoses, + int totalNumberOfDoses, + LocalDate vaccinationDate, + String countryCode, + String language + ) { + CovidCertificatePersonNameDto covidCertificatePersonNameDto = new CovidCertificatePersonNameDto( + familyName, + givenName); + + CovidCertificatePersonDto covidCertificatePersonDto = new CovidCertificatePersonDto( + covidCertificatePersonNameDto, + birthDate.toString()); + + VaccinationTouristCertificateDataDto vaccinationTouristCertificateDataDto = new VaccinationTouristCertificateDataDto( + medicalProductCode, + numberOfDoses, + totalNumberOfDoses, + vaccinationDate, + countryCode + ); + + return new VaccinationTouristCertificateCreateDto( + covidCertificatePersonDto, + List.of(vaccinationTouristCertificateDataDto), + language, + null, + null, + SystemSource.WebUI + ); + } + + public static VaccinationTouristCertificateCreateDto getVaccinationTouristCertificateCreateDto( + String medicalProductCode, String language, String inAppCode) { + return new VaccinationTouristCertificateCreateDto( + getCovidCertificatePersonDto(), + List.of(getVaccinationTouristCertificateDataDto(medicalProductCode)), + language, + null, + inAppCode, + SystemSource.WebUI + ); + } + public static TestCertificateCreateDto getTestCertificateCreateDto( String typeCode, String manufacturerCode, String language) { return new TestCertificateCreateDto( @@ -118,18 +206,34 @@ public static TestCertificateCreateDto getTestCertificateCreateDto( ); } + public static String getVaccinationTouristCertificateJSONWithInvalidVaccinationDate() { + return "{\"name\":{\"familyName\":\"faimlyName\",\"givenName\":\"givenName\"},\"dateOfBirth\":\"1990-05-13\",\"language\":\"de\",\"systemSource\":\"WebUI\",\"vaccinationTouristInfo\":[{\"medicinalProductCode\":\"EU/1/20/1507\",\"numberOfDoses\":2,\"totalNumberOfDoses\":2,\"vaccinationDate\":\"2010--0202\",\"countryOfVaccination\":\"DE\"}]}"; + } + public static String getVaccinationCertificateJSONWithInvalidVaccinationDate() { return "{\"name\":{\"familyName\":\"2eaf462f-3b6a-4088-9892-fe4461dda8a3\",\"givenName\":\"1c2828d9-9ed3-4f60-b843-4d4b4eec9dc9\"},\"dateOfBirth\":\"0c511a7c-dcc7-42d1-848c-b88159f036a4\",\"language\":\"de\",\"address\":{\"streetAndNr\":\"b8463a54-d9c9-4594-b2df-efafa4926c79\",\"zipCode\":86,\"city\":\"04cab8fc-0beb-4011-8109-e6a0e034c307\",\"cantonCodeSender\":\"3bedd305-9301-48e3-9473-26e8188b01f6\"},\"appCode\":\"DB1E7078-1E31-46FD-8605-F67105907D46\",\"systemSource\":\"ApiGateway\",\"vaccinationInfo\":[{\"medicinalProductCode\":\"7dc3e1c9-9ca9-4180-b407-0741549ba898\",\"numberOfDoses\":4,\"totalNumberOfDoses\":6,\"vaccinationDate\":\"2010--0202\",\"countryOfVaccination\":\"16ebd49a-de13-407b-984e-7e2cb9611dd5\"},{\"medicinalProductCode\":\"8b306ac9-1f87-4b09-9a3c-d38a211f14f8\",\"numberOfDoses\":7,\"totalNumberOfDoses\":8,\"vaccinationDate\":[2021,10,15],\"countryOfVaccination\":\"ea06cb48-e2cc-4a53-9f86-6e7221734728\"},{\"medicinalProductCode\":\"aedecc6e-a6ca-4149-8d72-e0d188f8d66d\",\"numberOfDoses\":7,\"totalNumberOfDoses\":8,\"vaccinationDate\":[2021,10,15],\"countryOfVaccination\":\"dfa035fc-21f0-447b-b8ee-ddcc651c8cd3\"}]}"; } + public static String getAntibodyCertificateCreateJSONWithInvalidPositiveTestResultDate() { + return "{\"name\":{\"familyName\":\"faimlyName\",\"givenName\":\"givenName\"},\"dateOfBirth\":\"1990-05-13\",\"language\":\"de\",\"address\":null,\"appCode\":null,\"systemSource\":\"WebUI\",\"userExtId\":null,\"antibodyInfo\":[{\"sampleDate\":\"2021-1117\",\"testingCenterOrFacility\":\"Test Center\"}],\"deliverablePerPost\":true}"; + } + public static String getRecoveryCertificateCreateJSONWithInvalidPositiveTestResultDate() { return "{\"name\":{\"familyName\":\"faimlyName\",\"givenName\":\"givenName\"},\"dateOfBirth\":\"1990-05-13\",\"language\":\"de\",\"address\":null,\"appCode\":\"null\",\"systemSource\":\"WebUI\",\"recoveryInfo\":[{\"dateOfFirstPositiveTestResult\":\"2010--0505\",\"countryOfTest\":\"CH\"}]}"; } + public static String getRecoveryRatCertificateCreateJSONWithInvalidPositiveTestResultDate() { + return "{\"name\":{\"familyName\":\"faimlyName\",\"givenName\":\"givenName\"},\"dateOfBirth\":\"1990-05-13\",\"language\":\"de\",\"address\":null,\"appCode\":\"null\",\"systemSource\":\"WebUI\",\"testInfo\":[{\"sampleDateTime\":\"2021-10-02T06:0000\",\"testingCentreOrFacility\":\"Test center\",\"memberStateOfTest\":\"CH\"}]}"; + } + public static String getTestCertificateCreateDtoJSONWithInvalidSampleDateTime() { return "{\"name\":{\"familyName\":\"faimlyName\",\"givenName\":\"givenName\"},\"dateOfBirth\":\"1990-05-13\",\"language\":\"de\",\"address\":null,\"appCode\":\"null\",\"systemSource\":\"WebUI\",\"testInfo\":[{\"manufacturerCode\":\"1833\",\"typeCode\":\"null\",\"sampleDateTime\":\"2010--0205\",\"testingCentreOrFacility\":\"Test Center\",\"memberStateOfTest\":\"CH\"}]}"; } + public static String getExceptionalCertificateCreateDtoJSONWithInvalidSampleDateTime() { + return "{\"name\":{\"familyName\":\"faimlyName\",\"givenName\":\"givenName\"},\"dateOfBirth\":\"1990-05-13\",\"language\":\"de\",\"address\":null,\"appCode\":null,\"systemSource\":\"WebUI\",\"userExtId\":null,\"exceptionalInfo\":[{\"validFrom\":\"2021-1002\",\"attestationIssuer\":\"Testing center\"}],\"deliverablePerPost\":true}"; + } + public static RecoveryCertificateCreateDto getRecoveryCertificateCreateDto(String language) { return new RecoveryCertificateCreateDto( getCovidCertificatePersonDto(), @@ -152,25 +256,47 @@ public static RecoveryCertificateCreateDto getRecoveryCertificateCreateDto(Strin ); } + public static RecoveryRatCertificateCreateDto getRecoveryRatCertificateCreateDto(String language) { + return new RecoveryRatCertificateCreateDto( + getCovidCertificatePersonDto(), + List.of(getRecoveryRatCertificateDataDto()), + language, + getCovidCertificateAddressDto(), + null, + SystemSource.WebUI + ); + } + + public static RecoveryRatCertificateCreateDto getRecoveryRatCertificateCreateDto( + String language, String inAppCode) { + return new RecoveryRatCertificateCreateDto( + getCovidCertificatePersonDto(), + List.of(getRecoveryRatCertificateDataDto()), + language, + null, + inAppCode, + SystemSource.WebUI + ); + } + public static AntibodyCertificateCreateDto getAntibodyCertificateCreateDto(String language) { return new AntibodyCertificateCreateDto( getCovidCertificatePersonDto(), List.of(getAntibodyCertificateDataDto()), language, - null, + getCovidCertificateAddressDto(), null, SystemSource.WebUI ); } - public static VaccinationTouristCertificateCreateDto getVaccinationTouristCertificateCreateDto( - String medicalProductCode, String language) { - return new VaccinationTouristCertificateCreateDto( + public static AntibodyCertificateCreateDto getAntibodyCertificateCreateDto(String language, String appCode) { + return new AntibodyCertificateCreateDto( getCovidCertificatePersonDto(), - List.of(getVaccinationTouristCertificateDataDto(medicalProductCode)), + List.of(getAntibodyCertificateDataDto()), language, null, - null, + appCode, SystemSource.WebUI ); } @@ -180,8 +306,19 @@ public static ExceptionalCertificateCreateDto getExceptionalCertificateCreateDto getCovidCertificatePersonDto(), List.of(getExceptionalCertificateDataDto()), language, + getCovidCertificateAddressDto(), null, + SystemSource.WebUI + ); + } + + public static ExceptionalCertificateCreateDto getExceptionalCertificateCreateDto(String language, String appCode) { + return new ExceptionalCertificateCreateDto( + getCovidCertificatePersonDto(), + List.of(getExceptionalCertificateDataDto()), + language, null, + appCode, SystemSource.WebUI ); } @@ -193,6 +330,14 @@ public static RecoveryCertificateDataDto getRecoveryCertificateDataDto() { ); } + public static RecoveryRatCertificateDataDto getRecoveryRatCertificateDataDto() { + return new RecoveryRatCertificateDataDto( + ZonedDateTime.of(LocalDate.of(2021, Month.OCTOBER, 2), LocalTime.of(22, 33), SWISS_TIMEZONE), + "Test center", + "CH" + ); + } + public static CovidCertificatePersonDto getCovidCertificatePersonDto() { return new CovidCertificatePersonDto( getCovidCertificatePersonNameDto(), @@ -217,6 +362,28 @@ public static VaccinationCertificateDataDto getVaccinationCertificateDataDto(Str ); } + public static VaccinationCertificateDataDto getVaccinationCertificateDataDtoWithInvalidVaccinationDate( + String medicalProductCode) { + return new VaccinationCertificateDataDto( + medicalProductCode, + 2, + 2, + LocalDate.now().plusDays(1), + "DE" + ); + } + + public static VaccinationTouristCertificateDataDto getVaccinationTouristCertificateDataDto( + String medicalProductCode) { + return new VaccinationTouristCertificateDataDto( + medicalProductCode, + 2, + 2, + LocalDate.of(2021, Month.APRIL, 29), + "CH" + ); + } + public static TestCertificateDataDto getTestCertificateDataDto( String typeCode, String manufacturerCode @@ -232,26 +399,14 @@ public static TestCertificateDataDto getTestCertificateDataDto( public static AntibodyCertificateDataDto getAntibodyCertificateDataDto() { return new AntibodyCertificateDataDto( - LocalDate.of(2021, Month.APRIL, 4), + LocalDate.of(2021, Month.NOVEMBER, 17), "Test Center" - - ); - } - - public static VaccinationTouristCertificateDataDto getVaccinationTouristCertificateDataDto( - String medicalProductCode) { - return new VaccinationTouristCertificateDataDto( - medicalProductCode, - 2, - 2, - LocalDate.of(2021, Month.APRIL, 29), - "CH" ); } public static ExceptionalCertificateDataDto getExceptionalCertificateDataDto() { return new ExceptionalCertificateDataDto( - LocalDate.of(2021, Month.APRIL, 29), + LocalDate.of(2021, Month.OCTOBER, 2), "Testing center" ); } @@ -284,8 +439,8 @@ public static VaccinationCertificateHcertDecodedDataDto getVaccinationCertificat "1119349007", "EU/1/20/1507", "ORG-100031184", - Integer.valueOf(2), - Integer.valueOf(2), + 2, + 2, LocalDate.now().minusDays(10), "CH", "Bundesamt für Gesundheit (BAG)", diff --git a/src/test/java/ch/admin/bag/covidcertificate/api/AntibodyCertificateQrCodeMapperTest.java b/src/test/java/ch/admin/bag/covidcertificate/api/AntibodyCertificateQrCodeMapperTest.java index ee98a52a..14176256 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/api/AntibodyCertificateQrCodeMapperTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/api/AntibodyCertificateQrCodeMapperTest.java @@ -1,25 +1,22 @@ package ch.admin.bag.covidcertificate.api; import ch.admin.bag.covidcertificate.api.mapper.AntibodyCertificateQrCodeMapper; -import ch.admin.bag.covidcertificate.api.mapper.TestCertificateQrCodeMapper; import ch.admin.bag.covidcertificate.api.request.AntibodyCertificateCreateDto; -import ch.admin.bag.covidcertificate.api.request.TestCertificateCreateDto; import ch.admin.bag.covidcertificate.api.valueset.IssuableTestDto; import ch.admin.bag.covidcertificate.service.domain.AntibodyCertificateQrCode; -import ch.admin.bag.covidcertificate.service.domain.TestCertificateQrCode; import com.flextrade.jfixture.JFixture; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.time.LocalDate; import java.time.LocalDateTime; import java.time.Month; import java.time.ZoneId; import java.time.ZonedDateTime; import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeTestValueSet; -import static ch.admin.bag.covidcertificate.TestModelProvider.*; -import static ch.admin.bag.covidcertificate.api.Constants.*; +import static ch.admin.bag.covidcertificate.TestModelProvider.getAntibodyCertificateCreateDto; +import static ch.admin.bag.covidcertificate.api.Constants.ISSUER; +import static ch.admin.bag.covidcertificate.api.Constants.VERSION; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -55,9 +52,10 @@ void mapsDateOfBirth() { @Test void mapsSampleDateTime() { - ZonedDateTime sampleDateTime = ZonedDateTime.of(LocalDateTime.of(2021, Month.APRIL, 4, 0, 0, 0), ZoneId.systemDefault()); - AntibodyCertificateQrCode actual = AntibodyCertificateQrCodeMapper.toAntibodyCertificateQrCode(getAntibodyCertificateCreateDto("de")); -// AntibodyCertificateQrCode actual = AntibodyCertificateQrCodeMapper.toAntibodyCertificateQrCode(incoming); + ZonedDateTime sampleDateTime = ZonedDateTime.of(LocalDateTime.of(2021, Month.NOVEMBER, 17, 0, 0, 0), + ZoneId.systemDefault()); + AntibodyCertificateQrCode actual = AntibodyCertificateQrCodeMapper.toAntibodyCertificateQrCode( + getAntibodyCertificateCreateDto("de")); assertEquals(sampleDateTime, actual.getAntibodyInfo().get(0).getSampleDateTime()); } diff --git a/src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificateGenerationServiceTest.java b/src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificateGenerationServiceTest.java index 71b8b32b..72f43815 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificateGenerationServiceTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificateGenerationServiceTest.java @@ -3,16 +3,16 @@ import ch.admin.bag.covidcertificate.api.Constants; import ch.admin.bag.covidcertificate.api.exception.CreateCertificateException; import ch.admin.bag.covidcertificate.api.mapper.CertificatePrintRequestDtoMapper; -import ch.admin.bag.covidcertificate.api.request.pdfgeneration.RecoveryCertificatePdfGenerateRequestDto; -import ch.admin.bag.covidcertificate.api.request.pdfgeneration.TestCertificatePdfGenerateRequestDto; -import ch.admin.bag.covidcertificate.api.request.pdfgeneration.VaccinationCertificatePdfGenerateRequestDto; -import ch.admin.bag.covidcertificate.api.request.pdfgeneration.VaccinationTouristCertificatePdfGenerateRequestDto; import ch.admin.bag.covidcertificate.client.inapp_delivery.InAppDeliveryClient; import ch.admin.bag.covidcertificate.client.inapp_delivery.domain.InAppDeliveryRequestDto; import ch.admin.bag.covidcertificate.client.printing.PrintQueueClient; import ch.admin.bag.covidcertificate.client.printing.domain.CertificatePrintRequestDto; import ch.admin.bag.covidcertificate.client.signing.SigningInformationDto; import ch.admin.bag.covidcertificate.service.document.PdfCertificateGenerationService; +import ch.admin.bag.covidcertificate.service.domain.AntibodyCertificatePdf; +import ch.admin.bag.covidcertificate.service.domain.AntibodyCertificateQrCode; +import ch.admin.bag.covidcertificate.service.domain.ExceptionalCertificatePdf; +import ch.admin.bag.covidcertificate.service.domain.ExceptionalCertificateQrCode; import ch.admin.bag.covidcertificate.service.domain.RecoveryCertificatePdf; import ch.admin.bag.covidcertificate.service.domain.RecoveryCertificateQrCode; import ch.admin.bag.covidcertificate.service.domain.TestCertificatePdf; @@ -20,6 +20,7 @@ import ch.admin.bag.covidcertificate.service.domain.VaccinationCertificatePdf; import ch.admin.bag.covidcertificate.service.domain.VaccinationCertificateQrCode; import ch.admin.bag.covidcertificate.service.domain.VaccinationTouristCertificatePdf; +import ch.admin.bag.covidcertificate.service.domain.VaccinationTouristCertificateQrCode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import com.flextrade.jfixture.JFixture; @@ -36,21 +37,19 @@ import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.jupiter.MockitoExtension; import se.digg.dgc.encoding.Barcode; -import se.digg.dgc.encoding.BarcodeException; -import se.digg.dgc.encoding.impl.DefaultBarcodeCreator; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.time.Instant; import java.time.LocalDateTime; -import java.time.ZoneId; -import java.time.ZonedDateTime; import java.util.Base64; +import static ch.admin.bag.covidcertificate.TestModelProvider.getAntibodyCertificateCreateDto; +import static ch.admin.bag.covidcertificate.TestModelProvider.getExceptionalCertificateCreateDto; import static ch.admin.bag.covidcertificate.TestModelProvider.getRecoveryCertificateCreateDto; +import static ch.admin.bag.covidcertificate.TestModelProvider.getRecoveryRatCertificateCreateDto; import static ch.admin.bag.covidcertificate.TestModelProvider.getTestCertificateCreateDto; import static ch.admin.bag.covidcertificate.TestModelProvider.getVaccinationCertificateCreateDto; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static ch.admin.bag.covidcertificate.TestModelProvider.getVaccinationTouristCertificateCreateDto; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -77,8 +76,6 @@ class CovidCertificateGenerationServiceTest { @Mock private CovidCertificateDtoMapperService covidCertificateDtoMapperService; @Mock - private CovidCertificatePdfGenerateRequestDtoMapperService covidCertificatePdfGenerateRequestDtoMapperService; - @Mock private CertificatePrintRequestDtoMapper certificatePrintRequestDtoMapper; @Mock private ObjectMapper objectMapper; @@ -101,6 +98,10 @@ public void setUp() throws IOException { .thenReturn(fixture.create(VaccinationCertificateQrCode.class)); lenient().when(covidCertificateDtoMapperService.toVaccinationCertificatePdf(any(), any())) .thenReturn(fixture.create(VaccinationCertificatePdf.class)); + lenient().when(covidCertificateDtoMapperService.toVaccinationTouristCertificateQrCode(any())) + .thenReturn(fixture.create(VaccinationTouristCertificateQrCode.class)); + lenient().when(covidCertificateDtoMapperService.toVaccinationTouristCertificatePdf(any(), any())) + .thenReturn(fixture.create(VaccinationTouristCertificatePdf.class)); lenient().when(covidCertificateDtoMapperService.toTestCertificateQrCode(any())) .thenReturn(fixture.create(TestCertificateQrCode.class)); lenient().when(covidCertificateDtoMapperService.toTestCertificatePdf(any(), any())) @@ -109,6 +110,18 @@ public void setUp() throws IOException { .thenReturn(fixture.create(RecoveryCertificateQrCode.class)); lenient().when(covidCertificateDtoMapperService.toRecoveryCertificatePdf(any(), any())) .thenReturn(fixture.create(RecoveryCertificatePdf.class)); + lenient().when(covidCertificateDtoMapperService.toRecoveryRatCertificateQrCode(any())) + .thenReturn(fixture.create(RecoveryCertificateQrCode.class)); + lenient().when(covidCertificateDtoMapperService.toRecoveryRatCertificatePdf(any(), any())) + .thenReturn(fixture.create(RecoveryCertificatePdf.class)); + lenient().when(covidCertificateDtoMapperService.toAntibodyCertificateQrCode(any())) + .thenReturn(fixture.create(AntibodyCertificateQrCode.class)); + lenient().when(covidCertificateDtoMapperService.toAntibodyCertificatePdf(any(), any())) + .thenReturn(fixture.create(AntibodyCertificatePdf.class)); + lenient().when(covidCertificateDtoMapperService.toExceptionalCertificateQrCode(any())) + .thenReturn(fixture.create(ExceptionalCertificateQrCode.class)); + lenient().when(covidCertificateDtoMapperService.toExceptionalCertificatePdf(any(), any())) + .thenReturn(fixture.create(ExceptionalCertificatePdf.class)); lenient().when(coseTime.calculateExpirationInstantPlusMonths(Constants.EXPIRATION_PERIOD_24_MONTHS)) .thenReturn(fixture.create(Instant.class)); @@ -120,402 +133,1099 @@ public void setUp() throws IOException { lenient().when(objectWriter.writeValueAsString(any())).thenReturn(fixture.create(String.class)); } - LocalDateTime getLocalDateTimeFromEpochMillis(long millis) { - var instant = Instant.ofEpochMilli(millis); - return ZonedDateTime.from(instant.atZone(ZoneId.systemDefault())).toLocalDateTime(); - } - @Nested - class GenerateVaccinationFromExistingCovidCertificate { + class GenerateVaccinationCovidCertificate { + @Test + void shouldMapDtoToVaccinationCertificateQrCode() throws IOException { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + verify(covidCertificateDtoMapperService).toVaccinationCertificateQrCode(createDto); + } + + @Test + void shouldMapDtoToVaccinationCertificatePdf() throws IOException { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var qrCodeData = fixture.create(VaccinationCertificateQrCode.class); + when(covidCertificateDtoMapperService.toVaccinationCertificateQrCode(createDto)).thenReturn(qrCodeData); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + verify(covidCertificateDtoMapperService).toVaccinationCertificatePdf(createDto, qrCodeData); + } + + @Test + void shouldGetSigningInformationForTheCovidCertificate() throws IOException { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + verify(signingInformationService).getVaccinationSigningInformation(createDto); + } + @Test - void shouldMapDtoToVaccinationCertificatePdf() { - var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); - verify(covidCertificatePdfGenerateRequestDtoMapperService).toVaccinationCertificatePdf( - pdfGenerateRequestDto); + void throwsCreateCertificateException_ifMapDtoToVaccinationCertificateQrCodeThrowsCreateCertificateException() { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificateDtoMapperService.toVaccinationCertificateQrCode(any())).thenThrow(expected); + + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateCovidCertificate(createDto)); + + assertEquals(expected.getError(), exception.getError()); } @Test - void throwsCreateCertificateException_ifMapDtoToVaccinationCertificatePdfThrowsCreateCertificateException() { - var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); + void throwsInvalidCountryOfVaccination_ifMapDtoToVaccinationCertificatePdfThrowsCreateCertificateException() { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); var expected = fixture.create(CreateCertificateException.class); - when(covidCertificatePdfGenerateRequestDtoMapperService.toVaccinationCertificatePdf(any())).thenThrow( - expected); + when(covidCertificateDtoMapperService.toVaccinationCertificatePdf(any(), any())).thenThrow(expected); CreateCertificateException exception = assertThrows(CreateCertificateException.class, - () -> service.generateFromExistingCovidCertificate( - pdfGenerateRequestDto) - ); + () -> service.generateCovidCertificate(createDto)); assertEquals(expected.getError(), exception.getError()); } @Test - void shouldCreatePdf_withCorrectPdfData() { - var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); - var vaccinationPdf = fixture.create(VaccinationCertificatePdf.class); - when(covidCertificatePdfGenerateRequestDtoMapperService.toVaccinationCertificatePdf(any())).thenReturn( - vaccinationPdf); + void shouldCreateBarcode_withCorrectContents() throws IOException { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var qrCodeData = fixture.create(VaccinationCertificateQrCode.class); + when(covidCertificateDtoMapperService.toVaccinationCertificateQrCode(createDto)).thenReturn(qrCodeData); + var contents = fixture.create(String.class); + var objectWriter = mock(ObjectWriter.class); + when(objectMapper.writer()).thenReturn(objectWriter); + when(objectWriter.writeValueAsString(qrCodeData)).thenReturn(contents); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + service.generateCovidCertificate(createDto); - verify(pdfCertificateGenerationService).generateCovidCertificate(eq(vaccinationPdf), any(), any()); + verify(barcodeService).createBarcode(eq(contents), any(), any()); } @Test - void shouldCreatePdf_withCorrectBarcode() throws BarcodeException { - var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); - var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), - StandardCharsets.US_ASCII); + void shouldCreateBarcode_usingCorrectSigningInformation() throws IOException { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + service.generateCovidCertificate(createDto); - verify(pdfCertificateGenerationService).generateCovidCertificate(any(), eq(barcode.getPayload()), any()); + verify(barcodeService).createBarcode(any(), eq(signingInformation), any()); } @Test - void shouldCreatePdf_withCorrectIssuedAt() { - var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); - var issuedAt = getLocalDateTimeFromEpochMillis(pdfGenerateRequestDto.getIssuedAt()); + void shouldCreatePdf() throws IOException { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var vaccinationPdf = fixture.create(VaccinationCertificatePdf.class); + var barcode = fixture.create(Barcode.class); + var now = LocalDateTime.now(); + when(covidCertificateDtoMapperService.toVaccinationCertificatePdf(any(), any())).thenReturn(vaccinationPdf); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + try (MockedStatic localDateTimeMock = Mockito.mockStatic(LocalDateTime.class)) { + localDateTimeMock.when(LocalDateTime::now).thenReturn(now); + service.generateCovidCertificate(createDto); - verify(pdfCertificateGenerationService).generateCovidCertificate(any(), any(), eq(issuedAt)); + verify(pdfCertificateGenerationService).generateCovidCertificate(vaccinationPdf, barcode.getPayload(), + now); + } } @Test - void shouldReturnBarcode() throws IOException, BarcodeException { - var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); - var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), - StandardCharsets.US_ASCII); + void shouldReturnBarcode() throws IOException { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var barcode = fixture.create(Barcode.class); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + var actual = service.generateCovidCertificate(createDto); - assertArrayEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + assertEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); } @Test - void shouldReturnPdf() { - var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); + void shouldReturnPdf() throws IOException { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); var pdf = fixture.create(byte[].class); when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + var actual = service.generateCovidCertificate(createDto); assertEquals(pdf, actual.getResponseDto().getPdf()); } @Test - void shouldReturnUVCI() { - var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + void shouldReturnUVCI() throws IOException { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + + var actual = service.generateCovidCertificate(createDto); assertNotNull(actual.getResponseDto().getUvci()); } + + @Test + void shouldSendInAppDelivery_withCorrectAppCode_whenAppCodeIsPassed() { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de", "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertEquals(createDto.getAppCode(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getCode()); + assertNotNull(uvciArgumentCaptor.getValue()); + } + + @Test + void shouldSendInAppDelivery_withCorrectHCert_whenAppCodeIsPassed() { + var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de", "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var barcode = fixture.create(Barcode.class); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), + inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertEquals(barcode.getPayload(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getHcert()); + assertNotNull(uvciArgumentCaptor.getValue()); + } + + @Test + void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { + var createDto = getVaccinationCertificateCreateDto( + "EU/1/20/1507", + "de", + "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = + ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var pdfByteArray = fixture.create(byte[].class); + var pdf = Base64.getEncoder().encodeToString(pdfByteArray); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn( + pdfByteArray); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), + inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertEquals(pdf, inAppDeliveryRequestDtoArgumentCaptor.getValue().getPdf()); + assertNotNull(uvciArgumentCaptor.getValue()); + } + + @Test + void shouldNotSendInAppDelivery_whenNoAppCodeIsPassed() { + var createDto = getVaccinationCertificateCreateDto( + "EU/1/20/1507", + "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verifyNoInteractions(inAppDeliveryClient); + } + + @Test + void shouldMapCreateDto_toCertificatePrintRequestDto_whenAddressPassed() { + var createDto = getVaccinationCertificateCreateDto( + "EU/1/20/1507", + "de"); + var qrCodeData = fixture.create(VaccinationCertificateQrCode.class); + var pdf = fixture.create(byte[].class); + when(covidCertificateDtoMapperService.toVaccinationCertificateQrCode(any())).thenReturn(qrCodeData); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verify(certificatePrintRequestDtoMapper, times(1)) + .toCertificatePrintRequestDto(pdf, qrCodeData.getVaccinationInfo().get(0).getIdentifier(), + createDto); + } + + @Test + void shouldCallPrintingService_whenAddressPassed() { + var createDto = getVaccinationCertificateCreateDto( + "EU/1/20/1507", + "de"); + var certificatePrintRequestDto = fixture.create(CertificatePrintRequestDto.class); + when(certificatePrintRequestDtoMapper.toCertificatePrintRequestDto(any(), any(), any())).thenReturn( + certificatePrintRequestDto); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verify(printQueueClient, times(1)).sendPrintJob(certificatePrintRequestDto); + } + + @Test + void shouldNotCallPrintingService_whenNoAddressPassed() { + var createDto = getVaccinationCertificateCreateDto( + "EU/1/20/1507", + "de", + "BITBITBIT"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verifyNoInteractions(printQueueClient); + verifyNoInteractions(certificatePrintRequestDtoMapper); + } } @Nested - class GenerateVaccinationTouristFromExistingCovidCertificate { + class GenerateVaccinationTouristCovidCertificate { @Test - void shouldMapDtoToVaccinationTouristCertificatePdf() { - var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); - verify(covidCertificatePdfGenerateRequestDtoMapperService).toVaccinationTouristCertificatePdf( - pdfGenerateRequestDto); + void shouldMapDtoToVaccinationTouristCertificateQrCode() throws IOException { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + verify(covidCertificateDtoMapperService).toVaccinationTouristCertificateQrCode(createDto); + } + + @Test + void shouldMapDtoToVaccinationTouristCertificatePdf() throws IOException { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); + var qrCodeData = fixture.create(VaccinationTouristCertificateQrCode.class); + when(covidCertificateDtoMapperService.toVaccinationTouristCertificateQrCode(createDto)).thenReturn( + qrCodeData); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + verify(covidCertificateDtoMapperService).toVaccinationTouristCertificatePdf(createDto, qrCodeData); + } + + @Test + void shouldGetSigningInformationForTheCovidCertificate() throws IOException { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + verify(signingInformationService).getVaccinationTouristSigningInformation(); } @Test - void throwsCreateCertificateException_ifMapDtoToVaccinationTouristCertificatePdfThrowsCreateCertificateException() { - var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); + void throwsCreateCertificateException_ifMapDtoToVaccinationTouristCertificateQrCodeThrowsCreateCertificateException() { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); var expected = fixture.create(CreateCertificateException.class); - when(covidCertificatePdfGenerateRequestDtoMapperService.toVaccinationTouristCertificatePdf( - any())).thenThrow(expected); + when(covidCertificateDtoMapperService.toVaccinationTouristCertificateQrCode(any())).thenThrow(expected); CreateCertificateException exception = assertThrows(CreateCertificateException.class, - () -> service.generateFromExistingCovidCertificate( - pdfGenerateRequestDto) - ); + () -> service.generateCovidCertificate(createDto)); + + assertEquals(expected.getError(), exception.getError()); + } + + @Test + void throwsInvalidCountryOfVaccinationTourist_ifMapDtoToVaccinationTouristCertificatePdfThrowsCreateCertificateException() { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificateDtoMapperService.toVaccinationTouristCertificatePdf(any(), any())).thenThrow(expected); + + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateCovidCertificate(createDto)); assertEquals(expected.getError(), exception.getError()); } @Test - void shouldCreatePdf_withCorrectPdfData() { - var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); - var vaccinationTouristPdf = fixture.create(VaccinationTouristCertificatePdf.class); - when(covidCertificatePdfGenerateRequestDtoMapperService.toVaccinationTouristCertificatePdf( - any())).thenReturn(vaccinationTouristPdf); + void shouldCreateBarcode_withCorrectContents() throws IOException { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); + var qrCodeData = fixture.create(VaccinationTouristCertificateQrCode.class); + when(covidCertificateDtoMapperService.toVaccinationTouristCertificateQrCode(createDto)).thenReturn( + qrCodeData); + var contents = fixture.create(String.class); + var objectWriter = mock(ObjectWriter.class); + when(objectMapper.writer()).thenReturn(objectWriter); + when(objectWriter.writeValueAsString(qrCodeData)).thenReturn(contents); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + + verify(barcodeService).createBarcode(eq(contents), any(), any()); + } + + @Test + void shouldCreateBarcode_usingCorrectSigningInformation() throws IOException { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + + verify(barcodeService).createBarcode(any(), eq(signingInformation), any()); + } + + @Test + void shouldCreatePdf() throws IOException { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); + var vaccinationPdf = fixture.create(VaccinationTouristCertificatePdf.class); + var barcode = fixture.create(Barcode.class); + var now = LocalDateTime.now(); + when(covidCertificateDtoMapperService.toVaccinationTouristCertificatePdf(any(), any())).thenReturn( + vaccinationPdf); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + try (MockedStatic localDateTimeMock = Mockito.mockStatic(LocalDateTime.class)) { + localDateTimeMock.when(LocalDateTime::now).thenReturn(now); + service.generateCovidCertificate(createDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(vaccinationPdf, barcode.getPayload(), + now); + } + } + + @Test + void shouldReturnBarcode() throws IOException { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); + var barcode = fixture.create(Barcode.class); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + var actual = service.generateCovidCertificate(createDto); + + assertEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + } + + @Test + void shouldReturnPdf() throws IOException { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); + var pdf = fixture.create(byte[].class); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + var actual = service.generateCovidCertificate(createDto); + + assertEquals(pdf, actual.getResponseDto().getPdf()); + } + + @Test + void shouldReturnUVCI() throws IOException { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + var actual = service.generateCovidCertificate(createDto); + + assertNotNull(actual.getResponseDto().getUvci()); + } + + @Test + void shouldSendInAppDelivery_withCorrectAppCode_whenAppCodeIsPassed() { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de", "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertEquals(createDto.getAppCode(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getCode()); + assertNotNull(uvciArgumentCaptor.getValue()); + } + + @Test + void shouldSendInAppDelivery_withCorrectHCert_whenAppCodeIsPassed() { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de", "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var barcode = fixture.create(Barcode.class); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), + inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertEquals(barcode.getPayload(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getHcert()); + assertNotNull(uvciArgumentCaptor.getValue()); + } + + @Test + void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { + var createDto = getVaccinationTouristCertificateCreateDto( + "EU/1/20/1507", + "de", + "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = + ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var pdfByteArray = fixture.create(byte[].class); + var pdf = Base64.getEncoder().encodeToString(pdfByteArray); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn( + pdfByteArray); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), + inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertEquals(pdf, inAppDeliveryRequestDtoArgumentCaptor.getValue().getPdf()); + assertNotNull(uvciArgumentCaptor.getValue()); + } + + @Test + void shouldNotSendInAppDelivery_whenNoAppCodeIsPassed() { + var createDto = getVaccinationTouristCertificateCreateDto( + "EU/1/20/1507", + "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verifyNoInteractions(inAppDeliveryClient); + } + + @Test + void shouldMapCreateDto_toCertificatePrintRequestDto_whenAddressPassed() { + var createDto = getVaccinationTouristCertificateCreateDto( + "EU/1/20/1507", + "de"); + var qrCodeData = fixture.create(VaccinationTouristCertificateQrCode.class); + var pdf = fixture.create(byte[].class); + when(covidCertificateDtoMapperService.toVaccinationTouristCertificateQrCode(any())).thenReturn(qrCodeData); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verify(certificatePrintRequestDtoMapper, times(1)) + .toCertificatePrintRequestDto(pdf, qrCodeData.getVaccinationTouristInfo().get(0).getIdentifier(), + createDto); + } + + @Test + void shouldCallPrintingService_whenAddressPassed() { + var createDto = getVaccinationTouristCertificateCreateDto( + "EU/1/20/1507", + "de"); + var certificatePrintRequestDto = fixture.create(CertificatePrintRequestDto.class); + when(certificatePrintRequestDtoMapper.toCertificatePrintRequestDto(any(), any(), any())).thenReturn( + certificatePrintRequestDto); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verify(printQueueClient, times(1)).sendPrintJob(certificatePrintRequestDto); + } + + @Test + void shouldNotCallPrintingService_whenNoAddressPassed() { + var createDto = getVaccinationTouristCertificateCreateDto( + "EU/1/20/1507", + "de", + "BITBITBIT"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getVaccinationTouristSigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verifyNoInteractions(printQueueClient); + verifyNoInteractions(certificatePrintRequestDtoMapper); + } + } + + @Nested + class GenerateTestCovidCertificate { + @Test + void shouldMapDtoToTestCertificateQrCode() throws IOException { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + verify(covidCertificateDtoMapperService).toTestCertificateQrCode(createDto); + } + + @Test + void shouldMapDtoToTestCertificatePdf() throws IOException { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var qrCodeData = fixture.create(TestCertificateQrCode.class); + when(covidCertificateDtoMapperService.toTestCertificateQrCode(createDto)).thenReturn(qrCodeData); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + verify(covidCertificateDtoMapperService).toTestCertificatePdf(createDto, qrCodeData); + } + + @Test + void shouldGetSigningInformationForTheCovidCertificate() throws IOException { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + verify(signingInformationService).getTestSigningInformation(); + } + + @Test + void throwsCreateCertificateException_ifMapDtoToTestCertificateQrCodeThrowsCreateCertificateException() { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificateDtoMapperService.toTestCertificateQrCode(any())).thenThrow(expected); + + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateCovidCertificate(createDto)); + + assertEquals(expected.getError(), exception.getError()); + } + + @Test + void throwsInvalidCountryOfTest_ifMapDtoToTestCertificatePdfThrowsCreateCertificateException() { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificateDtoMapperService.toTestCertificatePdf(any(), any())).thenThrow(expected); + + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateCovidCertificate(createDto)); + + assertEquals(expected.getError(), exception.getError()); + } + + @Test + void shouldCreateBarcode_withCorrectContents() throws IOException { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var qrCodeData = fixture.create(TestCertificateQrCode.class); + when(covidCertificateDtoMapperService.toTestCertificateQrCode(createDto)).thenReturn(qrCodeData); + var contents = fixture.create(String.class); + var objectWriter = mock(ObjectWriter.class); + when(objectMapper.writer()).thenReturn(objectWriter); + when(objectWriter.writeValueAsString(qrCodeData)).thenReturn(contents); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + + verify(barcodeService).createBarcode(eq(contents), any(), any()); + } + + @Test + void shouldCreateBarcode_usingCorrectSigningInformation() throws IOException { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + + service.generateCovidCertificate(createDto); + + verify(barcodeService).createBarcode(any(), eq(signingInformation), any()); + } + + @Test + void shouldCreatePdf() throws IOException { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var TestPdf = fixture.create(TestCertificatePdf.class); + var barcode = fixture.create(Barcode.class); + var now = LocalDateTime.now(); + when(covidCertificateDtoMapperService.toTestCertificatePdf(any(), any())).thenReturn(TestPdf); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + + try (MockedStatic localDateTimeMock = Mockito.mockStatic(LocalDateTime.class)) { + localDateTimeMock.when(LocalDateTime::now).thenReturn(now); + + service.generateCovidCertificate(createDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(TestPdf, barcode.getPayload(), + LocalDateTime.now()); + } + } + + @Test + void shouldReturnBarcode() throws IOException { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var barcode = fixture.create(Barcode.class); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + + var actual = service.generateCovidCertificate(createDto); + + assertEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + } + + @Test + void shouldReturnPdf() throws IOException { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var pdf = fixture.create(byte[].class); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + + var actual = service.generateCovidCertificate(createDto); + + assertEquals(pdf, actual.getResponseDto().getPdf()); + } + + @Test + void shouldReturnUVCI() throws IOException { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + + var actual = service.generateCovidCertificate(createDto); + + assertNotNull(actual.getResponseDto().getUvci()); + } + + @Test + void shouldSendInAppDelivery_withCorrectAppCode_whenAppCodeIsPassed() { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de", + "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = + ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), + inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertEquals(createDto.getAppCode(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getCode()); + assertNotNull(uvciArgumentCaptor.getValue()); + } + + @Test + void shouldSendInAppDelivery_withCorrectHCert_whenAppCodeIsPassed() { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de", + "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = + ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var barcode = fixture.create(Barcode.class); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), + inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertNotNull(uvciArgumentCaptor.getValue()); + assertEquals(barcode.getPayload(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getHcert()); + } + + @Test + void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de", + "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = + ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var pdfByteArray = fixture.create(byte[].class); + var pdf = Base64.getEncoder().encodeToString(pdfByteArray); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn( + pdfByteArray); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); - verify(pdfCertificateGenerationService).generateCovidCertificate(eq(vaccinationTouristPdf), any(), any()); + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), + inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertNotNull(uvciArgumentCaptor.getValue()); + assertEquals(pdf, inAppDeliveryRequestDtoArgumentCaptor.getValue().getPdf()); } @Test - void shouldCreatePdf_withCorrectBarcode() throws BarcodeException { - var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); - var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), - StandardCharsets.US_ASCII); - - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + void shouldNotSendInAppDelivery_whenNoAppCodeIsPassed() { + var createDto = getTestCertificateCreateDto( + null, + "1833", + "de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); - verify(pdfCertificateGenerationService).generateCovidCertificate(any(), eq(barcode.getPayload()), any()); + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verifyNoInteractions(inAppDeliveryClient); } + } + @Nested + class GenerateRecoveryCovidCertificate { @Test - void shouldCreatePdf_withCorrectIssuedAt() { - var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); - var issuedAt = getLocalDateTimeFromEpochMillis(pdfGenerateRequestDto.getIssuedAt()); - - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + void shouldMapDtoToRecoveryCertificateQrCode() throws IOException { + var createDto = getRecoveryCertificateCreateDto("de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - verify(pdfCertificateGenerationService).generateCovidCertificate(any(), any(), eq(issuedAt)); + service.generateCovidCertificate(createDto); + verify(covidCertificateDtoMapperService).toRecoveryCertificateQrCode(createDto); } @Test - void shouldReturnBarcode() throws IOException, BarcodeException { - var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); - var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), - StandardCharsets.US_ASCII); - - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + void shouldMapDtoToRecoveryCertificatePdf() throws IOException { + var createDto = getRecoveryCertificateCreateDto("de"); + var qrCodeData = fixture.create(RecoveryCertificateQrCode.class); + when(covidCertificateDtoMapperService.toRecoveryCertificateQrCode(createDto)).thenReturn(qrCodeData); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - assertArrayEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + service.generateCovidCertificate(createDto); + verify(covidCertificateDtoMapperService).toRecoveryCertificatePdf(createDto, qrCodeData); } @Test - void shouldReturnPdf() { - var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); - var pdf = fixture.create(byte[].class); - when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); - - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + void shouldGetSigningInformationForTheCovidCertificate() throws IOException { + var createDto = getRecoveryCertificateCreateDto("de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - assertEquals(pdf, actual.getResponseDto().getPdf()); + service.generateCovidCertificate(createDto); + verify(signingInformationService).getRecoverySigningInformation(createDto); } @Test - void shouldReturnUVCI() { - var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + void throwsCreateCertificateException_ifMapDtoToRecoveryCertificateQrCodeThrowsCreateCertificateException() { + var createDto = getRecoveryCertificateCreateDto("de"); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificateDtoMapperService.toRecoveryCertificateQrCode(any())).thenThrow(expected); - assertNotNull(actual.getResponseDto().getUvci()); - } - } + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateCovidCertificate(createDto)); - @Nested - class GenerateTestFromExistingCovidCertificate { - @Test - void shouldMapDtoToTestCertificatePdf() { - var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); - verify(covidCertificatePdfGenerateRequestDtoMapperService).toTestCertificatePdf(pdfGenerateRequestDto); + assertEquals(expected.getError(), exception.getError()); } @Test - void throwsCreateCertificateException_ifMapDtoToTestCertificatePdfThrowsCreateCertificateException() { - var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); + void throwsInvalidCountryOfRecovery_ifMapDtoToRecoveryCertificatePdfThrowsCreateCertificateException() { + var createDto = getRecoveryCertificateCreateDto("de"); var expected = fixture.create(CreateCertificateException.class); - when(covidCertificatePdfGenerateRequestDtoMapperService.toTestCertificatePdf(any())).thenThrow(expected); + when(covidCertificateDtoMapperService.toRecoveryCertificatePdf(any(), any())).thenThrow(expected); CreateCertificateException exception = assertThrows(CreateCertificateException.class, - () -> service.generateFromExistingCovidCertificate( - pdfGenerateRequestDto) - ); + () -> service.generateCovidCertificate(createDto)); assertEquals(expected.getError(), exception.getError()); } @Test - void shouldCreatePdf_withCorrectPdfData() { - var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); - var testPdf = fixture.create(TestCertificatePdf.class); - when(covidCertificatePdfGenerateRequestDtoMapperService.toTestCertificatePdf(any())).thenReturn(testPdf); + void shouldCreateBarcode_withCorrectContents() throws IOException { + var createDto = getRecoveryCertificateCreateDto("de"); + var qrCodeData = fixture.create(RecoveryCertificateQrCode.class); + when(covidCertificateDtoMapperService.toRecoveryCertificateQrCode(createDto)).thenReturn(qrCodeData); + var contents = fixture.create(String.class); + var objectWriter = mock(ObjectWriter.class); + when(objectMapper.writer()).thenReturn(objectWriter); + when(objectWriter.writeValueAsString(qrCodeData)).thenReturn(contents); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + service.generateCovidCertificate(createDto); - verify(pdfCertificateGenerationService).generateCovidCertificate(eq(testPdf), any(), any()); + verify(barcodeService).createBarcode(eq(contents), any(), any()); } @Test - void shouldCreatePdf_withCorrectBarcode() throws BarcodeException { - var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); - var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), - StandardCharsets.US_ASCII); + void shouldCreateBarcode_usingCorrectSigningInformation() throws IOException { + var createDto = getRecoveryCertificateCreateDto("de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + service.generateCovidCertificate(createDto); - verify(pdfCertificateGenerationService).generateCovidCertificate(any(), eq(barcode.getPayload()), any()); + verify(barcodeService).createBarcode(any(), eq(signingInformation), any()); } @Test - void shouldCreatePdf_withCorrectIssuedAt() { - var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); - var issuedAt = getLocalDateTimeFromEpochMillis(pdfGenerateRequestDto.getIssuedAt()); + void shouldCreatePdf() throws IOException { + var createDto = getRecoveryCertificateCreateDto("de"); + var RecoveryPdf = fixture.create(RecoveryCertificatePdf.class); + var barcode = fixture.create(Barcode.class); + var now = LocalDateTime.now(); + when(covidCertificateDtoMapperService.toRecoveryCertificatePdf(any(), any())).thenReturn(RecoveryPdf); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + + try (MockedStatic localDateTimeMock = Mockito.mockStatic(LocalDateTime.class)) { + localDateTimeMock.when(LocalDateTime::now).thenReturn(now); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + service.generateCovidCertificate(createDto); - verify(pdfCertificateGenerationService).generateCovidCertificate(any(), any(), eq(issuedAt)); + verify(pdfCertificateGenerationService).generateCovidCertificate(RecoveryPdf, barcode.getPayload(), + now); + } } @Test - void shouldReturnBarcode() throws IOException, BarcodeException { - var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); - var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), - StandardCharsets.US_ASCII); + void shouldReturnBarcode() throws IOException { + var createDto = getRecoveryCertificateCreateDto("de"); + var barcode = fixture.create(Barcode.class); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + var actual = service.generateCovidCertificate(createDto); - assertArrayEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + assertEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); } @Test - void shouldReturnPdf() { - var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); + void shouldReturnPdf() throws IOException { + var createDto = getRecoveryCertificateCreateDto("de"); var pdf = fixture.create(byte[].class); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + var actual = service.generateCovidCertificate(createDto); assertEquals(pdf, actual.getResponseDto().getPdf()); } @Test - void shouldReturnUVCI() { - var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + void shouldUVCI() throws IOException { + var createDto = getRecoveryCertificateCreateDto("de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - assertNotNull(actual.getResponseDto().getUvci()); - } - } + var actual = service.generateCovidCertificate(createDto); - @Nested - class GenerateRecoveryFromExistingCovidCertificate { - @Test - void shouldMapDtoToRecoveryCertificatePdf() { - var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); - verify(covidCertificatePdfGenerateRequestDtoMapperService).toRecoveryCertificatePdf(pdfGenerateRequestDto); + assertNotNull(actual.getResponseDto().getUvci()); } @Test - void throwsCreateCertificateException_ifMapDtoToRecoveryCertificatePdfThrowsCreateCertificateException() { - var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); - var expected = fixture.create(CreateCertificateException.class); - when(covidCertificatePdfGenerateRequestDtoMapperService.toRecoveryCertificatePdf(any())).thenThrow( - expected); + void shouldSendInAppDelivery_withCorrectAppCode_whenAppCodeIsPassed() { + var createDto = getRecoveryCertificateCreateDto( + "de", + "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = + ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - CreateCertificateException exception = assertThrows(CreateCertificateException.class, - () -> service.generateFromExistingCovidCertificate( - pdfGenerateRequestDto) - ); + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); - assertEquals(expected.getError(), exception.getError()); + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), + inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertNotNull(uvciArgumentCaptor.getValue()); + assertEquals(createDto.getAppCode(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getCode()); } @Test - void shouldCreatePdf_withCorrectPdfData() { - var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); - var recoveryPdf = fixture.create(RecoveryCertificatePdf.class); - when(covidCertificatePdfGenerateRequestDtoMapperService.toRecoveryCertificatePdf(any())).thenReturn( - recoveryPdf); + void shouldSendInAppDelivery_withCorrectHCert_whenAppCodeIsPassed() { + var createDto = getRecoveryCertificateCreateDto( + "de", + "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = + ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var barcode = fixture.create(Barcode.class); + when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); - verify(pdfCertificateGenerationService).generateCovidCertificate(eq(recoveryPdf), any(), any()); + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), + inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertNotNull(uvciArgumentCaptor.getValue()); + assertEquals(barcode.getPayload(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getHcert()); } @Test - void shouldCreatePdf_withCorrectBarcode() throws BarcodeException { - var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); - var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), - StandardCharsets.US_ASCII); + void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { + var createDto = getRecoveryCertificateCreateDto( + "de", + "BITBITBIT"); + var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); + var inAppDeliveryRequestDtoArgumentCaptor = + ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var pdfByteArray = fixture.create(byte[].class); + var pdf = Base64.getEncoder().encodeToString(pdfByteArray); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn( + pdfByteArray); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); - verify(pdfCertificateGenerationService).generateCovidCertificate(any(), eq(barcode.getPayload()), any()); + verify(inAppDeliveryClient, times(1)).deliverToApp( + uvciArgumentCaptor.capture(), + inAppDeliveryRequestDtoArgumentCaptor.capture()); + assertNotNull(uvciArgumentCaptor.getValue()); + assertEquals(pdf, inAppDeliveryRequestDtoArgumentCaptor.getValue().getPdf()); } @Test - void shouldCreatePdf_withCorrectIssuedAt() { - var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); - var issuedAt = getLocalDateTimeFromEpochMillis(pdfGenerateRequestDto.getIssuedAt()); - - service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + void shouldNotSendInAppDelivery_whenNoAppCodeIsPassed() { + var createDto = getRecoveryCertificateCreateDto("de"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - verify(pdfCertificateGenerationService).generateCovidCertificate(any(), any(), eq(issuedAt)); + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verifyNoInteractions(inAppDeliveryClient); } @Test - void shouldReturnBarcode() throws BarcodeException { - var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); - var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), - StandardCharsets.US_ASCII); - - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + void shouldMapCreateDto_toCertificatePrintRequestDto_whenAddressPassed() { + var createDto = getRecoveryCertificateCreateDto("de"); + var qrCodeData = fixture.create(RecoveryCertificateQrCode.class); + var pdf = fixture.create(byte[].class); + when(covidCertificateDtoMapperService.toRecoveryCertificateQrCode(any())).thenReturn(qrCodeData); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - assertArrayEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verify(certificatePrintRequestDtoMapper, times(1)) + .toCertificatePrintRequestDto(pdf, qrCodeData.getRecoveryInfo().get(0).getIdentifier(), createDto); } @Test - void shouldReturnPdf() { - var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); - var pdf = fixture.create(byte[].class); - when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); - - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + void shouldCallPrintingService_whenAddressPassed() { + var createDto = getRecoveryCertificateCreateDto("de"); + var certificatePrintRequestDto = fixture.create(CertificatePrintRequestDto.class); + when(certificatePrintRequestDtoMapper.toCertificatePrintRequestDto(any(), any(), any())).thenReturn( + certificatePrintRequestDto); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - assertEquals(pdf, actual.getResponseDto().getPdf()); + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verify(printQueueClient, times(1)).sendPrintJob(certificatePrintRequestDto); } @Test - void shouldReturnUVCI() { - var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); - var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + void shouldNotCallPrintingService_whenNoAddressPassed() { + var createDto = getRecoveryCertificateCreateDto( + "de", + "BITBITBIT"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); - assertNotNull(actual.getResponseDto().getUvci()); + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verifyNoInteractions(printQueueClient); + verifyNoInteractions(certificatePrintRequestDtoMapper); } } @Nested - class GenerateVaccinationCovidCertificate { + class GenerateRecoveryRatCovidCertificate { @Test - void shouldMapDtoToVaccinationCertificateQrCode() throws IOException { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + void shouldMapDtoToRecoveryRatCertificateQrCode() throws IOException { + var createDto = getRecoveryRatCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); - verify(covidCertificateDtoMapperService).toVaccinationCertificateQrCode(createDto); + verify(covidCertificateDtoMapperService).toRecoveryRatCertificateQrCode(createDto); } @Test - void shouldMapDtoToVaccinationCertificatePdf() throws IOException { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); - var qrCodeData = fixture.create(VaccinationCertificateQrCode.class); - when(covidCertificateDtoMapperService.toVaccinationCertificateQrCode(createDto)).thenReturn(qrCodeData); + void shouldMapDtoToRecoveryRatCertificatePdf() throws IOException { + var createDto = getRecoveryRatCertificateCreateDto("de"); + var qrCodeData = fixture.create(RecoveryCertificateQrCode.class); + when(covidCertificateDtoMapperService.toRecoveryRatCertificateQrCode(createDto)).thenReturn(qrCodeData); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); - verify(covidCertificateDtoMapperService).toVaccinationCertificatePdf(createDto, qrCodeData); + verify(covidCertificateDtoMapperService).toRecoveryRatCertificatePdf(createDto, qrCodeData); } @Test void shouldGetSigningInformationForTheCovidCertificate() throws IOException { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var createDto = getRecoveryRatCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); - verify(signingInformationService).getVaccinationSigningInformation(createDto); + verify(signingInformationService).getRecoveryRatSigningInformation(); } @Test - void throwsCreateCertificateException_ifMapDtoToVaccinationCertificateQrCodeThrowsCreateCertificateException() { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + void throwsCreateCertificateException_ifMapDtoToRecoveryRatCertificateQrCodeThrowsCreateCertificateException() { + var createDto = getRecoveryRatCertificateCreateDto("de"); var expected = fixture.create(CreateCertificateException.class); - when(covidCertificateDtoMapperService.toVaccinationCertificateQrCode(any())).thenThrow(expected); + when(covidCertificateDtoMapperService.toRecoveryRatCertificateQrCode(any())).thenThrow(expected); CreateCertificateException exception = assertThrows(CreateCertificateException.class, () -> service.generateCovidCertificate(createDto)); @@ -524,10 +1234,10 @@ void throwsCreateCertificateException_ifMapDtoToVaccinationCertificateQrCodeThro } @Test - void throwsInvalidCountryOfVaccination_ifMapDtoToVaccinationCertificatePdfThrowsCreateCertificateException() { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + void throwsInvalidCountryOfRecoveryRat_ifMapDtoToRecoveryRatCertificatePdfThrowsCreateCertificateException() { + var createDto = getRecoveryRatCertificateCreateDto("de"); var expected = fixture.create(CreateCertificateException.class); - when(covidCertificateDtoMapperService.toVaccinationCertificatePdf(any(), any())).thenThrow(expected); + when(covidCertificateDtoMapperService.toRecoveryRatCertificatePdf(any(), any())).thenThrow(expected); CreateCertificateException exception = assertThrows(CreateCertificateException.class, () -> service.generateCovidCertificate(createDto)); @@ -537,15 +1247,15 @@ void throwsInvalidCountryOfVaccination_ifMapDtoToVaccinationCertificatePdfThrows @Test void shouldCreateBarcode_withCorrectContents() throws IOException { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); - var qrCodeData = fixture.create(VaccinationCertificateQrCode.class); - when(covidCertificateDtoMapperService.toVaccinationCertificateQrCode(createDto)).thenReturn(qrCodeData); + var createDto = getRecoveryRatCertificateCreateDto("de"); + var qrCodeData = fixture.create(RecoveryCertificateQrCode.class); + when(covidCertificateDtoMapperService.toRecoveryRatCertificateQrCode(createDto)).thenReturn(qrCodeData); var contents = fixture.create(String.class); var objectWriter = mock(ObjectWriter.class); when(objectMapper.writer()).thenReturn(objectWriter); when(objectWriter.writeValueAsString(qrCodeData)).thenReturn(contents); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); @@ -554,9 +1264,9 @@ void shouldCreateBarcode_withCorrectContents() throws IOException { @Test void shouldCreateBarcode_usingCorrectSigningInformation() throws IOException { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var createDto = getRecoveryRatCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); @@ -565,31 +1275,32 @@ void shouldCreateBarcode_usingCorrectSigningInformation() throws IOException { @Test void shouldCreatePdf() throws IOException { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); - var vaccinationPdf = fixture.create(VaccinationCertificatePdf.class); + var createDto = getRecoveryRatCertificateCreateDto("de"); + var RecoveryPdf = fixture.create(RecoveryCertificatePdf.class); var barcode = fixture.create(Barcode.class); var now = LocalDateTime.now(); - when(covidCertificateDtoMapperService.toVaccinationCertificatePdf(any(), any())).thenReturn(vaccinationPdf); + when(covidCertificateDtoMapperService.toRecoveryRatCertificatePdf(any(), any())).thenReturn(RecoveryPdf); when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); try (MockedStatic localDateTimeMock = Mockito.mockStatic(LocalDateTime.class)) { localDateTimeMock.when(LocalDateTime::now).thenReturn(now); + service.generateCovidCertificate(createDto); - verify(pdfCertificateGenerationService).generateCovidCertificate(vaccinationPdf, barcode.getPayload(), + verify(pdfCertificateGenerationService).generateCovidCertificate(RecoveryPdf, barcode.getPayload(), now); } } @Test void shouldReturnBarcode() throws IOException { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var createDto = getRecoveryRatCertificateCreateDto("de"); var barcode = fixture.create(Barcode.class); when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); var actual = service.generateCovidCertificate(createDto); @@ -598,11 +1309,11 @@ void shouldReturnBarcode() throws IOException { @Test void shouldReturnPdf() throws IOException { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + var createDto = getRecoveryRatCertificateCreateDto("de"); var pdf = fixture.create(byte[].class); - when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); var actual = service.generateCovidCertificate(createDto); @@ -610,10 +1321,10 @@ void shouldReturnPdf() throws IOException { } @Test - void shouldReturnUVCI() throws IOException { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); + void shouldUVCI() throws IOException { + var createDto = getRecoveryRatCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); var actual = service.generateCovidCertificate(createDto); @@ -622,43 +1333,49 @@ void shouldReturnUVCI() throws IOException { @Test void shouldSendInAppDelivery_withCorrectAppCode_whenAppCodeIsPassed() { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de", "BITBITBIT"); + var createDto = getRecoveryRatCertificateCreateDto( + "de", + "BITBITBIT"); var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); - var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var inAppDeliveryRequestDtoArgumentCaptor = + ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verify(inAppDeliveryClient, times(1)).deliverToApp( - uvciArgumentCaptor.capture(), inAppDeliveryRequestDtoArgumentCaptor.capture()); - assertEquals(createDto.getAppCode(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getCode()); + uvciArgumentCaptor.capture(), + inAppDeliveryRequestDtoArgumentCaptor.capture()); assertNotNull(uvciArgumentCaptor.getValue()); + assertEquals(createDto.getAppCode(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getCode()); } @Test void shouldSendInAppDelivery_withCorrectHCert_whenAppCodeIsPassed() { - var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de", "BITBITBIT"); + var createDto = getRecoveryRatCertificateCreateDto( + "de", + "BITBITBIT"); var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); - var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); + var inAppDeliveryRequestDtoArgumentCaptor = + ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); var barcode = fixture.create(Barcode.class); when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verify(inAppDeliveryClient, times(1)).deliverToApp( uvciArgumentCaptor.capture(), inAppDeliveryRequestDtoArgumentCaptor.capture()); - assertEquals(barcode.getPayload(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getHcert()); assertNotNull(uvciArgumentCaptor.getValue()); + assertEquals(barcode.getPayload(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getHcert()); } @Test void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { - var createDto = getVaccinationCertificateCreateDto( - "EU/1/20/1507", + var createDto = getRecoveryRatCertificateCreateDto( "de", "BITBITBIT"); var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); @@ -669,24 +1386,22 @@ void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn( pdfByteArray); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verify(inAppDeliveryClient, times(1)).deliverToApp( uvciArgumentCaptor.capture(), inAppDeliveryRequestDtoArgumentCaptor.capture()); - assertEquals(pdf, inAppDeliveryRequestDtoArgumentCaptor.getValue().getPdf()); assertNotNull(uvciArgumentCaptor.getValue()); + assertEquals(pdf, inAppDeliveryRequestDtoArgumentCaptor.getValue().getPdf()); } @Test void shouldNotSendInAppDelivery_whenNoAppCodeIsPassed() { - var createDto = getVaccinationCertificateCreateDto( - "EU/1/20/1507", - "de"); + var createDto = getRecoveryRatCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verifyNoInteractions(inAppDeliveryClient); @@ -694,32 +1409,27 @@ void shouldNotSendInAppDelivery_whenNoAppCodeIsPassed() { @Test void shouldMapCreateDto_toCertificatePrintRequestDto_whenAddressPassed() { - var createDto = getVaccinationCertificateCreateDto( - "EU/1/20/1507", - "de"); - var qrCodeData = fixture.create(VaccinationCertificateQrCode.class); + var createDto = getRecoveryRatCertificateCreateDto("de"); + var qrCodeData = fixture.create(RecoveryCertificateQrCode.class); var pdf = fixture.create(byte[].class); - when(covidCertificateDtoMapperService.toVaccinationCertificateQrCode(any())).thenReturn(qrCodeData); + when(covidCertificateDtoMapperService.toRecoveryRatCertificateQrCode(any())).thenReturn(qrCodeData); when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verify(certificatePrintRequestDtoMapper, times(1)) - .toCertificatePrintRequestDto(pdf, qrCodeData.getVaccinationInfo().get(0).getIdentifier(), - createDto); + .toCertificatePrintRequestDto(pdf, qrCodeData.getRecoveryInfo().get(0).getIdentifier(), createDto); } @Test void shouldCallPrintingService_whenAddressPassed() { - var createDto = getVaccinationCertificateCreateDto( - "EU/1/20/1507", - "de"); + var createDto = getRecoveryRatCertificateCreateDto("de"); var certificatePrintRequestDto = fixture.create(CertificatePrintRequestDto.class); when(certificatePrintRequestDtoMapper.toCertificatePrintRequestDto(any(), any(), any())).thenReturn( certificatePrintRequestDto); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verify(printQueueClient, times(1)).sendPrintJob(certificatePrintRequestDto); @@ -727,12 +1437,11 @@ void shouldCallPrintingService_whenAddressPassed() { @Test void shouldNotCallPrintingService_whenNoAddressPassed() { - var createDto = getVaccinationCertificateCreateDto( - "EU/1/20/1507", + var createDto = getRecoveryRatCertificateCreateDto( "de", "BITBITBIT"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getVaccinationSigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getRecoveryRatSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verifyNoInteractions(printQueueClient); @@ -741,56 +1450,44 @@ void shouldNotCallPrintingService_whenNoAddressPassed() { } @Nested - class GenerateTestCovidCertificate { + class GenerateAntibodyCovidCertificate { @Test - void shouldMapDtoToTestCertificateQrCode() throws IOException { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); + void shouldMapDtoToAntibodyCertificateQrCode() throws IOException { + var createDto = getAntibodyCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); - verify(covidCertificateDtoMapperService).toTestCertificateQrCode(createDto); + verify(covidCertificateDtoMapperService).toAntibodyCertificateQrCode(createDto); } @Test - void shouldMapDtoToTestCertificatePdf() throws IOException { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); - var qrCodeData = fixture.create(TestCertificateQrCode.class); - when(covidCertificateDtoMapperService.toTestCertificateQrCode(createDto)).thenReturn(qrCodeData); + void shouldMapDtoToAntibodyCertificatePdf() throws IOException { + var createDto = getAntibodyCertificateCreateDto("de"); + var qrCodeData = fixture.create(AntibodyCertificateQrCode.class); + when(covidCertificateDtoMapperService.toAntibodyCertificateQrCode(createDto)).thenReturn(qrCodeData); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); - verify(covidCertificateDtoMapperService).toTestCertificatePdf(createDto, qrCodeData); + verify(covidCertificateDtoMapperService).toAntibodyCertificatePdf(createDto, qrCodeData); } @Test void shouldGetSigningInformationForTheCovidCertificate() throws IOException { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); + var createDto = getAntibodyCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); - verify(signingInformationService).getTestSigningInformation(); + verify(signingInformationService).getAntibodySigningInformation(); } @Test - void throwsCreateCertificateException_ifMapDtoToTestCertificateQrCodeThrowsCreateCertificateException() { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); + void throwsCreateCertificateException_ifMapDtoToAntibodyCertificateQrCodeThrowsCreateCertificateException() { + var createDto = getAntibodyCertificateCreateDto("de"); var expected = fixture.create(CreateCertificateException.class); - when(covidCertificateDtoMapperService.toTestCertificateQrCode(any())).thenThrow(expected); + when(covidCertificateDtoMapperService.toAntibodyCertificateQrCode(any())).thenThrow(expected); CreateCertificateException exception = assertThrows(CreateCertificateException.class, () -> service.generateCovidCertificate(createDto)); @@ -799,13 +1496,10 @@ void throwsCreateCertificateException_ifMapDtoToTestCertificateQrCodeThrowsCreat } @Test - void throwsInvalidCountryOfTest_ifMapDtoToTestCertificatePdfThrowsCreateCertificateException() { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); + void throwsInvalidCountryOfAntibody_ifMapDtoToAntibodyCertificatePdfThrowsCreateCertificateException() { + var createDto = getAntibodyCertificateCreateDto("de"); var expected = fixture.create(CreateCertificateException.class); - when(covidCertificateDtoMapperService.toTestCertificatePdf(any(), any())).thenThrow(expected); + when(covidCertificateDtoMapperService.toAntibodyCertificatePdf(any(), any())).thenThrow(expected); CreateCertificateException exception = assertThrows(CreateCertificateException.class, () -> service.generateCovidCertificate(createDto)); @@ -815,18 +1509,15 @@ void throwsInvalidCountryOfTest_ifMapDtoToTestCertificatePdfThrowsCreateCertific @Test void shouldCreateBarcode_withCorrectContents() throws IOException { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); - var qrCodeData = fixture.create(TestCertificateQrCode.class); - when(covidCertificateDtoMapperService.toTestCertificateQrCode(createDto)).thenReturn(qrCodeData); + var createDto = getAntibodyCertificateCreateDto("de"); + var qrCodeData = fixture.create(AntibodyCertificateQrCode.class); + when(covidCertificateDtoMapperService.toAntibodyCertificateQrCode(createDto)).thenReturn(qrCodeData); var contents = fixture.create(String.class); var objectWriter = mock(ObjectWriter.class); when(objectMapper.writer()).thenReturn(objectWriter); when(objectWriter.writeValueAsString(qrCodeData)).thenReturn(contents); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); @@ -835,12 +1526,9 @@ void shouldCreateBarcode_withCorrectContents() throws IOException { @Test void shouldCreateBarcode_usingCorrectSigningInformation() throws IOException { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); + var createDto = getAntibodyCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); @@ -849,38 +1537,32 @@ void shouldCreateBarcode_usingCorrectSigningInformation() throws IOException { @Test void shouldCreatePdf() throws IOException { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); - var TestPdf = fixture.create(TestCertificatePdf.class); + var createDto = getAntibodyCertificateCreateDto("de"); + var AntibodyPdf = fixture.create(AntibodyCertificatePdf.class); var barcode = fixture.create(Barcode.class); var now = LocalDateTime.now(); - when(covidCertificateDtoMapperService.toTestCertificatePdf(any(), any())).thenReturn(TestPdf); + when(covidCertificateDtoMapperService.toAntibodyCertificatePdf(any(), any())).thenReturn(AntibodyPdf); when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); try (MockedStatic localDateTimeMock = Mockito.mockStatic(LocalDateTime.class)) { localDateTimeMock.when(LocalDateTime::now).thenReturn(now); service.generateCovidCertificate(createDto); - verify(pdfCertificateGenerationService).generateCovidCertificate(TestPdf, barcode.getPayload(), - LocalDateTime.now()); + verify(pdfCertificateGenerationService).generateCovidCertificate(AntibodyPdf, barcode.getPayload(), + now); } } @Test void shouldReturnBarcode() throws IOException { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); + var createDto = getAntibodyCertificateCreateDto("de"); var barcode = fixture.create(Barcode.class); when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); var actual = service.generateCovidCertificate(createDto); @@ -889,14 +1571,11 @@ void shouldReturnBarcode() throws IOException { @Test void shouldReturnPdf() throws IOException { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); + var createDto = getAntibodyCertificateCreateDto("de"); var pdf = fixture.create(byte[].class); - when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); var actual = service.generateCovidCertificate(createDto); @@ -904,13 +1583,10 @@ void shouldReturnPdf() throws IOException { } @Test - void shouldReturnUVCI() throws IOException { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); + void shouldUVCI() throws IOException { + var createDto = getAntibodyCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); var actual = service.generateCovidCertificate(createDto); @@ -919,40 +1595,32 @@ void shouldReturnUVCI() throws IOException { @Test void shouldSendInAppDelivery_withCorrectAppCode_whenAppCodeIsPassed() { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de", - "BITBITBIT"); + var createDto = getAntibodyCertificateCreateDto("de", "BITBITBIT"); var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verify(inAppDeliveryClient, times(1)).deliverToApp( uvciArgumentCaptor.capture(), inAppDeliveryRequestDtoArgumentCaptor.capture()); - assertEquals(createDto.getAppCode(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getCode()); assertNotNull(uvciArgumentCaptor.getValue()); + assertEquals(createDto.getAppCode(), inAppDeliveryRequestDtoArgumentCaptor.getValue().getCode()); } @Test void shouldSendInAppDelivery_withCorrectHCert_whenAppCodeIsPassed() { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de", - "BITBITBIT"); + var createDto = getAntibodyCertificateCreateDto("de", "BITBITBIT"); var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); var barcode = fixture.create(Barcode.class); when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); @@ -965,11 +1633,7 @@ void shouldSendInAppDelivery_withCorrectHCert_whenAppCodeIsPassed() { @Test void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de", - "BITBITBIT"); + var createDto = getAntibodyCertificateCreateDto("de", "BITBITBIT"); var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); @@ -978,7 +1642,7 @@ void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn( pdfByteArray); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); @@ -991,57 +1655,93 @@ void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { @Test void shouldNotSendInAppDelivery_whenNoAppCodeIsPassed() { - var createDto = getTestCertificateCreateDto( - null, - "1833", - "de"); + var createDto = getAntibodyCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getTestSigningInformation()).thenReturn(signingInformation); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verifyNoInteractions(inAppDeliveryClient); } + + @Test + void shouldMapCreateDto_toCertificatePrintRequestDto_whenAddressPassed() { + var createDto = getAntibodyCertificateCreateDto("de"); + var qrCodeData = fixture.create(AntibodyCertificateQrCode.class); + var pdf = fixture.create(byte[].class); + when(covidCertificateDtoMapperService.toAntibodyCertificateQrCode(any())).thenReturn(qrCodeData); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verify(certificatePrintRequestDtoMapper, times(1)) + .toCertificatePrintRequestDto(pdf, qrCodeData.getAntibodyInfo().get(0).getIdentifier(), createDto); + } + + @Test + void shouldCallPrintingService_whenAddressPassed() { + var createDto = getAntibodyCertificateCreateDto("de"); + var certificatePrintRequestDto = fixture.create(CertificatePrintRequestDto.class); + when(certificatePrintRequestDtoMapper.toCertificatePrintRequestDto(any(), any(), any())).thenReturn( + certificatePrintRequestDto); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verify(printQueueClient, times(1)).sendPrintJob(certificatePrintRequestDto); + } + + @Test + void shouldNotCallPrintingService_whenNoAddressPassed() { + var createDto = getAntibodyCertificateCreateDto("de", "BITBITBIT"); + var signingInformation = fixture.create(SigningInformationDto.class); + when(signingInformationService.getAntibodySigningInformation()).thenReturn(signingInformation); + + assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); + verifyNoInteractions(printQueueClient); + verifyNoInteractions(certificatePrintRequestDtoMapper); + } } @Nested - class GenerateRecoveryCovidCertificate { + class GenerateExceptionalCovidCertificate { @Test - void shouldMapDtoToRecoveryCertificateQrCode() throws IOException { - var createDto = getRecoveryCertificateCreateDto("de"); + void shouldMapDtoToExceptionalCertificateQrCode() throws IOException { + var createDto = getExceptionalCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); - verify(covidCertificateDtoMapperService).toRecoveryCertificateQrCode(createDto); + verify(covidCertificateDtoMapperService).toExceptionalCertificateQrCode(createDto); } @Test - void shouldMapDtoToRecoveryCertificatePdf() throws IOException { - var createDto = getRecoveryCertificateCreateDto("de"); - var qrCodeData = fixture.create(RecoveryCertificateQrCode.class); - when(covidCertificateDtoMapperService.toRecoveryCertificateQrCode(createDto)).thenReturn(qrCodeData); + void shouldMapDtoToExceptionalCertificatePdf() throws IOException { + var createDto = getExceptionalCertificateCreateDto("de"); + var qrCodeData = fixture.create(ExceptionalCertificateQrCode.class); + when(covidCertificateDtoMapperService.toExceptionalCertificateQrCode(createDto)).thenReturn(qrCodeData); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); - verify(covidCertificateDtoMapperService).toRecoveryCertificatePdf(createDto, qrCodeData); + verify(covidCertificateDtoMapperService).toExceptionalCertificatePdf(createDto, qrCodeData); } @Test void shouldGetSigningInformationForTheCovidCertificate() throws IOException { - var createDto = getRecoveryCertificateCreateDto("de"); + var createDto = getExceptionalCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); - verify(signingInformationService).getRecoverySigningInformation(createDto); + verify(signingInformationService).getExceptionalSigningInformation(); } @Test - void throwsCreateCertificateException_ifMapDtoToRecoveryCertificateQrCodeThrowsCreateCertificateException() { - var createDto = getRecoveryCertificateCreateDto("de"); + void throwsCreateCertificateException_ifMapDtoToExceptionalCertificateQrCodeThrowsCreateCertificateException() { + var createDto = getExceptionalCertificateCreateDto("de"); var expected = fixture.create(CreateCertificateException.class); - when(covidCertificateDtoMapperService.toRecoveryCertificateQrCode(any())).thenThrow(expected); + when(covidCertificateDtoMapperService.toExceptionalCertificateQrCode(any())).thenThrow(expected); CreateCertificateException exception = assertThrows(CreateCertificateException.class, () -> service.generateCovidCertificate(createDto)); @@ -1050,10 +1750,10 @@ void throwsCreateCertificateException_ifMapDtoToRecoveryCertificateQrCodeThrowsC } @Test - void throwsInvalidCountryOfRecovery_ifMapDtoToRecoveryCertificatePdfThrowsCreateCertificateException() { - var createDto = getRecoveryCertificateCreateDto("de"); + void throwsInvalidCountryOfExceptional_ifMapDtoToExceptionalCertificatePdfThrowsCreateCertificateException() { + var createDto = getExceptionalCertificateCreateDto("de"); var expected = fixture.create(CreateCertificateException.class); - when(covidCertificateDtoMapperService.toRecoveryCertificatePdf(any(), any())).thenThrow(expected); + when(covidCertificateDtoMapperService.toExceptionalCertificatePdf(any(), any())).thenThrow(expected); CreateCertificateException exception = assertThrows(CreateCertificateException.class, () -> service.generateCovidCertificate(createDto)); @@ -1063,15 +1763,15 @@ void throwsInvalidCountryOfRecovery_ifMapDtoToRecoveryCertificatePdfThrowsCreate @Test void shouldCreateBarcode_withCorrectContents() throws IOException { - var createDto = getRecoveryCertificateCreateDto("de"); - var qrCodeData = fixture.create(RecoveryCertificateQrCode.class); - when(covidCertificateDtoMapperService.toRecoveryCertificateQrCode(createDto)).thenReturn(qrCodeData); + var createDto = getExceptionalCertificateCreateDto("de"); + var qrCodeData = fixture.create(ExceptionalCertificateQrCode.class); + when(covidCertificateDtoMapperService.toExceptionalCertificateQrCode(createDto)).thenReturn(qrCodeData); var contents = fixture.create(String.class); var objectWriter = mock(ObjectWriter.class); when(objectMapper.writer()).thenReturn(objectWriter); when(objectWriter.writeValueAsString(qrCodeData)).thenReturn(contents); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); @@ -1080,9 +1780,9 @@ void shouldCreateBarcode_withCorrectContents() throws IOException { @Test void shouldCreateBarcode_usingCorrectSigningInformation() throws IOException { - var createDto = getRecoveryCertificateCreateDto("de"); + var createDto = getExceptionalCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); service.generateCovidCertificate(createDto); @@ -1091,32 +1791,32 @@ void shouldCreateBarcode_usingCorrectSigningInformation() throws IOException { @Test void shouldCreatePdf() throws IOException { - var createDto = getRecoveryCertificateCreateDto("de"); - var RecoveryPdf = fixture.create(RecoveryCertificatePdf.class); + var createDto = getExceptionalCertificateCreateDto("de"); + var ExceptionalPdf = fixture.create(ExceptionalCertificatePdf.class); var barcode = fixture.create(Barcode.class); var now = LocalDateTime.now(); - when(covidCertificateDtoMapperService.toRecoveryCertificatePdf(any(), any())).thenReturn(RecoveryPdf); + when(covidCertificateDtoMapperService.toExceptionalCertificatePdf(any(), any())).thenReturn(ExceptionalPdf); when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); try (MockedStatic localDateTimeMock = Mockito.mockStatic(LocalDateTime.class)) { localDateTimeMock.when(LocalDateTime::now).thenReturn(now); service.generateCovidCertificate(createDto); - verify(pdfCertificateGenerationService).generateCovidCertificate(RecoveryPdf, barcode.getPayload(), + verify(pdfCertificateGenerationService).generateCovidCertificate(ExceptionalPdf, barcode.getPayload(), now); } } @Test void shouldReturnBarcode() throws IOException { - var createDto = getRecoveryCertificateCreateDto("de"); + var createDto = getExceptionalCertificateCreateDto("de"); var barcode = fixture.create(Barcode.class); when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); var actual = service.generateCovidCertificate(createDto); @@ -1125,10 +1825,10 @@ void shouldReturnBarcode() throws IOException { @Test void shouldReturnPdf() throws IOException { - var createDto = getRecoveryCertificateCreateDto("de"); + var createDto = getExceptionalCertificateCreateDto("de"); var pdf = fixture.create(byte[].class); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); var actual = service.generateCovidCertificate(createDto); @@ -1138,9 +1838,9 @@ void shouldReturnPdf() throws IOException { @Test void shouldUVCI() throws IOException { - var createDto = getRecoveryCertificateCreateDto("de"); + var createDto = getExceptionalCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); var actual = service.generateCovidCertificate(createDto); @@ -1149,14 +1849,12 @@ void shouldUVCI() throws IOException { @Test void shouldSendInAppDelivery_withCorrectAppCode_whenAppCodeIsPassed() { - var createDto = getRecoveryCertificateCreateDto( - "de", - "BITBITBIT"); + var createDto = getExceptionalCertificateCreateDto("de", "BITBITBIT"); var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); @@ -1169,16 +1867,14 @@ void shouldSendInAppDelivery_withCorrectAppCode_whenAppCodeIsPassed() { @Test void shouldSendInAppDelivery_withCorrectHCert_whenAppCodeIsPassed() { - var createDto = getRecoveryCertificateCreateDto( - "de", - "BITBITBIT"); + var createDto = getExceptionalCertificateCreateDto("de", "BITBITBIT"); var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); var barcode = fixture.create(Barcode.class); when(barcodeService.createBarcode(any(), any(), any())).thenReturn(barcode); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); @@ -1191,9 +1887,7 @@ void shouldSendInAppDelivery_withCorrectHCert_whenAppCodeIsPassed() { @Test void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { - var createDto = getRecoveryCertificateCreateDto( - "de", - "BITBITBIT"); + var createDto = getExceptionalCertificateCreateDto("de", "BITBITBIT"); var uvciArgumentCaptor = ArgumentCaptor.forClass(String.class); var inAppDeliveryRequestDtoArgumentCaptor = ArgumentCaptor.forClass(InAppDeliveryRequestDto.class); @@ -1202,7 +1896,7 @@ void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn( pdfByteArray); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); @@ -1215,9 +1909,9 @@ void shouldSendInAppDelivery_withCorrectPdfData_whenAppCodeIsPassed() { @Test void shouldNotSendInAppDelivery_whenNoAppCodeIsPassed() { - var createDto = getRecoveryCertificateCreateDto("de"); + var createDto = getExceptionalCertificateCreateDto("de"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verifyNoInteractions(inAppDeliveryClient); @@ -1225,27 +1919,28 @@ void shouldNotSendInAppDelivery_whenNoAppCodeIsPassed() { @Test void shouldMapCreateDto_toCertificatePrintRequestDto_whenAddressPassed() { - var createDto = getRecoveryCertificateCreateDto("de"); - var qrCodeData = fixture.create(RecoveryCertificateQrCode.class); + var createDto = getExceptionalCertificateCreateDto("de"); + var qrCodeData = fixture.create(ExceptionalCertificateQrCode.class); var pdf = fixture.create(byte[].class); - when(covidCertificateDtoMapperService.toRecoveryCertificateQrCode(any())).thenReturn(qrCodeData); + when(covidCertificateDtoMapperService.toExceptionalCertificateQrCode(any())).thenReturn(qrCodeData); when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verify(certificatePrintRequestDtoMapper, times(1)) - .toCertificatePrintRequestDto(pdf, qrCodeData.getRecoveryInfo().get(0).getIdentifier(), createDto); + .toCertificatePrintRequestDto(pdf, qrCodeData.getExceptionalInfo().get(0).getIdentifier(), + createDto); } @Test void shouldCallPrintingService_whenAddressPassed() { - var createDto = getRecoveryCertificateCreateDto("de"); + var createDto = getExceptionalCertificateCreateDto("de"); var certificatePrintRequestDto = fixture.create(CertificatePrintRequestDto.class); when(certificatePrintRequestDtoMapper.toCertificatePrintRequestDto(any(), any(), any())).thenReturn( certificatePrintRequestDto); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verify(printQueueClient, times(1)).sendPrintJob(certificatePrintRequestDto); @@ -1253,11 +1948,9 @@ void shouldCallPrintingService_whenAddressPassed() { @Test void shouldNotCallPrintingService_whenNoAddressPassed() { - var createDto = getRecoveryCertificateCreateDto( - "de", - "BITBITBIT"); + var createDto = getExceptionalCertificateCreateDto("de", "BITBITBIT"); var signingInformation = fixture.create(SigningInformationDto.class); - when(signingInformationService.getRecoverySigningInformation(any())).thenReturn(signingInformation); + when(signingInformationService.getExceptionalSigningInformation()).thenReturn(signingInformation); assertDoesNotThrow(() -> service.generateCovidCertificate(createDto)); verifyNoInteractions(printQueueClient); diff --git a/src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationServiceTest.java b/src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationServiceTest.java new file mode 100644 index 00000000..89d79e93 --- /dev/null +++ b/src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationServiceTest.java @@ -0,0 +1,726 @@ +package ch.admin.bag.covidcertificate.service; + +import ch.admin.bag.covidcertificate.api.Constants; +import ch.admin.bag.covidcertificate.api.exception.CreateCertificateException; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.AntibodyCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.ExceptionalCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.RecoveryCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.RecoveryRatCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.TestCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.VaccinationCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.api.request.pdfgeneration.VaccinationTouristCertificatePdfGenerateRequestDto; +import ch.admin.bag.covidcertificate.service.document.PdfCertificateGenerationService; +import ch.admin.bag.covidcertificate.service.domain.AntibodyCertificatePdf; +import ch.admin.bag.covidcertificate.service.domain.ExceptionalCertificatePdf; +import ch.admin.bag.covidcertificate.service.domain.RecoveryCertificatePdf; +import ch.admin.bag.covidcertificate.service.domain.RecoveryCertificateQrCode; +import ch.admin.bag.covidcertificate.service.domain.TestCertificatePdf; +import ch.admin.bag.covidcertificate.service.domain.TestCertificateQrCode; +import ch.admin.bag.covidcertificate.service.domain.VaccinationCertificatePdf; +import ch.admin.bag.covidcertificate.service.domain.VaccinationCertificateQrCode; +import ch.admin.bag.covidcertificate.service.domain.VaccinationTouristCertificatePdf; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.flextrade.jfixture.JFixture; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; +import se.digg.dgc.encoding.Barcode; +import se.digg.dgc.encoding.BarcodeException; +import se.digg.dgc.encoding.impl.DefaultBarcodeCreator; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +@RunWith(MockitoJUnitRunner.class) +class CovidCertificatePdfGenerationServiceTest { + private final JFixture fixture = new JFixture(); + @InjectMocks + private CovidCertificatePdfGenerationService service; + @Mock + private BarcodeService barcodeService; + @Mock + private PdfCertificateGenerationService pdfCertificateGenerationService; + @Mock + private CovidCertificateDtoMapperService covidCertificateDtoMapperService; + @Mock + private CovidCertificatePdfGenerateRequestDtoMapperService covidCertificatePdfGenerateRequestDtoMapperService; + @Mock + private ObjectMapper objectMapper; + @Mock + private COSETime coseTime; + + @BeforeEach + public void setUp() throws IOException { + lenient().when(barcodeService.createBarcode(any(), any(), any())).thenReturn(fixture.create(Barcode.class)); + lenient().when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())) + .thenReturn(fixture.create(byte[].class)); + + lenient().when(covidCertificateDtoMapperService.toVaccinationCertificateQrCode(any())) + .thenReturn(fixture.create(VaccinationCertificateQrCode.class)); + lenient().when(covidCertificateDtoMapperService.toVaccinationCertificatePdf(any(), any())) + .thenReturn(fixture.create(VaccinationCertificatePdf.class)); + lenient().when(covidCertificateDtoMapperService.toTestCertificateQrCode(any())) + .thenReturn(fixture.create(TestCertificateQrCode.class)); + lenient().when(covidCertificateDtoMapperService.toTestCertificatePdf(any(), any())) + .thenReturn(fixture.create(TestCertificatePdf.class)); + lenient().when(covidCertificateDtoMapperService.toRecoveryCertificateQrCode(any())) + .thenReturn(fixture.create(RecoveryCertificateQrCode.class)); + lenient().when(covidCertificateDtoMapperService.toRecoveryCertificatePdf(any(), any())) + .thenReturn(fixture.create(RecoveryCertificatePdf.class)); + + lenient().when(coseTime.calculateExpirationInstantPlusMonths(Constants.EXPIRATION_PERIOD_24_MONTHS)) + .thenReturn(fixture.create(Instant.class)); + lenient().when(coseTime.calculateExpirationInstantPlusDays(Constants.EXPIRATION_PERIOD_30_DAYS)) + .thenReturn(fixture.create(Instant.class)); + + ObjectWriter objectWriter = mock(ObjectWriter.class); + lenient().when(objectMapper.writer()).thenReturn(objectWriter); + lenient().when(objectWriter.writeValueAsString(any())).thenReturn(fixture.create(String.class)); + } + + LocalDateTime getLocalDateTimeFromEpochMillis(long millis) { + var instant = Instant.ofEpochMilli(millis); + return ZonedDateTime.from(instant.atZone(ZoneId.systemDefault())).toLocalDateTime(); + } + + @Nested + class GenerateVaccinationFromExistingCovidCertificate { + @Test + void shouldMapDtoToVaccinationCertificatePdf() { + var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + verify(covidCertificatePdfGenerateRequestDtoMapperService).toVaccinationCertificatePdf( + pdfGenerateRequestDto); + } + + @Test + void throwsCreateCertificateException_ifMapDtoToVaccinationCertificatePdfThrowsCreateCertificateException() { + var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toVaccinationCertificatePdf( + any())).thenThrow(expected); + + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateFromExistingCovidCertificate( + pdfGenerateRequestDto) + ); + + assertEquals(expected.getError(), exception.getError()); + } + + @Test + void shouldCreatePdf_withCorrectPdfData() { + var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); + var vaccinationPdf = fixture.create(VaccinationCertificatePdf.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toVaccinationCertificatePdf( + any())).thenReturn(vaccinationPdf); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(eq(vaccinationPdf), any(), any()); + } + + @Test + void shouldCreatePdf_withCorrectBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), eq(barcode.getPayload()), any()); + } + + @Test + void shouldCreatePdf_withCorrectIssuedAt() { + var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); + var issuedAt = getLocalDateTimeFromEpochMillis(pdfGenerateRequestDto.getIssuedAt()); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), any(), eq(issuedAt)); + } + + @Test + void shouldReturnBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertArrayEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + } + + @Test + void shouldReturnPdf() { + var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); + var pdf = fixture.create(byte[].class); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertEquals(pdf, actual.getResponseDto().getPdf()); + } + + @Test + void shouldReturnUVCI() { + var pdfGenerateRequestDto = fixture.create(VaccinationCertificatePdfGenerateRequestDto.class); + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertNotNull(actual.getResponseDto().getUvci()); + } + } + + @Nested + class GenerateVaccinationTouristFromExistingCovidCertificate { + @Test + void shouldMapDtoToVaccinationTouristCertificatePdf() { + var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + verify(covidCertificatePdfGenerateRequestDtoMapperService).toVaccinationTouristCertificatePdf( + pdfGenerateRequestDto); + } + + @Test + void throwsCreateCertificateException_ifMapDtoToVaccinationTouristCertificatePdfThrowsCreateCertificateException() { + var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toVaccinationTouristCertificatePdf( + any())).thenThrow(expected); + + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateFromExistingCovidCertificate( + pdfGenerateRequestDto) + ); + + assertEquals(expected.getError(), exception.getError()); + } + + @Test + void shouldCreatePdf_withCorrectPdfData() { + var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); + var vaccinationTouristPdf = fixture.create(VaccinationTouristCertificatePdf.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toVaccinationTouristCertificatePdf( + any())).thenReturn(vaccinationTouristPdf); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(eq(vaccinationTouristPdf), any(), any()); + } + + @Test + void shouldCreatePdf_withCorrectBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), eq(barcode.getPayload()), any()); + } + + @Test + void shouldCreatePdf_withCorrectIssuedAt() { + var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); + var issuedAt = getLocalDateTimeFromEpochMillis(pdfGenerateRequestDto.getIssuedAt()); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), any(), eq(issuedAt)); + } + + @Test + void shouldReturnBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertArrayEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + } + + @Test + void shouldReturnPdf() { + var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); + var pdf = fixture.create(byte[].class); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertEquals(pdf, actual.getResponseDto().getPdf()); + } + + @Test + void shouldReturnUVCI() { + var pdfGenerateRequestDto = fixture.create(VaccinationTouristCertificatePdfGenerateRequestDto.class); + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertNotNull(actual.getResponseDto().getUvci()); + } + } + + @Nested + class GenerateTestFromExistingCovidCertificate { + @Test + void shouldMapDtoToTestCertificatePdf() { + var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + verify(covidCertificatePdfGenerateRequestDtoMapperService).toTestCertificatePdf(pdfGenerateRequestDto); + } + + @Test + void throwsCreateCertificateException_ifMapDtoToTestCertificatePdfThrowsCreateCertificateException() { + var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toTestCertificatePdf(any())).thenThrow(expected); + + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateFromExistingCovidCertificate( + pdfGenerateRequestDto) + ); + + assertEquals(expected.getError(), exception.getError()); + } + + @Test + void shouldCreatePdf_withCorrectPdfData() { + var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); + var testPdf = fixture.create(TestCertificatePdf.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toTestCertificatePdf(any())).thenReturn(testPdf); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(eq(testPdf), any(), any()); + } + + @Test + void shouldCreatePdf_withCorrectBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), eq(barcode.getPayload()), any()); + } + + @Test + void shouldCreatePdf_withCorrectIssuedAt() { + var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); + var issuedAt = getLocalDateTimeFromEpochMillis(pdfGenerateRequestDto.getIssuedAt()); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), any(), eq(issuedAt)); + } + + @Test + void shouldReturnBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertArrayEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + } + + @Test + void shouldReturnPdf() { + var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); + var pdf = fixture.create(byte[].class); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertEquals(pdf, actual.getResponseDto().getPdf()); + } + + @Test + void shouldReturnUVCI() { + var pdfGenerateRequestDto = fixture.create(TestCertificatePdfGenerateRequestDto.class); + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertNotNull(actual.getResponseDto().getUvci()); + } + } + + @Nested + class GenerateRecoveryFromExistingCovidCertificate { + @Test + void shouldMapDtoToRecoveryCertificatePdf() { + var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + verify(covidCertificatePdfGenerateRequestDtoMapperService).toRecoveryCertificatePdf(pdfGenerateRequestDto); + } + + @Test + void throwsCreateCertificateException_ifMapDtoToRecoveryCertificatePdfThrowsCreateCertificateException() { + var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toRecoveryCertificatePdf(any())).thenThrow( + expected); + + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateFromExistingCovidCertificate( + pdfGenerateRequestDto) + ); + + assertEquals(expected.getError(), exception.getError()); + } + + @Test + void shouldCreatePdf_withCorrectPdfData() { + var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); + var recoveryPdf = fixture.create(RecoveryCertificatePdf.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toRecoveryCertificatePdf(any())).thenReturn( + recoveryPdf); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(eq(recoveryPdf), any(), any()); + } + + @Test + void shouldCreatePdf_withCorrectBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), eq(barcode.getPayload()), any()); + } + + @Test + void shouldCreatePdf_withCorrectIssuedAt() { + var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); + var issuedAt = getLocalDateTimeFromEpochMillis(pdfGenerateRequestDto.getIssuedAt()); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), any(), eq(issuedAt)); + } + + @Test + void shouldReturnBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertArrayEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + } + + @Test + void shouldReturnPdf() { + var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); + var pdf = fixture.create(byte[].class); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertEquals(pdf, actual.getResponseDto().getPdf()); + } + + @Test + void shouldReturnUVCI() { + var pdfGenerateRequestDto = fixture.create(RecoveryCertificatePdfGenerateRequestDto.class); + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertNotNull(actual.getResponseDto().getUvci()); + } + } + + @Nested + class GenerateRecoveryRatFromExistingCovidCertificate { + @Test + void shouldMapDtoToRecoveryCertificatePdf() { + var pdfGenerateRequestDto = fixture.create(RecoveryRatCertificatePdfGenerateRequestDto.class); + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + verify(covidCertificatePdfGenerateRequestDtoMapperService).toRecoveryRatCertificatePdf( + pdfGenerateRequestDto); + } + + @Test + void throwsCreateCertificateException_ifMapDtoToRecoveryCertificatePdfThrowsCreateCertificateException() { + var pdfGenerateRequestDto = fixture.create(RecoveryRatCertificatePdfGenerateRequestDto.class); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toRecoveryRatCertificatePdf(any())).thenThrow( + expected); + + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateFromExistingCovidCertificate( + pdfGenerateRequestDto) + ); + + assertEquals(expected.getError(), exception.getError()); + } + + @Test + void shouldCreatePdf_withCorrectPdfData() { + var pdfGenerateRequestDto = fixture.create(RecoveryRatCertificatePdfGenerateRequestDto.class); + var recoveryPdf = fixture.create(RecoveryCertificatePdf.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toRecoveryRatCertificatePdf(any())).thenReturn( + recoveryPdf); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(eq(recoveryPdf), any(), any()); + } + + @Test + void shouldCreatePdf_withCorrectBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(RecoveryRatCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), eq(barcode.getPayload()), any()); + } + + @Test + void shouldCreatePdf_withCorrectIssuedAt() { + var pdfGenerateRequestDto = fixture.create(RecoveryRatCertificatePdfGenerateRequestDto.class); + var issuedAt = getLocalDateTimeFromEpochMillis(pdfGenerateRequestDto.getIssuedAt()); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), any(), eq(issuedAt)); + } + + @Test + void shouldReturnBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(RecoveryRatCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertArrayEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + } + + @Test + void shouldReturnPdf() { + var pdfGenerateRequestDto = fixture.create(RecoveryRatCertificatePdfGenerateRequestDto.class); + var pdf = fixture.create(byte[].class); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertEquals(pdf, actual.getResponseDto().getPdf()); + } + + @Test + void shouldReturnUVCI() { + var pdfGenerateRequestDto = fixture.create(RecoveryRatCertificatePdfGenerateRequestDto.class); + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertNotNull(actual.getResponseDto().getUvci()); + } + } + + @Nested + class GenerateAntibodyFromExistingCovidCertificate { + @Test + void shouldMapDtoToRecoveryCertificatePdf() { + var pdfGenerateRequestDto = fixture.create(AntibodyCertificatePdfGenerateRequestDto.class); + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + verify(covidCertificatePdfGenerateRequestDtoMapperService).toAntibodyCertificatePdf(pdfGenerateRequestDto); + } + + @Test + void throwsCreateCertificateException_ifMapDtoToRecoveryCertificatePdfThrowsCreateCertificateException() { + var pdfGenerateRequestDto = fixture.create(AntibodyCertificatePdfGenerateRequestDto.class); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toAntibodyCertificatePdf(any())).thenThrow( + expected); + + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateFromExistingCovidCertificate( + pdfGenerateRequestDto) + ); + + assertEquals(expected.getError(), exception.getError()); + } + + @Test + void shouldCreatePdf_withCorrectPdfData() { + var pdfGenerateRequestDto = fixture.create(AntibodyCertificatePdfGenerateRequestDto.class); + var recoveryPdf = fixture.create(AntibodyCertificatePdf.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toAntibodyCertificatePdf(any())).thenReturn( + recoveryPdf); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(eq(recoveryPdf), any(), any()); + } + + @Test + void shouldCreatePdf_withCorrectBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(AntibodyCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), eq(barcode.getPayload()), any()); + } + + @Test + void shouldCreatePdf_withCorrectIssuedAt() { + var pdfGenerateRequestDto = fixture.create(AntibodyCertificatePdfGenerateRequestDto.class); + var issuedAt = getLocalDateTimeFromEpochMillis(pdfGenerateRequestDto.getIssuedAt()); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), any(), eq(issuedAt)); + } + + @Test + void shouldReturnBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(AntibodyCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertArrayEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + } + + @Test + void shouldReturnPdf() { + var pdfGenerateRequestDto = fixture.create(AntibodyCertificatePdfGenerateRequestDto.class); + var pdf = fixture.create(byte[].class); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertEquals(pdf, actual.getResponseDto().getPdf()); + } + + @Test + void shouldReturnUVCI() { + var pdfGenerateRequestDto = fixture.create(AntibodyCertificatePdfGenerateRequestDto.class); + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertNotNull(actual.getResponseDto().getUvci()); + } + } + + @Nested + class GenerateExceptionalFromExistingCovidCertificate { + @Test + void shouldMapDtoToRecoveryCertificatePdf() { + var pdfGenerateRequestDto = fixture.create(ExceptionalCertificatePdfGenerateRequestDto.class); + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + verify(covidCertificatePdfGenerateRequestDtoMapperService).toExceptionalCertificatePdf( + pdfGenerateRequestDto); + } + + @Test + void throwsCreateCertificateException_ifMapDtoToRecoveryCertificatePdfThrowsCreateCertificateException() { + var pdfGenerateRequestDto = fixture.create(ExceptionalCertificatePdfGenerateRequestDto.class); + var expected = fixture.create(CreateCertificateException.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toExceptionalCertificatePdf(any())).thenThrow( + expected); + + CreateCertificateException exception = assertThrows(CreateCertificateException.class, + () -> service.generateFromExistingCovidCertificate( + pdfGenerateRequestDto) + ); + + assertEquals(expected.getError(), exception.getError()); + } + + @Test + void shouldCreatePdf_withCorrectPdfData() { + var pdfGenerateRequestDto = fixture.create(ExceptionalCertificatePdfGenerateRequestDto.class); + var recoveryPdf = fixture.create(ExceptionalCertificatePdf.class); + when(covidCertificatePdfGenerateRequestDtoMapperService.toExceptionalCertificatePdf(any())).thenReturn( + recoveryPdf); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(eq(recoveryPdf), any(), any()); + } + + @Test + void shouldCreatePdf_withCorrectBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(ExceptionalCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), eq(barcode.getPayload()), any()); + } + + @Test + void shouldCreatePdf_withCorrectIssuedAt() { + var pdfGenerateRequestDto = fixture.create(ExceptionalCertificatePdfGenerateRequestDto.class); + var issuedAt = getLocalDateTimeFromEpochMillis(pdfGenerateRequestDto.getIssuedAt()); + + service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + verify(pdfCertificateGenerationService).generateCovidCertificate(any(), any(), eq(issuedAt)); + } + + @Test + void shouldReturnBarcode() throws BarcodeException { + var pdfGenerateRequestDto = fixture.create(ExceptionalCertificatePdfGenerateRequestDto.class); + var barcode = new DefaultBarcodeCreator().create(pdfGenerateRequestDto.getHcert(), + StandardCharsets.US_ASCII); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertArrayEquals(barcode.getImage(), actual.getResponseDto().getQrCode()); + } + + @Test + void shouldReturnPdf() { + var pdfGenerateRequestDto = fixture.create(ExceptionalCertificatePdfGenerateRequestDto.class); + var pdf = fixture.create(byte[].class); + when(pdfCertificateGenerationService.generateCovidCertificate(any(), any(), any())).thenReturn(pdf); + + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertEquals(pdf, actual.getResponseDto().getPdf()); + } + + @Test + void shouldReturnUVCI() { + var pdfGenerateRequestDto = fixture.create(ExceptionalCertificatePdfGenerateRequestDto.class); + var actual = service.generateFromExistingCovidCertificate(pdfGenerateRequestDto); + + assertNotNull(actual.getResponseDto().getUvci()); + } + } +} diff --git a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationControllerSecurityTest.java b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationControllerSecurityTest.java index fdb8f606..7cf40b1c 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationControllerSecurityTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationControllerSecurityTest.java @@ -1,8 +1,12 @@ package ch.admin.bag.covidcertificate.web.controller; +import ch.admin.bag.covidcertificate.api.request.AntibodyCertificateCreateDto; +import ch.admin.bag.covidcertificate.api.request.ExceptionalCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.RecoveryCertificateCreateDto; +import ch.admin.bag.covidcertificate.api.request.RecoveryRatCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.TestCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.VaccinationCertificateCreateDto; +import ch.admin.bag.covidcertificate.api.request.VaccinationTouristCertificateCreateDto; import ch.admin.bag.covidcertificate.api.response.CovidCertificateResponseEnvelope; import ch.admin.bag.covidcertificate.authorization.AuthorizationInterceptor; import ch.admin.bag.covidcertificate.authorization.AuthorizationService; @@ -32,9 +36,13 @@ import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeRecoveryCertificateCreateDto; import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeTestCertificateCreateDto; import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeVaccinationCertificateCreateDto; +import static ch.admin.bag.covidcertificate.TestModelProvider.getAntibodyCertificateCreateDto; +import static ch.admin.bag.covidcertificate.TestModelProvider.getExceptionalCertificateCreateDto; import static ch.admin.bag.covidcertificate.TestModelProvider.getRecoveryCertificateCreateDto; +import static ch.admin.bag.covidcertificate.TestModelProvider.getRecoveryRatCertificateCreateDto; import static ch.admin.bag.covidcertificate.TestModelProvider.getTestCertificateCreateDto; import static ch.admin.bag.covidcertificate.TestModelProvider.getVaccinationCertificateCreateDto; +import static ch.admin.bag.covidcertificate.TestModelProvider.getVaccinationTouristCertificateCreateDto; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.times; @@ -70,12 +78,24 @@ void setupMocks() throws IOException { lenient().when(covidCertificateGenerationService.generateCovidCertificate( any(VaccinationCertificateCreateDto.class))).thenReturn( fixture.create(CovidCertificateResponseEnvelope.class)); + lenient().when(covidCertificateGenerationService.generateCovidCertificate( + any(VaccinationTouristCertificateCreateDto.class))).thenReturn( + fixture.create(CovidCertificateResponseEnvelope.class)); lenient().when(covidCertificateGenerationService.generateCovidCertificate( any(TestCertificateCreateDto.class))).thenReturn( fixture.create(CovidCertificateResponseEnvelope.class)); lenient().when(covidCertificateGenerationService.generateCovidCertificate( any(RecoveryCertificateCreateDto.class))).thenReturn( fixture.create(CovidCertificateResponseEnvelope.class)); + lenient().when(covidCertificateGenerationService.generateCovidCertificate( + any(RecoveryRatCertificateCreateDto.class))).thenReturn( + fixture.create(CovidCertificateResponseEnvelope.class)); + lenient().when(covidCertificateGenerationService.generateCovidCertificate( + any(AntibodyCertificateCreateDto.class))).thenReturn( + fixture.create(CovidCertificateResponseEnvelope.class)); + lenient().when(covidCertificateGenerationService.generateCovidCertificate( + any(ExceptionalCertificateCreateDto.class))).thenReturn( + fixture.create(CovidCertificateResponseEnvelope.class)); } private void callCreateCertificateWithToken(String url, String requestBody, LocalDateTime tokenExpiration, String userRole, HttpStatus status) throws Exception { @@ -121,12 +141,52 @@ void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception @Test void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); - Mockito.verify(covidCertificateGenerationService, times(0)).generateCovidCertificate(any(VaccinationCertificateCreateDto.class)); + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(VaccinationCertificateCreateDto.class)); } - private void callCreateVaccinationCertificateWithToken(LocalDateTime tokenExpiration, String userRole, HttpStatus status) throws Exception { + private void callCreateVaccinationCertificateWithToken( + LocalDateTime tokenExpiration, String userRole, HttpStatus status) throws Exception { var createDto = getVaccinationCertificateCreateDto("EU/1/20/1507", "de"); - callCreateCertificateWithToken(URL, mapper.writeValueAsString(createDto), tokenExpiration, userRole, status); + callCreateCertificateWithToken(URL, mapper.writeValueAsString(createDto), tokenExpiration, userRole, + status); + } + } + + @Nested + class CreateVaccinationTouristCertificate { + private static final String URL = BASE_URL + "vaccination-tourist"; + + @Test + void returnsOKIfAuthorizationTokenValid() throws Exception { + callCreateVaccinationTouristCertificateWithToken(EXPIRED_IN_FUTURE, VALID_USER_ROLE, HttpStatus.FORBIDDEN); + callCreateVaccinationTouristCertificateWithToken(EXPIRED_IN_FUTURE, VALID_SUPERUSER_ROLE, + HttpStatus.FORBIDDEN); + // Feature is deactivated + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(VaccinationTouristCertificateCreateDto.class)); + } + + @Test + void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception { + callCreateVaccinationTouristCertificateWithToken(EXPIRED_IN_FUTURE, INVALID_USER_ROLE, + HttpStatus.FORBIDDEN); + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(VaccinationTouristCertificateCreateDto.class)); + } + + @Test + void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { + callCreateVaccinationTouristCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(VaccinationTouristCertificateCreateDto.class)); + } + + private void callCreateVaccinationTouristCertificateWithToken( + LocalDateTime tokenExpiration, String userRole, HttpStatus status) throws Exception { + var createDto = getVaccinationTouristCertificateCreateDto("EU/1/20/1507", "de"); + callCreateCertificateWithToken(URL, mapper.writeValueAsString(createDto), tokenExpiration, userRole, + status); } } @@ -137,7 +197,8 @@ class CreateTestCertificate { @Test void returnsOKIfAuthorizationTokenValid() throws Exception { callCreateTestCertificateWithToken(EXPIRED_IN_FUTURE, VALID_USER_ROLE, HttpStatus.OK); - Mockito.verify(covidCertificateGenerationService, times(1)).generateCovidCertificate(any(TestCertificateCreateDto.class)); + Mockito.verify(covidCertificateGenerationService, times(1)) + .generateCovidCertificate(any(TestCertificateCreateDto.class)); } @Test @@ -177,12 +238,119 @@ void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception @Test void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { callCreateRecoveryCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); - Mockito.verify(covidCertificateGenerationService, times(0)).generateCovidCertificate(any(RecoveryCertificateCreateDto.class)); + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(RecoveryCertificateCreateDto.class)); } - private void callCreateRecoveryCertificateWithToken(LocalDateTime tokenExpiration, String userRole, HttpStatus status) throws Exception { + private void callCreateRecoveryCertificateWithToken( + LocalDateTime tokenExpiration, String userRole, HttpStatus status) throws Exception { var createDto = getRecoveryCertificateCreateDto("de"); - callCreateCertificateWithToken(URL, mapper.writeValueAsString(createDto), tokenExpiration, userRole, status); + callCreateCertificateWithToken(URL, mapper.writeValueAsString(createDto), tokenExpiration, userRole, + status); + } + } + + @Nested + class CreateRecoveryRatCertificate { + private static final String URL = BASE_URL + "recovery-rat"; + + @Test + void returnsOKIfAuthorizationTokenValid() throws Exception { + callCreateRecoveryRatCertificateWithToken(EXPIRED_IN_FUTURE, VALID_USER_ROLE, HttpStatus.OK); + callCreateRecoveryRatCertificateWithToken(EXPIRED_IN_FUTURE, VALID_SUPERUSER_ROLE, HttpStatus.OK); + Mockito.verify(covidCertificateGenerationService, times(2)) + .generateCovidCertificate(any(RecoveryRatCertificateCreateDto.class)); + } + + @Test + void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception { + callCreateRecoveryRatCertificateWithToken(EXPIRED_IN_FUTURE, INVALID_USER_ROLE, HttpStatus.FORBIDDEN); + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(RecoveryRatCertificateCreateDto.class)); + } + + @Test + void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { + callCreateRecoveryRatCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(RecoveryRatCertificateCreateDto.class)); + } + + private void callCreateRecoveryRatCertificateWithToken( + LocalDateTime tokenExpiration, String userRole, HttpStatus status) throws Exception { + var createDto = getRecoveryRatCertificateCreateDto("de", "DB1E7078"); + callCreateCertificateWithToken(URL, mapper.writeValueAsString(createDto), tokenExpiration, userRole, + status); + } + } + + @Nested + class CreateAntibodyCertificate { + private static final String URL = BASE_URL + "antibody"; + + @Test + void returnsOKIfAuthorizationTokenValid() throws Exception { + callCreateAntibodyCertificateWithToken(EXPIRED_IN_FUTURE, VALID_USER_ROLE, HttpStatus.FORBIDDEN); + callCreateAntibodyCertificateWithToken(EXPIRED_IN_FUTURE, VALID_SUPERUSER_ROLE, HttpStatus.FORBIDDEN); + // Feature is deactivated + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(VaccinationTouristCertificateCreateDto.class)); + } + + @Test + void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception { + callCreateAntibodyCertificateWithToken(EXPIRED_IN_FUTURE, INVALID_USER_ROLE, HttpStatus.FORBIDDEN); + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(VaccinationTouristCertificateCreateDto.class)); + } + + @Test + void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { + callCreateAntibodyCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(VaccinationTouristCertificateCreateDto.class)); + } + + private void callCreateAntibodyCertificateWithToken( + LocalDateTime tokenExpiration, String userRole, HttpStatus status) throws Exception { + var createDto = getAntibodyCertificateCreateDto("de"); + callCreateCertificateWithToken(URL, mapper.writeValueAsString(createDto), tokenExpiration, userRole, + status); + } + } + + @Nested + class CreateExceptionalCertificate { + private static final String URL = BASE_URL + "exceptional"; + + @Test + void returnsOKIfAuthorizationTokenValid() throws Exception { + callCreateExceptionalCertificateWithToken(EXPIRED_IN_FUTURE, VALID_USER_ROLE, HttpStatus.FORBIDDEN); + callCreateExceptionalCertificateWithToken(EXPIRED_IN_FUTURE, VALID_SUPERUSER_ROLE, HttpStatus.FORBIDDEN); + // Feature is deactivated + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(VaccinationTouristCertificateCreateDto.class)); + } + + @Test + void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception { + callCreateExceptionalCertificateWithToken(EXPIRED_IN_FUTURE, INVALID_USER_ROLE, HttpStatus.FORBIDDEN); + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(VaccinationTouristCertificateCreateDto.class)); + } + + @Test + void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { + callCreateExceptionalCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); + Mockito.verify(covidCertificateGenerationService, times(0)) + .generateCovidCertificate(any(VaccinationTouristCertificateCreateDto.class)); + } + + private void callCreateExceptionalCertificateWithToken( + LocalDateTime tokenExpiration, String userRole, HttpStatus status) throws Exception { + var createDto = getExceptionalCertificateCreateDto("de"); + callCreateCertificateWithToken(URL, mapper.writeValueAsString(createDto), tokenExpiration, userRole, + status); } } } diff --git a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationControllerTest.java b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationControllerTest.java index 6fc48f1d..640ca65e 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationControllerTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationControllerTest.java @@ -1,9 +1,13 @@ package ch.admin.bag.covidcertificate.web.controller; import ch.admin.bag.covidcertificate.api.exception.CreateCertificateException; +import ch.admin.bag.covidcertificate.api.request.AntibodyCertificateCreateDto; +import ch.admin.bag.covidcertificate.api.request.ExceptionalCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.RecoveryCertificateCreateDto; +import ch.admin.bag.covidcertificate.api.request.RecoveryRatCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.TestCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.VaccinationCertificateCreateDto; +import ch.admin.bag.covidcertificate.api.request.VaccinationTouristCertificateCreateDto; import ch.admin.bag.covidcertificate.api.response.CovidCertificateCreateResponseDto; import ch.admin.bag.covidcertificate.api.response.CovidCertificateResponseEnvelope; import ch.admin.bag.covidcertificate.config.security.authentication.JeapAuthenticationToken; @@ -28,19 +32,32 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; +import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeAntibodyCertificateCreateDto; import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeCovidCertificateAddressDto; import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeCovidCertificateCreateResponseDto; import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeCreateCertificateException; +import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeExceptionalCertificateCreateDto; import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeRecoveryCertificateCreateDto; +import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeRecoveryRatCertificateCreateDto; import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeTestCertificateCreateDto; import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeVaccinationCertificateCreateDto; +import static ch.admin.bag.covidcertificate.FixtureCustomization.customizeVaccinationTouristCertificateCreateDto; +import static ch.admin.bag.covidcertificate.TestModelProvider.getAntibodyCertificateCreateDto; +import static ch.admin.bag.covidcertificate.TestModelProvider.getAntibodyCertificateCreateJSONWithInvalidPositiveTestResultDate; +import static ch.admin.bag.covidcertificate.TestModelProvider.getExceptionalCertificateCreateDto; +import static ch.admin.bag.covidcertificate.TestModelProvider.getExceptionalCertificateCreateDtoJSONWithInvalidSampleDateTime; import static ch.admin.bag.covidcertificate.TestModelProvider.getRecoveryCertificateCreateDto; import static ch.admin.bag.covidcertificate.TestModelProvider.getRecoveryCertificateCreateJSONWithInvalidPositiveTestResultDate; +import static ch.admin.bag.covidcertificate.TestModelProvider.getRecoveryRatCertificateCreateDto; +import static ch.admin.bag.covidcertificate.TestModelProvider.getRecoveryRatCertificateCreateJSONWithInvalidPositiveTestResultDate; import static ch.admin.bag.covidcertificate.TestModelProvider.getTestCertificateCreateDto; import static ch.admin.bag.covidcertificate.TestModelProvider.getTestCertificateCreateDtoJSONWithInvalidSampleDateTime; import static ch.admin.bag.covidcertificate.TestModelProvider.getVaccinationCertificateCreateDto; import static ch.admin.bag.covidcertificate.TestModelProvider.getVaccinationCertificateJSONWithInvalidVaccinationDate; +import static ch.admin.bag.covidcertificate.TestModelProvider.getVaccinationTouristCertificateCreateDtoWithoutAddress; +import static ch.admin.bag.covidcertificate.TestModelProvider.getVaccinationTouristCertificateJSONWithInvalidVaccinationDate; import static ch.admin.bag.covidcertificate.api.Constants.INVALID_DATE_OF_FIRST_POSITIVE_TEST_RESULT; +import static ch.admin.bag.covidcertificate.api.Constants.INVALID_EXCEPTIONAL_VALID_FROM_DATE; import static ch.admin.bag.covidcertificate.api.Constants.INVALID_SAMPLE_DATE_TIME; import static ch.admin.bag.covidcertificate.api.Constants.INVALID_VACCINATION_DATE; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -55,11 +72,6 @@ @ExtendWith(MockitoExtension.class) class CovidCertificateGenerationControllerTest { - private static final String BASE_URL = "/api/v1/covidcertificate/"; - private static final JFixture fixture = new JFixture(); - - private final ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().modules(new JavaTimeModule()).build(); - @InjectMocks private CovidCertificateGenerationController controller; @@ -77,11 +89,22 @@ class CovidCertificateGenerationControllerTest { private MockMvc mockMvc; + private static final String BASE_URL = "/api/v1/covidcertificate/"; + + private static final JFixture fixture = new JFixture(); + + private final ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().modules(new JavaTimeModule()).build(); + @BeforeAll static void setup() { customizeVaccinationCertificateCreateDto(fixture); + customizeVaccinationTouristCertificateCreateDto(fixture); customizeTestCertificateCreateDto(fixture); customizeRecoveryCertificateCreateDto(fixture); + customizeRecoveryRatCertificateCreateDto(fixture); + customizeAntibodyCertificateCreateDto(fixture); + customizeExceptionalCertificateCreateDto(fixture); + customizeCreateCertificateException(fixture); customizeCovidCertificateCreateResponseDto(fixture); } @@ -89,8 +112,8 @@ static void setup() { @BeforeEach void setupMocks() { this.mockMvc = standaloneSetup(controller, new ResponseStatusExceptionHandler()).build(); - lenient().when(jeapAuthorization.getJeapAuthenticationToken()).thenReturn( - fixture.create(JeapAuthenticationToken.class)); + lenient().when(jeapAuthorization.getJeapAuthenticationToken()) + .thenReturn(fixture.create(JeapAuthenticationToken.class)); } @Nested @@ -139,7 +162,7 @@ void returnsStatusCodeOfCreateCertificateException_ifOneWasThrown() throws Excep } @Test - void returns465StatusCode_ifDateParsingFailed() throws Exception { + void returns465StatusCode_ifVaccinationDateIsInvalid() throws Exception { var JSON = getVaccinationCertificateJSONWithInvalidVaccinationDate(); var errorCode = new CreateCertificateException(INVALID_VACCINATION_DATE).getError().getErrorCode(); @@ -154,6 +177,67 @@ void returns465StatusCode_ifDateParsingFailed() throws Exception { } } + @Nested + class CreateVaccinationTouristCertificate { + private static final String URL = BASE_URL + "vaccination-tourist"; + + @Test + void returnsCertificateWithOkStatus() throws Exception { + var createDto = getVaccinationTouristCertificateCreateDtoWithoutAddress( + "EU/1/20/1507", + "de"); + var responseDto = fixture.create(CovidCertificateCreateResponseDto.class); + var responseEnvelope = new CovidCertificateResponseEnvelope(responseDto, "someIdentifier"); + when(covidCertificateGenerationService.generateCovidCertificate( + any(VaccinationTouristCertificateCreateDto.class))).thenReturn(responseEnvelope); + + MvcResult result = mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(mapper.writeValueAsString(createDto))) + .andExpect(status().isOk()) + .andReturn(); + + CovidCertificateCreateResponseDto expectedDto = mapper.readValue( + result.getResponse().getContentAsString(), + CovidCertificateCreateResponseDto.class); + assertEquals(responseDto, expectedDto); + } + + @Test + void returnsStatusCodeOfCreateCertificateException_ifOneWasThrown() throws Exception { + var createDto = getVaccinationTouristCertificateCreateDtoWithoutAddress( + "EU/1/20/1507", + "de"); + var exception = fixture.create(CreateCertificateException.class); + when(covidCertificateGenerationService.generateCovidCertificate( + any(VaccinationTouristCertificateCreateDto.class))).thenThrow(exception); + + mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(mapper.writeValueAsString(createDto))) + .andExpect(status().is(exception.getError().getHttpStatus().value())); + } + + @Test + void returns465StatusCode_ifDateParsingFailed() throws Exception { + var JSON = getVaccinationTouristCertificateJSONWithInvalidVaccinationDate(); + + var errorCode = new CreateCertificateException(INVALID_VACCINATION_DATE).getError().getErrorCode(); + + mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(JSON)) + .andExpect(status().is(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.errorCode").value(errorCode)); + } + } + @Nested class CertificateCreateAddress { private static final String URL = BASE_URL + "vaccination"; @@ -345,4 +429,180 @@ void returns466StatusCode_ifDateParsingFailed() throws Exception { .andExpect(jsonPath("$.errorCode").value(errorCode)); } } + + @Nested + class CreateRecoveryRatCertificate { + private static final String URL = BASE_URL + "recovery-rat"; + + @Test + void returnsCertificateWithOkStatus() throws Exception { + var createDto = getRecoveryRatCertificateCreateDto("de"); + var responseDto = fixture.create(CovidCertificateCreateResponseDto.class); + var responseEnvelope = new CovidCertificateResponseEnvelope(responseDto, "someIdentifier"); + when(covidCertificateGenerationService.generateCovidCertificate( + any(RecoveryRatCertificateCreateDto.class))).thenReturn(responseEnvelope); + + MvcResult result = mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(mapper.writeValueAsString(createDto))) + .andExpect(status().isOk()) + .andReturn(); + + CovidCertificateCreateResponseDto expectedDto = mapper.readValue( + result.getResponse().getContentAsString(), + CovidCertificateCreateResponseDto.class); + assertEquals(responseDto, expectedDto); + } + + @Test + void returnsStatusCodeOfCreateCertificateException_ifOneWasThrown() throws Exception { + var createDto = getRecoveryRatCertificateCreateDto("de"); + var exception = fixture.create(CreateCertificateException.class); + when(covidCertificateGenerationService.generateCovidCertificate( + any(RecoveryRatCertificateCreateDto.class))).thenThrow(exception); + + mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(mapper.writeValueAsString(createDto))) + .andExpect(status().is(exception.getError().getHttpStatus().value())); + } + + + @Test + void returns466StatusCode_ifDateParsingFailed() throws Exception { + var JSON = getRecoveryRatCertificateCreateJSONWithInvalidPositiveTestResultDate(); + + var errorCode = new CreateCertificateException(INVALID_SAMPLE_DATE_TIME).getError().getErrorCode(); + + mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(JSON)) + .andExpect(status().is(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.errorCode").value(errorCode)); + } + } + + @Nested + class CreateAntibodyCertificate { + private static final String URL = BASE_URL + "antibody"; + + @Test + void returnsCertificateWithOkStatus() throws Exception { + var createDto = getAntibodyCertificateCreateDto("de"); + var responseDto = fixture.create(CovidCertificateCreateResponseDto.class); + var responseEnvelope = new CovidCertificateResponseEnvelope(responseDto, "someIdentifier"); + when(covidCertificateGenerationService.generateCovidCertificate( + any(AntibodyCertificateCreateDto.class))).thenReturn(responseEnvelope); + + MvcResult result = mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(mapper.writeValueAsString(createDto))) + .andExpect(status().isOk()) + .andReturn(); + + CovidCertificateCreateResponseDto expectedDto = mapper.readValue( + result.getResponse().getContentAsString(), + CovidCertificateCreateResponseDto.class); + assertEquals(responseDto, expectedDto); + } + + @Test + void returnsStatusCodeOfCreateCertificateException_ifOneWasThrown() throws Exception { + var createDto = getAntibodyCertificateCreateDto("de"); + var exception = fixture.create(CreateCertificateException.class); + when(covidCertificateGenerationService.generateCovidCertificate( + any(AntibodyCertificateCreateDto.class))).thenThrow(exception); + + mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(mapper.writeValueAsString(createDto))) + .andExpect(status().is(exception.getError().getHttpStatus().value())); + } + + + @Test + void returns466StatusCode_ifDateParsingFailed() throws Exception { + var JSON = getAntibodyCertificateCreateJSONWithInvalidPositiveTestResultDate(); + + var errorCode = new CreateCertificateException( + INVALID_DATE_OF_FIRST_POSITIVE_TEST_RESULT).getError().getErrorCode(); + + mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(JSON)) + .andExpect(status().is(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.errorCode").value(errorCode)); + } + } + + @Nested + class CreateExceptionalCertificate { + private static final String URL = BASE_URL + "exceptional"; + + @Test + void returnsCertificateWithOkStatus() throws Exception { + var createDto = getExceptionalCertificateCreateDto("de"); + var responseDto = fixture.create(CovidCertificateCreateResponseDto.class); + var responseEnvelope = new CovidCertificateResponseEnvelope(responseDto, "someIdentifier"); + when(covidCertificateGenerationService.generateCovidCertificate( + any(ExceptionalCertificateCreateDto.class))).thenReturn(responseEnvelope); + + MvcResult result = mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(mapper.writeValueAsString(createDto))) + .andExpect(status().isOk()) + .andReturn(); + + CovidCertificateCreateResponseDto expectedDto = mapper.readValue( + result.getResponse().getContentAsString(), + CovidCertificateCreateResponseDto.class); + assertEquals(responseDto, expectedDto); + } + + @Test + void returnsStatusCodeOfCreateCertificateException_ifOneWasThrown() throws Exception { + var createDto = getExceptionalCertificateCreateDto("de"); + var exception = fixture.create(CreateCertificateException.class); + when(covidCertificateGenerationService.generateCovidCertificate( + any(ExceptionalCertificateCreateDto.class))).thenThrow(exception); + + mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(mapper.writeValueAsString(createDto))) + .andExpect(status().is(exception.getError().getHttpStatus().value())); + } + + + @Test + void returns466StatusCode_ifDateParsingFailed() throws Exception { + var JSON = getExceptionalCertificateCreateDtoJSONWithInvalidSampleDateTime(); + + var errorCode = new CreateCertificateException( + INVALID_EXCEPTIONAL_VALID_FROM_DATE).getError().getErrorCode(); + + mockMvc.perform( + post(URL).accept(MediaType.APPLICATION_JSON_VALUE) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", fixture.create(String.class)) + .content(JSON)) + .andExpect(status().is(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.errorCode").value(errorCode)); + } + } } diff --git a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java index 811bf1d5..8ccf9976 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java @@ -1,8 +1,5 @@ package ch.admin.bag.covidcertificate.web.controller; -import ch.admin.bag.covidcertificate.api.request.RecoveryCertificateCreateDto; -import ch.admin.bag.covidcertificate.api.request.TestCertificateCreateDto; -import ch.admin.bag.covidcertificate.api.request.VaccinationCertificateCreateDto; import ch.admin.bag.covidcertificate.api.request.pdfgeneration.RecoveryCertificatePdfGenerateRequestDto; import ch.admin.bag.covidcertificate.api.request.pdfgeneration.TestCertificatePdfGenerateRequestDto; import ch.admin.bag.covidcertificate.api.request.pdfgeneration.VaccinationCertificatePdfGenerateRequestDto; @@ -13,7 +10,7 @@ import ch.admin.bag.covidcertificate.authorization.config.LocalDateTimeConverter; import ch.admin.bag.covidcertificate.authorization.config.RoleConfig; import ch.admin.bag.covidcertificate.config.security.OAuth2SecuredWebConfiguration; -import ch.admin.bag.covidcertificate.service.CovidCertificateGenerationService; +import ch.admin.bag.covidcertificate.service.CovidCertificatePdfGenerationService; import ch.admin.bag.covidcertificate.service.CovidCertificateVaccinationValidationService; import ch.admin.bag.covidcertificate.service.KpiDataService; import ch.admin.bag.covidcertificate.testutil.JwtTestUtil; @@ -46,7 +43,7 @@ class CovidCertificatePdfGenerationControllerSecurityTest extends AbstractSecuri private static final String BASE_URL = "/api/v1/covidcertificate/"; @MockBean - private CovidCertificateGenerationService covidCertificateGenerationService; + private CovidCertificatePdfGenerationService covidCertificatePdfGenerationService; @MockBean private KpiDataService kpiDataService; @@ -56,23 +53,23 @@ class CovidCertificatePdfGenerationControllerSecurityTest extends AbstractSecuri @BeforeEach void setupMocks() throws IOException { - lenient().when(covidCertificateGenerationService.generateCovidCertificate( - any(VaccinationCertificateCreateDto.class))).thenReturn( - fixture.create(CovidCertificateResponseEnvelope.class)); - lenient().when(covidCertificateGenerationService.generateCovidCertificate( - any(TestCertificateCreateDto.class))).thenReturn( - fixture.create(CovidCertificateResponseEnvelope.class)); - lenient().when(covidCertificateGenerationService.generateCovidCertificate( - any(RecoveryCertificateCreateDto.class))).thenReturn( - fixture.create(CovidCertificateResponseEnvelope.class)); - - lenient().when(covidCertificateGenerationService.generateFromExistingCovidCertificate( + // lenient().when(covidCertificatePdfGenerationService.generateCovidCertificate( + // any(VaccinationCertificateCreateDto.class))).thenReturn( + // fixture.create(CovidCertificateResponseEnvelope.class)); + // lenient().when(covidCertificatePdfGenerationService.generateCovidCertificate( + // any(TestCertificateCreateDto.class))).thenReturn( + // fixture.create(CovidCertificateResponseEnvelope.class)); + // lenient().when(covidCertificatePdfGenerationService.generateCovidCertificate( + // any(RecoveryCertificateCreateDto.class))).thenReturn( + // fixture.create(CovidCertificateResponseEnvelope.class)); + + lenient().when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( any(VaccinationCertificatePdfGenerateRequestDto.class))).thenReturn( fixture.create(CovidCertificateResponseEnvelope.class)); - lenient().when(covidCertificateGenerationService.generateFromExistingCovidCertificate( + lenient().when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( any(TestCertificatePdfGenerateRequestDto.class))).thenReturn( fixture.create(CovidCertificateResponseEnvelope.class)); - lenient().when(covidCertificateGenerationService.generateFromExistingCovidCertificate( + lenient().when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( any(RecoveryCertificatePdfGenerateRequestDto.class))).thenReturn( fixture.create(CovidCertificateResponseEnvelope.class)); } @@ -110,21 +107,21 @@ class GenerateVaccinationPdfFromExistingCertificate { void returnsOKIfAuthorizationTokenValid() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_USER_ROLE, HttpStatus.OK); callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_SUPERUSER_ROLE, HttpStatus.OK); - Mockito.verify(covidCertificateGenerationService, times(2)) + Mockito.verify(covidCertificatePdfGenerationService, times(2)) .generateFromExistingCovidCertificate(any(VaccinationCertificatePdfGenerateRequestDto.class)); } @Test void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, INVALID_USER_ROLE, HttpStatus.FORBIDDEN); - Mockito.verify(covidCertificateGenerationService, times(0)) + Mockito.verify(covidCertificatePdfGenerationService, times(0)) .generateFromExistingCovidCertificate(any(VaccinationCertificatePdfGenerateRequestDto.class)); } @Test void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); - Mockito.verify(covidCertificateGenerationService, times(0)) + Mockito.verify(covidCertificatePdfGenerationService, times(0)) .generateFromExistingCovidCertificate(any(VaccinationCertificatePdfGenerateRequestDto.class)); } @@ -144,21 +141,21 @@ class GenerateTestPdfFromExistingCertificate { void returnsOKIfAuthorizationTokenValid() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_USER_ROLE, HttpStatus.OK); callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_SUPERUSER_ROLE, HttpStatus.OK); - Mockito.verify(covidCertificateGenerationService, times(2)) + Mockito.verify(covidCertificatePdfGenerationService, times(2)) .generateFromExistingCovidCertificate(any(TestCertificatePdfGenerateRequestDto.class)); } @Test void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, INVALID_USER_ROLE, HttpStatus.FORBIDDEN); - Mockito.verify(covidCertificateGenerationService, times(0)) + Mockito.verify(covidCertificatePdfGenerationService, times(0)) .generateFromExistingCovidCertificate(any(TestCertificatePdfGenerateRequestDto.class)); } @Test void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); - Mockito.verify(covidCertificateGenerationService, times(0)) + Mockito.verify(covidCertificatePdfGenerationService, times(0)) .generateFromExistingCovidCertificate(any(TestCertificatePdfGenerateRequestDto.class)); } @@ -178,21 +175,21 @@ class GenerateRecoveryPdfFromExistingCertificate { void returnsOKIfAuthorizationTokenValid() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_USER_ROLE, HttpStatus.OK); callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_SUPERUSER_ROLE, HttpStatus.OK); - Mockito.verify(covidCertificateGenerationService, times(2)) + Mockito.verify(covidCertificatePdfGenerationService, times(2)) .generateFromExistingCovidCertificate(any(RecoveryCertificatePdfGenerateRequestDto.class)); } @Test void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, INVALID_USER_ROLE, HttpStatus.FORBIDDEN); - Mockito.verify(covidCertificateGenerationService, times(0)) + Mockito.verify(covidCertificatePdfGenerationService, times(0)) .generateFromExistingCovidCertificate(any(RecoveryCertificatePdfGenerateRequestDto.class)); } @Test void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); - Mockito.verify(covidCertificateGenerationService, times(0)) + Mockito.verify(covidCertificatePdfGenerationService, times(0)) .generateFromExistingCovidCertificate(any(RecoveryCertificatePdfGenerateRequestDto.class)); } diff --git a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerTest.java b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerTest.java index 453b3abb..f5be75a8 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerTest.java @@ -8,7 +8,7 @@ import ch.admin.bag.covidcertificate.api.response.CovidCertificateResponseEnvelope; import ch.admin.bag.covidcertificate.config.security.authentication.JeapAuthenticationToken; import ch.admin.bag.covidcertificate.config.security.authentication.ServletJeapAuthorization; -import ch.admin.bag.covidcertificate.service.CovidCertificateGenerationService; +import ch.admin.bag.covidcertificate.service.CovidCertificatePdfGenerationService; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.flextrade.jfixture.JFixture; @@ -46,7 +46,7 @@ class CovidCertificatePdfGenerationControllerTest { private CovidCertificatePdfGenerateController controller; @Mock - private CovidCertificateGenerationService covidCertificateGenerationService; + private CovidCertificatePdfGenerationService covidCertificatePdfGenerationService; @Mock private ServletJeapAuthorization jeapAuthorization; @@ -75,7 +75,7 @@ void returnsCertificateWithOkStatus() throws Exception { .create(VaccinationCertificatePdfGenerateRequestDto.class); var responseDto = fixture.create(CovidCertificateCreateResponseDto.class); var responseEnvelope = new CovidCertificateResponseEnvelope(responseDto, "someIdentifier"); - when(covidCertificateGenerationService.generateFromExistingCovidCertificate( + when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( any(VaccinationCertificatePdfGenerateRequestDto.class))).thenReturn(responseEnvelope); MvcResult result = mockMvc.perform( @@ -97,7 +97,7 @@ void returnsStatusCodeOfCreateCertificateException_ifOneWasThrown() throws Excep var pdfGenerateRequestDto = fixture .create(VaccinationCertificatePdfGenerateRequestDto.class); var exception = fixture.create(CreateCertificateException.class); - when(covidCertificateGenerationService.generateFromExistingCovidCertificate( + when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( any(VaccinationCertificatePdfGenerateRequestDto.class))).thenThrow(exception); mockMvc.perform( @@ -119,7 +119,7 @@ void returnsCertificateWithOkStatus() throws Exception { .create(TestCertificatePdfGenerateRequestDto.class); var responseDto = fixture.create(CovidCertificateCreateResponseDto.class); var responseEnvelope = new CovidCertificateResponseEnvelope(responseDto, "someIdentifier"); - when(covidCertificateGenerationService.generateFromExistingCovidCertificate( + when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( any(TestCertificatePdfGenerateRequestDto.class))).thenReturn(responseEnvelope); MvcResult result = mockMvc.perform( @@ -141,7 +141,7 @@ void returnsStatusCodeOfCreateCertificateException_ifOneWasThrown() throws Excep var pdfGenerateRequestDto = fixture .create(TestCertificatePdfGenerateRequestDto.class); var exception = fixture.create(CreateCertificateException.class); - when(covidCertificateGenerationService.generateFromExistingCovidCertificate( + when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( any(TestCertificatePdfGenerateRequestDto.class))).thenThrow(exception); mockMvc.perform( @@ -164,7 +164,7 @@ void returnsCertificateWithOkStatus() throws Exception { var expectedDto = fixture.create(CovidCertificateCreateResponseDto.class); var expectedEnvelope = fixture.create(CovidCertificateResponseEnvelope.class); expectedEnvelope.setResponseDto(expectedDto); - when(covidCertificateGenerationService.generateFromExistingCovidCertificate( + when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( any(RecoveryCertificatePdfGenerateRequestDto.class))).thenReturn(expectedEnvelope); MvcResult result = mockMvc.perform( @@ -186,7 +186,7 @@ void returnsStatusCodeOfCreateCertificateException_ifOneWasThrown() throws Excep var pdfGenerateRequestDto = fixture .create(RecoveryCertificatePdfGenerateRequestDto.class); var exception = fixture.create(CreateCertificateException.class); - when(covidCertificateGenerationService.generateFromExistingCovidCertificate( + when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( any(RecoveryCertificatePdfGenerateRequestDto.class))).thenThrow(exception); mockMvc.perform( diff --git a/src/test/java/ch/admin/bag/covidcertificate/web/controller/RevocationControllerTest.java b/src/test/java/ch/admin/bag/covidcertificate/web/controller/RevocationControllerTest.java index f49a60a1..8e8b7b9b 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/web/controller/RevocationControllerTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/web/controller/RevocationControllerTest.java @@ -107,108 +107,4 @@ void returnsStatusCodeOfRevocationException_ifOneWasThrown() throws Exception { } } - - /* - // TODO VACCINECER-2086: Enable Mass-revocation - @Nested - @DisplayName("POST " + REVOCATION_LIST_CHECK_URL) - class CheckMassRevocation { - @Test - @DisplayName("GIVEN a valid uvci list THEN status 202 is returned") - void revokeCertificateAndReturnCreatedStatus() throws Exception { - var createDto = fixture.create(RevocationListDto.class); - - mockMvc.perform(post(REVOCATION_LIST_CHECK_URL) - .accept(MediaType.ALL_VALUE) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .header("Authorization", fixture.create(String.class)) - .content(mapper.writeValueAsString(createDto))) - .andExpect(status().isAccepted()); - } - - @Test - @DisplayName("GIVEN a uvci list WHEN it contains already revoked uvcis THEN the UvcisWithError are returned") - void returnsAlreadyRevokedUvcisAsUvcisWithError() throws Exception { - var createDto = fixture.create(RevocationListDto.class); - var uvciToErrorMessage = fixture.collections().createMap(String.class, String.class); - when(revocationService.getUvcisWithErrorMessage(any())).thenReturn(uvciToErrorMessage); - - MockHttpServletResponse response = mockMvc.perform(post(REVOCATION_LIST_CHECK_URL) - .accept(MediaType.ALL_VALUE) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .header("Authorization", fixture.create(String.class)) - .content(mapper.writeValueAsString(createDto))) - .andExpect(status().isAccepted()).andReturn().getResponse(); - - CheckRevocationListResponseDto expectedDto = mapper.readValue(response.getContentAsString(), CheckRevocationListResponseDto.class); - assertThat(expectedDto.getUvciToErrorMessage()).isNotNull(); - } - - @Test - @DisplayName("GIVEN a uvci list WHEN it contains not existing uvcis THEN we the UvcisWithWarning are returned") - void returnsNotExistingUvcisAsUvcisWithWarning() throws Exception { - var createDto = fixture.create(RevocationListDto.class); - var uvciToWarningMessage = fixture.collections().createMap(String.class, String.class); - when(revocationService.getNotExistingUvcis(any())).thenReturn(uvciToWarningMessage); - - MockHttpServletResponse response = mockMvc.perform(post(REVOCATION_LIST_CHECK_URL) - .accept(MediaType.ALL_VALUE) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .header("Authorization", fixture.create(String.class)) - .content(mapper.writeValueAsString(createDto))) - .andExpect(status().isAccepted()).andReturn().getResponse(); - - CheckRevocationListResponseDto expectedDto = mapper.readValue(response.getContentAsString(), CheckRevocationListResponseDto.class); - assertThat(expectedDto.getUvciToWarningMessage()).isEqualTo(uvciToWarningMessage); - } - - @Test - @DisplayName("GIVEN a uvci list WHEN some are already revoked and some are not existing THEN the revocable uvcis contain warning uvcis but no error uvcis") - void returnsValidAndWarningUvcisAsRevocable() throws Exception { - var testUvcis = Arrays.asList(FixtureCustomization.createUVCI(), FixtureCustomization.createUVCI(), FixtureCustomization.createUVCI()); - var createDto = new RevocationListDto(testUvcis, fixture.create(SystemSource.class), fixture.create(String.class)); - - var errorUvcis = testUvcis.subList(0, 1).stream().collect(Collectors.toMap(s -> s, s -> "any error")); - when(revocationService.getUvcisWithErrorMessage(any())).thenReturn(errorUvcis); - var warningUvcis = testUvcis.subList(1, 2).stream().collect(Collectors.toMap(s -> s, s -> "any warning")); - when(revocationService.getNotExistingUvcis(any())).thenReturn(warningUvcis); - - MockHttpServletResponse response = mockMvc.perform(post(REVOCATION_LIST_CHECK_URL) - .accept(MediaType.ALL_VALUE) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .header("Authorization", fixture.create(String.class)) - .content(mapper.writeValueAsString(createDto))) - .andExpect(status().isAccepted()).andReturn().getResponse(); - - CheckRevocationListResponseDto expectedDto = mapper.readValue(response.getContentAsString(), CheckRevocationListResponseDto.class); - assertThat(expectedDto.getRevocableUvcis()).containsAll(warningUvcis.keySet()); - assertThat(expectedDto.getRevocableUvcis()).doesNotContainAnyElementsOf(errorUvcis.keySet()); - } - - } - - @Nested - @DisplayName("POST " + REVOCATION_LIST_URL) - class MassRevocation { - @Test - @DisplayName("GIVEN a uvci and uvci is not revoked WHEN uvci is called for revocation THEN we return created status") - void revokeCertificateAndReturnCreatedStatus() throws Exception { - var createDto = fixture.create(RevocationListDto.class); - when(revocationService.getUvcisWithErrorMessage(anyList())).thenReturn(new HashMap<>()); - doNothing().when(revocationService).createRevocation(anyString(), anyBoolean()); - - MockHttpServletResponse response = mockMvc - .perform(post(REVOCATION_LIST_URL) - .accept(MediaType.ALL_VALUE) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .header("Authorization", fixture.create(String.class)) - .content(mapper.writeValueAsString(createDto))) - .andExpect(status().isCreated()).andReturn().getResponse(); - - String result = response.getContentAsString(); - assertThat(result).isNotNull(); - } - - } - */ } diff --git a/src/test/java/ch/admin/bag/covidcertificate/web/controller/RevocationListControllerTest.java b/src/test/java/ch/admin/bag/covidcertificate/web/controller/RevocationListControllerTest.java index da7cd479..65949b2a 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/web/controller/RevocationListControllerTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/web/controller/RevocationListControllerTest.java @@ -33,6 +33,7 @@ @ExtendWith(MockitoExtension.class) class RevocationListControllerTest { + @InjectMocks private RevocationListController controller; @Mock From 58627a461624d0aa8015b8cfc9cd64859ba5f180 Mon Sep 17 00:00:00 2001 From: Iris Hunkeler Date: Fri, 8 Jul 2022 14:23:44 +0200 Subject: [PATCH 10/23] Update to version 4.4.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0cffabf4..5e2d1673 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ ch.admin.bag.covidcertificate cc-management-service - 4.4.1 + 4.4.2 cc-management-service Service for generating Covid Certificates From 818a558f5ebd797df5cd5ae5bb1538ed58c29932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20L=C3=B6sing?= Date: Fri, 8 Jul 2022 15:24:14 +0200 Subject: [PATCH 11/23] Renamed controller and service according feedback. Removed debug output. --- ...ficateGeneratePdfFromExistingService.java} | 2 +- ...ateGeneratePdfFromExistingController.java} | 6 ++-- .../CovidCertificateGenerationController.java | 11 ------- ...teGeneratePdfFromExistingServiceTest.java} | 4 +-- ...tePdfGenerationControllerSecurityTest.java | 30 +++++++++---------- ...ertificatePdfGenerationControllerTest.java | 18 +++++------ 6 files changed, 30 insertions(+), 41 deletions(-) rename src/main/java/ch/admin/bag/covidcertificate/service/{CovidCertificatePdfGenerationService.java => CovidCertificateGeneratePdfFromExistingService.java} (99%) rename src/main/java/ch/admin/bag/covidcertificate/web/controller/{CovidCertificatePdfGenerateController.java => CovidCertificateGeneratePdfFromExistingController.java} (95%) rename src/test/java/ch/admin/bag/covidcertificate/service/{CovidCertificatePdfGenerationServiceTest.java => CovidCertificateGeneratePdfFromExistingServiceTest.java} (99%) diff --git a/src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationService.java b/src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificateGeneratePdfFromExistingService.java similarity index 99% rename from src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationService.java rename to src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificateGeneratePdfFromExistingService.java index 03d775c9..67e82364 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationService.java +++ b/src/main/java/ch/admin/bag/covidcertificate/service/CovidCertificateGeneratePdfFromExistingService.java @@ -29,7 +29,7 @@ @Service @Slf4j @RequiredArgsConstructor -public class CovidCertificatePdfGenerationService { +public class CovidCertificateGeneratePdfFromExistingService { private final CovidCertificatePdfGenerateRequestDtoMapperService pdfDtoMapperService; private final PdfCertificateGenerationService pdfCertificateGenerationService; diff --git a/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerateController.java b/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGeneratePdfFromExistingController.java similarity index 95% rename from src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerateController.java rename to src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGeneratePdfFromExistingController.java index 01be224d..d33a0f6d 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerateController.java +++ b/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGeneratePdfFromExistingController.java @@ -9,7 +9,7 @@ import ch.admin.bag.covidcertificate.api.request.pdfgeneration.VaccinationTouristCertificatePdfGenerateRequestDto; import ch.admin.bag.covidcertificate.api.response.CovidCertificateCreateResponseDto; import ch.admin.bag.covidcertificate.api.response.CovidCertificateResponseEnvelope; -import ch.admin.bag.covidcertificate.service.CovidCertificatePdfGenerationService; +import ch.admin.bag.covidcertificate.service.CovidCertificateGeneratePdfFromExistingService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; @@ -23,9 +23,9 @@ @RequestMapping("/api/v1/covidcertificate/fromexisting") @RequiredArgsConstructor @Slf4j -public class CovidCertificatePdfGenerateController { +public class CovidCertificateGeneratePdfFromExistingController { - private final CovidCertificatePdfGenerationService covidCertificateGenerationService; + private final CovidCertificateGeneratePdfFromExistingService covidCertificateGenerationService; @PostMapping("/vaccination") public CovidCertificateCreateResponseDto generateVaccinationPdfFromExistingCertificate( diff --git a/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationController.java b/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationController.java index d1e56400..00cd0159 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationController.java +++ b/src/main/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificateGenerationController.java @@ -12,8 +12,6 @@ import ch.admin.bag.covidcertificate.service.CovidCertificateGenerationService; import ch.admin.bag.covidcertificate.service.CovidCertificateVaccinationValidationService; import ch.admin.bag.covidcertificate.service.KpiDataService; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; @@ -160,15 +158,6 @@ public CovidCertificateCreateResponseDto createMedicalExemptionCertificate( log.info("Call of create for exceptional certificate"); createDto.validate(); - try { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.findAndRegisterModules(); - objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - String demo = objectMapper.writeValueAsString(createDto); - log.info("Moinsen demo is: {}", demo); - } catch (Exception ex) { - log.error("Moinsen writing failed: ", ex); - } CovidCertificateResponseEnvelope responseEnvelope = covidCertificateGenerationService .generateCovidCertificate(createDto); CovidCertificateCreateResponseDto responseDto = responseEnvelope.getResponseDto(); diff --git a/src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationServiceTest.java b/src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificateGeneratePdfFromExistingServiceTest.java similarity index 99% rename from src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationServiceTest.java rename to src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificateGeneratePdfFromExistingServiceTest.java index 89d79e93..f9a922c1 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificatePdfGenerationServiceTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/service/CovidCertificateGeneratePdfFromExistingServiceTest.java @@ -55,10 +55,10 @@ @ExtendWith(MockitoExtension.class) @RunWith(MockitoJUnitRunner.class) -class CovidCertificatePdfGenerationServiceTest { +class CovidCertificateGeneratePdfFromExistingServiceTest { private final JFixture fixture = new JFixture(); @InjectMocks - private CovidCertificatePdfGenerationService service; + private CovidCertificateGeneratePdfFromExistingService service; @Mock private BarcodeService barcodeService; @Mock diff --git a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java index 8ccf9976..7d6f07ed 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java @@ -10,7 +10,7 @@ import ch.admin.bag.covidcertificate.authorization.config.LocalDateTimeConverter; import ch.admin.bag.covidcertificate.authorization.config.RoleConfig; import ch.admin.bag.covidcertificate.config.security.OAuth2SecuredWebConfiguration; -import ch.admin.bag.covidcertificate.service.CovidCertificatePdfGenerationService; +import ch.admin.bag.covidcertificate.service.CovidCertificateGeneratePdfFromExistingService; import ch.admin.bag.covidcertificate.service.CovidCertificateVaccinationValidationService; import ch.admin.bag.covidcertificate.service.KpiDataService; import ch.admin.bag.covidcertificate.testutil.JwtTestUtil; @@ -34,7 +34,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@WebMvcTest(value = {CovidCertificatePdfGenerateController.class, OAuth2SecuredWebConfiguration.class, +@WebMvcTest(value = {CovidCertificateGeneratePdfFromExistingController.class, OAuth2SecuredWebConfiguration.class, AuthorizationInterceptor.class, AuthorizationService.class, AuthorizationConfig.class, RoleConfig.class, LocalDateTimeConverter.class}) @ActiveProfiles({"test", "authorization"}) @@ -43,7 +43,7 @@ class CovidCertificatePdfGenerationControllerSecurityTest extends AbstractSecuri private static final String BASE_URL = "/api/v1/covidcertificate/"; @MockBean - private CovidCertificatePdfGenerationService covidCertificatePdfGenerationService; + private CovidCertificateGeneratePdfFromExistingService covidCertificateGeneratePdfFromExistingService; @MockBean private KpiDataService kpiDataService; @@ -63,13 +63,13 @@ void setupMocks() throws IOException { // any(RecoveryCertificateCreateDto.class))).thenReturn( // fixture.create(CovidCertificateResponseEnvelope.class)); - lenient().when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( + lenient().when(covidCertificateGeneratePdfFromExistingService.generateFromExistingCovidCertificate( any(VaccinationCertificatePdfGenerateRequestDto.class))).thenReturn( fixture.create(CovidCertificateResponseEnvelope.class)); - lenient().when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( + lenient().when(covidCertificateGeneratePdfFromExistingService.generateFromExistingCovidCertificate( any(TestCertificatePdfGenerateRequestDto.class))).thenReturn( fixture.create(CovidCertificateResponseEnvelope.class)); - lenient().when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( + lenient().when(covidCertificateGeneratePdfFromExistingService.generateFromExistingCovidCertificate( any(RecoveryCertificatePdfGenerateRequestDto.class))).thenReturn( fixture.create(CovidCertificateResponseEnvelope.class)); } @@ -107,21 +107,21 @@ class GenerateVaccinationPdfFromExistingCertificate { void returnsOKIfAuthorizationTokenValid() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_USER_ROLE, HttpStatus.OK); callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_SUPERUSER_ROLE, HttpStatus.OK); - Mockito.verify(covidCertificatePdfGenerationService, times(2)) + Mockito.verify(covidCertificateGeneratePdfFromExistingService, times(2)) .generateFromExistingCovidCertificate(any(VaccinationCertificatePdfGenerateRequestDto.class)); } @Test void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, INVALID_USER_ROLE, HttpStatus.FORBIDDEN); - Mockito.verify(covidCertificatePdfGenerationService, times(0)) + Mockito.verify(covidCertificateGeneratePdfFromExistingService, times(0)) .generateFromExistingCovidCertificate(any(VaccinationCertificatePdfGenerateRequestDto.class)); } @Test void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); - Mockito.verify(covidCertificatePdfGenerationService, times(0)) + Mockito.verify(covidCertificateGeneratePdfFromExistingService, times(0)) .generateFromExistingCovidCertificate(any(VaccinationCertificatePdfGenerateRequestDto.class)); } @@ -141,21 +141,21 @@ class GenerateTestPdfFromExistingCertificate { void returnsOKIfAuthorizationTokenValid() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_USER_ROLE, HttpStatus.OK); callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_SUPERUSER_ROLE, HttpStatus.OK); - Mockito.verify(covidCertificatePdfGenerationService, times(2)) + Mockito.verify(covidCertificateGeneratePdfFromExistingService, times(2)) .generateFromExistingCovidCertificate(any(TestCertificatePdfGenerateRequestDto.class)); } @Test void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, INVALID_USER_ROLE, HttpStatus.FORBIDDEN); - Mockito.verify(covidCertificatePdfGenerationService, times(0)) + Mockito.verify(covidCertificateGeneratePdfFromExistingService, times(0)) .generateFromExistingCovidCertificate(any(TestCertificatePdfGenerateRequestDto.class)); } @Test void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); - Mockito.verify(covidCertificatePdfGenerationService, times(0)) + Mockito.verify(covidCertificateGeneratePdfFromExistingService, times(0)) .generateFromExistingCovidCertificate(any(TestCertificatePdfGenerateRequestDto.class)); } @@ -175,21 +175,21 @@ class GenerateRecoveryPdfFromExistingCertificate { void returnsOKIfAuthorizationTokenValid() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_USER_ROLE, HttpStatus.OK); callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, VALID_SUPERUSER_ROLE, HttpStatus.OK); - Mockito.verify(covidCertificatePdfGenerationService, times(2)) + Mockito.verify(covidCertificateGeneratePdfFromExistingService, times(2)) .generateFromExistingCovidCertificate(any(RecoveryCertificatePdfGenerateRequestDto.class)); } @Test void returnsForbiddenIfAuthorizationTokenWithInvalidUserRole() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_FUTURE, INVALID_USER_ROLE, HttpStatus.FORBIDDEN); - Mockito.verify(covidCertificatePdfGenerationService, times(0)) + Mockito.verify(covidCertificateGeneratePdfFromExistingService, times(0)) .generateFromExistingCovidCertificate(any(RecoveryCertificatePdfGenerateRequestDto.class)); } @Test void returnsUnauthorizedIfAuthorizationTokenExpired() throws Exception { callCreateVaccinationCertificateWithToken(EXPIRED_IN_PAST, VALID_USER_ROLE, HttpStatus.UNAUTHORIZED); - Mockito.verify(covidCertificatePdfGenerationService, times(0)) + Mockito.verify(covidCertificateGeneratePdfFromExistingService, times(0)) .generateFromExistingCovidCertificate(any(RecoveryCertificatePdfGenerateRequestDto.class)); } diff --git a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerTest.java b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerTest.java index f5be75a8..1bbd9683 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerTest.java @@ -8,7 +8,7 @@ import ch.admin.bag.covidcertificate.api.response.CovidCertificateResponseEnvelope; import ch.admin.bag.covidcertificate.config.security.authentication.JeapAuthenticationToken; import ch.admin.bag.covidcertificate.config.security.authentication.ServletJeapAuthorization; -import ch.admin.bag.covidcertificate.service.CovidCertificatePdfGenerationService; +import ch.admin.bag.covidcertificate.service.CovidCertificateGeneratePdfFromExistingService; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.flextrade.jfixture.JFixture; @@ -43,10 +43,10 @@ class CovidCertificatePdfGenerationControllerTest { private final ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().modules(new JavaTimeModule()).build(); @InjectMocks - private CovidCertificatePdfGenerateController controller; + private CovidCertificateGeneratePdfFromExistingController controller; @Mock - private CovidCertificatePdfGenerationService covidCertificatePdfGenerationService; + private CovidCertificateGeneratePdfFromExistingService covidCertificateGeneratePdfFromExistingService; @Mock private ServletJeapAuthorization jeapAuthorization; @@ -75,7 +75,7 @@ void returnsCertificateWithOkStatus() throws Exception { .create(VaccinationCertificatePdfGenerateRequestDto.class); var responseDto = fixture.create(CovidCertificateCreateResponseDto.class); var responseEnvelope = new CovidCertificateResponseEnvelope(responseDto, "someIdentifier"); - when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( + when(covidCertificateGeneratePdfFromExistingService.generateFromExistingCovidCertificate( any(VaccinationCertificatePdfGenerateRequestDto.class))).thenReturn(responseEnvelope); MvcResult result = mockMvc.perform( @@ -97,7 +97,7 @@ void returnsStatusCodeOfCreateCertificateException_ifOneWasThrown() throws Excep var pdfGenerateRequestDto = fixture .create(VaccinationCertificatePdfGenerateRequestDto.class); var exception = fixture.create(CreateCertificateException.class); - when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( + when(covidCertificateGeneratePdfFromExistingService.generateFromExistingCovidCertificate( any(VaccinationCertificatePdfGenerateRequestDto.class))).thenThrow(exception); mockMvc.perform( @@ -119,7 +119,7 @@ void returnsCertificateWithOkStatus() throws Exception { .create(TestCertificatePdfGenerateRequestDto.class); var responseDto = fixture.create(CovidCertificateCreateResponseDto.class); var responseEnvelope = new CovidCertificateResponseEnvelope(responseDto, "someIdentifier"); - when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( + when(covidCertificateGeneratePdfFromExistingService.generateFromExistingCovidCertificate( any(TestCertificatePdfGenerateRequestDto.class))).thenReturn(responseEnvelope); MvcResult result = mockMvc.perform( @@ -141,7 +141,7 @@ void returnsStatusCodeOfCreateCertificateException_ifOneWasThrown() throws Excep var pdfGenerateRequestDto = fixture .create(TestCertificatePdfGenerateRequestDto.class); var exception = fixture.create(CreateCertificateException.class); - when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( + when(covidCertificateGeneratePdfFromExistingService.generateFromExistingCovidCertificate( any(TestCertificatePdfGenerateRequestDto.class))).thenThrow(exception); mockMvc.perform( @@ -164,7 +164,7 @@ void returnsCertificateWithOkStatus() throws Exception { var expectedDto = fixture.create(CovidCertificateCreateResponseDto.class); var expectedEnvelope = fixture.create(CovidCertificateResponseEnvelope.class); expectedEnvelope.setResponseDto(expectedDto); - when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( + when(covidCertificateGeneratePdfFromExistingService.generateFromExistingCovidCertificate( any(RecoveryCertificatePdfGenerateRequestDto.class))).thenReturn(expectedEnvelope); MvcResult result = mockMvc.perform( @@ -186,7 +186,7 @@ void returnsStatusCodeOfCreateCertificateException_ifOneWasThrown() throws Excep var pdfGenerateRequestDto = fixture .create(RecoveryCertificatePdfGenerateRequestDto.class); var exception = fixture.create(CreateCertificateException.class); - when(covidCertificatePdfGenerationService.generateFromExistingCovidCertificate( + when(covidCertificateGeneratePdfFromExistingService.generateFromExistingCovidCertificate( any(RecoveryCertificatePdfGenerateRequestDto.class))).thenThrow(exception); mockMvc.perform( From b0abde8e86312073515b7aad921e540ca1d6686f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20L=C3=B6sing?= Date: Fri, 8 Jul 2022 15:43:14 +0200 Subject: [PATCH 12/23] Removed unnecessary code. --- ...tificatePdfGenerationControllerSecurityTest.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java index 7d6f07ed..7886b855 100644 --- a/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java +++ b/src/test/java/ch/admin/bag/covidcertificate/web/controller/CovidCertificatePdfGenerationControllerSecurityTest.java @@ -25,7 +25,6 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.ResultMatcher; -import java.io.IOException; import java.time.LocalDateTime; import static org.mockito.ArgumentMatchers.any; @@ -52,17 +51,7 @@ class CovidCertificatePdfGenerationControllerSecurityTest extends AbstractSecuri private CovidCertificateVaccinationValidationService covidCertificateVaccinationValidationService; @BeforeEach - void setupMocks() throws IOException { - // lenient().when(covidCertificatePdfGenerationService.generateCovidCertificate( - // any(VaccinationCertificateCreateDto.class))).thenReturn( - // fixture.create(CovidCertificateResponseEnvelope.class)); - // lenient().when(covidCertificatePdfGenerationService.generateCovidCertificate( - // any(TestCertificateCreateDto.class))).thenReturn( - // fixture.create(CovidCertificateResponseEnvelope.class)); - // lenient().when(covidCertificatePdfGenerationService.generateCovidCertificate( - // any(RecoveryCertificateCreateDto.class))).thenReturn( - // fixture.create(CovidCertificateResponseEnvelope.class)); - + void setupMocks() { lenient().when(covidCertificateGeneratePdfFromExistingService.generateFromExistingCovidCertificate( any(VaccinationCertificatePdfGenerateRequestDto.class))).thenReturn( fixture.create(CovidCertificateResponseEnvelope.class)); From b6c1e05c1ff0641161ca34ea3206f91650fa6c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20L=C3=B6sing?= Date: Fri, 8 Jul 2022 15:49:09 +0200 Subject: [PATCH 13/23] Prepare next release. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5e2d1673..6797acac 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ ch.admin.bag.covidcertificate cc-management-service - 4.4.2 + 4.4.3 cc-management-service Service for generating Covid Certificates From c141d77c7e13690284058458cbf552b2829886e0 Mon Sep 17 00:00:00 2001 From: Iris Hunkeler Date: Wed, 13 Jul 2022 10:42:26 +0200 Subject: [PATCH 14/23] VACCINECER-2238 clean up client id --- .../security/authentication/JeapAuthenticationToken.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/ch/admin/bag/covidcertificate/config/security/authentication/JeapAuthenticationToken.java b/src/main/java/ch/admin/bag/covidcertificate/config/security/authentication/JeapAuthenticationToken.java index c385714d..b62c8030 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/config/security/authentication/JeapAuthenticationToken.java +++ b/src/main/java/ch/admin/bag/covidcertificate/config/security/authentication/JeapAuthenticationToken.java @@ -1,6 +1,5 @@ package ch.admin.bag.covidcertificate.config.security.authentication; -import org.apache.commons.lang3.StringUtils; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.jwt.Jwt; @@ -28,8 +27,7 @@ public JeapAuthenticationToken(Jwt jwt, Set userRoles) { * @return The client id specified in this token. */ public String getClientId() { - String client_id = getToken().getClaimAsString("client_id"); - return StringUtils.isNotBlank(client_id) ? client_id : getToken().getClaimAsString("clientId"); + return getToken().getClaimAsString("clientId"); } /** From a8e0e9542e539a05ab8043e53e4faecdd69b56fe Mon Sep 17 00:00:00 2001 From: Iris Hunkeler Date: Thu, 14 Jul 2022 15:26:44 +0200 Subject: [PATCH 15/23] VACCINECER-2158 change trust store password and move to cups variable --- .../CCManagementServiceApplication.java | 55 ++++++++++-------- src/main/resources/application-abn.yml | 5 +- src/main/resources/application-dev.yml | 5 +- src/main/resources/application-local.yml | 6 +- src/main/resources/application-prod.yml | 5 +- src/main/resources/truststore.jks | Bin 10011 -> 10011 bytes 6 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/main/java/ch/admin/bag/covidcertificate/CCManagementServiceApplication.java b/src/main/java/ch/admin/bag/covidcertificate/CCManagementServiceApplication.java index fd116e46..7405180a 100644 --- a/src/main/java/ch/admin/bag/covidcertificate/CCManagementServiceApplication.java +++ b/src/main/java/ch/admin/bag/covidcertificate/CCManagementServiceApplication.java @@ -8,6 +8,7 @@ import org.springframework.cache.annotation.EnableCaching; import org.springframework.core.env.Environment; import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.util.StringUtils; import java.util.Objects; @@ -19,29 +20,33 @@ @Slf4j public class CCManagementServiceApplication { - public static void main(String[] args) { - - String filePath= Objects.requireNonNull(Thread.currentThread() - .getContextClassLoader().getResource("truststore.jks")).getFile(); - System.setProperty("javax.net.ssl.trustStore", filePath); - System.setProperty("javax.net.ssl.trustStorePassword","changeit"); - - Environment env = SpringApplication.run(CCManagementServiceApplication.class, args).getEnvironment(); - - String protocol = "http"; - if (env.getProperty("server.ssl.key-store") != null) { - protocol = "https"; - } - log.info("\n----------------------------------------------------------\n\t" + - "Yeah!!! {} is running! \n\t" + - "\n" + - "\tSwaggerUI: \t{}://localhost:{}/swagger-ui.html\n\t" + - "Profile(s): \t{}" + - "\n----------------------------------------------------------", - env.getProperty("spring.application.name"), - protocol, - env.getProperty("server.port"), - env.getActiveProfiles()); - - } + public static void main(String[] args) { + Environment env = SpringApplication.run(CCManagementServiceApplication.class, args).getEnvironment(); + + String truststorePassword = env.getProperty("cc-management-service.truststore.password"); + if (StringUtils.hasText(truststorePassword)) { + String filePath = Objects.requireNonNull(Thread.currentThread() + .getContextClassLoader().getResource("truststore.jks")).getFile(); + System.setProperty("javax.net.ssl.trustStore", filePath); + System.setProperty("javax.net.ssl.trustStorePassword", truststorePassword); + log.info("Custom truststore initialized"); + } else { + log.info("No custom truststore initialized"); + } + + String protocol = "http"; + if (env.getProperty("server.ssl.key-store") != null) { + protocol = "https"; + } + log.info("\n----------------------------------------------------------\n\t" + + "Yeah!!! {} is running! \n\t" + + "\n" + + "\tSwaggerUI: \t{}://localhost:{}/swagger-ui.html\n\t" + + "Profile(s): \t{}" + + "\n----------------------------------------------------------", + env.getProperty("spring.application.name"), + protocol, + env.getProperty("server.port"), + env.getActiveProfiles()); + } } diff --git a/src/main/resources/application-abn.yml b/src/main/resources/application-abn.yml index 66fce91e..e7d47288 100644 --- a/src/main/resources/application-abn.yml +++ b/src/main/resources/application-abn.yml @@ -35,6 +35,9 @@ cc-management-service: allowed-origin: "https://www.covidcertificate-a.admin.ch" + truststore: + password: ${vcap.services.cc_trust_store.credentials.password} + cc-signing-service: url: "https://covidcertificate-signing-a.bag.admin.ch/bag-vaccinecer-webapp/sign" verify-url: "https://covidcertificate-signing-a.bag.admin.ch/bag-vaccinecer-webapp/sign/verify" @@ -49,7 +52,7 @@ cc-inapp-delivery-service: ch-covidcertificate-backend-verifier-service: url: "https://ch-covidcertificate-backend-verifier-ws.abn.app.cfap02.atlantica.admin.ch/dcga/v1/valueSets" -## Mutual-SSL configuration +## Mutual-SSL configuration to connect from management-service to signing-service app: conn: cc-signing-service: diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 4ee81d6f..408e8a55 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -38,6 +38,9 @@ cc-management-service: rapid-test-import: cron: "0 0 */1 * * ?" ## Every hour + truststore: + password: ${vcap.services.cc_trust_store.credentials.password} + cc-signing-service: url: "https://covidcertificate-signing-d.bag.admin.ch/bag-vaccinecer-webapp/sign" verify-url: "https://covidcertificate-signing-d.bag.admin.ch/bag-vaccinecer-webapp/sign/verify" @@ -52,7 +55,7 @@ cc-inapp-delivery-service: ch-covidcertificate-backend-verifier-service: url: "https://ch-covidcertificate-backend-verifier-ws.dev.app.cfap02.atlantica.admin.ch/dcga/v1/valueSets" -## Mutual-SSL configuration +## Mutual-SSL configuration to connect from management-service to signing-service app: conn: cc-signing-service: diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index febb3e8a..5a210ef0 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -39,6 +39,10 @@ cc-management-service: rapid-test-import: cron: "0 * * * * *" ## Every minute + # truststore password is not set locally since we don't need it + truststore: + password: + cc-signing-service: #When started as spring boot application # url: "https://localhost:9090/sign" @@ -58,7 +62,7 @@ cc-inapp-delivery-service: ch-covidcertificate-backend-verifier-service: url: "https://ch-covidcertificate-backend-verifier-ws.dev.app.cfap02.atlantica.admin.ch/dcga/v1/valueSets" -## Mutual-SSL configuration +## Mutual-SSL configuration to connect from management-service to signing-service app: conn: cc-signing-service: diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 762d3ac8..6af263eb 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -38,6 +38,9 @@ cc-management-service: allowed-origin: "https://www.covidcertificate.admin.ch" + truststore: + password: ${vcap.services.cc_trust_store.credentials.password} + cc-signing-service: url: "https://covidcertificate-signing.bag.admin.ch/bag-vaccinecer-webapp/sign" verify-url: "https://covidcertificate-signing.bag.admin.ch/bag-vaccinecer-webapp/sign/verify" @@ -52,7 +55,7 @@ cc-inapp-delivery-service: ch-covidcertificate-backend-verifier-service: url: "https://ch-covidcertificate-backend-verifier-ws.app.cfap02.atlantica.admin.ch/dcga/v1/valueSets" -## Mutual-SSL configuration +## Mutual-SSL configuration to connect from management-service to signing-service app: conn: cc-signing-service: diff --git a/src/main/resources/truststore.jks b/src/main/resources/truststore.jks index b1c9fbf523031f29e4920eb2b607650e5280c968..5cf27620953f8510980ff3e6ca316f2d9c0436e2 100644 GIT binary patch delta 52 zcmbR3H`|Zr-`jt085kItfS7G_2AdDtM!^`i&0Bbar9@`x1Wq@+Eg7?sWApyoizHYk I&VS(o0PeICmH+?% delta 52 zcmbR3H`|Zr-`jt085kItfS7G_Fk2$qMnQMB&0Bbar9`xf<7TSpSsWB>-g)AJ$NKG; Ip3Hdz0O~gs;{X5v From 0c8330a0cff7f13000bb0ca56e3ecc52841b5740 Mon Sep 17 00:00:00 2001 From: Iris Hunkeler Date: Thu, 14 Jul 2022 15:58:23 +0200 Subject: [PATCH 16/23] update to version 4.4.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6797acac..67e23b9a 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ ch.admin.bag.covidcertificate cc-management-service - 4.4.3 + 4.4.4 cc-management-service Service for generating Covid Certificates From bfa06eba11f8502095590498bb243d3b78faffed Mon Sep 17 00:00:00 2001 From: Nino Di Natale Date: Mon, 18 Jul 2022 15:13:00 +0200 Subject: [PATCH 17/23] adjusted report urls --- .run/CCManagementServiceApplication.run.xml | 3 +-- src/main/resources/application-authorization.yml | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.run/CCManagementServiceApplication.run.xml b/.run/CCManagementServiceApplication.run.xml index 86d8635e..d451ba66 100644 --- a/.run/CCManagementServiceApplication.run.xml +++ b/.run/CCManagementServiceApplication.run.xml @@ -1,6 +1,6 @@ - + From ca5fea562ddb9d74e3963f51b8282a9f255af1f8 Mon Sep 17 00:00:00 2001 From: ndinat <97943873+ndinat@users.noreply.github.com> Date: Mon, 18 Jul 2022 15:15:23 +0200 Subject: [PATCH 19/23] Update CCManagementServiceApplication.run.xml --- .run/CCManagementServiceApplication.run.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/.run/CCManagementServiceApplication.run.xml b/.run/CCManagementServiceApplication.run.xml index 44db90d2..400f937e 100644 --- a/.run/CCManagementServiceApplication.run.xml +++ b/.run/CCManagementServiceApplication.run.xml @@ -10,6 +10,7 @@