diff --git a/src/main/java/com/wcc/platform/configuration/MentorshipConfig.java b/src/main/java/com/wcc/platform/configuration/MentorshipConfig.java index b9b24ad9..b1ae1484 100644 --- a/src/main/java/com/wcc/platform/configuration/MentorshipConfig.java +++ b/src/main/java/com/wcc/platform/configuration/MentorshipConfig.java @@ -9,8 +9,7 @@ * Configuration properties for mentorship-related settings. This class binds to properties under * the prefix "mentorship" in the application configuration file. * - *

Properties: - daysCycleOpen: Number of days a mentorship cycle remains open for registration. - * Default is 10. - validation.enabled: Flag to enable or disable mentorship cycle validation during + *

Properties: - validation.enabled: Flag to enable or disable mentorship cycle validation during * mentee registration. Default is true. Set to false for testing and debugging purposes. */ @Getter @@ -19,12 +18,6 @@ @ConfigurationProperties(prefix = "mentorship") public class MentorshipConfig { - /** the default n. days for the mentorship cycle remains open from the beginning of the month. */ - private static final int DEFAULT_DAYS = 10; - - /** Number of days a mentorship cycle remains open for registration. */ - private int daysCycleOpen = DEFAULT_DAYS; - /** Validation-specific configuration. */ private Validation validation = new Validation(); diff --git a/src/main/java/com/wcc/platform/configuration/ObjectMapperConfig.java b/src/main/java/com/wcc/platform/configuration/ObjectMapperConfig.java index 6516a749..469d09c6 100644 --- a/src/main/java/com/wcc/platform/configuration/ObjectMapperConfig.java +++ b/src/main/java/com/wcc/platform/configuration/ObjectMapperConfig.java @@ -1,6 +1,7 @@ package com.wcc.platform.configuration; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.module.SimpleModule; @@ -41,6 +42,7 @@ public ObjectMapper objectMapper() { final ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); diff --git a/src/main/java/com/wcc/platform/domain/platform/member/MemberDto.java b/src/main/java/com/wcc/platform/domain/platform/member/MemberDto.java index ad97a4cd..b1118fb1 100644 --- a/src/main/java/com/wcc/platform/domain/platform/member/MemberDto.java +++ b/src/main/java/com/wcc/platform/domain/platform/member/MemberDto.java @@ -26,6 +26,7 @@ public class MemberDto { @Schema(accessMode = Schema.AccessMode.READ_ONLY) @JsonProperty(access = JsonProperty.Access.READ_ONLY) private Long id; + private String fullName; private String position; private String email; diff --git a/src/main/java/com/wcc/platform/domain/platform/mentorship/MentorshipCycleEntity.java b/src/main/java/com/wcc/platform/domain/platform/mentorship/MentorshipCycleEntity.java index ee92de09..192d226f 100644 --- a/src/main/java/com/wcc/platform/domain/platform/mentorship/MentorshipCycleEntity.java +++ b/src/main/java/com/wcc/platform/domain/platform/mentorship/MentorshipCycleEntity.java @@ -1,5 +1,6 @@ package com.wcc.platform.domain.platform.mentorship; +import com.wcc.platform.domain.cms.pages.mentorship.MentorsPage; import java.time.LocalDate; import java.time.Month; import java.time.Year; @@ -52,11 +53,20 @@ public boolean isActive() { } /** - * Convert to MentorshipCycle value object for backward compatibility. + * Convert to MentorsPage.OpenCycle for backward compatibility. + * + * @return MentorsPage.OpenCycle value object + */ + public MentorsPage.OpenCycle toOpenCycleValue() { + return new MentorshipCycle(mentorshipType, cycleMonth).toOpenCycle(); + } + + /** + * Convert to MentorshipCycle value object. * * @return MentorshipCycle value object */ public MentorshipCycle toMentorshipCycle() { - return new MentorshipCycle(mentorshipType, cycleMonth != null ? cycleMonth : null); + return new MentorshipCycle(mentorshipType, cycleMonth); } } diff --git a/src/main/java/com/wcc/platform/repository/postgres/mentorship/PostgresMenteeApplicationRepository.java b/src/main/java/com/wcc/platform/repository/postgres/mentorship/PostgresMenteeApplicationRepository.java index 8cd4c59c..3c934141 100644 --- a/src/main/java/com/wcc/platform/repository/postgres/mentorship/PostgresMenteeApplicationRepository.java +++ b/src/main/java/com/wcc/platform/repository/postgres/mentorship/PostgresMenteeApplicationRepository.java @@ -54,7 +54,8 @@ public class PostgresMenteeApplicationRepository implements MenteeApplicationRep private static final String INSERT_APPLICATION = "INSERT INTO mentee_applications " - + "(mentee_id, mentor_id, cycle_id, priority_order, application_status, application_message, why_mentor) " + + "(mentee_id, mentor_id, cycle_id, priority_order, " + + "application_status, application_message, why_mentor) " + "VALUES (?, ?, ?, ?, ?::application_status, ?, ?) " + "RETURNING application_id"; @@ -163,8 +164,7 @@ public List getAll() { @Override public Long countMenteeApplications(final Long menteeId, final Long cycleId) { - final Long count = jdbc.queryForObject(COUNT_MENTEE_APPS, Long.class, menteeId, cycleId); - return count != null ? count : 0L; + return jdbc.queryForObject(COUNT_MENTEE_APPS, Long.class, menteeId, cycleId); } private MenteeApplication mapRow(final ResultSet rs) throws SQLException { diff --git a/src/main/java/com/wcc/platform/service/MenteeService.java b/src/main/java/com/wcc/platform/service/MenteeService.java index 06736d96..4793e40a 100644 --- a/src/main/java/com/wcc/platform/service/MenteeService.java +++ b/src/main/java/com/wcc/platform/service/MenteeService.java @@ -1,15 +1,11 @@ package com.wcc.platform.service; -import com.wcc.platform.configuration.MentorshipConfig; import com.wcc.platform.domain.exceptions.*; import com.wcc.platform.domain.platform.member.Member; -import com.wcc.platform.domain.platform.mentorship.CycleStatus; import com.wcc.platform.domain.platform.mentorship.Mentee; import com.wcc.platform.domain.platform.mentorship.MenteeApplication; import com.wcc.platform.domain.platform.mentorship.MenteeRegistration; -import com.wcc.platform.domain.platform.mentorship.MentorshipCycle; import com.wcc.platform.domain.platform.mentorship.MentorshipCycleEntity; -import com.wcc.platform.domain.platform.mentorship.MentorshipType; import com.wcc.platform.domain.platform.type.MemberType; import com.wcc.platform.domain.platform.type.RoleType; import com.wcc.platform.repository.MemberRepository; @@ -17,7 +13,6 @@ import com.wcc.platform.repository.MenteeRepository; import com.wcc.platform.repository.MentorRepository; import com.wcc.platform.repository.MentorshipCycleRepository; -import java.time.Year; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -28,11 +23,7 @@ @Service @AllArgsConstructor public class MenteeService { - private static final int MAX_MENTORS = 5; - - private final MentorshipService mentorshipService; - private final MentorshipConfig mentorshipConfig; private final MentorshipCycleRepository cycleRepository; private final MenteeApplicationRepository registrationsRepo; private final MenteeRepository menteeRepository; @@ -62,8 +53,14 @@ public List getAllMentees() { public Mentee saveRegistration(final MenteeRegistration request) { validateMentors(request); - final Year cycleYear = request.cycleYear() != null ? request.cycleYear() : Year.now(); - final var cycle = getMentorshipCycle(request.mentorshipType(), cycleYear); + final var cycle = getCurrentCycle(); + + if (!request.mentorshipType().equals(cycle.getMentorshipType())) { + throw new InvalidMentorshipTypeException( + String.format( + "Mentee mentorship type '%s' does not match current cycle type '%s'", + request.mentorshipType(), cycle.getMentorshipType())); + } final var menteeId = ensureMenteeId(request.mentee()); if (menteeId != null) { @@ -255,49 +252,13 @@ private void validateMentors(final MenteeRegistration registrationRequest) { * Retrieves the MentorshipCycleEntity for the given mentorship type and cycle year. Validates * that the cycle is open and the mentorship type matches the current cycle. * - * @param mentorshipType The type of mentorship for which the cycle is being retrieved. - * @param cycleYear The year of the mentorship cycle. * @return The MentorshipCycleEntity corresponding to the specified type and year. * @throws MentorshipCycleClosedException If the mentorship cycle is closed. - * @throws InvalidMentorshipTypeException If the mentorship type does not match the current cycle - * type. */ - private MentorshipCycleEntity getMentorshipCycle( - final MentorshipType mentorshipType, final Year cycleYear) { - final var openCycle = cycleRepository.findByYearAndType(cycleYear, mentorshipType); - - if (openCycle.isPresent()) { - final MentorshipCycleEntity cycle = openCycle.get(); - - if (mentorshipConfig.getValidation().isEnabled() && cycle.getStatus() != CycleStatus.OPEN) { - throw new MentorshipCycleClosedException( - String.format( - "Mentorship cycle for %s in %d is %s. Registration is not available.", - mentorshipType, cycleYear.getValue(), cycle.getStatus())); - } - - return cycle; - } - - // Fallback to old mentorship service validation for backward compatibility - final MentorshipCycle currentCycle = mentorshipService.getCurrentCycle(); - - if (currentCycle == MentorshipService.CYCLE_CLOSED) { - throw new MentorshipCycleClosedException( - "Mentorship cycle is currently closed. Registration is not available."); - } - - if (mentorshipType != currentCycle.cycle()) { - throw new InvalidMentorshipTypeException( - String.format( - "Mentee mentorship type '%s' does not match current cycle type '%s'.", - mentorshipType, currentCycle.cycle())); - } - - return MentorshipCycleEntity.builder() - .cycleYear(cycleYear) - .mentorshipType(mentorshipType) - .build(); + private MentorshipCycleEntity getCurrentCycle() { + return cycleRepository + .findOpenCycle() + .orElseThrow(() -> new MentorshipCycleClosedException("Mentorship cycle is closed")); } /** diff --git a/src/main/java/com/wcc/platform/service/MentorshipService.java b/src/main/java/com/wcc/platform/service/MentorshipService.java index 72d1059d..e6008167 100644 --- a/src/main/java/com/wcc/platform/service/MentorshipService.java +++ b/src/main/java/com/wcc/platform/service/MentorshipService.java @@ -8,67 +8,45 @@ import com.wcc.platform.domain.exceptions.MemberNotFoundException; import com.wcc.platform.domain.exceptions.MentorStatusException; import com.wcc.platform.domain.platform.member.ProfileStatus; +import com.wcc.platform.domain.platform.mentorship.CycleStatus; import com.wcc.platform.domain.platform.mentorship.Mentor; import com.wcc.platform.domain.platform.mentorship.MentorDto; -import com.wcc.platform.domain.platform.mentorship.MentorshipCycle; -import com.wcc.platform.domain.platform.mentorship.MentorshipType; +import com.wcc.platform.domain.platform.mentorship.MentorshipCycleEntity; import com.wcc.platform.domain.platform.type.RoleType; import com.wcc.platform.domain.resource.MemberProfilePicture; import com.wcc.platform.domain.resource.Resource; import com.wcc.platform.repository.MemberProfilePictureRepository; import com.wcc.platform.repository.MemberRepository; import com.wcc.platform.repository.MentorRepository; +import com.wcc.platform.repository.MentorshipCycleRepository; import com.wcc.platform.utils.FiltersUtil; -import java.time.LocalDate; -import java.time.Month; -import java.time.ZoneId; -import java.time.ZonedDateTime; import java.util.List; import java.util.Optional; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; /** Platform Service. */ @Slf4j @Service +@AllArgsConstructor @SuppressWarnings({ "PMD.ExcessiveImports", "PMD.TooManyMethods" }) // TODO: https://github.com/Women-Coding-Community/wcc-backend/issues/520 public class MentorshipService { - /* package */ static final MentorshipCycle CYCLE_CLOSED = new MentorshipCycle(null, null); + public static final MentorshipCycleEntity CLOSED_CYCLE = + MentorshipCycleEntity.builder().status(CycleStatus.CLOSED).build(); - private static final String EUROPE_LONDON = "Europe/London"; - private static final MentorshipCycle ACTIVE_LONG_TERM = - new MentorshipCycle(MentorshipType.LONG_TERM, Month.MARCH); private static final int MINIMUM_HOURS = 2; - private final MentorRepository mentorRepository; private final MemberRepository memberRepository; + private final MentorshipCycleRepository cycleRepository; private final UserProvisionService userProvisionService; private final MemberProfilePictureRepository profilePicRepo; - private final int daysCycleOpen; private final MentorshipNotificationService notificationService; - @Autowired - public MentorshipService( - final MentorRepository mentorRepository, - final MemberRepository memberRepository, - final UserProvisionService userProvisionService, - final MemberProfilePictureRepository profilePicRepo, - final @Value("${mentorship.daysCycleOpen}") int daysCycleOpen, - final MentorshipNotificationService notificationService) { - this.mentorRepository = mentorRepository; - this.memberRepository = memberRepository; - this.userProvisionService = userProvisionService; - this.profilePicRepo = profilePicRepo; - this.daysCycleOpen = daysCycleOpen; - this.notificationService = notificationService; - } - /** * Create a mentor record. * @@ -136,7 +114,7 @@ public MentorsPage getMentorsPage( final var mentors = FiltersUtil.applyFilters(getAllActiveMentors(currentCycle), filters); return mentorsPage.updateUpdate( - currentCycle.toOpenCycle(), FiltersUtil.mentorshipAllFilters(), mentors); + currentCycle.toOpenCycleValue(), FiltersUtil.mentorshipAllFilters(), mentors); } public MentorsPage getMentorsPage(final MentorsPage mentorsPage) { @@ -144,8 +122,8 @@ public MentorsPage getMentorsPage(final MentorsPage mentorsPage) { } /** - * Return all mentors ignoring their status and the current cycle. - * Intended for privileged (admin/leader) use only. + * Return all mentors ignoring their status and the current cycle. Intended for privileged + * (admin/leader) use only. * * @return list of all mentor DTOs regardless of {@link ProfileStatus}. */ @@ -155,6 +133,18 @@ public List getAllMentors() { .toList(); } + /** + * Retrieves the mentorship cycle for the given mentorship type and cycle year. If no open cycle + * is found, returns a default closed cycle. + * + * @return The MentorshipCycleEntity + */ + public MentorshipCycleEntity getCurrentCycle() { + final var openCycle = cycleRepository.findOpenCycle(); + + return openCycle.orElse(CLOSED_CYCLE); + } + /** * Return all ACTIVE mentors in the current cycle. Mentors with PENDING or REJECTED status are * always excluded regardless of the cycle state. @@ -165,44 +155,20 @@ public List getAllActiveMentors() { return getAllActiveMentors(getCurrentCycle()); } - private List getAllActiveMentors(final MentorshipCycle currentCycle) { + private List getAllActiveMentors(final MentorshipCycleEntity currentCycle) { final var allActiveMentors = mentorRepository.getAll().stream() .filter(m -> m.getProfileStatus() == ProfileStatus.ACTIVE); - if (currentCycle == CYCLE_CLOSED) { + if (currentCycle.getStatus() == CycleStatus.CLOSED) { return allActiveMentors.map(mentor -> enrichWithProfilePicture(mentor.toDto())).toList(); } return allActiveMentors - .map(mentor -> enrichWithProfilePicture(mentor.toDto(currentCycle))) + .map(mentor -> enrichWithProfilePicture(mentor.toDto(currentCycle.toMentorshipCycle()))) .toList(); } - /* package */ MentorshipCycle getCurrentCycle() { - final ZonedDateTime londonTime = nowLondon(); - final LocalDate currentDate = londonTime.toLocalDate(); - - final var currentMonth = currentDate.getMonth(); - final int dayOfMonth = currentDate.getDayOfMonth(); - - if (currentMonth == Month.MARCH && dayOfMonth <= daysCycleOpen) { - return ACTIVE_LONG_TERM; - } - - if (currentMonth.getValue() >= Month.MAY.getValue() - && currentMonth.getValue() <= Month.NOVEMBER.getValue() - && dayOfMonth <= daysCycleOpen) { - return new MentorshipCycle(MentorshipType.AD_HOC, currentMonth); - } - - return CYCLE_CLOSED; - } - - /* package */ ZonedDateTime nowLondon() { - return ZonedDateTime.now(ZoneId.of(EUROPE_LONDON)); - } - private MentorDto enrichWithProfilePicture(final MentorDto dto) { final Optional profilePicture = fetchProfilePicture(dto.getId()); diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9acacbba..69ad343c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -37,7 +37,6 @@ backend: url: ${SPRING_APP_BASE_URL:http://localhost:8080} mentorship: - daysCycleOpen: 10 validation: enabled: false diff --git a/src/test/java/com/wcc/platform/configuration/MentorshipConfigTest.java b/src/test/java/com/wcc/platform/configuration/MentorshipConfigTest.java index c17bad32..e865c178 100644 --- a/src/test/java/com/wcc/platform/configuration/MentorshipConfigTest.java +++ b/src/test/java/com/wcc/platform/configuration/MentorshipConfigTest.java @@ -12,20 +12,10 @@ class MentorshipConfigTest { void shouldHaveDefaultValues() { MentorshipConfig config = new MentorshipConfig(); - assertThat(config.getDaysCycleOpen()).isEqualTo(10); assertThat(config.getValidation()).isNotNull(); assertThat(config.getValidation().isEnabled()).isTrue(); } - @Test - @DisplayName("Given custom daysCycleOpen When setting value Then should update correctly") - void shouldSetDaysCycleOpen() { - MentorshipConfig config = new MentorshipConfig(); - config.setDaysCycleOpen(15); - - assertThat(config.getDaysCycleOpen()).isEqualTo(15); - } - @Test @DisplayName("Given validation enabled When disabling Then should update correctly") void shouldDisableValidation() { @@ -57,4 +47,4 @@ void shouldSetNewValidationObject() { assertThat(config.getValidation()).isEqualTo(newValidation); assertThat(config.getValidation().isEnabled()).isFalse(); } -} \ No newline at end of file +} diff --git a/src/test/java/com/wcc/platform/controller/MentorControllerTest.java b/src/test/java/com/wcc/platform/controller/MentorControllerTest.java index 89eda513..3a426ea4 100644 --- a/src/test/java/com/wcc/platform/controller/MentorControllerTest.java +++ b/src/test/java/com/wcc/platform/controller/MentorControllerTest.java @@ -78,65 +78,6 @@ void shouldCreateMentorAndReturnCreated() throws Exception { .andExpect(jsonPath("$.profileStatus", is("PENDING"))); } - @Test - @DisplayName( - "Given mentor payload with unknown nested field, " - + "when creating mentor, then return 400 with field context") - void shouldReturnBadRequestWithFieldContextForUnknownJsonField() throws Exception { - var invalidMentorPayload = - """ - { - "fullName": "fullName MENTOR", - "position": "position MENTOR", - "email": "email@mentor", - "slackDisplayName": "slackDisplayName", - "country": { - "countryCode": "ES", - "countryName": "Spain" - }, - "city": "City", - "companyName": "Company name", - "images": [], - "network": [], - "bio": "Mentor bio", - "spokenLanguages": ["English"], - "skills": { - "yearsExperience": 2, - "areas": [ - { - "name": "BACKEND", - "proficiencyLevel": "BEGINNER" - } - ], - "languages": [], - "mentorshipFocus": [] - }, - "menteeSection": { - "idealMentee": "ideal mentee description", - "additional": "additional", - "longTerm": { - "maxMentees": 1, - "hoursPerMentee": 4 - }, - "adHoc": [] - } - } - """; - - mockMvc - .perform( - MockMvcRequestBuilders.post(API_MENTORS) - .header(API_KEY_HEADER, API_KEY_VALUE) - .contentType(APPLICATION_JSON) - .content(invalidMentorPayload)) - .andExpect(status().isBadRequest()) - .andExpect( - jsonPath( - "$.message", - is( - "Unrecognized field 'name' at 'skills.areas[0].name'. Allowed fields: proficiencyLevel, technicalArea"))); - } - @Test @DisplayName("Given valid mentor ID and DTO, when updating mentor, then return 200 OK") void shouldUpdateMentorAndReturnOk() throws Exception { diff --git a/src/test/java/com/wcc/platform/service/MenteeServiceTest.java b/src/test/java/com/wcc/platform/service/MenteeServiceTest.java index bc6c150c..7542824a 100644 --- a/src/test/java/com/wcc/platform/service/MenteeServiceTest.java +++ b/src/test/java/com/wcc/platform/service/MenteeServiceTest.java @@ -12,7 +12,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.wcc.platform.configuration.MentorshipConfig; import com.wcc.platform.domain.exceptions.DuplicatedPriorityException; import com.wcc.platform.domain.exceptions.InvalidMentorshipTypeException; import com.wcc.platform.domain.exceptions.MenteeRegistrationLimitException; @@ -26,7 +25,6 @@ import com.wcc.platform.domain.platform.mentorship.MenteeApplicationDto; import com.wcc.platform.domain.platform.mentorship.MenteeRegistration; import com.wcc.platform.domain.platform.mentorship.Mentor; -import com.wcc.platform.domain.platform.mentorship.MentorshipCycle; import com.wcc.platform.domain.platform.mentorship.MentorshipCycleEntity; import com.wcc.platform.domain.platform.mentorship.MentorshipType; import com.wcc.platform.domain.platform.type.MemberType; @@ -51,9 +49,6 @@ class MenteeServiceTest { @Mock private MenteeApplicationRepository applicationRepository; @Mock private MenteeRepository menteeRepository; - @Mock private MentorshipService mentorshipService; - @Mock private MentorshipConfig mentorshipConfig; - @Mock private MentorshipConfig.Validation validation; @Mock private MentorshipCycleRepository cycleRepository; @Mock private MemberRepository memberRepository; @Mock private MentorRepository mentorRepository; @@ -65,12 +60,8 @@ class MenteeServiceTest { @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); - when(mentorshipConfig.getValidation()).thenReturn(validation); - when(validation.isEnabled()).thenReturn(true); menteeService = new MenteeService( - mentorshipService, - mentorshipConfig, cycleRepository, applicationRepository, menteeRepository, @@ -79,6 +70,14 @@ void setUp() { userProvisionService); mentee = createMenteeTest(null, "Test Mentee", "test@wcc.com"); when(mentorRepository.findById(any())).thenReturn(Optional.of(Mentor.mentorBuilder().build())); + + var openCycle = + MentorshipCycleEntity.builder() + .cycleId(1L) + .status(CycleStatus.OPEN) + .mentorshipType(MentorshipType.AD_HOC) + .build(); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(openCycle)); } @Test @@ -110,8 +109,7 @@ void testSaveRegistrationMentee() { when(menteeRepository.findById(any())) .thenReturn(Optional.empty()) .thenReturn(Optional.of(mentee)); - when(cycleRepository.findByYearAndType(currentYear, MentorshipType.AD_HOC)) - .thenReturn(Optional.of(cycle)); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(cycle)); when(applicationRepository.findByMenteeAndCycle(any(), any())).thenReturn(List.of()); Mentee result = menteeService.saveRegistration(registration); @@ -160,8 +158,7 @@ void shouldThrowExceptionWhenRegistrationLimitExceeded() { .build(); when(menteeRepository.findById(1L)).thenReturn(Optional.of(menteeWithId)); - when(cycleRepository.findByYearAndType(currentYear, MentorshipType.AD_HOC)) - .thenReturn(Optional.of(cycle)); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(cycle)); when(applicationRepository.findByMenteeAndCycle(any(), any())).thenReturn(List.of()); when(applicationRepository.countMenteeApplications(1L, 1L)).thenReturn(5L); @@ -210,8 +207,7 @@ void shouldThrowExceptionWhenPriorityAlreadyExists() { .build(); when(menteeRepository.findById(1L)).thenReturn(Optional.of(menteeWithId)); - when(cycleRepository.findByYearAndType(currentYear, MentorshipType.AD_HOC)) - .thenReturn(Optional.of(cycle)); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(cycle)); // Simulate existing application with priority 1 var existingApplication = @@ -264,8 +260,7 @@ void shouldThrowExceptionWhenPriorityDuplicatedInRequest() { .build(); when(menteeRepository.findById(1L)).thenReturn(Optional.of(menteeWithId)); - when(cycleRepository.findByYearAndType(currentYear, MentorshipType.AD_HOC)) - .thenReturn(Optional.of(cycle)); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(cycle)); when(applicationRepository.findByMenteeAndCycle(1L, 1L)).thenReturn(List.of()); @@ -297,14 +292,14 @@ void shouldThrowExceptionWhenCycleIsClosed() { currentYear, List.of( new MenteeApplicationDto(1L, 1, "Test application message", "Test why mentor"))); - when(mentorshipService.getCurrentCycle()).thenReturn(MentorshipService.CYCLE_CLOSED); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.empty()); MentorshipCycleClosedException exception = assertThrows( MentorshipCycleClosedException.class, () -> menteeService.saveRegistration(registration)); - assertThat(exception.getMessage()).contains("Mentorship cycle is currently closed"); + assertThat(exception.getMessage()).contains("Mentorship cycle is closed"); } @Test @@ -321,8 +316,14 @@ void shouldThrowExceptionWhenMenteeTypeDoesNotMatchCycleType() { List.of( new MenteeApplicationDto(1L, 1, "Test application message", "Test why mentor"))); - MentorshipCycle longTermCycle = new MentorshipCycle(MentorshipType.LONG_TERM, Month.MARCH); - when(mentorshipService.getCurrentCycle()).thenReturn(longTermCycle); + when(cycleRepository.findOpenCycle()) + .thenReturn( + Optional.of( + MentorshipCycleEntity.builder() + .mentorshipType(MentorshipType.LONG_TERM) + .cycleMonth(Month.MARCH) + .status(CycleStatus.OPEN) + .build())); InvalidMentorshipTypeException exception = assertThrows( @@ -347,8 +348,14 @@ void shouldSaveRegistrationMenteeWhenCycleIsOpenAndTypeMatches() { List.of( new MenteeApplicationDto(1L, 1, "Test application message", "Test why mentor"))); - MentorshipCycle adHocCycle = new MentorshipCycle(MentorshipType.AD_HOC, Month.MAY); - when(mentorshipService.getCurrentCycle()).thenReturn(adHocCycle); + var cycle = + MentorshipCycleEntity.builder() + .mentorshipType(MentorshipType.AD_HOC) + .cycleMonth(Month.MAY) + .status(CycleStatus.OPEN) + .build(); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(cycle)); + Member existingMember = Member.builder().id(1L).build(); when(memberRepository.findByEmail(anyString())).thenReturn(Optional.of(existingMember)); when(menteeRepository.create(any(Mentee.class))) @@ -364,7 +371,7 @@ void shouldSaveRegistrationMenteeWhenCycleIsOpenAndTypeMatches() { assertThat(result).isEqualTo(mentee); verify(menteeRepository).create(any(Mentee.class)); - verify(mentorshipService).getCurrentCycle(); + verify(cycleRepository, atLeastOnce()).findOpenCycle(); verify(mentorRepository).findById(1L); } @@ -392,9 +399,9 @@ void shouldThrowExceptionWhenMentorDoesNotExist() { @Test @DisplayName( - "Given validation is disabled, when creating mentee, " - + "then should skip validation and create successfully") - void shouldSkipValidationWhenValidationIsDisabled() { + "Given an open cycle matching the registration type, when creating mentee, " + + "then should create successfully") + void shouldCreateMenteeWhenOpenCycleMatches() { var currentYear = Year.now(); MenteeRegistration registration = new MenteeRegistration( @@ -403,11 +410,15 @@ void shouldSkipValidationWhenValidationIsDisabled() { currentYear, List.of( new MenteeApplicationDto(1L, 1, "Test application message", "Test why mentor"))); - when(validation.isEnabled()).thenReturn(false); - when(cycleRepository.findByYearAndType(any(), any())).thenReturn(Optional.empty()); - when(mentorshipService.getCurrentCycle()) - .thenReturn(new MentorshipCycle(MentorshipType.AD_HOC, Month.JANUARY)); + when(cycleRepository.findOpenCycle()) + .thenReturn( + Optional.of( + MentorshipCycleEntity.builder() + .mentorshipType(MentorshipType.AD_HOC) + .cycleMonth(Month.MAY) + .status(CycleStatus.OPEN) + .build())); Member existingMember = Member.builder().id(1L).build(); when(memberRepository.findByEmail(anyString())).thenReturn(Optional.of(existingMember)); when(menteeRepository.create(any())).thenAnswer(invocation -> invocation.getArgument(0)); @@ -422,7 +433,7 @@ void shouldSkipValidationWhenValidationIsDisabled() { assertThat(result).isEqualTo(mentee); verify(menteeRepository).create(any(Mentee.class)); - verify(mentorshipService).getCurrentCycle(); + verify(cycleRepository, atLeastOnce()).findOpenCycle(); } @Test @@ -465,8 +476,7 @@ void shouldUseExistingMemberWhenMenteeEmailAlreadyExists() { .build(); when(memberRepository.findByEmail(mentee.getEmail())).thenReturn(Optional.of(existingMember)); - when(cycleRepository.findByYearAndType(currentYear, MentorshipType.AD_HOC)) - .thenReturn(Optional.of(cycle)); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(cycle)); when(applicationRepository.findByMenteeAndCycle(any(), any())).thenReturn(List.of()); when(menteeRepository.create(any(Mentee.class))) .thenAnswer(invocation -> invocation.getArgument(0)); @@ -509,8 +519,7 @@ void shouldFallbackToExistingMemberWhenProvidedIdDoesNotExistButEmailExists() { when(menteeRepository.findById(12_345L)).thenReturn(Optional.empty()); when(memberRepository.findByEmail("existing@test.com")) .thenReturn(Optional.of(Member.builder().id(999L).build())); - when(cycleRepository.findByYearAndType(currentYear, MentorshipType.AD_HOC)) - .thenReturn(Optional.of(cycle)); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(cycle)); when(applicationRepository.findByMenteeAndCycle(any(), any())).thenReturn(List.of()); when(applicationRepository.countMenteeApplications(any(), any())).thenReturn(0L); when(menteeRepository.findById(999L)) @@ -556,14 +565,13 @@ void shouldDefaultToCurrentYearWhenCycleYearIsNull() { when(menteeRepository.findById(any())) .thenReturn(Optional.empty()) .thenReturn(Optional.of(mentee)); - when(cycleRepository.findByYearAndType(currentYear, MentorshipType.AD_HOC)) - .thenReturn(Optional.of(cycle)); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(cycle)); when(applicationRepository.findByMenteeAndCycle(any(), any())).thenReturn(List.of()); Mentee result = menteeService.saveRegistration(registration); assertThat(result).isEqualTo(mentee); - verify(cycleRepository).findByYearAndType(currentYear, MentorshipType.AD_HOC); + verify(cycleRepository, atLeastOnce()).findOpenCycle(); } @Test @@ -588,8 +596,7 @@ void shouldReturnExistingMenteeWhenIdExistsInRepository() { .status(CycleStatus.OPEN) .build(); - when(cycleRepository.findByYearAndType(currentYear, MentorshipType.AD_HOC)) - .thenReturn(Optional.of(cycle)); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(cycle)); when(menteeRepository.findById(5L)).thenReturn(Optional.of(existingMentee)); when(applicationRepository.findByMenteeAndCycle(any(), any())).thenReturn(List.of()); when(applicationRepository.countMenteeApplications(any(), any())).thenReturn(0L); @@ -640,8 +647,7 @@ void shouldPreserveMemberTypesWhenExistingMentorRegistersAsMentee() { .thenReturn(Optional.of(existingMentorMember)); when(memberRepository.findById(100L)).thenReturn(Optional.of(existingMentorMember)); when(menteeRepository.findById(100L)).thenReturn(Optional.empty()); - when(cycleRepository.findByYearAndType(currentYear, MentorshipType.AD_HOC)) - .thenReturn(Optional.of(cycle)); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(cycle)); when(applicationRepository.findByMenteeAndCycle(any(), any())).thenReturn(List.of()); when(applicationRepository.countMenteeApplications(100L, 1L)).thenReturn(0L); // Capture the created mentee to verify member types diff --git a/src/test/java/com/wcc/platform/service/MentorshipServiceFilteringTest.java b/src/test/java/com/wcc/platform/service/MentorshipServiceFilteringTest.java index cc42194c..80edd008 100644 --- a/src/test/java/com/wcc/platform/service/MentorshipServiceFilteringTest.java +++ b/src/test/java/com/wcc/platform/service/MentorshipServiceFilteringTest.java @@ -17,9 +17,10 @@ import com.wcc.platform.domain.cms.pages.mentorship.MentorsPage; import com.wcc.platform.domain.platform.member.Member; import com.wcc.platform.domain.platform.member.ProfileStatus; +import com.wcc.platform.domain.platform.mentorship.CycleStatus; import com.wcc.platform.domain.platform.mentorship.LanguageProficiency; import com.wcc.platform.domain.platform.mentorship.Mentor; -import com.wcc.platform.domain.platform.mentorship.MentorshipCycle; +import com.wcc.platform.domain.platform.mentorship.MentorshipCycleEntity; import com.wcc.platform.domain.platform.mentorship.MentorshipType; import com.wcc.platform.domain.platform.mentorship.Skills; import com.wcc.platform.domain.platform.mentorship.TechnicalAreaProficiency; @@ -29,6 +30,7 @@ import com.wcc.platform.repository.MemberProfilePictureRepository; import com.wcc.platform.repository.MemberRepository; import com.wcc.platform.repository.MentorRepository; +import com.wcc.platform.repository.MentorshipCycleRepository; import java.time.Month; import java.util.List; import org.junit.jupiter.api.BeforeEach; @@ -43,6 +45,7 @@ class MentorshipServiceFilteringTest { @Mock private MentorRepository mentorRepository; @Mock private MemberRepository memberRepository; + @Mock private MentorshipCycleRepository cycleRepository; @Mock private MemberProfilePictureRepository profilePicRepo; @Mock private UserProvisionService userProvisionService; @Mock private MentorshipNotificationService notificationService; @@ -55,8 +58,19 @@ void setUp() { service = spy( new MentorshipService( - mentorRepository, memberRepository, userProvisionService, profilePicRepo, 10, notificationService)); - doReturn(new MentorshipCycle(MentorshipType.AD_HOC, Month.MAY)).when(service).getCurrentCycle(); + mentorRepository, + memberRepository, + cycleRepository, + userProvisionService, + profilePicRepo, + notificationService)); + var cycle = + MentorshipCycleEntity.builder() + .mentorshipType(MentorshipType.AD_HOC) + .cycleMonth(Month.MAY) + .status(CycleStatus.OPEN) + .build(); + doReturn(cycle).when(service).getCurrentCycle(); mentorsPage = SetupMentorshipPagesFactories.createMentorPageTest(); mentor1 = buildMentor( diff --git a/src/test/java/com/wcc/platform/service/MentorshipServiceRetrievalTest.java b/src/test/java/com/wcc/platform/service/MentorshipServiceRetrievalTest.java index 09294e76..41ff926e 100644 --- a/src/test/java/com/wcc/platform/service/MentorshipServiceRetrievalTest.java +++ b/src/test/java/com/wcc/platform/service/MentorshipServiceRetrievalTest.java @@ -2,7 +2,7 @@ import static com.wcc.platform.factories.SetupMentorFactories.createMemberProfilePictureTest; import static com.wcc.platform.factories.SetupMentorFactories.createResourceTest; -import static com.wcc.platform.service.MentorshipService.CYCLE_CLOSED; +import static com.wcc.platform.service.MentorshipService.CLOSED_CYCLE; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Answers.RETURNS_DEEP_STUBS; @@ -14,16 +14,16 @@ import com.wcc.platform.domain.cms.attributes.ImageType; import com.wcc.platform.domain.platform.member.ProfileStatus; +import com.wcc.platform.domain.platform.mentorship.CycleStatus; import com.wcc.platform.domain.platform.mentorship.Mentor; import com.wcc.platform.domain.platform.mentorship.MentorDto; -import com.wcc.platform.domain.platform.mentorship.MentorshipCycle; +import com.wcc.platform.domain.platform.mentorship.MentorshipCycleEntity; import com.wcc.platform.domain.platform.mentorship.MentorshipType; import com.wcc.platform.repository.MemberProfilePictureRepository; import com.wcc.platform.repository.MemberRepository; import com.wcc.platform.repository.MentorRepository; +import com.wcc.platform.repository.MentorshipCycleRepository; import java.time.Month; -import java.time.ZoneId; -import java.time.ZonedDateTime; import java.util.List; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; @@ -39,6 +39,7 @@ class MentorshipServiceRetrievalTest { @Mock private MentorRepository mentorRepository; @Mock private MemberRepository memberRepository; + @Mock private MentorshipCycleRepository cycleRepository; @Mock private UserProvisionService userProvisionService; @Mock private MemberProfilePictureRepository profilePicRepo; @Mock private MentorshipNotificationService notificationService; @@ -46,17 +47,15 @@ class MentorshipServiceRetrievalTest { @BeforeEach void setUp() { - final var daysOpen = 10; - MockitoAnnotations.openMocks(this); service = spy( new MentorshipService( mentorRepository, memberRepository, + cycleRepository, userProvisionService, profilePicRepo, - daysOpen, notificationService)); } @@ -69,7 +68,7 @@ void whenGetAllMentorsGivenCycleClosedThenReturnDtos() { when(mentorRepository.getAll()).thenReturn(List.of(mentor)); when(profilePicRepo.findByMemberId(1L)).thenReturn(Optional.empty()); - doReturn(CYCLE_CLOSED).when(service).getCurrentCycle(); + doReturn(CLOSED_CYCLE).when(service).getCurrentCycle(); var result = service.getAllActiveMentors(); @@ -85,7 +84,11 @@ void whenGetAllMentorsGivenAdHocCycleOpenThenReturnDtos() { when(dto.getId()).thenReturn(1L); when(mentorRepository.getAll()).thenReturn(List.of(mentor)); - var cycle = new MentorshipCycle(MentorshipType.AD_HOC, Month.MAY); + var cycle = + MentorshipCycleEntity.builder() + .mentorshipType(MentorshipType.AD_HOC) + .cycleMonth(Month.MAY) + .build(); doReturn(cycle).when(service).getCurrentCycle(); var result = service.getAllActiveMentors(); @@ -103,7 +106,11 @@ void whenGetAllMentorsGivenLongTermCycleOpenThenReturnDtos() { when(mentorRepository.getAll()).thenReturn(List.of(mentor)); when(profilePicRepo.findByMemberId(1L)).thenReturn(Optional.empty()); - var cycle = new MentorshipCycle(MentorshipType.LONG_TERM, Month.MARCH); + var cycle = + MentorshipCycleEntity.builder() + .mentorshipType(MentorshipType.LONG_TERM) + .cycleMonth(Month.MARCH) + .build(); doReturn(cycle).when(service).getCurrentCycle(); var result = service.getAllActiveMentors(); @@ -116,42 +123,30 @@ private T any() { } @Test - void testGetCurrentCycleReturnsLongTermDuringMarchWithinOpenDays() { - var marchDate = ZonedDateTime.of(2024, 3, 5, 12, 0, 0, 0, ZoneId.of("Europe/London")); - doReturn(marchDate).when(service).nowLondon(); - - var result = service.getCurrentCycle(); - - assertEquals(MentorshipType.LONG_TERM, result.cycle()); - } - - @Test - void testGetCurrentCycleReturnsAdHocFromMayWithinOpenDays() { - var mayDate = ZonedDateTime.of(2024, 5, 5, 12, 0, 0, 0, ZoneId.of("Europe/London")); - doReturn(mayDate).when(service).nowLondon(); + void testGetCurrentCycleReturnsOpenCycle() { + var cycle = + MentorshipCycleEntity.builder() + .mentorshipType(MentorshipType.LONG_TERM) + .cycleMonth(Month.MARCH) + .status(CycleStatus.OPEN) + .build(); + when(cycleRepository.findOpenCycle()).thenReturn(Optional.of(cycle)); var result = service.getCurrentCycle(); - assertEquals(MentorshipType.AD_HOC, result.cycle()); - assertEquals(Month.MAY, result.month()); + assertEquals(MentorshipType.LONG_TERM, result.getMentorshipType()); + assertEquals(Month.MARCH, result.getCycleMonth()); } @Test - void testGetCurrentCycleReturnsClosedOutsideWindows() { - // January - Closed - var janDate = ZonedDateTime.of(2024, 1, 5, 12, 0, 0, 0, ZoneId.of("Europe/London")); - doReturn(janDate).when(service).nowLondon(); - assertEquals(CYCLE_CLOSED, service.getCurrentCycle()); - - // March after 10 days - Closed - var marchLateDate = ZonedDateTime.of(2024, 3, 15, 12, 0, 0, 0, ZoneId.of("Europe/London")); - doReturn(marchLateDate).when(service).nowLondon(); - assertEquals(CYCLE_CLOSED, service.getCurrentCycle()); - - // April - Closed - var aprilDate = ZonedDateTime.of(2024, 4, 5, 12, 0, 0, 0, ZoneId.of("Europe/London")); - doReturn(aprilDate).when(service).nowLondon(); - assertEquals(CYCLE_CLOSED, service.getCurrentCycle()); + void testGetCurrentCycleReturnsClosedWhenNoOpenCycle() { + when(cycleRepository.findOpenCycle()).thenReturn(Optional.empty()); + + try { + service.getCurrentCycle(); + } catch (com.wcc.platform.domain.exceptions.MentorshipCycleClosedException e) { + assertEquals("Mentorship cycle is closed", e.getMessage()); + } } @Test @@ -171,7 +166,7 @@ void shouldMergeProfilePictureIntoImagesWhenMentorHasProfilePicture() { var profilePicture = createMemberProfilePictureTest(1L).toBuilder().resource(resource).build(); when(profilePicRepo.findByMemberId(1L)).thenReturn(Optional.of(profilePicture)); - doReturn(CYCLE_CLOSED).when(service).getCurrentCycle(); + doReturn(CLOSED_CYCLE).when(service).getCurrentCycle(); var result = service.getAllActiveMentors(); @@ -196,7 +191,7 @@ void shouldReturnEmptyImagesWhenMentorHasNoProfilePicture() { when(mentorRepository.getAll()).thenReturn(List.of(mentor)); when(profilePicRepo.findByMemberId(1L)).thenReturn(Optional.empty()); - doReturn(CYCLE_CLOSED).when(service).getCurrentCycle(); + doReturn(CLOSED_CYCLE).when(service).getCurrentCycle(); var result = service.getAllActiveMentors(); @@ -218,7 +213,7 @@ void shouldHandleExceptionWhenFetchingProfilePictureFails() { when(mentorRepository.getAll()).thenReturn(List.of(mentor)); when(profilePicRepo.findByMemberId(1L)).thenThrow(new RuntimeException("Database error")); - doReturn(CYCLE_CLOSED).when(service).getCurrentCycle(); + doReturn(CLOSED_CYCLE).when(service).getCurrentCycle(); var result = service.getAllActiveMentors(); @@ -245,7 +240,7 @@ void shouldPreservePronounsWhenEnrichedWithProfilePicture() { var profilePicture = createMemberProfilePictureTest(1L).toBuilder().resource(resource).build(); when(profilePicRepo.findByMemberId(1L)).thenReturn(Optional.of(profilePicture)); - doReturn(CYCLE_CLOSED).when(service).getCurrentCycle(); + doReturn(CLOSED_CYCLE).when(service).getCurrentCycle(); var result = service.getAllActiveMentors(); diff --git a/src/test/java/com/wcc/platform/service/MentorshipServiceTest.java b/src/test/java/com/wcc/platform/service/MentorshipServiceTest.java index 9f833844..8a9b5492 100644 --- a/src/test/java/com/wcc/platform/service/MentorshipServiceTest.java +++ b/src/test/java/com/wcc/platform/service/MentorshipServiceTest.java @@ -27,9 +27,11 @@ import com.wcc.platform.domain.exceptions.MentorStatusException; import com.wcc.platform.domain.platform.member.Member; import com.wcc.platform.domain.platform.member.ProfileStatus; +import com.wcc.platform.domain.platform.mentorship.CycleStatus; import com.wcc.platform.domain.platform.mentorship.Mentor; import com.wcc.platform.domain.platform.mentorship.MentorDto; import com.wcc.platform.domain.platform.mentorship.MentorshipCycle; +import com.wcc.platform.domain.platform.mentorship.MentorshipCycleEntity; import com.wcc.platform.domain.platform.mentorship.MentorshipType; import com.wcc.platform.domain.platform.mentorship.Skills; import com.wcc.platform.domain.platform.type.MemberType; @@ -37,6 +39,7 @@ import com.wcc.platform.repository.MemberProfilePictureRepository; import com.wcc.platform.repository.MemberRepository; import com.wcc.platform.repository.MentorRepository; +import com.wcc.platform.repository.MentorshipCycleRepository; import java.time.Month; import java.util.List; import java.util.Optional; @@ -49,7 +52,7 @@ import org.mockito.MockitoAnnotations; import org.mockito.junit.jupiter.MockitoExtension; -@SuppressWarnings("PMD.TooManyMethods") +@SuppressWarnings({"PMD.TooManyMethods", "PMD.ExcessiveImports"}) @ExtendWith(MockitoExtension.class) class MentorshipServiceTest { @@ -58,6 +61,7 @@ class MentorshipServiceTest { @Mock private UserProvisionService userProvisionService; @Mock private MemberProfilePictureRepository profilePicRepo; @Mock private MentorshipNotificationService notificationService; + @Mock private MentorshipCycleRepository cycleRepository; private Mentor mentor; private Mentor updatedMentor; private MentorDto mentorDto; @@ -70,7 +74,6 @@ public MentorshipServiceTest() { @BeforeEach void setUp() { - final int daysOpen = 10; MockitoAnnotations.openMocks(this); mentor = createMentorTest(); mentorDto = createMentorDtoTest(1L, MemberType.DIRECTOR); @@ -81,9 +84,9 @@ void setUp() { new MentorshipService( mentorRepository, memberRepository, + cycleRepository, userProvisionService, profilePicRepo, - daysOpen, notificationService)); } @@ -101,9 +104,6 @@ void whenCreateGivenMentorAlreadyExistsThenThrowDuplicatedMemberException() { verify(mentorRepository, never()).create(any()); } - @Test - @DisplayName( - "Given mentor with new email and no existing ID conflict, when creating mentor, then create and provision user role") void whenCreateGivenMentorDoesNotExistThenCreateMentor() { var mentor = mock(Mentor.class); var menteeSection = mock(MenteeSection.class); @@ -449,15 +449,21 @@ void shouldReturnOnlyActiveMentorsWhenCycleIsOpen() { var activeMentor = mock(Mentor.class); var pendingMentor = mock(Mentor.class); var activeMentorDto = mock(MentorDto.class); - var openCycle = new MentorshipCycle(MentorshipType.LONG_TERM, Month.MARCH); + var openCycle = + Optional.of( + MentorshipCycleEntity.builder() + .mentorshipType(MentorshipType.LONG_TERM) + .cycleMonth(Month.MARCH) + .status(CycleStatus.OPEN) + .build()); when(activeMentor.getProfileStatus()).thenReturn(ProfileStatus.ACTIVE); when(pendingMentor.getProfileStatus()).thenReturn(ProfileStatus.PENDING); - when(activeMentor.toDto(openCycle)).thenReturn(activeMentorDto); + when(activeMentor.toDto(any(MentorshipCycle.class))).thenReturn(activeMentorDto); when(activeMentorDto.getId()).thenReturn(1L); when(mentorRepository.getAll()).thenReturn(List.of(activeMentor, pendingMentor)); when(profilePicRepo.findByMemberId(1L)).thenReturn(Optional.empty()); - when(service.getCurrentCycle()).thenReturn(openCycle); + when(cycleRepository.findOpenCycle()).thenReturn(openCycle); List result = service.getAllActiveMentors(); @@ -466,8 +472,8 @@ void shouldReturnOnlyActiveMentorsWhenCycleIsOpen() { @Test @DisplayName( - "Given active and pending mentors with a closed cycle, when getAllActiveMentors is called, then all" - + " active mentors are returned") + "Given active and pending mentors with a closed cycle, " + + "when getAllActiveMentors is called, then exception is throws for closed cycle") void shouldReturnOnlyActiveMentorsWhenCycleIsClosed() { var activeMentor = mock(Mentor.class); var pendingMentor = mock(Mentor.class); @@ -479,7 +485,8 @@ void shouldReturnOnlyActiveMentorsWhenCycleIsClosed() { when(activeMentorDto.getId()).thenReturn(1L); when(mentorRepository.getAll()).thenReturn(List.of(activeMentor, pendingMentor)); when(profilePicRepo.findByMemberId(1L)).thenReturn(Optional.empty()); - when(service.getCurrentCycle()).thenReturn(MentorshipService.CYCLE_CLOSED); + when(service.getCurrentCycle()) + .thenReturn(MentorshipCycleEntity.builder().status(CycleStatus.CLOSED).build()); List result = service.getAllActiveMentors(); diff --git a/src/testInt/java/com/wcc/platform/service/MenteeServiceIntegrationTest.java b/src/testInt/java/com/wcc/platform/service/MenteeServiceIntegrationTest.java index b60ebf52..f8d08bb8 100644 --- a/src/testInt/java/com/wcc/platform/service/MenteeServiceIntegrationTest.java +++ b/src/testInt/java/com/wcc/platform/service/MenteeServiceIntegrationTest.java @@ -312,24 +312,39 @@ void shouldThrowExceptionWhenMentorDoesNotExist() { } private void ensureLongTermCycleExists() { - final var cycle = cycleRepository.findByYearAndType(TEST_YEAR_2026, MentorshipType.LONG_TERM); - if (cycle.isEmpty()) { - cycleRepository.create( - MentorshipCycleEntity.builder() - .cycleYear(TEST_YEAR_2026) - .mentorshipType(MentorshipType.LONG_TERM) - .cycleMonth(Month.MARCH) - .registrationStartDate(LocalDate.now().minusDays(1)) - .registrationEndDate(LocalDate.now().plusDays(10)) - .cycleStartDate(LocalDate.now().plusDays(15)) - .status(CycleStatus.OPEN) - .maxMenteesPerMentor(MAX_MENTEES_PER_MENTOR) - .description("Test Cycle") - .build()); - } + cycleRepository + .findOpenCycle() + .ifPresent( + cycle -> { + cycle.setStatus(CycleStatus.CLOSED); + cycleRepository.update(cycle.getCycleId(), cycle); + }); + + final var cycle = + MentorshipCycleEntity.builder() + .cycleYear(TEST_YEAR_2026) + .mentorshipType(MentorshipType.LONG_TERM) + .cycleMonth(Month.MARCH) + .registrationStartDate(LocalDate.now().minusDays(1)) + .registrationEndDate(LocalDate.now().plusDays(10)) + .cycleStartDate(LocalDate.now().plusDays(15)) + .status(CycleStatus.OPEN) + .maxMenteesPerMentor(MAX_MENTEES_PER_MENTOR) + .description("Test Cycle") + .build(); + final var savedCycle = cycleRepository.create(cycle); + createdCycles.add(savedCycle.getCycleId()); } private void createAdHocCycle() { + cycleRepository + .findOpenCycle() + .ifPresent( + cycle -> { + cycle.setStatus(CycleStatus.CLOSED); + cycleRepository.update(cycle.getCycleId(), cycle); + }); + final var adHocCycle = MentorshipCycleEntity.builder() .cycleYear(TEST_YEAR_2028)