diff --git a/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementController.java b/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementController.java index c9b79cf9..4f7685bb 100644 --- a/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementController.java +++ b/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementController.java @@ -2,6 +2,7 @@ import com.RDS.skilltree.Common.Response.GenericResponse; import jakarta.persistence.EntityNotFoundException; +import jakarta.validation.Valid; import jakarta.validation.constraints.Min; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -46,4 +47,14 @@ public ResponseEntity> getEndorsementById(@PathV return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new GenericResponse(null, message)); } } + + @PostMapping(value="") + public ResponseEntity> postEndorsement(@RequestBody @Valid EndorsementDRO endorsementDRO) { + + EndorsementModel endorsementModel = endorsementService.createEndorsement(endorsementDRO); + if (endorsementModel != null) + return new ResponseEntity<>(new GenericResponse(EndorsementDTO.toDto(endorsementModel), ""), HttpStatus.CREATED); + return new ResponseEntity<>(new GenericResponse(null,"Failed to create endorsement"), HttpStatus.BAD_REQUEST); + + } } diff --git a/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementDRO.java b/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementDRO.java new file mode 100644 index 00000000..a9181244 --- /dev/null +++ b/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementDRO.java @@ -0,0 +1,21 @@ +package com.RDS.skilltree.Endorsement; + +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class EndorsementDRO { + @NotNull(message = "user id cannot be null") + private UUID userId; + @NotNull(message = "skill id cannot be null") + private UUID skillId; + +} diff --git a/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementService.java b/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementService.java index e76d6d4e..678f2509 100644 --- a/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementService.java +++ b/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementService.java @@ -7,4 +7,5 @@ public interface EndorsementService { EndorsementDTO getEndorsementById(UUID id); Page getEndorsements(PageRequest pageRequest); + EndorsementModel createEndorsement(EndorsementDRO endorsementDRO); } diff --git a/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementServiceImpl.java b/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementServiceImpl.java index 4c820b20..80a6cdb2 100644 --- a/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementServiceImpl.java +++ b/skill-tree/src/main/java/com/RDS/skilltree/Endorsement/EndorsementServiceImpl.java @@ -1,5 +1,10 @@ package com.RDS.skilltree.Endorsement; +import com.RDS.skilltree.Exceptions.NoEntityException; +import com.RDS.skilltree.Skill.SkillModel; +import com.RDS.skilltree.Skill.SkillRepository; +import com.RDS.skilltree.User.UserModel; +import com.RDS.skilltree.User.UserRepository; import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; @@ -13,6 +18,8 @@ @RequiredArgsConstructor public class EndorsementServiceImpl implements EndorsementService { private final EndorsementRepository endorsementRepository; + private final UserRepository userRepository; + private final SkillRepository skillRepository; @Override public EndorsementDTO getEndorsementById(UUID id) throws IllegalStateException { @@ -25,4 +32,24 @@ public EndorsementDTO getEndorsementById(UUID id) throws IllegalStateException { public Page getEndorsements(PageRequest pageRequest) { return endorsementRepository.findAll(pageRequest); } + + @Override + public EndorsementModel createEndorsement(EndorsementDRO endorsementDRO) { + UUID userId = endorsementDRO.getUserId(); + UUID skillId = endorsementDRO.getSkillId(); + Optional userOptional = userRepository.findById(userId); + Optional skillOptional = skillRepository.findById(skillId); + if (userOptional.isPresent() && skillOptional.isPresent()) { + EndorsementModel endorsementModel = EndorsementModel.builder() + .user(userOptional.get()) + .skill(skillOptional.get()) + .build(); + + return endorsementRepository.save(endorsementModel); + } else { + if (userOptional.isEmpty()) + throw new NoEntityException("User with id:" + userId + " not found"); + throw new NoEntityException("Skill with id:" + skillId + " not found"); + } + } } \ No newline at end of file diff --git a/skill-tree/src/main/java/com/RDS/skilltree/EndorsementList/EndorsementListDRO.java b/skill-tree/src/main/java/com/RDS/skilltree/EndorsementList/EndorsementListDRO.java new file mode 100644 index 00000000..1bb2ff6d --- /dev/null +++ b/skill-tree/src/main/java/com/RDS/skilltree/EndorsementList/EndorsementListDRO.java @@ -0,0 +1,20 @@ +package com.RDS.skilltree.EndorsementList; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Builder +public class EndorsementListDRO { + private String description; + private UUID endorsementId; + private UUID endorserId; + private EndorsementType type; + +} diff --git a/skill-tree/src/main/java/com/RDS/skilltree/EndorsementList/EndorsementListDTO.java b/skill-tree/src/main/java/com/RDS/skilltree/EndorsementList/EndorsementListDTO.java new file mode 100644 index 00000000..c69d1f26 --- /dev/null +++ b/skill-tree/src/main/java/com/RDS/skilltree/EndorsementList/EndorsementListDTO.java @@ -0,0 +1,19 @@ +package com.RDS.skilltree.EndorsementList; + +import com.RDS.skilltree.User.UserModel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +import java.util.UUID; + +@Builder +@Data +@AllArgsConstructor +public class EndorsementListDTO { + private UUID id; + private String description; + private UserModel endorser; + private EndorsementType type; + +} diff --git a/skill-tree/src/main/java/com/RDS/skilltree/EndorsementList/EndorsementListService.java b/skill-tree/src/main/java/com/RDS/skilltree/EndorsementList/EndorsementListService.java new file mode 100644 index 00000000..43630f2e --- /dev/null +++ b/skill-tree/src/main/java/com/RDS/skilltree/EndorsementList/EndorsementListService.java @@ -0,0 +1,52 @@ +package com.RDS.skilltree.EndorsementList; + +import com.RDS.skilltree.Endorsement.EndorsementModel; +import com.RDS.skilltree.Endorsement.EndorsementRepository; +import com.RDS.skilltree.Exceptions.NoEntityException; +import com.RDS.skilltree.User.UserModel; +import com.RDS.skilltree.User.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; +import java.util.UUID; + +@Service +public class EndorsementListService { + @Autowired + private final EndorsementListRepository endorsementListRepository; + private final EndorsementRepository endorsementRepository; + private final UserRepository userRepository; + + public EndorsementListService(EndorsementListRepository endorsementListRepository, EndorsementRepository endorsementRepository, UserRepository userRepository) { + this.endorsementListRepository = endorsementListRepository; + this.endorsementRepository = endorsementRepository; + this.userRepository = userRepository; + } + + + public EndorsementListModel createEndorsementListEntry(EndorsementListDRO endorsementListDRO) { + EndorsementListModel endorsementListEntry = new EndorsementListModel(); + + UUID endorserId = endorsementListDRO.getEndorserId(); + UUID endorsementId = endorsementListDRO.getEndorsementId(); + Optional endorserOptional = userRepository.findById(endorserId); + Optional endorsementOptional = endorsementRepository.findById(endorsementId); + if (endorserOptional.isPresent() && endorsementOptional.isPresent()) { + + endorsementListEntry.setEndorser(endorserOptional.get()); + endorsementListEntry.setEndorsement(endorsementOptional.get()); + endorsementListEntry.setDescription(endorsementListDRO.getDescription()); + endorsementListEntry.setType(endorsementListDRO.getType()); + endorsementListRepository.save(endorsementListEntry); + return endorsementListEntry; + + } else { + if (endorserOptional.isEmpty()) + throw new NoEntityException("User with id:" + endorserId + " not found"); + throw new NoEntityException("Endorsement with id:" + endorsementId + " not found"); + } + + } + +} diff --git a/skill-tree/src/test/java/com/RDS/skilltree/EndorsementsIntegrationTests.java b/skill-tree/src/test/java/com/RDS/skilltree/EndorsementsIntegrationTests.java index 600681cc..027773c3 100644 --- a/skill-tree/src/test/java/com/RDS/skilltree/EndorsementsIntegrationTests.java +++ b/skill-tree/src/test/java/com/RDS/skilltree/EndorsementsIntegrationTests.java @@ -1,22 +1,64 @@ package com.RDS.skilltree; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.restassured.RestAssured; +import com.RDS.skilltree.Skill.*; +import com.RDS.skilltree.User.*; +import com.RDS.skilltree.Endorsement.*; import io.restassured.response.Response; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.UUID; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.*; -@TestInstance(value = TestInstance.Lifecycle.PER_CLASS) -public class EndorsementsIntegrationTests { +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +public class EndorsementsIntegrationTests extends TestContainerManager { + + private UserRepository userRepository; + private SkillRepository skillRepository; + private final UserService userService; + private final SkillsService skillsService; + private UserDTO user; + private SkillDTO skill; + private EndorsementRepository endorsementRepository; + @Autowired - private ObjectMapper objectMapper; + public EndorsementsIntegrationTests(UserService userService, UserRepository userRepository, SkillsService skillsService, SkillRepository skillRepository, EndorsementRepository endorsementRepository) { + this.userService = userService; + this.userRepository = userRepository; + this.skillsService = skillsService; + this.skillRepository = skillRepository; + this.endorsementRepository = endorsementRepository; + } + + @BeforeEach + private void addData() throws MalformedURLException { + user = userService.createUser(UserDRO.builder() + .role(UserRole.MEMBER) + .rdsUserId("p6Bo61VEClhtVdwW0ihg") + .lastName("Doe") + .firstName("John") + .imageUrl(new URL("https://res.cloudinary.com/realdevsquad/image/upload/v1666193594/profile/p6Bo61VEClhtVdwW0iGH/lezguwdq5bgzawa3.jpg")) + .build()); - @BeforeAll - public void setup() { - RestAssured.baseURI = "http://localhost:8080"; + skill = skillsService.createSkill( + SkillDRO.builder() + .name("Java") + .type(SkillType.ATOMIC) + .createdBy(user.getId()) + .build()); + } + + @AfterEach + private void cleanUp() { + endorsementRepository.deleteAll(); + skillRepository.deleteAll(); + userRepository.deleteAll(); } @Test @@ -113,6 +155,71 @@ public void testAPIReturns400_OnInvalidParameterPassed() { .body("message", equalTo("Invalid endorsementId passed")); } + @Test + @DisplayName("Return 200 on endorsements creation") + public void testAPIReturns201_OnEndorsementCreation() { + UUID userId = user.getId(); + UUID skillId = skill.getId(); + + EndorsementDRO endorsementDRO = new EndorsementDRO(); + endorsementDRO.setUserId(userId); + endorsementDRO.setSkillId(skillId); + Response response = given() + .contentType("application/json") + .body(endorsementDRO) + .post("/v1/endorsements"); + + + response.then() + .statusCode(201) + .contentType("application/json") + .body("data.user.firstName", equalTo("John")) + .body("data.skill.name", equalTo("Java")); + } + + @Test + @DisplayName("Return 400 on endorsements userid null") + public void testAPIReturns400_OnEndorsementCreationUserIdNull() { + + UUID skillId = skill.getId(); + + EndorsementDRO endorsementDRO = new EndorsementDRO(); + + endorsementDRO.setSkillId(skillId); + Response response = given() + .contentType("application/json") + .body(endorsementDRO) + .post("/v1/endorsements"); + + + response.then() + .statusCode(400) + .contentType("application/json") + .body("data", equalTo(null)) + .body("message", equalTo("user id cannot be null")); + } + + @Test + @DisplayName("Return 400 on endorsements skillid null") + public void testAPIReturns400_OnEndorsementCreationSkillIdNull() { + UUID userId = user.getId(); + + EndorsementDRO endorsementDRO = new EndorsementDRO(); + endorsementDRO.setUserId(userId); + + Response response = given() + .contentType("application/json") + .body(endorsementDRO) + .post("/v1/endorsements"); + + + response.then() + .statusCode(400) + .contentType("application/json") + .body("data", equalTo(null)) + .body("message", equalTo("skill id cannot be null")); + } + @Test @Disabled @DisplayName("Return 200 on endorsements updation") @@ -182,4 +289,5 @@ public void testAPIReturn404_OnEndorsementNotFound() { .body("code", equalTo(404)) .body("message", equalTo("Endorsement not found")); } + } diff --git a/skill-tree/src/test/java/com/RDS/skilltree/SkillTreeApplicationTests.java b/skill-tree/src/test/java/com/RDS/skilltree/SkillTreeApplicationTests.java index cbafce90..3c78720e 100644 --- a/skill-tree/src/test/java/com/RDS/skilltree/SkillTreeApplicationTests.java +++ b/skill-tree/src/test/java/com/RDS/skilltree/SkillTreeApplicationTests.java @@ -6,8 +6,7 @@ @SpringBootTest class SkillTreeApplicationTests { - @Test - void contextLoads() { - } - + @Test + void contextLoads() { + } } diff --git a/skill-tree/src/test/java/com/RDS/skilltree/unit/EndorsementListServiceTest.java b/skill-tree/src/test/java/com/RDS/skilltree/unit/EndorsementListServiceTest.java new file mode 100644 index 00000000..3e73afa7 --- /dev/null +++ b/skill-tree/src/test/java/com/RDS/skilltree/unit/EndorsementListServiceTest.java @@ -0,0 +1,119 @@ +package com.RDS.skilltree.unit; + +import com.RDS.skilltree.Endorsement.EndorsementModel; +import com.RDS.skilltree.Endorsement.EndorsementRepository; +import com.RDS.skilltree.EndorsementList.*; +import com.RDS.skilltree.Exceptions.NoEntityException; +import com.RDS.skilltree.User.UserModel; +import com.RDS.skilltree.User.UserRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.Optional; +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class EndorsementListServiceTest { + + @Mock + private EndorsementListRepository endorsementListRepository; + + @Mock + private EndorsementRepository endorsementRepository; + + @Mock + private UserRepository userRepository; + + @InjectMocks + private EndorsementListService endorsementListService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void testCreateEndorsementListEntry() { + // Mock data + UUID endorserId = UUID.randomUUID(); + UUID endorsementId = UUID.randomUUID(); + EndorsementListDRO endorsementListDRO = new EndorsementListDRO(); + endorsementListDRO.setEndorserId(endorserId); + endorsementListDRO.setEndorsementId(endorsementId); + endorsementListDRO.setDescription("Test Description"); + endorsementListDRO.setType(EndorsementType.POSITIVE); + + UserModel mockUser = new UserModel(); + mockUser.setId(endorserId); + + EndorsementModel mockEndorsement = EndorsementModel.builder() + .id(endorsementId) + .build(); + + // Mock the repository behavior + when(userRepository.findById(endorserId)).thenReturn(Optional.of(mockUser)); + when(endorsementRepository.findById(endorsementId)).thenReturn(Optional.of(mockEndorsement)); + + // Call the service method + EndorsementListModel result = endorsementListService.createEndorsementListEntry(endorsementListDRO); + + // Verify the interactions + verify(endorsementListRepository, times(1)).save(any(EndorsementListModel.class)); + + // Assertions + assertNotNull(result); + assertEquals(endorserId, result.getEndorser().getId()); + assertEquals(endorsementId, result.getEndorsement().getId()); + assertEquals("Test Description", result.getDescription()); + assertEquals(EndorsementType.POSITIVE, result.getType()); + } + + @Test + void testCreateEndorsementListEntryWithInvalidUser() { + UUID endorserId = UUID.randomUUID(); + UUID endorsementId = UUID.randomUUID(); + EndorsementListDRO endorsementListDRO = new EndorsementListDRO(); + endorsementListDRO.setEndorserId(endorserId); + endorsementListDRO.setEndorsementId(endorsementId); + + // Mock the repository behavior for an invalid user + when(userRepository.findById(endorserId)).thenReturn(Optional.empty()); + + // Assert that a NoEntityException is thrown + NoEntityException exception = assertThrows(NoEntityException.class, + () -> endorsementListService.createEndorsementListEntry(endorsementListDRO)); + assertEquals("User with id:" + endorserId + " not found", exception.getMessage()); + + // Verify that save method is not called + verify(endorsementListRepository, never()).save(any(EndorsementListModel.class)); + } + + @Test + void testCreateEndorsementListEntryWithInvalidEndorsement() { + UUID endorserId = UUID.randomUUID(); + UUID endorsementId = UUID.randomUUID(); + EndorsementListDRO endorsementListDRO = new EndorsementListDRO(); + endorsementListDRO.setEndorserId(endorserId); + endorsementListDRO.setEndorsementId(endorsementId); + + UserModel mockUser = new UserModel(); + mockUser.setId(endorserId); + + // Mock the repository behavior for an invalid endorsement + when(userRepository.findById(endorserId)).thenReturn(Optional.of(mockUser)); + when(endorsementRepository.findById(endorsementId)).thenReturn(Optional.empty()); + + // Assert that a NoEntityException is thrown + NoEntityException exception = assertThrows(NoEntityException.class, + () -> endorsementListService.createEndorsementListEntry(endorsementListDRO)); + assertEquals("Endorsement with id:" + endorsementId + " not found", exception.getMessage()); + + // Verify that save method is not called + verify(endorsementListRepository, never()).save(any(EndorsementListModel.class)); + } +} diff --git a/skill-tree/src/test/java/com/RDS/skilltree/unit/EndorsementServiceTest.java b/skill-tree/src/test/java/com/RDS/skilltree/unit/EndorsementServiceTest.java index 777654d1..d3047097 100644 --- a/skill-tree/src/test/java/com/RDS/skilltree/unit/EndorsementServiceTest.java +++ b/skill-tree/src/test/java/com/RDS/skilltree/unit/EndorsementServiceTest.java @@ -1,11 +1,15 @@ package com.RDS.skilltree.unit; +import com.RDS.skilltree.Endorsement.EndorsementDRO; import com.RDS.skilltree.Endorsement.EndorsementDTO; import com.RDS.skilltree.Endorsement.EndorsementModel; import com.RDS.skilltree.Endorsement.EndorsementRepository; import com.RDS.skilltree.Endorsement.EndorsementServiceImpl; +import com.RDS.skilltree.Exceptions.NoEntityException; import com.RDS.skilltree.Skill.SkillModel; +import com.RDS.skilltree.Skill.SkillRepository; import com.RDS.skilltree.User.UserModel; +import com.RDS.skilltree.User.UserRepository; import jakarta.persistence.EntityNotFoundException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -19,13 +23,19 @@ import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) public class EndorsementServiceTest { @Mock private EndorsementRepository endorsementRepository; + @Mock + private UserRepository userRepository; + + @Mock + private SkillRepository skillRepository; + @InjectMocks @Autowired private EndorsementServiceImpl endorsementService; @@ -67,4 +77,89 @@ public void itShouldHandleEndorsementNotFound() { // Verify the exception message assertEquals("No endorsement with the id " + nonExistentEndorsementId + " found", exception.getMessage()); } + + @Test + void testCreateEndorsement() { + // Mock data + UUID userId = UUID.randomUUID(); + UUID skillId = UUID.randomUUID(); + UUID endorsementId = UUID.randomUUID(); + EndorsementDRO endorsementDRO = new EndorsementDRO(); + endorsementDRO.setUserId(userId); + endorsementDRO.setSkillId(skillId); + + UserModel mockUser = UserModel.builder().id(userId).build(); + SkillModel mockSkill = SkillModel.builder().id(skillId).build(); + EndorsementModel mockEndorsement = EndorsementModel.builder() + .id(endorsementId) + .user(mockUser) + .skill(mockSkill) + .build(); + mockEndorsement.setCreatedAt(Instant.now()); + mockEndorsement.setUpdatedAt(Instant.now()); + mockEndorsement.setCreatedBy(mockUser); + mockEndorsement.setUpdatedBy(mockUser); + + // Mock the repository behavior + when(userRepository.findById(userId)).thenReturn(Optional.of(mockUser)); + when(skillRepository.findById(skillId)).thenReturn(Optional.of(mockSkill)); + when(endorsementRepository.save(any(EndorsementModel.class))).thenReturn(mockEndorsement); + + + // Call the service method + EndorsementModel result = endorsementService.createEndorsement(endorsementDRO); + + // Verify the interactions + verify(endorsementRepository, times(1)).save(any(EndorsementModel.class)); + + // Assertions + assertNotNull(result); + assertEquals(userId, result.getUser().getId()); + assertEquals(skillId, result.getSkill().getId()); + } + + @Test + void testCreateEndorsementWithInvalidUser() { + UUID userId = UUID.randomUUID(); + UUID skillId = UUID.randomUUID(); + EndorsementDRO endorsementDRO = new EndorsementDRO(); + endorsementDRO.setUserId(userId); + endorsementDRO.setSkillId(skillId); + + // Mock the repository behavior for an invalid user + when(userRepository.findById(userId)).thenReturn(Optional.empty()); + + // Assert that a NoEntityException is thrown + NoEntityException exception = assertThrows(NoEntityException.class, + () -> endorsementService.createEndorsement(endorsementDRO)); + assertEquals("User with id:" + userId + " not found", exception.getMessage()); + + // Verify that save method is not called + verify(endorsementRepository, never()).save(any(EndorsementModel.class)); + } + + @Test + void testCreateEndorsementWithInvalidSkill() { + UUID userId = UUID.randomUUID(); + UUID skillId = UUID.randomUUID(); + EndorsementDRO endorsementDRO = new EndorsementDRO(); + endorsementDRO.setUserId(userId); + endorsementDRO.setSkillId(skillId); + + UserModel mockUser = new UserModel(); + mockUser.setId(userId); + + // Mock the repository behavior for an invalid skill + when(userRepository.findById(userId)).thenReturn(Optional.of(mockUser)); + when(skillRepository.findById(skillId)).thenReturn(Optional.empty()); + + // Assert that a NoEntityException is thrown + NoEntityException exception = assertThrows(NoEntityException.class, + () -> endorsementService.createEndorsement(endorsementDRO)); + assertEquals("Skill with id:" + skillId + " not found", exception.getMessage()); + + // Verify that save method is not called + verify(endorsementRepository, never()).save(any(EndorsementModel.class)); + } + } \ No newline at end of file