From 7e27cc5ed5900c17d5f0a68b9df258ca7f383608 Mon Sep 17 00:00:00 2001 From: Shyam Vishwakarma <144812100+Shyam-Vishwakarma@users.noreply.github.com> Date: Wed, 27 Nov 2024 23:26:26 +0530 Subject: [PATCH] Add integration tests for GET /v1/skills/requests route (#169) * add integration tests for GET v1/skills, add test DB configuration * fix format violation * Update test configuration to create schema using Flyway * Add integration test for v1/skills/requests route * Add custom result matcher for mockMvc responses * Add security config for test environment to mock logged in users * Add Use of CustomMockUser instead of AuthCookie * Add spring-security test dependency --- skill-tree/pom.xml | 5 + .../resources/application-test.properties | 6 +- .../GetAllSkillRequestIntegrationTest.java | 285 ++++++++++++++++++ .../skills/GetAllSkillsIntegrationTest.java | 34 +-- .../test/java/utils/CustomResultMatchers.java | 99 ++++++ .../utils/CustomSecurityContextFactory.java | 39 +++ .../test/java/utils/WithCustomMockUser.java | 13 + 7 files changed, 462 insertions(+), 19 deletions(-) create mode 100644 skill-tree/src/test/java/com/RDS/skilltree/skills/GetAllSkillRequestIntegrationTest.java create mode 100644 skill-tree/src/test/java/utils/CustomResultMatchers.java create mode 100644 skill-tree/src/test/java/utils/CustomSecurityContextFactory.java create mode 100644 skill-tree/src/test/java/utils/WithCustomMockUser.java diff --git a/skill-tree/pom.xml b/skill-tree/pom.xml index ac132714..c840309b 100644 --- a/skill-tree/pom.xml +++ b/skill-tree/pom.xml @@ -90,6 +90,11 @@ org.springframework.boot spring-boot-starter-security + + org.springframework.security + spring-security-test + test + diff --git a/skill-tree/src/main/resources/application-test.properties b/skill-tree/src/main/resources/application-test.properties index 02c453f3..5d9cfc71 100644 --- a/skill-tree/src/main/resources/application-test.properties +++ b/skill-tree/src/main/resources/application-test.properties @@ -3,6 +3,10 @@ cookieName=rds-session-v2-development spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/skilltreetestdb spring.datasource.username=${MYSQL_DB_USERNAME} spring.datasource.password=${MYSQL_DB_PASSWORD} + spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver -spring.jpa.hibernate.ddl-auto=create-drop + +spring.flyway.enabled=true +spring.flyway.locations=classpath:db/migrations + spring.jpa.show-sql=true diff --git a/skill-tree/src/test/java/com/RDS/skilltree/skills/GetAllSkillRequestIntegrationTest.java b/skill-tree/src/test/java/com/RDS/skilltree/skills/GetAllSkillRequestIntegrationTest.java new file mode 100644 index 00000000..90dbcd91 --- /dev/null +++ b/skill-tree/src/test/java/com/RDS/skilltree/skills/GetAllSkillRequestIntegrationTest.java @@ -0,0 +1,285 @@ +package com.RDS.skilltree.skills; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.RDS.skilltree.dtos.RdsGetUserDetailsResDto; +import com.RDS.skilltree.enums.SkillTypeEnum; +import com.RDS.skilltree.enums.UserSkillStatusEnum; +import com.RDS.skilltree.models.Endorsement; +import com.RDS.skilltree.models.Skill; +import com.RDS.skilltree.models.UserSkills; +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.JWTUtils; +import com.RDS.skilltree.viewmodels.RdsUserViewModel; +import io.jsonwebtoken.Claims; +import jakarta.servlet.http.Cookie; +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.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import utils.CustomResultMatchers; +import utils.WithCustomMockUser; + +@SpringBootTest +@AutoConfigureMockMvc +@ActiveProfiles("test") +public class GetAllSkillRequestIntegrationTest { + @Autowired private MockMvc mockMvc; + + @Autowired private UserSkillRepository userSkillRepository; + + @Autowired private EndorsementRepository endorsementRepository; + + @MockBean private RdsService rdsService; + + @Autowired private SkillRepository skillRepository; + + @MockBean private JWTUtils jwtUtils; + + private final String route = "/v1/skills/requests"; + + @BeforeEach + void setUp() { + // Clean up repositories + skillRepository.deleteAll(); + endorsementRepository.deleteAll(); + userSkillRepository.deleteAll(); + + // Setup super-user detail + RdsUserViewModel superUser = new RdsUserViewModel(); + superUser.setId("super-user-id"); + RdsUserViewModel.Roles roles = new RdsUserViewModel.Roles(); + roles.setSuper_user(true); + superUser.setRoles(roles); + + RdsGetUserDetailsResDto superUserDetails = new RdsGetUserDetailsResDto(); + superUserDetails.setUser(superUser); + + // Setup normal-users detail + RdsUserViewModel normalUser = new RdsUserViewModel(); + normalUser.setId("user-id"); + RdsUserViewModel.Roles normalUserRoles = new RdsUserViewModel.Roles(); + normalUserRoles.setSuper_user(false); + normalUser.setRoles(normalUserRoles); + + RdsGetUserDetailsResDto normalUserDetails = new RdsGetUserDetailsResDto(); + normalUserDetails.setUser(normalUser); + + RdsUserViewModel normalUser2 = new RdsUserViewModel(); + normalUser2.setId("user-id-2"); + normalUser2.setRoles(normalUserRoles); + RdsGetUserDetailsResDto normalUser2Details = new RdsGetUserDetailsResDto(); + normalUser2Details.setUser(normalUser2); + + // Setup mock skills + Skill skill1 = new Skill(); + skill1.setName("Java"); + skill1.setType(SkillTypeEnum.ATOMIC); + skill1.setCreatedBy("super-user-id"); + + Skill skill2 = new Skill(); + skill2.setName("Springboot"); + skill2.setType(SkillTypeEnum.ATOMIC); + skill2.setCreatedBy("super-user-id"); + + skillRepository.save(skill1); + skillRepository.save(skill2); + + // Setup mock user-skills + UserSkills userSkills1 = new UserSkills(); + userSkills1.setSkill(skill1); + userSkills1.setUserId("user-id"); + userSkills1.setStatus(UserSkillStatusEnum.PENDING); + + UserSkills userSkills2 = new UserSkills(); + userSkills2.setSkill(skill2); + userSkills2.setUserId("user-id"); + userSkills2.setStatus(UserSkillStatusEnum.APPROVED); + + UserSkills userSkills3 = new UserSkills(); + userSkills3.setSkill(skill2); + userSkills3.setUserId("user-id-2"); + userSkills3.setStatus(UserSkillStatusEnum.PENDING); + + userSkillRepository.save(userSkills1); + userSkillRepository.save(userSkills2); + userSkillRepository.save(userSkills3); + + // Setup mock endorsements + Endorsement endorsement1 = new Endorsement(); + endorsement1.setId(1); + endorsement1.setEndorserId("super-user-id"); + endorsement1.setEndorseId("user-id"); + endorsement1.setSkill(skill1); + endorsement1.setMessage("endorsement message"); + + Endorsement endorsement2 = new Endorsement(); + endorsement2.setId(3); + endorsement2.setEndorserId("user-id-2"); + endorsement2.setEndorseId("user-id"); + endorsement2.setSkill(skill2); + endorsement2.setMessage("skill2 for user-id"); + + Endorsement endorsement3 = new Endorsement(); + endorsement3.setId(4); + endorsement3.setEndorserId("super-user-id"); + endorsement3.setEndorseId("user-id-2"); + endorsement3.setSkill(skill2); + endorsement3.setMessage("skill2 for user-id-2"); + + endorsementRepository.save(endorsement1); + endorsementRepository.save(endorsement2); + endorsementRepository.save(endorsement3); + + // Setup RDS service mock responses + when(rdsService.getUserDetails("super-user-id")).thenReturn(superUserDetails); + when(rdsService.getUserDetails("user-id-2")).thenReturn(normalUser2Details); + when(rdsService.getUserDetails("user-id")).thenReturn(normalUserDetails); + + // Mock JWTUtils to bypass actual JWT verification + Claims mockClaims = mock(Claims.class); + when(mockClaims.get("userId", String.class)).thenReturn("super-user-id"); + when(jwtUtils.validateToken(anyString())).thenReturn(mockClaims); + } + + @Test + @DisplayName("Happy flow for SuperUser - should return all requests") + @WithCustomMockUser( + username = "super-user-id", + authorities = {"SUPERUSER"}) + public void getAllRequests_asSuperUser_shouldReturnAllRequests() throws Exception { + mockMvc + .perform(MockMvcRequestBuilders.get(route).contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultHandlers.print()) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(CustomResultMatchers.hasSkillRequest("Java", "user-id", "PENDING")) + .andExpect( + CustomResultMatchers.hasEndorsement( + "Java", "user-id", "super-user-id", "endorsement message")) + .andExpect(CustomResultMatchers.hasSkillRequest("Springboot", "user-id", "APPROVED")) + .andExpect( + CustomResultMatchers.hasEndorsement( + "Springboot", "user-id", "user-id-2", "skill2 for user-id")) + .andExpect(CustomResultMatchers.hasSkillRequest("Springboot", "user-id-2", "PENDING")) + .andExpect( + CustomResultMatchers.hasEndorsement( + "Springboot", "user-id-2", "super-user-id", "skill2 for user-id-2")) + .andExpect(CustomResultMatchers.hasUser("user-id", " ")) + .andExpect(CustomResultMatchers.hasUser("user-id-2", " ")) + .andExpect(CustomResultMatchers.hasUser("super-user-id", " ")); + } + + @Test + @DisplayName("Happy flow for normal user - Get all requests where user is endorser") + @WithCustomMockUser( + username = "user-id-2", + authorities = {"USER"}) + public void getAllRequests_asNormalUser_shouldReturnAllRequestsByEndorser() throws Exception { + mockMvc + .perform(MockMvcRequestBuilders.get(route).contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultHandlers.print()) + .andExpect(CustomResultMatchers.hasSkillRequest("Springboot", "user-id", "APPROVED")) + .andExpect( + CustomResultMatchers.hasEndorsement( + "Springboot", "user-id", "user-id-2", "skill2 for user-id")) + .andExpect(CustomResultMatchers.hasUser("user-id", " ")) + .andExpect(CustomResultMatchers.hasUser("user-id-2", " ")); + } + + @Test + @DisplayName("Filter requests by status - should return filtered requests") + @WithCustomMockUser( + username = "super-user-id", + authorities = {"SUPERUSER"}) + public void getAllRequests_ByStatus_ShouldReturnFilteredRequests() throws Exception { + mockMvc + .perform( + MockMvcRequestBuilders.get(route + "?status=APPROVED") + .contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultHandlers.print()) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(CustomResultMatchers.hasSkillRequest("Springboot", "user-id", "APPROVED")) + .andExpect( + CustomResultMatchers.hasEndorsement( + "Springboot", "user-id", "user-id-2", "skill2 for user-id")) + .andExpect(CustomResultMatchers.hasUser("user-id", " ")) + .andExpect(CustomResultMatchers.hasUser("user-id-2", " ")); + } + + @Test + @DisplayName("If no skill Requests endorsed by user then return empty lists") + @WithCustomMockUser( + username = "user-id", + authorities = {"USER"}) + public void noSkillRequestsEndorsedByUser_ShouldReturnEmptyLists() throws Exception { + mockMvc + .perform(MockMvcRequestBuilders.get(route).contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultHandlers.print()) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.requests").isEmpty()) + .andExpect(MockMvcResultMatchers.jsonPath("$.users").isEmpty()); + } + + @Test + @DisplayName("If no matching skill requests by status then return empty lists") + @WithCustomMockUser( + username = "user-id", + authorities = {"USER"}) + public void noMatchingRequestsByStatus_ShouldReturnEmptyLists() throws Exception { + mockMvc + .perform( + MockMvcRequestBuilders.get(route + "?status=REJECTED") + .contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultHandlers.print()) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.requests").isEmpty()) + .andExpect(MockMvcResultMatchers.jsonPath("$.users").isEmpty()); + } + + @Test + @DisplayName("If no skill requests in DB - return empty lists") + @WithCustomMockUser( + username = "super-user-id", + authorities = {"SUPERUSER"}) + public void getAllRequests_NoData_ShouldReturnEmptyLists() throws Exception { + skillRepository.deleteAll(); + endorsementRepository.deleteAll(); + userSkillRepository.deleteAll(); + + mockMvc + .perform(MockMvcRequestBuilders.get(route).contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultHandlers.print()) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.requests").isEmpty()) + .andExpect(MockMvcResultMatchers.jsonPath("$.users").isEmpty()); + } + + @Test + @DisplayName("if invalid cookie, return 401") + public void ifInvalidCoolie_ShouldReturnUnauthorized() throws Exception { + Cookie authCookie = + new Cookie( + "cookie", + "eyJhbGciOiJSUzI1NiIsInR5cCI.eyJ1c2VySWQiOiI2N2lSeXJOTWQ.E-EtcPOj7Ca5l8JuE0hwky0rRikYSNZBvC"); + + mockMvc + .perform( + MockMvcRequestBuilders.get(route) + .cookie(authCookie) + .contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultHandlers.print()) + .andExpect(MockMvcResultMatchers.status().isUnauthorized()); + } +} diff --git a/skill-tree/src/test/java/com/RDS/skilltree/skills/GetAllSkillsIntegrationTest.java b/skill-tree/src/test/java/com/RDS/skilltree/skills/GetAllSkillsIntegrationTest.java index b16ac200..cca60e09 100644 --- a/skill-tree/src/test/java/com/RDS/skilltree/skills/GetAllSkillsIntegrationTest.java +++ b/skill-tree/src/test/java/com/RDS/skilltree/skills/GetAllSkillsIntegrationTest.java @@ -18,6 +18,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import utils.WithCustomMockUser; @SpringBootTest @AutoConfigureMockMvc @@ -30,15 +31,10 @@ public class GetAllSkillsIntegrationTest { @Autowired private MockMvc mockMvc; - private Cookie authCookie; + private final String route = "/v1/skills"; @BeforeEach public void setUp() { - authCookie = - new Cookie( - "rds-session-v2-development", - "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJzOXpRVW00WGJWRXo3eHpSa2FadiIsInJvbGUiOiJzdXBlcl91c2VyIiwiaWF0IjoxNzI4NjY0NjA2LCJleHAiOjE3MzEyNTY2MDZ9.EyOFKrVcbleuTjUGic3GzOzYRDoLU4IShyoboe0MHlvWFOAfU2pchpXLE4NcyvdGUZ_tvoUecHd4kUkR8MkhxnkRNU3HE7N-1c1tFeYXZL0KfScJE9YzDXAl113Hx3eZVvYbhNjNUttbDlH4s_kR6YABC3sdbLGKEiLfmp9VeAs"); - skillRepository.deleteAll(); Skill skill1 = new Skill(); skill1.setName("Java"); @@ -54,14 +50,13 @@ public void setUp() { } @Test + @WithCustomMockUser( + username = "rds-user", + authorities = {"SUPERUSER"}) @DisplayName("happy flow - returns all skills that are in db") public void getAllSkillsHappyFlow() throws Exception { - mockMvc - .perform( - MockMvcRequestBuilders.get("/v1/skills") - .cookie(authCookie) - .accept(MediaType.APPLICATION_JSON)) + .perform(MockMvcRequestBuilders.get(route).accept(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$[0].name").value("Java")) .andExpect(MockMvcResultMatchers.jsonPath("$[1].name").value("Springboot")) @@ -70,14 +65,14 @@ public void getAllSkillsHappyFlow() throws Exception { @Test @DisplayName("if no skills available, return empty list") + @WithCustomMockUser( + username = "rds-user", + authorities = {"SUPERUSER"}) public void noSkillsAvailable_shouldReturnEmptyList() throws Exception { skillRepository.deleteAll(); mockMvc - .perform( - MockMvcRequestBuilders.get("/v1/skills") - .cookie(authCookie) - .accept(MediaType.APPLICATION_JSON)) + .perform(MockMvcRequestBuilders.get(route).accept(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$").isEmpty()); } @@ -85,11 +80,14 @@ public void noSkillsAvailable_shouldReturnEmptyList() throws Exception { @Test @DisplayName("if invalid cookie, return 401") public void ifInvalidCoolie_returnUnauthorized() throws Exception { + Cookie authCookie = + new Cookie( + "cookie", + "eyJhbGciOiJSUzI1NiIsInR5cCI.eyJ1c2VySWQiOiI2N2lSeXJOTWQ.E-EtcPOj7Ca5l8JuE0hwky0rRikYSNZBvC"); + mockMvc .perform( - MockMvcRequestBuilders.get("/v1/skills") - .cookie(new Cookie("cookie1", "eyJhbGciOiJSUz.eyJhbGciOiJSUz.EyJhbGciOiJSUz")) - .accept(MediaType.APPLICATION_JSON)) + MockMvcRequestBuilders.get(route).cookie(authCookie).accept(MediaType.APPLICATION_JSON)) .andExpect(MockMvcResultMatchers.status().isUnauthorized()); } } diff --git a/skill-tree/src/test/java/utils/CustomResultMatchers.java b/skill-tree/src/test/java/utils/CustomResultMatchers.java new file mode 100644 index 00000000..5eb85e6c --- /dev/null +++ b/skill-tree/src/test/java/utils/CustomResultMatchers.java @@ -0,0 +1,99 @@ +package utils; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.test.web.servlet.ResultMatcher; + +public class CustomResultMatchers { + + public static ResultMatcher hasSkillRequest(String skillName, String endorseId, String status) { + return result -> { + String json = result.getResponse().getContentAsString(); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode root = objectMapper.readTree(json); + + // Find the request for the given skillName and endorseId + JsonNode matchingSkillRequest = findMatchingSkillRequest(root, skillName, endorseId); + assertThat(matchingSkillRequest).isNotNull().isNotEmpty(); + + assertThat(matchingSkillRequest.get("endorseId").asText()).isEqualTo(endorseId); + assertThat(matchingSkillRequest.get("status").asText()).isEqualTo(status); + }; + } + + public static ResultMatcher hasEndorsement( + String skillName, String endorseId, String endorserId, String message) { + return result -> { + String json = result.getResponse().getContentAsString(); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode root = objectMapper.readTree(json); + + // Find the request for the given skillName and endorseId + JsonNode matchingSkillRequest = findMatchingSkillRequest(root, skillName, endorseId); + assertThat(matchingSkillRequest).isNotNull().isNotEmpty(); + + // Check endorsements + JsonNode endorsements = matchingSkillRequest.get("endorsements"); + assertThat(endorsements).isNotNull().isNotEmpty(); + + // Find matching endorsement by endorserId + JsonNode matchingEndorsement = findByField(endorsements, "endorserId", endorserId); + assertThat(matchingEndorsement).isNotNull(); + + // Assert endorsement details + assertThat(matchingEndorsement.get("endorserId").asText()).isEqualTo(endorserId); + assertThat(matchingEndorsement.get("message").asText()).isEqualTo(message); + }; + } + + public static ResultMatcher hasUser(String userId, String name) { + return result -> { + String json = result.getResponse().getContentAsString(); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode root = objectMapper.readTree(json); + + JsonNode users = root.get("users"); + assertThat(users).isNotNull().isNotEmpty(); + + // Find user by userId + JsonNode matchingUser = findByField(users, "id", userId); + assertThat(matchingUser).isNotNull(); + + // Assert user details + assertThat(matchingUser.get("id").asText()).isEqualTo(userId); + assertThat(matchingUser.get("name").asText()).isEqualTo(name); + }; + } + + private static JsonNode findByField(JsonNode array, String fieldName, String value) { + for (JsonNode node : array) { + if (node.has(fieldName) && node.get(fieldName).asText().equals(value)) { + return node; + } + } + return null; + } + + private static JsonNode findMatchingSkillRequest( + JsonNode root, String skillName, String endorseId) { + JsonNode requests = root.get("requests"); + assertThat(requests).isNotNull().isNotEmpty(); + + return findBySkillAndEndorseId(requests, skillName, endorseId); + } + + private static JsonNode findBySkillAndEndorseId( + JsonNode array, String skillName, String endorseId) { + for (JsonNode node : array) { + if (node.has("skillName") + && node.get("skillName").asText().equals(skillName) + && node.has("endorseId") + && node.get("endorseId").asText().equals(endorseId)) { + return node; + } + } + return null; + } +} diff --git a/skill-tree/src/test/java/utils/CustomSecurityContextFactory.java b/skill-tree/src/test/java/utils/CustomSecurityContextFactory.java new file mode 100644 index 00000000..bcb98cac --- /dev/null +++ b/skill-tree/src/test/java/utils/CustomSecurityContextFactory.java @@ -0,0 +1,39 @@ +package utils; + +import com.RDS.skilltree.enums.UserRoleEnum; +import com.RDS.skilltree.models.JwtUser; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.test.context.support.WithSecurityContextFactory; + +public class CustomSecurityContextFactory + implements WithSecurityContextFactory { + @Override + public SecurityContext createSecurityContext(WithCustomMockUser customMockUser) { + SecurityContext context = SecurityContextHolder.createEmptyContext(); + + List roles = + Arrays.stream(customMockUser.authorities()).map(UserRoleEnum::valueOf).toList(); + UserRoleEnum mainRole = roles.isEmpty() ? UserRoleEnum.USER : roles.get(0); + + // Create jwt user + JwtUser jwtUser = new JwtUser(customMockUser.username(), mainRole); + + // Map roles to Spring Security authorities + List authorities = + roles.stream() + .map(role -> new SimpleGrantedAuthority(role.name())) + .collect(Collectors.toList()); + + // Set JwtUser as the principal in Authentication + Authentication auth = new UsernamePasswordAuthenticationToken(jwtUser, null, authorities); + context.setAuthentication(auth); + return context; + } +} diff --git a/skill-tree/src/test/java/utils/WithCustomMockUser.java b/skill-tree/src/test/java/utils/WithCustomMockUser.java new file mode 100644 index 00000000..c913d2fd --- /dev/null +++ b/skill-tree/src/test/java/utils/WithCustomMockUser.java @@ -0,0 +1,13 @@ +package utils; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import org.springframework.security.test.context.support.WithSecurityContext; + +@Retention(RetentionPolicy.RUNTIME) +@WithSecurityContext(factory = CustomSecurityContextFactory.class) +public @interface WithCustomMockUser { + String username() default "test-user"; + + String[] authorities() default {}; +}