Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
epicsoft-llc committed Sep 22, 2021
1 parent 13da374 commit e509274
Show file tree
Hide file tree
Showing 8 changed files with 364 additions and 11 deletions.
19 changes: 13 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,19 @@
<version>${spring.test.version}</version><!--$NO-MVN-MAN-VER$-->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version><!--$NO-MVN-MAN-VER$-->
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.assertj/assertj-core -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.21.0</version><!--$NO-MVN-MAN-VER$-->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand All @@ -195,12 +208,6 @@
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version><!--$NO-MVN-MAN-VER$-->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
@RequiredArgsConstructor
public class DccTokenController {

private static final String PATH = "/token";
static final String PATH = "/token";

private final AccessTokenService accessTokenService;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@
@RequiredArgsConstructor
public class IdentityController {

public static final String PATH_ALL = "/identity";
static final String PATH_ALL = "/identity";

private static final String PATH_ELEMENT = "/identity/{element}";
static final String PATH_ELEMENT = "/identity/{element}";

private static final String PATH_ELEMENT_TYPE = "/identity/{element}/{type}";
static final String PATH_ELEMENT_TYPE = "/identity/{element}/{type}";

private final IdentityService identityService;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
@RequiredArgsConstructor
public class InitializeController {

private static final String PATH = "/initialize/{subject}";
static final String PATH = "/initialize/{subject}";

private final InitializeService initializeService;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@

import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;

@Value
@Builder
@Jacksonized
public class QrCodeDto {

// Type of the requested protocol
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/*-
* ---license-start
* European Digital COVID Certificate Validation Decorator Service / dgca-validation-decorator
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*/

package eu.europa.ec.dgc.validation.decorator.controller;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import eu.europa.ec.dgc.validation.decorator.dto.DccTokenRequest;
import eu.europa.ec.dgc.validation.decorator.dto.IdentityResponse.ServiceIdentityResponse;
import eu.europa.ec.dgc.validation.decorator.entity.ServiceTokenContentResponse;
import eu.europa.ec.dgc.validation.decorator.entity.ServiceTokenContentResponse.OccurrenceInfoResponse;
import eu.europa.ec.dgc.validation.decorator.entity.ServiceTokenContentResponse.SubjectResponse;
import eu.europa.ec.dgc.validation.decorator.entity.ValidationServiceInitializeResponse;
import eu.europa.ec.dgc.validation.decorator.repository.BackendRepository;
import eu.europa.ec.dgc.validation.decorator.repository.ValidationServiceRepository;
import eu.europa.ec.dgc.validation.decorator.service.AccessTokenService;
import eu.europa.ec.dgc.validation.decorator.service.IdentityService;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.util.Arrays;
import java.util.Base64;
import java.util.Map;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.util.UriComponentsBuilder;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class DccTokenControllerTest {

@LocalServerPort
private int port;

@Autowired
private TestRestTemplate restTpl;

@Autowired
private AccessTokenService accessTokenService;

@Autowired
private IdentityService identityService;

@MockBean
private ValidationServiceRepository validationServiceRepositoryMock;

@MockBean
private BackendRepository backendRepository;

private String subject;

private ServiceIdentityResponse service;

@BeforeEach
public void before() {
this.subject = UUID.randomUUID().toString();
this.service = this.identityService.getIdentity("service", "ValidationService").getService().get(0);

final ValidationServiceInitializeResponse initialize = this.buildValidationServiceInitializeMock();
when(this.validationServiceRepositoryMock.initialize(any(), any(), any(), any())).thenReturn(initialize);

final ServiceTokenContentResponse tokenContent = this.buildServiceTokenContentMock();
when(this.backendRepository.tokenContent(any())).thenReturn(tokenContent);
when(this.backendRepository.tokenContent(any(), any())).thenReturn(tokenContent);
}

@SuppressWarnings("unchecked")
@Test
void token_withValidTokenAndService_successResponse() {
// GIVEN
final String token = this.accessTokenService.buildHeaderToken(this.subject);
final DccTokenRequest body = new DccTokenRequest();
body.setService(this.service.getId());
body.setPubKey(UUID.randomUUID().toString());
// AND
final String url = UriComponentsBuilder.fromUriString("http://localhost")
.port(port)
.path(DccTokenController.PATH.replace("{subject}", this.subject))
.toUriString();
final HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", token);
final HttpEntity<DccTokenRequest> entity = new HttpEntity<>(body, headers);
// WHEN
ResponseEntity<String> result = this.restTpl.exchange(url, HttpMethod.POST, entity, String.class);
// THEN
assertThat(result).isNotNull();
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getBody()).isNotBlank();
assertThat(accessTokenService.isValid(result.getBody())).isTrue();
// AND tokenContent
final Map<String, Object> tokenContent = accessTokenService.parseAccessToken(result.getBody());
assertThat(tokenContent)
.containsKeys("sub", "aud", "t", "v", "iss", "exp", "iat", "vc", "jti")
.contains(entry("sub", this.subject));
// AND occurrenceInfo
assertThat(tokenContent.get("vc")).isNotNull().isInstanceOf(Map.class);
final Map<String, Object> occurrenceInfo = (Map<String, Object>) tokenContent.get("vc");
assertThat(occurrenceInfo).containsKeys("lang", "fnt", "gnt", "dob", "coa", "cod", "roa", "type", "category",
"validationClock", "validFrom", "validTo");
}

private ValidationServiceInitializeResponse buildValidationServiceInitializeMock() {
final ValidationServiceInitializeResponse initialize = new ValidationServiceInitializeResponse();
initialize.setSubject(subject);
initialize.setExp(Instant.now().plusSeconds(60).toEpochMilli());
initialize.setAud("ValidationServiceInitializeResponse");
return initialize;
}

private ServiceTokenContentResponse buildServiceTokenContentMock() {
final String serviceId = Base64.getUrlEncoder().withoutPadding().encodeToString(service.getId().getBytes());
final SubjectResponse subjectResponse = new SubjectResponse();
subjectResponse.setId(UUID.fromString(subject));
subjectResponse.setForename("Lionel");
subjectResponse.setLastname("Kuhic");
subjectResponse.setBirthDate("1994-05-25");
subjectResponse.setServiceIdUsed(serviceId);
subjectResponse.setJti(UUID.randomUUID().toString());

final OffsetDateTime departureTime = OffsetDateTime.now().plusDays(1);
final OccurrenceInfoResponse occurrenceInfo = new OccurrenceInfoResponse();
occurrenceInfo.setFrom("East Kizzieshire");
occurrenceInfo.setTo("South Duncanhaven");
occurrenceInfo.setTime(departureTime);
occurrenceInfo.setType(2);
occurrenceInfo.setCategories(Arrays.asList("Standard"));
occurrenceInfo.setConditionTypes(Arrays.asList("r", "v", "t"));
occurrenceInfo.setCountryOfArrival("TT");
occurrenceInfo.setRegionOfArrival("TT");
occurrenceInfo.setCountryOfDeparture("TD");
occurrenceInfo.setRegionOfDeparture("TD");
occurrenceInfo.setDepartureTime(departureTime);
occurrenceInfo.setArrivalTime(departureTime.plusHours(8).plusMinutes(24));
occurrenceInfo.setLanguage("en-en");

final ServiceTokenContentResponse tokenContent = new ServiceTokenContentResponse();
tokenContent.setReference("TestBookingReference");
tokenContent.setTime(OffsetDateTime.now());
tokenContent.getSubjects().add(subjectResponse);
tokenContent.setFlightInfo(occurrenceInfo);
return tokenContent;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*-
* ---license-start
* European Digital COVID Certificate Validation Decorator Service / dgca-validation-decorator
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ---license-end
*/

package eu.europa.ec.dgc.validation.decorator.controller;

import static org.assertj.core.api.Assertions.assertThat;
import eu.europa.ec.dgc.validation.decorator.dto.IdentityResponse;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.web.util.UriComponentsBuilder;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class IdentityControllerTest {

@LocalServerPort
private int port;

@Autowired
private TestRestTemplate restTpl;

@Test
void identityAll_withoutVariales_successWithAllIdentities() {
// GIVEN
final String url = UriComponentsBuilder.fromUriString("http://localhost")
.port(port)
.path(IdentityController.PATH_ALL)
.toUriString();
// WHEN
final IdentityResponse result = restTpl.getForObject(url, IdentityResponse.class);
// THEN
assertThat(result).isNotNull();
assertThat(result.getVerificationMethod()).hasSizeGreaterThanOrEqualTo(4);
assertThat(result.getService()).hasSizeGreaterThanOrEqualTo(4);
}

@ParameterizedTest
@ValueSource(strings = { "verificationMethod", "service" })
void identityElement_withElement_successWithElement(final String element) {
// GIVEN
final String url = UriComponentsBuilder.fromUriString("http://localhost")
.port(port)
.path(IdentityController.PATH_ELEMENT.replace("{element}", element))
.toUriString();
// WHEN
final IdentityResponse result = restTpl.getForObject(url, IdentityResponse.class);
// THEN
assertThat(result).isNotNull();
// AND
if ("verificationMethod".equals(element)) {
assertThat(result.getVerificationMethod()).hasSizeGreaterThanOrEqualTo(4);
assertThat(result.getService()).hasSize(0);
} else {
assertThat(result.getVerificationMethod()).hasSize(0);
assertThat(result.getService()).hasSizeGreaterThanOrEqualTo(4);
}
}

@ParameterizedTest
@ValueSource(strings = { "ValidationService", "AccessTokenService", "ServiceProvider", "CancellationService",
"StatusService" })
void identityType_withServiceAndType_successWithServiceAndType(final String type) {
// GIVEN
String element = "service";
final String url = UriComponentsBuilder.fromUriString("http://localhost")
.port(port)
.path(IdentityController.PATH_ELEMENT_TYPE.replace("{element}", element).replace("{type}", type))
.toUriString();
// WHEN
final IdentityResponse result = restTpl.getForObject(url, IdentityResponse.class);
// THEN
assertThat(result).isNotNull();
assertThat(result.getVerificationMethod()).hasSize(0);
assertThat(result.getService()).hasSize(1);
}
}
Loading

0 comments on commit e509274

Please sign in to comment.