Skip to content

Commit

Permalink
Uniformity in unit testing and integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sayfjawad committed Dec 26, 2024
1 parent 4d3c8d0 commit 2b97626
Show file tree
Hide file tree
Showing 24 changed files with 379 additions and 105 deletions.
16 changes: 14 additions & 2 deletions src/test/java/nl/ictu/TestingWebApplicationTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
Expand All @@ -31,8 +32,12 @@ class TestingWebApplicationTests {
private TestRestTemplate restTemplate;

@Test
@DisplayName("""
Given the Spring Boot application is running with actuator enabled
When accessing the /actuator/health endpoint
Then the response should contain a status of 'UP'
""")
void testActuatorHealthEndpoint() {

final int actuatorPort = environment.getProperty("local.management.port", Integer.class);
assertThat(
restTemplate.getForObject("http://localhost:" + actuatorPort + "/actuator/health",
Expand All @@ -41,6 +46,12 @@ void testActuatorHealthEndpoint() {
}

@Test
@DisplayName("""
Given a request to get a token with a BSN identifier
When sending the request to /v1/getToken
Then the response should include a token
And the token can be used to exchange for the identifier type BSN
""")
void testGetAtokenExchangeForBSN() {
// get a token
final var getTokenBody = Map.of("recipientOIN", "54321543215432154321", "identifier",
Expand All @@ -55,6 +66,7 @@ void testGetAtokenExchangeForBSN() {
.extracting("body")
.asInstanceOf(InstanceOfAssertFactories.map(String.class, Void.class))
.containsKey("token");

// change token for identifier
final var token = (String) tokenExchange.getBody().get("token");
final var exchangeTokenBody = Map.of("token", token, "identifierType", "BSN");
Expand All @@ -70,4 +82,4 @@ void testGetAtokenExchangeForBSN() {
.asInstanceOf(InstanceOfAssertFactories.map(String.class, Map.class))
.containsExactly(entry("identifier", Map.of("type", "BSN", "value", "012345679")));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@

import nl.ictu.service.exception.IdentifierPrivateKeyException;
import nl.ictu.service.exception.TokenPrivateKeyException;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

class PseudoniemenServicePropertiesTest {

@Test
@DisplayName("""
Given an empty token private key
When validating
When TokenPrivateKeyException is thrown
""")
void validate_WhenTokenPrivateKeyIsEmpty_ThrowsTokenPrivateKeyException() {
// GIVEN
PseudoniemenServiceProperties props = new PseudoniemenServiceProperties()
Expand All @@ -20,6 +26,10 @@ void validate_WhenTokenPrivateKeyIsEmpty_ThrowsTokenPrivateKeyException() {
}

@Test
@DisplayName("""
Given an empty identifier private key
When validating, then IdentifierPrivateKeyException is thrown
""")
void validate_WhenIdentifierPrivateKeyIsEmpty_ThrowsIdentifierPrivateKeyException() {
// GIVEN
PseudoniemenServiceProperties props = new PseudoniemenServiceProperties()
Expand All @@ -30,6 +40,10 @@ void validate_WhenIdentifierPrivateKeyIsEmpty_ThrowsIdentifierPrivateKeyExceptio
}

@Test
@DisplayName("""
Given both keys are set when validating
Then no exception is thrown
""")
void validate_WhenBothKeysAreSet_NoExceptionIsThrown() {
// GIVEN
PseudoniemenServiceProperties props = new PseudoniemenServiceProperties()
Expand Down
11 changes: 10 additions & 1 deletion src/test/java/nl/ictu/controller/GlobalExceptionHandlerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ class GlobalExceptionHandlerTest {

// Test for handleGenericException
@Test
@DisplayName("""
Given an invalid endpoint
When a GET request is made
Then an internal server error is returned with an appropriate message
""")
void handleGenericException_ShouldReturnInternalServerErrorWithMessage() throws Exception {

mockMvc.perform(get("/non-existent-endpoint")) // Assuming no controller is mapped to this
Expand All @@ -42,7 +47,11 @@ void handleGenericException_ShouldReturnInternalServerErrorWithMessage() throws
}

@Test
@DisplayName("exchangeToken() -> 422 UNPROCESSABLE_ENTITY on exception")
@DisplayName("""
Given a stubbed controller and service
When the service throws various exceptions
Then the system responds with UNPROCESSABLE_ENTITY and the exception message
""")
void exchangeToken_ShouldReturnUnprocessableEntity() {
// GIVEN: a stubbed controller and service
// WHEN: the service throws an exception
Expand Down
6 changes: 5 additions & 1 deletion src/test/java/nl/ictu/controller/IndexControllerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ class IndexControllerTest {
private final MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller).build();

@Test
@DisplayName("GET / -> Redirects to Swagger UI")
@DisplayName("""
Given a request to the root endpoint
When performing a GET request
Then the response redirects to Swagger UI
""")
void testRedirectToSwaggerUi() throws Exception {
// WHEN & THEN
mockMvc.perform(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ class ExchangeIdentifierControllerTest {
private ExchangeIdentifierController controller;

@Test
@DisplayName("exchangeIdentifier() -> Returns 200 OK with response on success")
@DisplayName("""
Given a valid request and service response
When calling exchangeIdentifier()
Then it returns 200 OK with the expected response
""")
void testExchangeIdentifier_Success() {
// GIVEN
String callerOIN = "123456789";
Expand All @@ -41,7 +45,11 @@ void testExchangeIdentifier_Success() {
}

@Test
@DisplayName("exchangeIdentifier() -> Throws exception when service fails")
@DisplayName("""
Given a valid request and service throws an exception
When calling exchangeIdentifier()
Then it throws the same exception with the correct message
""")
void testExchangeIdentifier_ServiceThrowsException() {
// GIVEN
String callerOIN = "123456789";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ class ExchangeTokenControllerTest {
private ObjectMapper objectMapper;

@Test
@DisplayName("exchangeToken() -> 200 OK on success")
@DisplayName("""
Given a valid token and identifier type
When calling exchangeToken()
Then it returns 200 OK with the expected identifier in the response
""")
void exchangeToken_ShouldReturnOk() throws Exception {
// GIVEN: a request payload
WsExchangeTokenRequest requestPayload = new WsExchangeTokenRequest();
Expand Down Expand Up @@ -64,7 +68,11 @@ void exchangeToken_ShouldReturnOk() throws Exception {
}

@Test
@DisplayName("exchangeToken() -> 422 UNPROCESSABLE_ENTITY on exception")
@DisplayName("""
Given an invalid token and identifier type
When calling exchangeToken()
Then it returns 422 UNPROCESSABLE_ENTITY with the appropriate error
""")
void exchangeToken_ShouldReturnUnprocessableEntity() throws Exception {
// GIVEN: a request payload
WsExchangeTokenRequest requestPayload = new WsExchangeTokenRequest();
Expand Down
19 changes: 15 additions & 4 deletions src/test/java/nl/ictu/service/ExchangeIdentifierServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ class ExchangeIdentifierServiceTest {
private ExchangeIdentifierService exchangeIdentifierService;

@Test
@DisplayName("exchangeIdentifier() -> BSN -> ORGANISATION_PSEUDO path")
@DisplayName("""
Given a BSN identifier and recipientIdentifierType ORGANISATION_PSEUDO
When exchangeIdentifier() is called
Then it should return a response with ORGANISATION_PSEUDO type and encrypted value
""")
void testExchangeIdentifier_BsnToOrgPseudo() throws Exception {
// GIVEN
var request = new WsExchangeIdentifierRequest()
Expand All @@ -48,7 +52,6 @@ void testExchangeIdentifier_BsnToOrgPseudo() throws Exception {
WsExchangeIdentifierResponse actualResponse =
exchangeIdentifierService.exchangeIdentifier(request);
// THEN
// Verify the returned response is what the mapper gave back
org.junit.jupiter.api.Assertions.assertNotNull(actualResponse);
org.junit.jupiter.api.Assertions.assertNotNull(actualResponse.getIdentifier());
org.junit.jupiter.api.Assertions.assertEquals(ORGANISATION_PSEUDO,
Expand All @@ -58,7 +61,11 @@ void testExchangeIdentifier_BsnToOrgPseudo() throws Exception {
}

@Test
@DisplayName("exchangeIdentifier() -> ORGANISATION_PSEUDO -> BSN path")
@DisplayName("""
Given an ORGANISATION_PSEUDO identifier and recipientIdentifierType BSN
When exchangeIdentifier() is called
Then it should return a response with BSN type and decrypted value
""")
void testExchangeIdentifier_OrgPseudoToBsn() throws Exception {
// GIVEN
var request = new WsExchangeIdentifierRequest()
Expand All @@ -82,7 +89,11 @@ void testExchangeIdentifier_OrgPseudoToBsn() throws Exception {
}

@Test
@DisplayName("exchangeIdentifier() -> throws InvalidWsIdentifierRequestTypeException for unsupported mappings")
@DisplayName("""
Given a request with unsupported identifier mapping (BSN -> BSN or ORG_PSEUDO -> ORG_PSEUDO)
When exchangeIdentifier() is called
Then it should throw InvalidWsIdentifierRequestTypeException
""")
void testExchangeIdentifier_UnsupportedMapping_ThrowsException() {
// GIVEN
var request = new WsExchangeIdentifierRequest()
Expand Down
34 changes: 21 additions & 13 deletions src/test/java/nl/ictu/service/ExchangeTokenServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class ExchangeTokenServiceTest {
private final String callerOIN = "123456789";
private final String encryptedToken = "encryptedTokenValue";
private final String decodedToken = "decodedTokenValue";

@Mock
private AesGcmCryptographer aesGcmCryptographer;
@Mock
Expand All @@ -42,18 +43,22 @@ class ExchangeTokenServiceTest {
private BsnTokenMapper bsnTokenMapper;
@InjectMocks
private ExchangeTokenService exchangeTokenService;

private Token mockToken;

@BeforeEach
void setUp() {
// Setup mock token object
mockToken = Token.builder().build();
mockToken.setRecipientOIN(callerOIN);
mockToken.setBsn("987654321");
}

@Test
@DisplayName("exchangeToken() -> BSN identifier")
@DisplayName("""
Given a BSN identifier
When exchangeToken() is called
Then it should return a valid response mapped by BsnTokenMapper
""")
void testExchangeToken_BsnIdentifier() throws Exception {
// GIVEN
var request = new WsExchangeTokenRequest().token(encryptedToken).identifierType(BSN);
Expand All @@ -64,8 +69,7 @@ void testExchangeToken_BsnIdentifier() throws Exception {
var expectedResponse = new WsExchangeTokenResponse();
when(bsnTokenMapper.map(mockToken)).thenReturn(expectedResponse);
// WHEN
WsExchangeTokenResponse actualResponse =
exchangeTokenService.exchangeToken(callerOIN, request);
WsExchangeTokenResponse actualResponse = exchangeTokenService.exchangeToken(callerOIN, request);
// THEN
verify(aesGcmCryptographer).decrypt(encryptedToken, callerOIN);
verify(tokenCoder).decode(decodedToken);
Expand All @@ -75,21 +79,22 @@ void testExchangeToken_BsnIdentifier() throws Exception {
}

@Test
@DisplayName("exchangeToken() -> ORGANISATION_PSEUDO identifier")
@DisplayName("""
Given an ORGANISATION_PSEUDO identifier
When exchangeToken() is called
Then it should return a valid response mapped by OrganisationPseudoTokenMapper
""")
void testExchangeToken_OrganisationPseudoIdentifier() throws Exception {
// GIVEN
var request =
new WsExchangeTokenRequest().token(encryptedToken)
.identifierType(ORGANISATION_PSEUDO);
var request = new WsExchangeTokenRequest().token(encryptedToken).identifierType(ORGANISATION_PSEUDO);
// Stubbing dependencies
when(aesGcmCryptographer.decrypt(encryptedToken, callerOIN)).thenReturn(decodedToken);
when(tokenCoder.decode(decodedToken)).thenReturn(mockToken);
when(oinValidator.isValid(callerOIN, mockToken)).thenReturn(true);
var expectedResponse = new WsExchangeTokenResponse();
when(organisationPseudoTokenMapper.map(callerOIN, mockToken)).thenReturn(expectedResponse);
// WHEN
WsExchangeTokenResponse actualResponse =
exchangeTokenService.exchangeToken(callerOIN, request);
WsExchangeTokenResponse actualResponse = exchangeTokenService.exchangeToken(callerOIN, request);
// THEN
verify(aesGcmCryptographer).decrypt(encryptedToken, callerOIN);
verify(tokenCoder).decode(decodedToken);
Expand All @@ -99,7 +104,11 @@ void testExchangeToken_OrganisationPseudoIdentifier() throws Exception {
}

@Test
@DisplayName("exchangeToken() -> Invalid OIN")
@DisplayName("""
Given an invalid OIN
When exchangeToken() is called
Then it should throw InvalidOINException
""")
void testExchangeToken_InvalidOIN() throws Exception {
// GIVEN
var request = new WsExchangeTokenRequest().token(encryptedToken).identifierType(BSN);
Expand All @@ -108,8 +117,7 @@ void testExchangeToken_InvalidOIN() throws Exception {
when(tokenCoder.decode(decodedToken)).thenReturn(mockToken);
when(oinValidator.isValid(callerOIN, mockToken)).thenReturn(false); // Invalid OIN
// WHEN & THEN
assertThrows(InvalidOINException.class,
() -> exchangeTokenService.exchangeToken(callerOIN, request));
assertThrows(InvalidOINException.class, () -> exchangeTokenService.exchangeToken(callerOIN, request));
verify(aesGcmCryptographer).decrypt(encryptedToken, callerOIN);
verify(tokenCoder).decode(decodedToken);
verify(oinValidator).isValid(callerOIN, mockToken);
Expand Down
Loading

0 comments on commit 2b97626

Please sign in to comment.