From 9706a09648ae6fe434872305c2d347e51e079a18 Mon Sep 17 00:00:00 2001 From: Shyam Vishwakarma Date: Fri, 23 May 2025 01:51:35 +0530 Subject: [PATCH 1/9] refactor: add exception messages in constants and replace its usage --- .../src/main/java/com/RDS/skilltree/utils/Constants.java | 4 ++++ .../RDS/skilltree/viewmodels/UpdateEndorsementViewModel.java | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/skill-tree/src/main/java/com/RDS/skilltree/utils/Constants.java b/skill-tree/src/main/java/com/RDS/skilltree/utils/Constants.java index da443a25..2e135f18 100644 --- a/skill-tree/src/main/java/com/RDS/skilltree/utils/Constants.java +++ b/skill-tree/src/main/java/com/RDS/skilltree/utils/Constants.java @@ -8,5 +8,9 @@ public static final class ExceptionMessages { public static final String SKILL_NOT_FOUND = "Skill does not exist"; public static final String ENDORSEMENT_ALREADY_EXISTS = "Endorsement already exists"; public static final String ENDORSEMENT_NOT_FOUND = "Endorsement not found"; + public static final String ENDORSEMENT_MESSAGE_EMPTY = "Endorsement message cannot be empty"; + public static final String USER_NOT_FOUND = "Error getting user details"; + public static final String UNAUTHORIZED_ENDORSEMENT_UPDATE = + "Not authorized to update this endorsement"; } } diff --git a/skill-tree/src/main/java/com/RDS/skilltree/viewmodels/UpdateEndorsementViewModel.java b/skill-tree/src/main/java/com/RDS/skilltree/viewmodels/UpdateEndorsementViewModel.java index 0b1685a7..010fa53c 100644 --- a/skill-tree/src/main/java/com/RDS/skilltree/viewmodels/UpdateEndorsementViewModel.java +++ b/skill-tree/src/main/java/com/RDS/skilltree/viewmodels/UpdateEndorsementViewModel.java @@ -1,5 +1,6 @@ package com.RDS.skilltree.viewmodels; +import com.RDS.skilltree.utils.Constants.ExceptionMessages; import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.Setter; @@ -7,6 +8,6 @@ @Getter @Setter public class UpdateEndorsementViewModel { - @NotNull(message = "Message cannot be empty") + @NotNull(message = ExceptionMessages.ENDORSEMENT_MESSAGE_EMPTY) private String message; } From 34d8f73bea46882a526d76a00e2040e7e30ef1bb Mon Sep 17 00:00:00 2001 From: Shyam Vishwakarma Date: Fri, 23 May 2025 01:53:12 +0530 Subject: [PATCH 2/9] test: add integration tests for PATCH v1/endorsements/{endorsementId} --- .../UpdateEndorsementsIntegrationTest.java | 374 ++++++++++++++++++ 1 file changed, 374 insertions(+) create mode 100644 skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java diff --git a/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java b/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java new file mode 100644 index 00000000..262ae730 --- /dev/null +++ b/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java @@ -0,0 +1,374 @@ +package com.RDS.skilltree.integration.skills; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; +import static utils.TestDataHelper.createEndorsementViewModel; +import static utils.TestDataHelper.createUserDetails; + +import com.RDS.skilltree.TestContainerManager; +import com.RDS.skilltree.dtos.RdsGetUserDetailsResDto; +import com.RDS.skilltree.exceptions.UserNotFoundException; +import com.RDS.skilltree.models.Endorsement; +import com.RDS.skilltree.models.Skill; +import com.RDS.skilltree.repositories.EndorsementRepository; +import com.RDS.skilltree.repositories.SkillRepository; +import com.RDS.skilltree.repositories.UserSkillRepository; +import com.RDS.skilltree.services.external.RdsService; +import com.RDS.skilltree.utils.Constants.ExceptionMessages; +import com.RDS.skilltree.utils.JWTUtils; +import com.RDS.skilltree.viewmodels.EndorsementViewModel; +import com.RDS.skilltree.viewmodels.UpdateEndorsementViewModel; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.servlet.http.Cookie; +import java.util.Map; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import utils.RestAPIHelper; +import utils.TestDataHelper; +import utils.WithCustomMockUser; + +@AutoConfigureMockMvc +@ActiveProfiles("test") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@Import({TestContainerManager.class}) +public class UpdateEndorsementsIntegrationTest { + @Autowired private EndorsementRepository endorsementRepository; + @Autowired private SkillRepository skillRepository; + @Autowired private UserSkillRepository userSkillRepository; + + @Autowired private MockMvc mockMvc; + @Autowired private ObjectMapper objectMapper; + + @MockBean private RdsService rdsService; + @MockBean private JWTUtils jwtUtils; + + private final String superUserId = "super-user-id"; + private final String userId1 = "user-id-1"; + private final String userId2 = "user-id-2"; + + private final String SKILL_NAME = "Java"; + private final String INITIAL_MESSAGE = "Initial message"; + private final String NEW_MESSAGE = "Updated message"; + + @BeforeEach + void setUp() { + skillRepository.deleteAll(); + endorsementRepository.deleteAll(); + userSkillRepository.deleteAll(); + + RdsGetUserDetailsResDto superUserDetails = createUserDetails(superUserId, true); + + RdsGetUserDetailsResDto user1Details = createUserDetails(userId1, false); + RdsGetUserDetailsResDto user2Details = createUserDetails(userId2, false); + + when(rdsService.getUserDetails(superUserId)).thenReturn(superUserDetails); + when(rdsService.getUserDetails(userId1)).thenReturn(user1Details); + when(rdsService.getUserDetails(userId2)).thenReturn(user2Details); + } + + private Skill createAndSaveSkill(String skillName) { + return skillRepository.save(TestDataHelper.createSkill(skillName, superUserId)); + } + + private Endorsement createAndSaveEndorsement( + Skill skill, String endorseId, String endorserId, String message) { + Endorsement endorsement = + TestDataHelper.createEndorsement(skill, endorseId, endorserId, message); + return endorsementRepository.save(endorsement); + } + + private EndorsementViewModel extractEndorsementFromResult(MvcResult result) throws Exception { + String responseJson = result.getResponse().getContentAsString(); + return objectMapper.readValue(responseJson, EndorsementViewModel.class); + } + + private void assertIsEqual( + EndorsementViewModel actualEndorsement, EndorsementViewModel expectedEndorsement) { + expectedEndorsement.setId(actualEndorsement.getId()); + assertThat(actualEndorsement).usingRecursiveComparison().isEqualTo(expectedEndorsement); + } + + private MvcResult performPatchRequest(String url, String requestBody) throws Exception { + return mockMvc + .perform( + MockMvcRequestBuilders.patch(url) + .contentType(MediaType.APPLICATION_JSON) + .content(requestBody)) + .andDo(MockMvcResultHandlers.print()) + .andReturn(); + } + + private String createUrl(Integer endorsementId) { + return String.format("/v1/endorsements/%d", endorsementId); + } + + private UpdateEndorsementViewModel createRequestModel(String newMessage) { + UpdateEndorsementViewModel updateEndorsementViewModel = new UpdateEndorsementViewModel(); + updateEndorsementViewModel.setMessage(newMessage); + return updateEndorsementViewModel; + } + + @Test + @DisplayName("Happy flow for superuser - Successfully update endorsement message") + @WithCustomMockUser( + username = superUserId, + authorities = {"SUPERUSER"}) + public void updateEndorsement_superUser_whenRequestValid_shouldUpdateEndorsement() + throws Exception { + Skill skill = createAndSaveSkill(SKILL_NAME); + Endorsement existingEndorsement = + createAndSaveEndorsement(skill, userId1, superUserId, INITIAL_MESSAGE); + + UpdateEndorsementViewModel updateEndorsementViewModel = createRequestModel(NEW_MESSAGE); + String updateBody = objectMapper.writeValueAsString(updateEndorsementViewModel); + MvcResult result = performPatchRequest(createUrl(existingEndorsement.getId()), updateBody); + + assertThat(result.getResponse().getStatus()).isEqualTo(200); + EndorsementViewModel actualEndorsement = extractEndorsementFromResult(result); + + existingEndorsement.setMessage(updateEndorsementViewModel.getMessage()); + EndorsementViewModel expectedEndorsement = + createEndorsementViewModel(existingEndorsement, rdsService); + assertIsEqual(actualEndorsement, expectedEndorsement); + + Endorsement dbEndorsement = + endorsementRepository.findById(existingEndorsement.getId()).orElseThrow(); + assertThat(dbEndorsement.getMessage()).isEqualTo(updateEndorsementViewModel.getMessage()); + } + + @Test + @DisplayName("Happy flow for non-superuser - Successfully update endorsement message") + @WithCustomMockUser( + username = userId1, + authorities = {"USER"}) + public void updateEndorsement_user_whenRequestValid_shouldUpdateEndorsement() throws Exception { + Skill skill = createAndSaveSkill(SKILL_NAME); + Endorsement existingEndorsement = + createAndSaveEndorsement(skill, userId2, userId1, INITIAL_MESSAGE); + + UpdateEndorsementViewModel updateEndorsementViewModel = createRequestModel(NEW_MESSAGE); + String updateBody = objectMapper.writeValueAsString(updateEndorsementViewModel); + + MvcResult result = performPatchRequest(createUrl(existingEndorsement.getId()), updateBody); + + assertThat(result.getResponse().getStatus()).isEqualTo(200); + EndorsementViewModel actualEndorsement = extractEndorsementFromResult(result); + + existingEndorsement.setMessage(updateEndorsementViewModel.getMessage()); + EndorsementViewModel expectedEndorsement = + createEndorsementViewModel(existingEndorsement, rdsService); + assertIsEqual(actualEndorsement, expectedEndorsement); + + Endorsement dbEndorsement = + endorsementRepository.findById(existingEndorsement.getId()).orElseThrow(); + assertThat(dbEndorsement.getMessage()).isEqualTo(updateEndorsementViewModel.getMessage()); + } + + @Test + @DisplayName("Endorsement does not exist, should return endorsement not found") + @WithCustomMockUser( + username = userId1, + authorities = {"USER"}) + public void updateEndorsement_whenEndorsementIdDoesNotExist_shouldReturnNotFound() + throws Exception { + Integer nonExistentEndorsementId = 999; + + UpdateEndorsementViewModel requestModel = createRequestModel(NEW_MESSAGE); + String updateBody = objectMapper.writeValueAsString(requestModel); + + MvcResult result = performPatchRequest(createUrl(nonExistentEndorsementId), updateBody); + assertThat(result.getResponse().getStatus()).isEqualTo(404); + assertThat(result.getResponse().getContentAsString()) + .contains(ExceptionMessages.ENDORSEMENT_NOT_FOUND); + } + + @Test + @Disabled + @DisplayName("when user is not the endorser, should not update endorsement") + @WithCustomMockUser( + username = userId1, + authorities = {"USER"}) + public void updateEndorsement_othersEndorsement_shouldUNotUpdateEndorsement() throws Exception { + Skill skill = createAndSaveSkill(SKILL_NAME); + Endorsement existingEndorsement = + createAndSaveEndorsement(skill, userId2, superUserId, INITIAL_MESSAGE); + + UpdateEndorsementViewModel updateEndorsementViewModel = createRequestModel(NEW_MESSAGE); + String updateBody = objectMapper.writeValueAsString(updateEndorsementViewModel); + + MvcResult result = performPatchRequest(createUrl(existingEndorsement.getId()), updateBody); + + assertThat(result.getResponse().getStatus()).isEqualTo(403); + assertThat(result.getResponse().getContentAsString()) + .contains(ExceptionMessages.UNAUTHORIZED_ENDORSEMENT_UPDATE); + + Endorsement dbEndorsement = + endorsementRepository.findById(existingEndorsement.getId()).orElseThrow(); + assertThat(dbEndorsement).usingRecursiveComparison().isEqualTo(existingEndorsement); + } + + @Test + @Disabled + @DisplayName("Message is empty string, request is not valid") + @WithCustomMockUser( + username = userId1, + authorities = {"USER"}) + public void updateEndorsement_whenMessageIsValidAndEmpty_shouldReturnBadRequest() + throws Exception { + Skill skill = createAndSaveSkill(SKILL_NAME); + Endorsement existingEndorsement = + createAndSaveEndorsement(skill, userId2, userId1, INITIAL_MESSAGE); + + UpdateEndorsementViewModel requestModel = createRequestModel(""); + String updateBody = objectMapper.writeValueAsString(requestModel); + + MvcResult result = performPatchRequest(createUrl(existingEndorsement.getId()), updateBody); + assertThat(result.getResponse().getStatus()).isEqualTo(400); + assertThat(result.getResponse().getContentAsString()) + .contains(ExceptionMessages.ENDORSEMENT_MESSAGE_EMPTY); + } + + @Test + @Disabled + @DisplayName("RdsService fails to get 'endorser' details, should return 404") + @WithCustomMockUser( + username = "non-existent-endorser-id", + authorities = {"USER"}) + public void updateEndorsement_whenRdsServiceFailsForEndorserDetails_shouldReturn404() + throws Exception { + Skill skill = createAndSaveSkill(SKILL_NAME); + String endorserId = "non-existent-endorser-id"; + Endorsement existingEndorsement = + createAndSaveEndorsement(skill, userId2, endorserId, INITIAL_MESSAGE); + + UpdateEndorsementViewModel requestModel = createRequestModel(NEW_MESSAGE); + String updateBody = objectMapper.writeValueAsString(requestModel); + + when(rdsService.getUserDetails(endorserId)) + .thenThrow(new UserNotFoundException(ExceptionMessages.USER_NOT_FOUND)); + + MvcResult result = performPatchRequest(createUrl(existingEndorsement.getId()), updateBody); + assertThat(result.getResponse().getStatus()).isEqualTo(404); + assertThat(result.getResponse().getContentAsString()) + .contains(ExceptionMessages.USER_NOT_FOUND); + + Endorsement dbEndorsement = + endorsementRepository.findById(existingEndorsement.getId()).orElseThrow(); + assertThat(dbEndorsement).usingRecursiveComparison().isEqualTo(existingEndorsement); + } + + @Test + @Disabled + @DisplayName("RdsService fails to get 'endorse' details, should return 404") + @WithCustomMockUser( + username = userId1, + authorities = {"USER"}) + public void updateEndorsement_whenRdsServiceFailsForEndorseDetails_shouldReturn404() + throws Exception { + Skill skill = createAndSaveSkill(SKILL_NAME); + String endorseId = "non-existent-endorse-id"; + Endorsement existingEndorsement = + createAndSaveEndorsement(skill, endorseId, userId1, INITIAL_MESSAGE); + + UpdateEndorsementViewModel requestModel = createRequestModel(NEW_MESSAGE); + String updateBody = objectMapper.writeValueAsString(requestModel); + + when(rdsService.getUserDetails(endorseId)) + .thenThrow(new UserNotFoundException(ExceptionMessages.USER_NOT_FOUND)); + + MvcResult result = performPatchRequest(createUrl(existingEndorsement.getId()), updateBody); + assertThat(result.getResponse().getStatus()).isEqualTo(404); + assertThat(result.getResponse().getContentAsString()) + .contains(ExceptionMessages.USER_NOT_FOUND); + + Endorsement dbEndorsement = + endorsementRepository.findById(existingEndorsement.getId()).orElseThrow(); + assertThat(dbEndorsement).usingRecursiveComparison().isEqualTo(existingEndorsement); + } + + @Test + @DisplayName("Message is null, request is not valid") + @WithCustomMockUser( + username = userId1, + authorities = {"USER"}) + public void updateEndorsement_whenRequestBodyMessageIsNull_shouldReturnBadRequest() + throws Exception { + Skill skill = createAndSaveSkill(SKILL_NAME); + Endorsement existingEndorsement = + createAndSaveEndorsement(skill, userId2, userId1, INITIAL_MESSAGE); + + UpdateEndorsementViewModel requestModel = createRequestModel(null); + String updateBody = objectMapper.writeValueAsString(requestModel); + + MvcResult result = performPatchRequest(createUrl(existingEndorsement.getId()), updateBody); + assertThat(result.getResponse().getStatus()).isEqualTo(400); + assertThat(result.getResponse().getContentAsString()) + .contains(ExceptionMessages.ENDORSEMENT_MESSAGE_EMPTY); + } + + @Test + @DisplayName("Message field is missing, request is not valid") + @WithCustomMockUser( + username = userId1, + authorities = {"USER"}) + public void updateEndorsement_whenRequestBodyMessageFieldIsMissing_shouldReturnBadRequest() + throws Exception { + Skill skill = createAndSaveSkill(SKILL_NAME); + Endorsement existingEndorsement = + createAndSaveEndorsement(skill, userId2, userId1, INITIAL_MESSAGE); + + String requestBody = "{}"; + MvcResult result = performPatchRequest(createUrl(existingEndorsement.getId()), requestBody); + assertThat(result.getResponse().getStatus()).isEqualTo(400); + assertThat(result.getResponse().getContentAsString()) + .contains(ExceptionMessages.ENDORSEMENT_MESSAGE_EMPTY); + } + + @Test + @DisplayName("User is unauthorized, should return 403") + public void updateEndorsement_whenUserIsUnauthorized_shouldReturn403() throws Exception { + Skill skill = createAndSaveSkill(SKILL_NAME); + Endorsement existingEndorsement = + createAndSaveEndorsement(skill, userId2, userId1, INITIAL_MESSAGE); + + UpdateEndorsementViewModel requestModel = createRequestModel(NEW_MESSAGE); + String updateBody = objectMapper.writeValueAsString(requestModel); + Map.Entry cookie = + RestAPIHelper.getGuestUserCookie().entrySet().iterator().next(); + MvcResult result = + mockMvc + .perform( + MockMvcRequestBuilders.patch(createUrl(existingEndorsement.getId())) + .contentType(MediaType.APPLICATION_JSON) + .content(updateBody) + .cookie(new Cookie(cookie.getKey(), cookie.getValue()))) + .andReturn(); + + assertThat(result.getResponse().getStatus()).isEqualTo(403); + } + + @Test + @DisplayName("User is unauthorized, should return 401") + public void updateEndorsement_whenUserIsUnauthenticated_shouldReturn401() throws Exception { + Skill skill = createAndSaveSkill(SKILL_NAME); + Endorsement existingEndorsement = + createAndSaveEndorsement(skill, userId2, userId1, INITIAL_MESSAGE); + + UpdateEndorsementViewModel requestModel = createRequestModel(NEW_MESSAGE); + String updateBody = objectMapper.writeValueAsString(requestModel); + + MvcResult result = performPatchRequest(createUrl(existingEndorsement.getId()), updateBody); + assertThat(result.getResponse().getStatus()).isEqualTo(401); + } +} From d688c909d115a37f96707604c3a05bb767db7396 Mon Sep 17 00:00:00 2001 From: Shyam Vishwakarma Date: Fri, 23 May 2025 01:54:13 +0530 Subject: [PATCH 3/9] fix: update cookie name to be consistent with RESTApiHelper --- skill-tree/src/main/resources/application-test.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skill-tree/src/main/resources/application-test.properties b/skill-tree/src/main/resources/application-test.properties index 55ca50d8..5a1e9459 100644 --- a/skill-tree/src/main/resources/application-test.properties +++ b/skill-tree/src/main/resources/application-test.properties @@ -1,4 +1,4 @@ -cookieName=rds-session-v2-development +cookieName=rds-session-v2 test.db.mysql-image=mysql:8.1.0 spring.flyway.enabled=true spring.flyway.locations=classpath:db/migrations From 66be30e679498c295044a8f11a231861411978db Mon Sep 17 00:00:00 2001 From: Shyam Vishwakarma Date: Fri, 23 May 2025 02:02:02 +0530 Subject: [PATCH 4/9] refactor: use exception msg defined in constants instead of hardcoded string --- .../skilltree/services/external/RdsServiceImplementation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skill-tree/src/main/java/com/RDS/skilltree/services/external/RdsServiceImplementation.java b/skill-tree/src/main/java/com/RDS/skilltree/services/external/RdsServiceImplementation.java index 8bbb98db..99ed4f5e 100644 --- a/skill-tree/src/main/java/com/RDS/skilltree/services/external/RdsServiceImplementation.java +++ b/skill-tree/src/main/java/com/RDS/skilltree/services/external/RdsServiceImplementation.java @@ -2,6 +2,7 @@ import com.RDS.skilltree.dtos.RdsGetUserDetailsResDto; import com.RDS.skilltree.exceptions.UserNotFoundException; +import com.RDS.skilltree.utils.Constants.ExceptionMessages; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,7 +27,7 @@ public RdsGetUserDetailsResDto getUserDetails(String id) { return restTemplate.getForObject(url, RdsGetUserDetailsResDto.class); } catch (RestClientException error) { log.error("Error calling url {}, error: {}", url, error.getMessage()); - throw new UserNotFoundException("Error getting user details"); + throw new UserNotFoundException(ExceptionMessages.USER_NOT_FOUND); } } } From 8492174e664f3719479d1daa3c5c8769972afee0 Mon Sep 17 00:00:00 2001 From: Shyam Vishwakarma Date: Fri, 23 May 2025 02:52:12 +0530 Subject: [PATCH 5/9] fix: add messages for disabled tests --- .../skills/UpdateEndorsementsIntegrationTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java b/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java index 262ae730..550dd926 100644 --- a/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java +++ b/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java @@ -194,7 +194,7 @@ public void updateEndorsement_whenEndorsementIdDoesNotExist_shouldReturnNotFound } @Test - @Disabled + @Disabled("Fails due to authorization bug tracked in #206 – re-enable once fixed") @DisplayName("when user is not the endorser, should not update endorsement") @WithCustomMockUser( username = userId1, @@ -219,7 +219,7 @@ public void updateEndorsement_othersEndorsement_shouldUNotUpdateEndorsement() th } @Test - @Disabled + @Disabled("Fails due to validation bug tracked in #206 – re-enable once fixed") @DisplayName("Message is empty string, request is not valid") @WithCustomMockUser( username = userId1, @@ -240,7 +240,7 @@ public void updateEndorsement_whenMessageIsValidAndEmpty_shouldReturnBadRequest( } @Test - @Disabled + @Disabled("Fails due to bug tracked in #206 – re-enable once fixed") @DisplayName("RdsService fails to get 'endorser' details, should return 404") @WithCustomMockUser( username = "non-existent-endorser-id", @@ -269,7 +269,7 @@ public void updateEndorsement_whenRdsServiceFailsForEndorserDetails_shouldReturn } @Test - @Disabled + @Disabled("Fails due to bug tracked in #206 – re-enable once fixed") @DisplayName("RdsService fails to get 'endorse' details, should return 404") @WithCustomMockUser( username = userId1, From 85e13bcc1035267b19204b921c26dc98311315e2 Mon Sep 17 00:00:00 2001 From: Shyam Vishwakarma Date: Fri, 23 May 2025 17:49:47 +0530 Subject: [PATCH 6/9] fix: update test name for more clarity --- .../integration/skills/UpdateEndorsementsIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java b/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java index 550dd926..7b7f24e0 100644 --- a/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java +++ b/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java @@ -359,7 +359,7 @@ public void updateEndorsement_whenUserIsUnauthorized_shouldReturn403() throws Ex } @Test - @DisplayName("User is unauthorized, should return 401") + @DisplayName("User is unauthenticated, should return 401") public void updateEndorsement_whenUserIsUnauthenticated_shouldReturn401() throws Exception { Skill skill = createAndSaveSkill(SKILL_NAME); Endorsement existingEndorsement = From 4e6d8e8d17973d2c70b9c1aca55259db08716e7c Mon Sep 17 00:00:00 2001 From: Shyam Vishwakarma Date: Thu, 29 May 2025 21:31:12 +0530 Subject: [PATCH 7/9] fix: fix typo in test name --- .../integration/skills/UpdateEndorsementsIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java b/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java index 7b7f24e0..33867582 100644 --- a/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java +++ b/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java @@ -199,7 +199,7 @@ public void updateEndorsement_whenEndorsementIdDoesNotExist_shouldReturnNotFound @WithCustomMockUser( username = userId1, authorities = {"USER"}) - public void updateEndorsement_othersEndorsement_shouldUNotUpdateEndorsement() throws Exception { + public void updateEndorsement_othersEndorsement_shouldNotUpdateEndorsement() throws Exception { Skill skill = createAndSaveSkill(SKILL_NAME); Endorsement existingEndorsement = createAndSaveEndorsement(skill, userId2, superUserId, INITIAL_MESSAGE); From 78cf2d4615c06693ad468e594aa36e32729c3242 Mon Sep 17 00:00:00 2001 From: Shyam Vishwakarma Date: Fri, 30 May 2025 19:46:40 +0530 Subject: [PATCH 8/9] fix: add access denied, invalid-token excetpton msg in constants --- .../RDS/skilltree/exceptions/GlobalExceptionHandler.java | 6 ++---- .../src/main/java/com/RDS/skilltree/utils/Constants.java | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/skill-tree/src/main/java/com/RDS/skilltree/exceptions/GlobalExceptionHandler.java b/skill-tree/src/main/java/com/RDS/skilltree/exceptions/GlobalExceptionHandler.java index 3af16875..447f65fc 100644 --- a/skill-tree/src/main/java/com/RDS/skilltree/exceptions/GlobalExceptionHandler.java +++ b/skill-tree/src/main/java/com/RDS/skilltree/exceptions/GlobalExceptionHandler.java @@ -1,5 +1,6 @@ package com.RDS.skilltree.exceptions; +import com.RDS.skilltree.utils.Constants.ExceptionMessages; import com.RDS.skilltree.utils.GenericResponse; import jakarta.validation.ConstraintViolationException; import java.util.List; @@ -27,10 +28,7 @@ public ResponseEntity> handleNoEntityException(NoEntityE @ExceptionHandler({AuthenticationException.class, InsufficientAuthenticationException.class}) public ResponseEntity> handleInvalidBearerTokenException(Exception ex) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED) - .body( - new GenericResponse<>( - null, - "The access token provided is expired, revoked, malformed, or invalid for other reasons.")); + .body(new GenericResponse<>(ExceptionMessages.INVALID_ACCESS_TOKEN)); } @ExceptionHandler({AccessDeniedException.class}) diff --git a/skill-tree/src/main/java/com/RDS/skilltree/utils/Constants.java b/skill-tree/src/main/java/com/RDS/skilltree/utils/Constants.java index 2e135f18..26e61621 100644 --- a/skill-tree/src/main/java/com/RDS/skilltree/utils/Constants.java +++ b/skill-tree/src/main/java/com/RDS/skilltree/utils/Constants.java @@ -12,5 +12,8 @@ public static final class ExceptionMessages { public static final String USER_NOT_FOUND = "Error getting user details"; public static final String UNAUTHORIZED_ENDORSEMENT_UPDATE = "Not authorized to update this endorsement"; + public static final String INVALID_ACCESS_TOKEN = + "The access token provided is expired, revoked, malformed, or invalid for other reasons."; + public static final String ACCESS_DENIED = "Access Denied"; } } From 92b726f8375c307d21c729cf013aea4cb9baf4c9 Mon Sep 17 00:00:00 2001 From: Shyam Vishwakarma Date: Fri, 30 May 2025 19:47:28 +0530 Subject: [PATCH 9/9] fix: add check for exception msgs in tests, remove a redundant test case --- .../UpdateEndorsementsIntegrationTest.java | 25 +++---------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java b/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java index 33867582..94e1cd77 100644 --- a/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java +++ b/skill-tree/src/test/java/com/RDS/skilltree/integration/skills/UpdateEndorsementsIntegrationTest.java @@ -32,7 +32,6 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import utils.RestAPIHelper; import utils.TestDataHelper; import utils.WithCustomMockUser; @@ -105,7 +104,6 @@ private MvcResult performPatchRequest(String url, String requestBody) throws Exc MockMvcRequestBuilders.patch(url) .contentType(MediaType.APPLICATION_JSON) .content(requestBody)) - .andDo(MockMvcResultHandlers.print()) .andReturn(); } @@ -297,26 +295,6 @@ public void updateEndorsement_whenRdsServiceFailsForEndorseDetails_shouldReturn4 assertThat(dbEndorsement).usingRecursiveComparison().isEqualTo(existingEndorsement); } - @Test - @DisplayName("Message is null, request is not valid") - @WithCustomMockUser( - username = userId1, - authorities = {"USER"}) - public void updateEndorsement_whenRequestBodyMessageIsNull_shouldReturnBadRequest() - throws Exception { - Skill skill = createAndSaveSkill(SKILL_NAME); - Endorsement existingEndorsement = - createAndSaveEndorsement(skill, userId2, userId1, INITIAL_MESSAGE); - - UpdateEndorsementViewModel requestModel = createRequestModel(null); - String updateBody = objectMapper.writeValueAsString(requestModel); - - MvcResult result = performPatchRequest(createUrl(existingEndorsement.getId()), updateBody); - assertThat(result.getResponse().getStatus()).isEqualTo(400); - assertThat(result.getResponse().getContentAsString()) - .contains(ExceptionMessages.ENDORSEMENT_MESSAGE_EMPTY); - } - @Test @DisplayName("Message field is missing, request is not valid") @WithCustomMockUser( @@ -356,6 +334,7 @@ public void updateEndorsement_whenUserIsUnauthorized_shouldReturn403() throws Ex .andReturn(); assertThat(result.getResponse().getStatus()).isEqualTo(403); + assertThat(result.getResponse().getContentAsString()).contains(ExceptionMessages.ACCESS_DENIED); } @Test @@ -370,5 +349,7 @@ public void updateEndorsement_whenUserIsUnauthenticated_shouldReturn401() throws MvcResult result = performPatchRequest(createUrl(existingEndorsement.getId()), updateBody); assertThat(result.getResponse().getStatus()).isEqualTo(401); + assertThat(result.getResponse().getContentAsString()) + .contains(ExceptionMessages.INVALID_ACCESS_TOKEN); } }