From 78c542211f2d37684ba9f740a323cc02de3987da Mon Sep 17 00:00:00 2001 From: Urio999 Date: Sat, 21 Dec 2024 16:31:59 +0200 Subject: [PATCH 1/9] init commit --- .../greencity/controller/EventController.java | 5 +- .../controller/EventControllerTest.java | 78 ++++++++-------- .../ManagementEventControllerTest.java | 34 +++---- .../dto/event/EventDateInformationDto.java | 18 ++++ .../dto/event/EventInformationDto.java | 21 +++++ .../greencity/dto/event/EventResponseDto.java | 23 +++++ .../java/greencity/service/EventService.java | 4 +- .../greencity/mapping/events/EventMapper.java | 92 +++++++++++++++++++ .../greencity/service/EventServiceImpl.java | 38 +++++++- .../service/EventServiceImplTest.java | 90 +++++++++--------- 10 files changed, 295 insertions(+), 108 deletions(-) create mode 100644 service-api/src/main/java/greencity/dto/event/EventDateInformationDto.java create mode 100644 service-api/src/main/java/greencity/dto/event/EventInformationDto.java create mode 100644 service-api/src/main/java/greencity/dto/event/EventResponseDto.java create mode 100644 service/src/main/java/greencity/mapping/events/EventMapper.java diff --git a/core/src/main/java/greencity/controller/EventController.java b/core/src/main/java/greencity/controller/EventController.java index efe4cdb498..5aeeb097e6 100644 --- a/core/src/main/java/greencity/controller/EventController.java +++ b/core/src/main/java/greencity/controller/EventController.java @@ -12,6 +12,7 @@ import greencity.dto.event.AddressDto; import greencity.dto.event.EventAttenderDto; import greencity.dto.event.EventDto; +import greencity.dto.event.EventResponseDto; import greencity.dto.event.UpdateEventRequestDto; import greencity.dto.filter.FilterEventDto; import greencity.dto.user.UserVO; @@ -157,7 +158,7 @@ public ResponseEntity update( content = @Content(examples = @ExampleObject(HttpStatuses.NOT_FOUND))) }) @GetMapping("/{eventId}") - public ResponseEntity getEvent( + public ResponseEntity getEvent( @PathVariable Long eventId, @Parameter(hidden = true) Principal principal) { return ResponseEntity.ok().body(eventService.getEvent(eventId, principal)); @@ -494,4 +495,4 @@ public ResponseEntity getAllAttendersCount(@RequestParam(name = "user-id") public ResponseEntity getOrganizersCount(@RequestParam(name = "user-id") Long userId) { return ResponseEntity.ok().body(eventService.getCountOfOrganizedEventsByUserId(userId)); } -} \ No newline at end of file +} diff --git a/core/src/test/java/greencity/controller/EventControllerTest.java b/core/src/test/java/greencity/controller/EventControllerTest.java index 169c615ad6..8a89cb3f22 100644 --- a/core/src/test/java/greencity/controller/EventControllerTest.java +++ b/core/src/test/java/greencity/controller/EventControllerTest.java @@ -503,45 +503,45 @@ void updateBadRequestTest() { .andExpect(status().isBadRequest()); } - @Test - @SneakyThrows - void getEventTest() { - mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", 1L).principal(principal)) - .andExpect(status().isOk()); - - verify(eventService).getEvent(1L, principal); - } - - @Test - @SneakyThrows - void getEventFailedTest() { - mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", "not_number").principal(principal)) - .andExpect(status().isBadRequest()); - - verify(eventService, times(0)).getEvent(1L, principal); - } - - @Test - @SneakyThrows - void getEventResponseTest() { - EventDto eventDto = getEventDto(); - - when(eventService.getEvent(1L, principal)).thenReturn(eventDto); - - MvcResult result = mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", 1L) - .principal(principal) - .accept(MediaType.APPLICATION_JSON) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andReturn(); - - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.findAndRegisterModules(); - EventDto responseEventDto = objectMapper.readValue(result.getResponse().getContentAsString(), EventDto.class); - - assertEquals(eventDto, responseEventDto); - - verify(eventService).getEvent(1L, principal); - } +// @Test +// @SneakyThrows +// void getEventTest() { +// mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", 1L).principal(principal)) +// .andExpect(status().isOk()); +// +// verify(eventService).getEvent(1L, principal); +// } + +// @Test +// @SneakyThrows +// void getEventFailedTest() { +// mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", "not_number").principal(principal)) +// .andExpect(status().isBadRequest()); +// +// verify(eventService, times(0)).getEvent(1L, principal); +// } + +// @Test +// @SneakyThrows +// void getEventResponseTest() { +// EventDto eventDto = getEventDto(); +// +// when(eventService.getEvent(1L, principal)).thenReturn(eventDto); +// +// MvcResult result = mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", 1L) +// .principal(principal) +// .accept(MediaType.APPLICATION_JSON) +// .contentType(MediaType.APPLICATION_JSON)) +// .andExpect(status().isOk()).andReturn(); +// +// ObjectMapper objectMapper = new ObjectMapper(); +// objectMapper.findAndRegisterModules(); +// EventDto responseEventDto = objectMapper.readValue(result.getResponse().getContentAsString(), EventDto.class); +// +// assertEquals(eventDto, responseEventDto); +// +// verify(eventService).getEvent(1L, principal); +// } @Test @SneakyThrows diff --git a/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java b/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java index 16aa094249..c2d5d103c6 100644 --- a/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java +++ b/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java @@ -211,23 +211,23 @@ void testEditEvents() { verify(eventService, times(1)).update(any(UpdateEventRequestDto.class), eq("user"), any(MultipartFile[].class)); } - @Test - void testGetEditPage() throws Exception { - EventDto mockEventDto = new EventDto(); - when(restClient.findByEmail(anyString())).thenReturn(new UserVO()); - mockEventDto.setId(1L); - - when(eventService.getEvent(eq(1L), any(Principal.class))).thenReturn(mockEventDto); - - mockMvc.perform(get(managementEventsLink + "/edit/{id}", 1L) - .principal(() -> "user")) - .andExpect(status().isOk()) - .andExpect(view().name("core/management_edit_event")) - .andExpect(model().attributeExists("eventDto")) - .andExpect(model().attribute("eventDto", mockEventDto)); - - verify(eventService, times(1)).getEvent(eq(1L), any(Principal.class)); - } +// @Test +// void testGetEditPage() throws Exception { +// EventDto mockEventDto = new EventDto(); +// when(restClient.findByEmail(anyString())).thenReturn(new UserVO()); +// mockEventDto.setId(1L); +// +// when(eventService.getEvent(eq(1L), any(Principal.class))).thenReturn(mockEventDto); +// +// mockMvc.perform(get(managementEventsLink + "/edit/{id}", 1L) +// .principal(() -> "user")) +// .andExpect(status().isOk()) +// .andExpect(view().name("core/management_edit_event")) +// .andExpect(model().attributeExists("eventDto")) +// .andExpect(model().attribute("eventDto", mockEventDto)); +// +// verify(eventService, times(1)).getEvent(eq(1L), any(Principal.class)); +// } @Test @SneakyThrows diff --git a/service-api/src/main/java/greencity/dto/event/EventDateInformationDto.java b/service-api/src/main/java/greencity/dto/event/EventDateInformationDto.java new file mode 100644 index 0000000000..4f8bb7cdd8 --- /dev/null +++ b/service-api/src/main/java/greencity/dto/event/EventDateInformationDto.java @@ -0,0 +1,18 @@ +package greencity.dto.event; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; + +@SuperBuilder +@NoArgsConstructor +@Getter +@Setter +@EqualsAndHashCode(callSuper = true) +public class EventDateInformationDto extends AbstractEventDateLocationDto { + private Long id; + private EventResponseDto event; + private AddressDto coordinates; +} diff --git a/service-api/src/main/java/greencity/dto/event/EventInformationDto.java b/service-api/src/main/java/greencity/dto/event/EventInformationDto.java new file mode 100644 index 0000000000..bd9faeb650 --- /dev/null +++ b/service-api/src/main/java/greencity/dto/event/EventInformationDto.java @@ -0,0 +1,21 @@ +package greencity.dto.event; + +import greencity.dto.tag.TagUaEnDto; +import jakarta.validation.constraints.NotEmpty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.util.List; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +public class EventInformationDto { + private String title; + private String description; + private boolean isOpen; + @NotEmpty + private List tags; +} diff --git a/service-api/src/main/java/greencity/dto/event/EventResponseDto.java b/service-api/src/main/java/greencity/dto/event/EventResponseDto.java new file mode 100644 index 0000000000..580d9dee60 --- /dev/null +++ b/service-api/src/main/java/greencity/dto/event/EventResponseDto.java @@ -0,0 +1,23 @@ +package greencity.dto.event; + +import jakarta.validation.constraints.Max; +import lombok.Builder; +import lombok.Data; +import org.springframework.lang.Nullable; +import java.util.List; + +@Data +@Builder +public class EventResponseDto { + private EventInformationDto eventInformation; + + @Max(7) + private List dates; + + @Nullable + private String titleImage; + + @Nullable + @Max(4) + private List additionalImages; +} diff --git a/service-api/src/main/java/greencity/service/EventService.java b/service-api/src/main/java/greencity/service/EventService.java index 4ecc0e648e..0b729ecbaf 100644 --- a/service-api/src/main/java/greencity/service/EventService.java +++ b/service-api/src/main/java/greencity/service/EventService.java @@ -6,6 +6,7 @@ import greencity.dto.event.AddressDto; import greencity.dto.event.EventAttenderDto; import greencity.dto.event.EventDto; +import greencity.dto.event.EventResponseDto; import greencity.dto.event.EventVO; import greencity.dto.event.UpdateEventRequestDto; import greencity.dto.filter.FilterEventDto; @@ -40,7 +41,8 @@ public interface EventService { * @param eventId - event id. * @return {@link EventDto} instance. */ - EventDto getEvent(Long eventId, Principal principal); + EventResponseDto getEvent(Long eventId, Principal principal); + // EventDto getEvent(Long eventId, Principal principal); /** * Method for getting all Event instances filtered. diff --git a/service/src/main/java/greencity/mapping/events/EventMapper.java b/service/src/main/java/greencity/mapping/events/EventMapper.java new file mode 100644 index 0000000000..201c9cb531 --- /dev/null +++ b/service/src/main/java/greencity/mapping/events/EventMapper.java @@ -0,0 +1,92 @@ +package greencity.mapping.events; + +import greencity.dto.event.AddressDto; +import greencity.dto.event.EventDateInformationDto; +import greencity.dto.event.EventInformationDto; +import greencity.dto.event.EventResponseDto; +import greencity.dto.tag.TagUaEnDto; +import greencity.entity.event.Event; +import greencity.entity.event.EventImages; +import greencity.entity.localization.TagTranslation; +import org.modelmapper.AbstractConverter; +import org.springframework.stereotype.Component; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Mapper class for converting {@link Event} into {@link EventResponseDto}. + */ +@Component +public class EventMapper extends AbstractConverter { + private static final String LANGUAGE_UA = "ua"; + private static final String LANGUAGE_EN = "en"; + private static final int MAX_ADDITIONAL_IMAGES = 4; + + /** + * Converts an {@link Event} into {@link EventResponseDto}. + * + * @param event the source object to convert + * @return the converted {@link EventResponseDto} object + */ + @Override + protected EventResponseDto convert(Event event) { + EventInformationDto eventInformation = EventInformationDto.builder() + .title(event.getTitle()) + .description(event.getDescription()) + .isOpen(event.isOpen()) + .tags(event.getTags().stream() + .map(tag -> TagUaEnDto.builder() + .id(tag.getId()) + .nameUa(tag.getTagTranslations().stream() + .filter(tt -> LANGUAGE_EN.equals(tt.getLanguage().getCode())) + .findFirst() + .map(TagTranslation::getName) + .orElse(null)) + .nameEn(tag.getTagTranslations().stream() + .filter(tt -> LANGUAGE_UA.equals(tt.getLanguage().getCode())) + .findFirst() + .map(TagTranslation::getName) + .orElse(null)) + .build()) + .collect(Collectors.toList())) + .build(); + + List dateInformation = event.getDates().stream() + .map(date -> EventDateInformationDto.builder() + .startDate(date.getStartDate()) + .finishDate(date.getFinishDate()) + .onlineLink(date.getOnlineLink()) + .coordinates(AddressDto.builder() + .latitude(date.getAddress().getLatitude()) + .longitude(date.getAddress().getLongitude()) + .streetEn(date.getAddress().getStreetEn()) + .streetUa(date.getAddress().getStreetUa()) + .houseNumber(date.getAddress().getHouseNumber()) + .cityEn(date.getAddress().getCityEn()) + .cityUa(date.getAddress().getCityUa()) + .regionEn(date.getAddress().getRegionEn()) + .regionUa(date.getAddress().getRegionUa()) + .countryEn(date.getAddress().getCountryEn()) + .countryUa(date.getAddress().getCountryUa()) + .formattedAddressEn(date.getAddress().getFormattedAddressEn()) + .formattedAddressUa(date.getAddress().getFormattedAddressUa()) + .build()) + .build()) + .collect(Collectors.toList()); + + String titleImage = event.getTitleImage(); + List additionalImages = event.getAdditionalImages().stream() + .map(EventImages::getLink) + .toList(); + + return EventResponseDto.builder() + .eventInformation(eventInformation) + .dates(dateInformation) + .titleImage(event.getTitleImage()) + .additionalImages(event.getAdditionalImages().stream() + .map(EventImages::getLink) + .limit(MAX_ADDITIONAL_IMAGES) + .collect(Collectors.toList())) + .build(); + } +} diff --git a/service/src/main/java/greencity/service/EventServiceImpl.java b/service/src/main/java/greencity/service/EventServiceImpl.java index 5b3970b62d..1495e49d93 100644 --- a/service/src/main/java/greencity/service/EventServiceImpl.java +++ b/service/src/main/java/greencity/service/EventServiceImpl.java @@ -13,6 +13,7 @@ import greencity.dto.event.EventAuthorDto; import greencity.dto.event.EventDateLocationDto; import greencity.dto.event.EventDto; +import greencity.dto.event.EventResponseDto; import greencity.dto.event.EventVO; import greencity.dto.event.UpdateEventDto; import greencity.dto.event.UpdateEventRequestDto; @@ -223,18 +224,33 @@ public void delete(Long eventId, String email) { ratingCalculation.ratingCalculation(ratingPointsRepo.findByNameOrThrow("UNDO_CREATE_EVENT"), userVO); } + // /** + // * {@inheritDoc} + // */ + // @Override + // public EventDto getEvent(Long eventId, Principal principal) { + // Event event = eventRepo.findById(eventId) + // .orElseThrow(() -> new NotFoundException(ErrorMessage.EVENT_NOT_FOUND)); + // if (principal != null) { + // User currentUser = + // modelMapper.map(restClient.findByEmail(principal.getName()), User.class); + // return buildEventDto(event, currentUser.getId()); + // } + // return buildEventDto(event); + // } + /** * {@inheritDoc} */ @Override - public EventDto getEvent(Long eventId, Principal principal) { + public EventResponseDto getEvent(Long eventId, Principal principal) { Event event = eventRepo.findById(eventId) .orElseThrow(() -> new NotFoundException(ErrorMessage.EVENT_NOT_FOUND)); if (principal != null) { User currentUser = modelMapper.map(restClient.findByEmail(principal.getName()), User.class); - return buildEventDto(event, currentUser.getId()); + return buildEventResponseDto(event, currentUser.getId()); } - return buildEventDto(event); + return modelMapper.map(event, EventResponseDto.class); } /** @@ -713,6 +729,20 @@ private void setFollowers(Collection eventDtos, Long userId) { eventDtos.forEach(eventDto -> eventDto.setFavorite(followedEventIds.contains(eventDto.getId()))); } + private EventResponseDto buildEventResponseDto(Event event, Long userId) { + EventResponseDto eventResponseDto = modelMapper.map(event, EventResponseDto.class); + Integer currentUserGrade = event.getEventGrades() + .stream() + .filter(g -> g.getUser() != null && g.getUser().getId().equals(userId)) + .map(EventGrade::getGrade) + .findFirst() + .orElse(null); + setFollowers(List.of(), userId); + setSubscribes(List.of(), userId); + + return eventResponseDto; + } + private EventDto buildEventDto(Event event, Long userId) { EventDto eventDto = modelMapper.map(event, EventDto.class); Integer currentUserGrade = event.getEventGrades() @@ -1047,4 +1077,4 @@ private boolean removeDislikeIfExists(Event event, UserVO userVO) { } return false; } -} \ No newline at end of file +} diff --git a/service/src/test/java/greencity/service/EventServiceImplTest.java b/service/src/test/java/greencity/service/EventServiceImplTest.java index 427409b7f2..04051796e2 100644 --- a/service/src/test/java/greencity/service/EventServiceImplTest.java +++ b/service/src/test/java/greencity/service/EventServiceImplTest.java @@ -518,51 +518,51 @@ void deleteEventThrowsBadRequestExceptionTest() { verify(eventRepo).findById(1L); } - @Test - void getEventWithoutUser() { - Event event = ModelUtils.getEvent(); - EventDto eventDto = ModelUtils.getEventDto(); - - when(eventRepo.findById(anyLong())).thenReturn(Optional.of(event)); - when(modelMapper.map(event, EventDto.class)).thenReturn(eventDto); - - EventDto actual = eventService.getEvent(1L, null); - - assertEquals(eventDto.getId(), actual.getId()); - assertEquals(eventDto.getAdditionalImages(), actual.getAdditionalImages()); - assertEquals(eventDto.getTitleImage(), actual.getTitleImage()); - assertFalse(actual.isSubscribed()); - assertFalse(actual.isFavorite()); - assertNull(actual.getCurrentUserGrade()); - verify(eventRepo, never()).findFavoritesAmongEventIds(anyList(), anyLong()); - verify(eventRepo, never()).findSubscribedAmongEventIds(anyList(), anyLong()); - } - - @Test - void getEventWithCurrentUser() { - Event event = ModelUtils.getEvent(); - EventDto eventDto = ModelUtils.getEventDto(); - List eventIds = List.of(eventDto.getId()); - Principal principal = ModelUtils.getPrincipal(); - User user = ModelUtils.getUser(); - - event.setEventGrades(List.of(EventGrade.builder().grade(5).user(user).event(event).build())); - - when(modelMapper.map(testUserVo, User.class)).thenReturn(user); - when(restClient.findByEmail(principal.getName())).thenReturn(testUserVo); - when(eventRepo.findById(anyLong())).thenReturn(Optional.of(event)); - when(modelMapper.map(event, EventDto.class)).thenReturn(eventDto); - when(eventRepo.findFavoritesAmongEventIds(eventIds, user.getId())).thenReturn(List.of(event)); - when(eventRepo.findSubscribedAmongEventIds(eventIds, user.getId())).thenReturn(List.of(event)); - - EventDto actual = eventService.getEvent(1L, principal); - - assertTrue(actual.isSubscribed()); - assertTrue(actual.isFavorite()); - assertEquals(5, actual.getCurrentUserGrade()); - verify(eventRepo).findFavoritesAmongEventIds(eventIds, user.getId()); - verify(eventRepo).findSubscribedAmongEventIds(eventIds, user.getId()); - } +// @Test +// void getEventWithoutUser() { +// Event event = ModelUtils.getEvent(); +// EventDto eventDto = ModelUtils.getEventDto(); +// +// when(eventRepo.findById(anyLong())).thenReturn(Optional.of(event)); +// when(modelMapper.map(event, EventDto.class)).thenReturn(eventDto); +// +// EventDto actual = eventService.getEvent(1L, null); +// +// assertEquals(eventDto.getId(), actual.getId()); +// assertEquals(eventDto.getAdditionalImages(), actual.getAdditionalImages()); +// assertEquals(eventDto.getTitleImage(), actual.getTitleImage()); +// assertFalse(actual.isSubscribed()); +// assertFalse(actual.isFavorite()); +// assertNull(actual.getCurrentUserGrade()); +// verify(eventRepo, never()).findFavoritesAmongEventIds(anyList(), anyLong()); +// verify(eventRepo, never()).findSubscribedAmongEventIds(anyList(), anyLong()); +// } + +// @Test +// void getEventWithCurrentUser() { +// Event event = ModelUtils.getEvent(); +// EventDto eventDto = ModelUtils.getEventDto(); +// List eventIds = List.of(eventDto.getId()); +// Principal principal = ModelUtils.getPrincipal(); +// User user = ModelUtils.getUser(); +// +// event.setEventGrades(List.of(EventGrade.builder().grade(5).user(user).event(event).build())); +// +// when(modelMapper.map(testUserVo, User.class)).thenReturn(user); +// when(restClient.findByEmail(principal.getName())).thenReturn(testUserVo); +// when(eventRepo.findById(anyLong())).thenReturn(Optional.of(event)); +// when(modelMapper.map(event, EventDto.class)).thenReturn(eventDto); +// when(eventRepo.findFavoritesAmongEventIds(eventIds, user.getId())).thenReturn(List.of(event)); +// when(eventRepo.findSubscribedAmongEventIds(eventIds, user.getId())).thenReturn(List.of(event)); +// +// EventDto actual = eventService.getEvent(1L, principal); +// +// assertTrue(actual.isSubscribed()); +// assertTrue(actual.isFavorite()); +// assertEquals(5, actual.getCurrentUserGrade()); +// verify(eventRepo).findFavoritesAmongEventIds(eventIds, user.getId()); +// verify(eventRepo).findSubscribedAmongEventIds(eventIds, user.getId()); +// } @Test void addAttenderToOpenEvent() { From 927ceb3537c36145396b262f8cc6f4d938368eec Mon Sep 17 00:00:00 2001 From: Urio999 Date: Mon, 27 Jan 2025 21:44:35 +0200 Subject: [PATCH 2/9] updated EventResponseDto, added /v2/{eventId} endpoint --- .../java/greencity/config/SecurityConfig.java | 1 + .../greencity/controller/EventController.java | 23 ++++- .../controller/EventControllerTest.java | 78 ++++++++-------- .../ManagementEventControllerTest.java | 34 +++---- .../dto/event/EventInformationDto.java | 1 - .../greencity/dto/event/EventResponseDto.java | 34 +++++++ .../java/greencity/service/EventService.java | 11 ++- .../greencity/mapping/events/EventMapper.java | 57 ++++++++++-- .../greencity/service/EventServiceImpl.java | 30 +++---- .../service/EventServiceImplTest.java | 90 +++++++++---------- 10 files changed, 231 insertions(+), 128 deletions(-) diff --git a/core/src/main/java/greencity/config/SecurityConfig.java b/core/src/main/java/greencity/config/SecurityConfig.java index 7950baae96..ae69546ae3 100644 --- a/core/src/main/java/greencity/config/SecurityConfig.java +++ b/core/src/main/java/greencity/config/SecurityConfig.java @@ -193,6 +193,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti EVENTS, EVENTS + "/addresses", EVENTS + EVENT_ID, + EVENTS + "/v2" + EVENT_ID, EVENTS + EVENT_ID + ATTENDERS, "/languages/codes", SEARCH + ECO_NEWS, diff --git a/core/src/main/java/greencity/controller/EventController.java b/core/src/main/java/greencity/controller/EventController.java index 5aeeb097e6..63d4ba0e3e 100644 --- a/core/src/main/java/greencity/controller/EventController.java +++ b/core/src/main/java/greencity/controller/EventController.java @@ -158,12 +158,33 @@ public ResponseEntity update( content = @Content(examples = @ExampleObject(HttpStatuses.NOT_FOUND))) }) @GetMapping("/{eventId}") - public ResponseEntity getEvent( + public ResponseEntity getEvent( @PathVariable Long eventId, @Parameter(hidden = true) Principal principal) { return ResponseEntity.ok().body(eventService.getEvent(eventId, principal)); } + /** + * Method for getting the event by event id version 2. + * + * @return {@link EventResponseDto} instance. + * @author Yurii Osovskyi. + */ + @Operation(summary = "Get the event") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = HttpStatuses.OK), + @ApiResponse(responseCode = "400", description = HttpStatuses.BAD_REQUEST, + content = @Content(examples = @ExampleObject(HttpStatuses.BAD_REQUEST))), + @ApiResponse(responseCode = "404", description = HttpStatuses.NOT_FOUND, + content = @Content(examples = @ExampleObject(HttpStatuses.NOT_FOUND))) + }) + @GetMapping("/v2/{eventId}") + public ResponseEntity getEventV2( + @PathVariable Long eventId, + @Parameter(hidden = true) Principal principal) { + return ResponseEntity.ok().body(eventService.getEventV2(eventId, principal)); + } + /** * Method for getting pages of events. * diff --git a/core/src/test/java/greencity/controller/EventControllerTest.java b/core/src/test/java/greencity/controller/EventControllerTest.java index 8a89cb3f22..169c615ad6 100644 --- a/core/src/test/java/greencity/controller/EventControllerTest.java +++ b/core/src/test/java/greencity/controller/EventControllerTest.java @@ -503,45 +503,45 @@ void updateBadRequestTest() { .andExpect(status().isBadRequest()); } -// @Test -// @SneakyThrows -// void getEventTest() { -// mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", 1L).principal(principal)) -// .andExpect(status().isOk()); -// -// verify(eventService).getEvent(1L, principal); -// } - -// @Test -// @SneakyThrows -// void getEventFailedTest() { -// mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", "not_number").principal(principal)) -// .andExpect(status().isBadRequest()); -// -// verify(eventService, times(0)).getEvent(1L, principal); -// } - -// @Test -// @SneakyThrows -// void getEventResponseTest() { -// EventDto eventDto = getEventDto(); -// -// when(eventService.getEvent(1L, principal)).thenReturn(eventDto); -// -// MvcResult result = mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", 1L) -// .principal(principal) -// .accept(MediaType.APPLICATION_JSON) -// .contentType(MediaType.APPLICATION_JSON)) -// .andExpect(status().isOk()).andReturn(); -// -// ObjectMapper objectMapper = new ObjectMapper(); -// objectMapper.findAndRegisterModules(); -// EventDto responseEventDto = objectMapper.readValue(result.getResponse().getContentAsString(), EventDto.class); -// -// assertEquals(eventDto, responseEventDto); -// -// verify(eventService).getEvent(1L, principal); -// } + @Test + @SneakyThrows + void getEventTest() { + mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", 1L).principal(principal)) + .andExpect(status().isOk()); + + verify(eventService).getEvent(1L, principal); + } + + @Test + @SneakyThrows + void getEventFailedTest() { + mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", "not_number").principal(principal)) + .andExpect(status().isBadRequest()); + + verify(eventService, times(0)).getEvent(1L, principal); + } + + @Test + @SneakyThrows + void getEventResponseTest() { + EventDto eventDto = getEventDto(); + + when(eventService.getEvent(1L, principal)).thenReturn(eventDto); + + MvcResult result = mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/{eventId}", 1L) + .principal(principal) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()).andReturn(); + + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.findAndRegisterModules(); + EventDto responseEventDto = objectMapper.readValue(result.getResponse().getContentAsString(), EventDto.class); + + assertEquals(eventDto, responseEventDto); + + verify(eventService).getEvent(1L, principal); + } @Test @SneakyThrows diff --git a/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java b/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java index c2d5d103c6..16aa094249 100644 --- a/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java +++ b/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java @@ -211,23 +211,23 @@ void testEditEvents() { verify(eventService, times(1)).update(any(UpdateEventRequestDto.class), eq("user"), any(MultipartFile[].class)); } -// @Test -// void testGetEditPage() throws Exception { -// EventDto mockEventDto = new EventDto(); -// when(restClient.findByEmail(anyString())).thenReturn(new UserVO()); -// mockEventDto.setId(1L); -// -// when(eventService.getEvent(eq(1L), any(Principal.class))).thenReturn(mockEventDto); -// -// mockMvc.perform(get(managementEventsLink + "/edit/{id}", 1L) -// .principal(() -> "user")) -// .andExpect(status().isOk()) -// .andExpect(view().name("core/management_edit_event")) -// .andExpect(model().attributeExists("eventDto")) -// .andExpect(model().attribute("eventDto", mockEventDto)); -// -// verify(eventService, times(1)).getEvent(eq(1L), any(Principal.class)); -// } + @Test + void testGetEditPage() throws Exception { + EventDto mockEventDto = new EventDto(); + when(restClient.findByEmail(anyString())).thenReturn(new UserVO()); + mockEventDto.setId(1L); + + when(eventService.getEvent(eq(1L), any(Principal.class))).thenReturn(mockEventDto); + + mockMvc.perform(get(managementEventsLink + "/edit/{id}", 1L) + .principal(() -> "user")) + .andExpect(status().isOk()) + .andExpect(view().name("core/management_edit_event")) + .andExpect(model().attributeExists("eventDto")) + .andExpect(model().attribute("eventDto", mockEventDto)); + + verify(eventService, times(1)).getEvent(eq(1L), any(Principal.class)); + } @Test @SneakyThrows diff --git a/service-api/src/main/java/greencity/dto/event/EventInformationDto.java b/service-api/src/main/java/greencity/dto/event/EventInformationDto.java index bd9faeb650..be72ff3a80 100644 --- a/service-api/src/main/java/greencity/dto/event/EventInformationDto.java +++ b/service-api/src/main/java/greencity/dto/event/EventInformationDto.java @@ -15,7 +15,6 @@ public class EventInformationDto { private String title; private String description; - private boolean isOpen; @NotEmpty private List tags; } diff --git a/service-api/src/main/java/greencity/dto/event/EventResponseDto.java b/service-api/src/main/java/greencity/dto/event/EventResponseDto.java index 580d9dee60..c9c324c4a5 100644 --- a/service-api/src/main/java/greencity/dto/event/EventResponseDto.java +++ b/service-api/src/main/java/greencity/dto/event/EventResponseDto.java @@ -1,16 +1,27 @@ package greencity.dto.event; +import com.fasterxml.jackson.annotation.JsonProperty; +import greencity.enums.EventType; import jakarta.validation.constraints.Max; import lombok.Builder; import lombok.Data; import org.springframework.lang.Nullable; +import java.time.LocalDate; import java.util.List; @Data @Builder public class EventResponseDto { + private Long id; + private EventInformationDto eventInformation; + private EventAuthorDto organizer; + + private LocalDate creationDate; + + private Boolean isOpen; + @Max(7) private List dates; @@ -20,4 +31,27 @@ public class EventResponseDto { @Nullable @Max(4) private List additionalImages; + + private EventType type; + + @JsonProperty("isSubscribed") + private boolean isSubscribed; + + @JsonProperty("isFavorite") + private boolean isFavorite; + + private Boolean isRelevant; + + private Integer likes; + + private Integer dislikes; + + private Integer countComments; + + @JsonProperty("isOrganizedByFriend") + private boolean isOrganizedByFriend; + + private Double eventRate; + + private Double currentUserGrade; } diff --git a/service-api/src/main/java/greencity/service/EventService.java b/service-api/src/main/java/greencity/service/EventService.java index 0b729ecbaf..a5333e0b5d 100644 --- a/service-api/src/main/java/greencity/service/EventService.java +++ b/service-api/src/main/java/greencity/service/EventService.java @@ -41,8 +41,15 @@ public interface EventService { * @param eventId - event id. * @return {@link EventDto} instance. */ - EventResponseDto getEvent(Long eventId, Principal principal); - // EventDto getEvent(Long eventId, Principal principal); + EventDto getEvent(Long eventId, Principal principal); + + /** + * Method for getting Event instance. + * + * @param eventId - event id. + * @return {@link EventResponseDto} instance. + */ + EventResponseDto getEventV2(Long eventId, Principal principal); /** * Method for getting all Event instances filtered. diff --git a/service/src/main/java/greencity/mapping/events/EventMapper.java b/service/src/main/java/greencity/mapping/events/EventMapper.java index 201c9cb531..7f7a3acdf7 100644 --- a/service/src/main/java/greencity/mapping/events/EventMapper.java +++ b/service/src/main/java/greencity/mapping/events/EventMapper.java @@ -1,15 +1,24 @@ package greencity.mapping.events; import greencity.dto.event.AddressDto; +import greencity.dto.event.EventAuthorDto; import greencity.dto.event.EventDateInformationDto; import greencity.dto.event.EventInformationDto; import greencity.dto.event.EventResponseDto; import greencity.dto.tag.TagUaEnDto; +import greencity.entity.User; import greencity.entity.event.Event; +import greencity.entity.event.EventDateLocation; +import greencity.entity.event.EventGrade; import greencity.entity.event.EventImages; import greencity.entity.localization.TagTranslation; +import greencity.service.CommentService; +import lombok.NonNull; import org.modelmapper.AbstractConverter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; +import java.time.ZonedDateTime; import java.util.List; import java.util.stream.Collectors; @@ -22,6 +31,13 @@ public class EventMapper extends AbstractConverter { private static final String LANGUAGE_EN = "en"; private static final int MAX_ADDITIONAL_IMAGES = 4; + private final CommentService commentService; + + @Autowired + public EventMapper(@Lazy CommentService commentService) { + this.commentService = commentService; + } + /** * Converts an {@link Event} into {@link EventResponseDto}. * @@ -33,7 +49,6 @@ protected EventResponseDto convert(Event event) { EventInformationDto eventInformation = EventInformationDto.builder() .title(event.getTitle()) .description(event.getDescription()) - .isOpen(event.isOpen()) .tags(event.getTags().stream() .map(tag -> TagUaEnDto.builder() .id(tag.getId()) @@ -48,11 +63,14 @@ protected EventResponseDto convert(Event event) { .map(TagTranslation::getName) .orElse(null)) .build()) - .collect(Collectors.toList())) + .toList()) .build(); + User organizer = event.getOrganizer(); + List dateInformation = event.getDates().stream() .map(date -> EventDateInformationDto.builder() + .id(date.getId()) .startDate(date.getStartDate()) .finishDate(date.getFinishDate()) .onlineLink(date.getOnlineLink()) @@ -74,19 +92,42 @@ protected EventResponseDto convert(Event event) { .build()) .collect(Collectors.toList()); - String titleImage = event.getTitleImage(); - List additionalImages = event.getAdditionalImages().stream() - .map(EventImages::getLink) - .toList(); - return EventResponseDto.builder() + .id(event.getId()) .eventInformation(eventInformation) + .organizer(EventAuthorDto.builder() + .id(organizer.getId()) + .name(organizer.getName()) + .organizerRating(organizer.getEventOrganizerRating()) + .email(organizer.getEmail()) + .build()) + .creationDate(event.getCreationDate()) + .isOpen(event.isOpen()) .dates(dateInformation) .titleImage(event.getTitleImage()) + .isRelevant(isRelevantCheck(event.getDates())) + .likes(event.getUsersLikedEvents().size()) + .dislikes(event.getUsersDislikedEvents().size()) + .countComments(commentService.countCommentsForEvent(event.getId())) + .type(event.getType()) + .eventRate(calculateEventRate(event.getEventGrades())) + .currentUserGrade(organizer.getRating()) .additionalImages(event.getAdditionalImages().stream() .map(EventImages::getLink) .limit(MAX_ADDITIONAL_IMAGES) - .collect(Collectors.toList())) + .toList()) .build(); } + + private boolean isRelevantCheck(@NonNull List dates) { + return dates.getLast().getFinishDate().isAfter(ZonedDateTime.now()) + || dates.getLast().getFinishDate().isEqual(ZonedDateTime.now()); + } + + private double calculateEventRate(List eventGrades) { + return eventGrades.stream() + .mapToInt(EventGrade::getGrade) + .average() + .orElse(0.0); + } } diff --git a/service/src/main/java/greencity/service/EventServiceImpl.java b/service/src/main/java/greencity/service/EventServiceImpl.java index 1495e49d93..91add03a11 100644 --- a/service/src/main/java/greencity/service/EventServiceImpl.java +++ b/service/src/main/java/greencity/service/EventServiceImpl.java @@ -224,26 +224,26 @@ public void delete(Long eventId, String email) { ratingCalculation.ratingCalculation(ratingPointsRepo.findByNameOrThrow("UNDO_CREATE_EVENT"), userVO); } - // /** - // * {@inheritDoc} - // */ - // @Override - // public EventDto getEvent(Long eventId, Principal principal) { - // Event event = eventRepo.findById(eventId) - // .orElseThrow(() -> new NotFoundException(ErrorMessage.EVENT_NOT_FOUND)); - // if (principal != null) { - // User currentUser = - // modelMapper.map(restClient.findByEmail(principal.getName()), User.class); - // return buildEventDto(event, currentUser.getId()); - // } - // return buildEventDto(event); - // } + /** + * {@inheritDoc} + */ + @Override + public EventDto getEvent(Long eventId, Principal principal) { + Event event = eventRepo.findById(eventId) + .orElseThrow(() -> new NotFoundException(ErrorMessage.EVENT_NOT_FOUND)); + if (principal != null) { + User currentUser = + modelMapper.map(restClient.findByEmail(principal.getName()), User.class); + return buildEventDto(event, currentUser.getId()); + } + return buildEventDto(event); + } /** * {@inheritDoc} */ @Override - public EventResponseDto getEvent(Long eventId, Principal principal) { + public EventResponseDto getEventV2(Long eventId, Principal principal) { Event event = eventRepo.findById(eventId) .orElseThrow(() -> new NotFoundException(ErrorMessage.EVENT_NOT_FOUND)); if (principal != null) { diff --git a/service/src/test/java/greencity/service/EventServiceImplTest.java b/service/src/test/java/greencity/service/EventServiceImplTest.java index 04051796e2..427409b7f2 100644 --- a/service/src/test/java/greencity/service/EventServiceImplTest.java +++ b/service/src/test/java/greencity/service/EventServiceImplTest.java @@ -518,51 +518,51 @@ void deleteEventThrowsBadRequestExceptionTest() { verify(eventRepo).findById(1L); } -// @Test -// void getEventWithoutUser() { -// Event event = ModelUtils.getEvent(); -// EventDto eventDto = ModelUtils.getEventDto(); -// -// when(eventRepo.findById(anyLong())).thenReturn(Optional.of(event)); -// when(modelMapper.map(event, EventDto.class)).thenReturn(eventDto); -// -// EventDto actual = eventService.getEvent(1L, null); -// -// assertEquals(eventDto.getId(), actual.getId()); -// assertEquals(eventDto.getAdditionalImages(), actual.getAdditionalImages()); -// assertEquals(eventDto.getTitleImage(), actual.getTitleImage()); -// assertFalse(actual.isSubscribed()); -// assertFalse(actual.isFavorite()); -// assertNull(actual.getCurrentUserGrade()); -// verify(eventRepo, never()).findFavoritesAmongEventIds(anyList(), anyLong()); -// verify(eventRepo, never()).findSubscribedAmongEventIds(anyList(), anyLong()); -// } - -// @Test -// void getEventWithCurrentUser() { -// Event event = ModelUtils.getEvent(); -// EventDto eventDto = ModelUtils.getEventDto(); -// List eventIds = List.of(eventDto.getId()); -// Principal principal = ModelUtils.getPrincipal(); -// User user = ModelUtils.getUser(); -// -// event.setEventGrades(List.of(EventGrade.builder().grade(5).user(user).event(event).build())); -// -// when(modelMapper.map(testUserVo, User.class)).thenReturn(user); -// when(restClient.findByEmail(principal.getName())).thenReturn(testUserVo); -// when(eventRepo.findById(anyLong())).thenReturn(Optional.of(event)); -// when(modelMapper.map(event, EventDto.class)).thenReturn(eventDto); -// when(eventRepo.findFavoritesAmongEventIds(eventIds, user.getId())).thenReturn(List.of(event)); -// when(eventRepo.findSubscribedAmongEventIds(eventIds, user.getId())).thenReturn(List.of(event)); -// -// EventDto actual = eventService.getEvent(1L, principal); -// -// assertTrue(actual.isSubscribed()); -// assertTrue(actual.isFavorite()); -// assertEquals(5, actual.getCurrentUserGrade()); -// verify(eventRepo).findFavoritesAmongEventIds(eventIds, user.getId()); -// verify(eventRepo).findSubscribedAmongEventIds(eventIds, user.getId()); -// } + @Test + void getEventWithoutUser() { + Event event = ModelUtils.getEvent(); + EventDto eventDto = ModelUtils.getEventDto(); + + when(eventRepo.findById(anyLong())).thenReturn(Optional.of(event)); + when(modelMapper.map(event, EventDto.class)).thenReturn(eventDto); + + EventDto actual = eventService.getEvent(1L, null); + + assertEquals(eventDto.getId(), actual.getId()); + assertEquals(eventDto.getAdditionalImages(), actual.getAdditionalImages()); + assertEquals(eventDto.getTitleImage(), actual.getTitleImage()); + assertFalse(actual.isSubscribed()); + assertFalse(actual.isFavorite()); + assertNull(actual.getCurrentUserGrade()); + verify(eventRepo, never()).findFavoritesAmongEventIds(anyList(), anyLong()); + verify(eventRepo, never()).findSubscribedAmongEventIds(anyList(), anyLong()); + } + + @Test + void getEventWithCurrentUser() { + Event event = ModelUtils.getEvent(); + EventDto eventDto = ModelUtils.getEventDto(); + List eventIds = List.of(eventDto.getId()); + Principal principal = ModelUtils.getPrincipal(); + User user = ModelUtils.getUser(); + + event.setEventGrades(List.of(EventGrade.builder().grade(5).user(user).event(event).build())); + + when(modelMapper.map(testUserVo, User.class)).thenReturn(user); + when(restClient.findByEmail(principal.getName())).thenReturn(testUserVo); + when(eventRepo.findById(anyLong())).thenReturn(Optional.of(event)); + when(modelMapper.map(event, EventDto.class)).thenReturn(eventDto); + when(eventRepo.findFavoritesAmongEventIds(eventIds, user.getId())).thenReturn(List.of(event)); + when(eventRepo.findSubscribedAmongEventIds(eventIds, user.getId())).thenReturn(List.of(event)); + + EventDto actual = eventService.getEvent(1L, principal); + + assertTrue(actual.isSubscribed()); + assertTrue(actual.isFavorite()); + assertEquals(5, actual.getCurrentUserGrade()); + verify(eventRepo).findFavoritesAmongEventIds(eventIds, user.getId()); + verify(eventRepo).findSubscribedAmongEventIds(eventIds, user.getId()); + } @Test void addAttenderToOpenEvent() { From b8e88f281f35a9e437cf1145be8bd7af24c97d8f Mon Sep 17 00:00:00 2001 From: Urio999 Date: Thu, 30 Jan 2025 00:50:37 +0200 Subject: [PATCH 3/9] added tests --- core/src/test/java/greencity/ModelUtils.java | 61 +++++++++++++++++- .../controller/EventControllerTest.java | 31 +++++++++ .../greencity/dto/event/EventResponseDto.java | 2 +- .../mapping/events/EventDtoMapper.java | 21 ++----- ...apper.java => EventResponseDtoMapper.java} | 30 +++------ .../greencity/service/EventServiceImpl.java | 1 + .../main/java/greencity/utils/EventUtils.java | 23 +++++++ .../src/test/java/greencity/ModelUtils.java | 40 ++++++++++++ .../events/EventResponseDtoMapperTest.java | 54 ++++++++++++++++ .../service/EventServiceImplTest.java | 46 ++++++++++++++ .../java/greencity/utils/EventUtilsTest.java | 63 +++++++++++++++++++ 11 files changed, 330 insertions(+), 42 deletions(-) rename service/src/main/java/greencity/mapping/events/{EventMapper.java => EventResponseDtoMapper.java} (83%) create mode 100644 service/src/main/java/greencity/utils/EventUtils.java create mode 100644 service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java create mode 100644 service/src/test/java/greencity/utils/EventUtilsTest.java diff --git a/core/src/test/java/greencity/ModelUtils.java b/core/src/test/java/greencity/ModelUtils.java index c883f6db26..62097b5d6f 100644 --- a/core/src/test/java/greencity/ModelUtils.java +++ b/core/src/test/java/greencity/ModelUtils.java @@ -18,8 +18,11 @@ import greencity.dto.event.AddEventDtoRequest; import greencity.dto.event.AddressDto; import greencity.dto.event.EventAuthorDto; +import greencity.dto.event.EventDateInformationDto; import greencity.dto.event.EventDateLocationDto; import greencity.dto.event.EventDto; +import greencity.dto.event.EventInformationDto; +import greencity.dto.event.EventResponseDto; import greencity.dto.event.UpdateEventDateLocationDto; import greencity.dto.event.UpdateEventRequestDto; import greencity.dto.favoriteplace.FavoritePlaceDto; @@ -39,6 +42,7 @@ import greencity.dto.location.LocationDto; import greencity.dto.location.MapBoundsDto; import greencity.dto.place.PlaceByBoundsDto; +import greencity.dto.tag.TagDto; import greencity.dto.todolistitem.CustomToDoListItemResponseDto; import greencity.dto.todolistitem.ToDoListItemPostDto; import greencity.dto.todolistitem.ToDoListItemRequestDto; @@ -59,6 +63,7 @@ import greencity.enums.ArticleType; import greencity.enums.CommentStatus; import greencity.enums.EventStatus; +import greencity.enums.EventType; import greencity.enums.Role; import greencity.enums.ToDoListItemStatus; import greencity.enums.TagType; @@ -66,8 +71,11 @@ import java.security.Principal; import java.sql.Date; import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.time.ZoneId; +import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Arrays; @@ -588,4 +596,55 @@ public static List getPlaceByBoundsDto() { .location(new LocationDto()) .build()); } -} \ No newline at end of file + + public static EventResponseDto getEventResponseDto() { + return EventResponseDto.builder() + .id(1L) + .eventInformation(EventInformationDto.builder() + .title("Test Event") + .description("New Test Event") + .tags(List.of(TagUaEnDto.builder() + .id(2L) + .nameUa("Соціальний") + .nameEn("Social") + .build())) + .build()) + .organizer(EventAuthorDto.builder().id(1L).name("Test").email("test@email.com").build()) + .creationDate(LocalDate.of(2025, 1, 10)) + .isOpen(true) + .dates(List.of( + EventDateInformationDto.builder() + .startDate(ZonedDateTime.of(2025, 12, 26, 12, 30, 0, 0, ZoneOffset.UTC)) + .finishDate(ZonedDateTime.of(2025, 12, 26, 21, 59, 0, 0, ZoneOffset.UTC)) + .onlineLink("www.testlink.com") + .coordinates(AddressDto.builder() + .latitude(50.44628775288652) + .longitude(30.49364829378446) + .streetEn("Halytska Square") + .streetUa("Галицька площа") + .houseNumber("1") + .cityEn("Kyiv") + .cityUa("Київ") + .regionEn("Kyiv") + .regionUa("місто Київ") + .countryEn("Ukraine") + .countryUa("Україна") + .formattedAddressEn("Halytska Sq, 1, Kyiv, Ukraine, 02000") + .formattedAddressUa("Галицька пл., 1, Київ, Україна, 02000") + .build()) + .build())) + .titleImage("https://test.png") + .additionalImages(List.of("https://test1.png", "https://test2.png")) + .type(EventType.OFFLINE) + .isRelevant(true) + .likes(3) + .dislikes(1) + .countComments(1) + .eventRate(20.0) + .currentUserGrade(50) + .isSubscribed(false) + .isFavorite(false) + .isOrganizedByFriend(false) + .build(); + } +} diff --git a/core/src/test/java/greencity/controller/EventControllerTest.java b/core/src/test/java/greencity/controller/EventControllerTest.java index 91ae6768cf..fad20c3f5a 100644 --- a/core/src/test/java/greencity/controller/EventControllerTest.java +++ b/core/src/test/java/greencity/controller/EventControllerTest.java @@ -7,6 +7,7 @@ import greencity.dto.PageableAdvancedDto; import greencity.dto.event.AddEventDtoRequest; import greencity.dto.event.EventDto; +import greencity.dto.event.EventResponseDto; import greencity.dto.event.UpdateEventRequestDto; import greencity.dto.filter.FilterEventDto; import greencity.dto.user.UserVO; @@ -756,4 +757,34 @@ void declineRequestTest() { .andExpect(status().isOk()); verify(eventService).declineRequest(eventId, principal.getName(), userId); } + + @Test + @SneakyThrows + void getEventV2Test() { + Long eventId = 1L; + EventResponseDto eventResponseDto = ModelUtils.getEventResponseDto(); + + when(eventService.getEventV2(eventId, principal)).thenReturn(eventResponseDto); + + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.findAndRegisterModules(); + String expectedJson = objectMapper.writeValueAsString(eventResponseDto); + + mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/v2/{eventId}", eventId) + .principal(principal) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json(expectedJson)); + + verify(eventService, times(1)).getEventV2(eventId, principal); + } + + @Test + @SneakyThrows + void getEventV2FailedTest() { + mockMvc.perform(get(EVENTS_CONTROLLER_LINK + "/v2/{eventId}", "not_number").principal(principal)) + .andExpect(status().isBadRequest()); + + verify(eventService, times(0)).getEventV2(1L, principal); + } } diff --git a/service-api/src/main/java/greencity/dto/event/EventResponseDto.java b/service-api/src/main/java/greencity/dto/event/EventResponseDto.java index c9c324c4a5..37749b3143 100644 --- a/service-api/src/main/java/greencity/dto/event/EventResponseDto.java +++ b/service-api/src/main/java/greencity/dto/event/EventResponseDto.java @@ -53,5 +53,5 @@ public class EventResponseDto { private Double eventRate; - private Double currentUserGrade; + private Integer currentUserGrade; } diff --git a/service/src/main/java/greencity/mapping/events/EventDtoMapper.java b/service/src/main/java/greencity/mapping/events/EventDtoMapper.java index 5cf4c2ee8a..1a4b8b1056 100644 --- a/service/src/main/java/greencity/mapping/events/EventDtoMapper.java +++ b/service/src/main/java/greencity/mapping/events/EventDtoMapper.java @@ -9,10 +9,9 @@ import greencity.entity.event.Address; import greencity.entity.event.Event; import greencity.entity.event.EventDateLocation; -import greencity.entity.event.EventGrade; import greencity.entity.event.EventImages; -import java.time.ZonedDateTime; import greencity.service.CommentService; +import greencity.utils.EventUtils; import org.modelmapper.AbstractConverter; import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; @@ -51,7 +50,7 @@ public EventDto convert(Event event) { eventDto.setTitleImage(event.getTitleImage()); eventDto.setOpen(event.isOpen()); eventDto.setType(event.getType()); - eventDto.setIsRelevant(isRelevant(event.getDates())); + eventDto.setIsRelevant(EventUtils.isRelevant(event.getDates())); eventDto.setLikes(event.getUsersLikedEvents().size()); eventDto.setCountComments(commentService.countCommentsForEvent(event.getId())); User organizer = event.getOrganizer(); @@ -80,7 +79,7 @@ public EventDto convert(Event event) { eventDto.setAdditionalImages(event.getAdditionalImages().stream() .map(EventImages::getLink).collect(Collectors.toList())); } - eventDto.setEventRate(calculateEventRate(event.getEventGrades())); + eventDto.setEventRate(EventUtils.calculateEventRate(event.getEventGrades())); return eventDto; } @@ -111,16 +110,4 @@ private EventDateLocationDto convertEventDateLocation(EventDateLocation eventDat } return eventDateLocationDto; } - - private double calculateEventRate(List eventGrades) { - return eventGrades.stream() - .mapToInt(EventGrade::getGrade) - .average() - .orElse(0.0); - } - - private boolean isRelevant(List dates) { - return dates.getLast().getFinishDate().isAfter(ZonedDateTime.now()) - || dates.getLast().getFinishDate().isEqual(ZonedDateTime.now()); - } -} \ No newline at end of file +} diff --git a/service/src/main/java/greencity/mapping/events/EventMapper.java b/service/src/main/java/greencity/mapping/events/EventResponseDtoMapper.java similarity index 83% rename from service/src/main/java/greencity/mapping/events/EventMapper.java rename to service/src/main/java/greencity/mapping/events/EventResponseDtoMapper.java index 7f7a3acdf7..5a1b1cefda 100644 --- a/service/src/main/java/greencity/mapping/events/EventMapper.java +++ b/service/src/main/java/greencity/mapping/events/EventResponseDtoMapper.java @@ -8,17 +8,14 @@ import greencity.dto.tag.TagUaEnDto; import greencity.entity.User; import greencity.entity.event.Event; -import greencity.entity.event.EventDateLocation; -import greencity.entity.event.EventGrade; import greencity.entity.event.EventImages; import greencity.entity.localization.TagTranslation; import greencity.service.CommentService; -import lombok.NonNull; +import greencity.utils.EventUtils; import org.modelmapper.AbstractConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; -import java.time.ZonedDateTime; import java.util.List; import java.util.stream.Collectors; @@ -26,7 +23,7 @@ * Mapper class for converting {@link Event} into {@link EventResponseDto}. */ @Component -public class EventMapper extends AbstractConverter { +public class EventResponseDtoMapper extends AbstractConverter { private static final String LANGUAGE_UA = "ua"; private static final String LANGUAGE_EN = "en"; private static final int MAX_ADDITIONAL_IMAGES = 4; @@ -34,7 +31,7 @@ public class EventMapper extends AbstractConverter { private final CommentService commentService; @Autowired - public EventMapper(@Lazy CommentService commentService) { + public EventResponseDtoMapper(@Lazy CommentService commentService) { this.commentService = commentService; } @@ -53,12 +50,12 @@ protected EventResponseDto convert(Event event) { .map(tag -> TagUaEnDto.builder() .id(tag.getId()) .nameUa(tag.getTagTranslations().stream() - .filter(tt -> LANGUAGE_EN.equals(tt.getLanguage().getCode())) + .filter(tt -> LANGUAGE_UA.equals(tt.getLanguage().getCode())) .findFirst() .map(TagTranslation::getName) .orElse(null)) .nameEn(tag.getTagTranslations().stream() - .filter(tt -> LANGUAGE_UA.equals(tt.getLanguage().getCode())) + .filter(tt -> LANGUAGE_EN.equals(tt.getLanguage().getCode())) .findFirst() .map(TagTranslation::getName) .orElse(null)) @@ -105,29 +102,16 @@ protected EventResponseDto convert(Event event) { .isOpen(event.isOpen()) .dates(dateInformation) .titleImage(event.getTitleImage()) - .isRelevant(isRelevantCheck(event.getDates())) + .isRelevant(EventUtils.isRelevant(event.getDates())) .likes(event.getUsersLikedEvents().size()) .dislikes(event.getUsersDislikedEvents().size()) .countComments(commentService.countCommentsForEvent(event.getId())) .type(event.getType()) - .eventRate(calculateEventRate(event.getEventGrades())) - .currentUserGrade(organizer.getRating()) + .eventRate(EventUtils.calculateEventRate(event.getEventGrades())) .additionalImages(event.getAdditionalImages().stream() .map(EventImages::getLink) .limit(MAX_ADDITIONAL_IMAGES) .toList()) .build(); } - - private boolean isRelevantCheck(@NonNull List dates) { - return dates.getLast().getFinishDate().isAfter(ZonedDateTime.now()) - || dates.getLast().getFinishDate().isEqual(ZonedDateTime.now()); - } - - private double calculateEventRate(List eventGrades) { - return eventGrades.stream() - .mapToInt(EventGrade::getGrade) - .average() - .orElse(0.0); - } } diff --git a/service/src/main/java/greencity/service/EventServiceImpl.java b/service/src/main/java/greencity/service/EventServiceImpl.java index 7873d78d31..b82cc6ce93 100644 --- a/service/src/main/java/greencity/service/EventServiceImpl.java +++ b/service/src/main/java/greencity/service/EventServiceImpl.java @@ -743,6 +743,7 @@ private EventResponseDto buildEventResponseDto(Event event, Long userId) { .orElse(null); setFollowers(List.of(), userId); setSubscribes(List.of(), userId); + eventResponseDto.setCurrentUserGrade(currentUserGrade); return eventResponseDto; } diff --git a/service/src/main/java/greencity/utils/EventUtils.java b/service/src/main/java/greencity/utils/EventUtils.java new file mode 100644 index 0000000000..d8461862dd --- /dev/null +++ b/service/src/main/java/greencity/utils/EventUtils.java @@ -0,0 +1,23 @@ +package greencity.utils; + +import greencity.entity.event.EventDateLocation; +import greencity.entity.event.EventGrade; +import java.time.ZonedDateTime; +import java.util.List; + +public class EventUtils { + public static boolean isRelevant(List dates) { + if (dates == null || dates.isEmpty()) { + return false; + } + return dates.getLast().getFinishDate().isAfter(ZonedDateTime.now()) + || dates.getLast().getFinishDate().isEqual(ZonedDateTime.now()); + } + + public static double calculateEventRate(List eventGrades) { + return eventGrades.stream() + .mapToInt(EventGrade::getGrade) + .average() + .orElse(0.0); + } +} diff --git a/service/src/test/java/greencity/ModelUtils.java b/service/src/test/java/greencity/ModelUtils.java index 053af00f65..6a8e7a6f22 100644 --- a/service/src/test/java/greencity/ModelUtils.java +++ b/service/src/test/java/greencity/ModelUtils.java @@ -42,8 +42,11 @@ import greencity.dto.event.AddressDto; import greencity.dto.event.EventAttenderDto; import greencity.dto.event.EventAuthorDto; +import greencity.dto.event.EventDateInformationDto; import greencity.dto.event.EventDateLocationDto; import greencity.dto.event.EventDto; +import greencity.dto.event.EventInformationDto; +import greencity.dto.event.EventResponseDto; import greencity.dto.event.EventVO; import greencity.dto.event.UpdateAddressDto; import greencity.dto.event.UpdateEventDateLocationDto; @@ -3431,4 +3434,41 @@ public static CategoryDto getCategoryDto() { "Category Ua", 1L); } + + public static EventResponseDto getEventResponseDto() { + return EventResponseDto.builder() + .id(1L) + .eventInformation(EventInformationDto.builder() + .title("Title") + .description("New Test Event") + .tags(List.of(TagUaEnDto.builder() + .id(2L) + .nameUa("Соціальний") + .nameEn("Social") + .build())) + .build()) + .organizer(EventAuthorDto.builder().id(1L).name("Test").build()) + .creationDate(LocalDate.of(2025, 1, 10)) + .isOpen(true) + .dates(List.of( + EventDateInformationDto.builder() + .startDate(ZonedDateTime.of(2025, 12, 26, 12, 30, 0, 0, ZoneOffset.UTC)) + .finishDate(ZonedDateTime.of(2025, 12, 26, 21, 59, 0, 0, ZoneOffset.UTC)) + .onlineLink("www.link.com") + .coordinates(getAddressDtoCorrect()).build())) + .type(EventType.OFFLINE) + .isRelevant(true) + .countComments(1) + .isSubscribed(false) + .isFavorite(false) + .isOrganizedByFriend(false) + .build(); + } + + public static EventDateLocation createEventDateLocation(ZonedDateTime start, ZonedDateTime finish) { + return EventDateLocation.builder() + .startDate(start) + .finishDate(finish) + .build(); + } } diff --git a/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java b/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java new file mode 100644 index 0000000000..082e419d22 --- /dev/null +++ b/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java @@ -0,0 +1,54 @@ +package greencity.mapping.events; + +import greencity.ModelUtils; +import greencity.dto.event.EventResponseDto; +import greencity.entity.event.Event; +import greencity.entity.event.EventDateLocation; +import greencity.entity.event.EventGrade; +import greencity.service.CommentService; +import greencity.utils.EventUtils; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static greencity.ModelUtils.getEvent; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@ExtendWith(SpringExtension.class) +class EventResponseDtoMapperTest { + @InjectMocks + EventResponseDtoMapper mapper; + + @Mock + CommentService commentService; + + @Test + void convertTest() { + Event event = getEvent(); + event.setAdditionalImages(new ArrayList<>()); + event.setUsersLikedEvents(Set.of(ModelUtils.getUser())); + EventResponseDto expected = ModelUtils.getEventResponseDto(); + + EventResponseDto result = mapper.convert(event); + + assertEquals(expected.getEventInformation().getTitle(), result.getEventInformation().getTitle()); + assertEquals(event.getUsersLikedEvents().size(), result.getLikes()); + } + + @Test + void isRelevantFieldTest() { + when(commentService.countCommentsForEvent(any())).thenReturn(0); + Event event = getEvent(); + EventResponseDto result = mapper.convert(event); + assertTrue(result.getIsRelevant()); + } +} diff --git a/service/src/test/java/greencity/service/EventServiceImplTest.java b/service/src/test/java/greencity/service/EventServiceImplTest.java index b32447eabb..8411cec132 100644 --- a/service/src/test/java/greencity/service/EventServiceImplTest.java +++ b/service/src/test/java/greencity/service/EventServiceImplTest.java @@ -13,6 +13,7 @@ import greencity.dto.event.EventAttenderDto; import greencity.dto.event.EventDateLocationDto; import greencity.dto.event.EventDto; +import greencity.dto.event.EventResponseDto; import greencity.dto.event.UpdateEventDto; import greencity.dto.event.UpdateEventRequestDto; import greencity.dto.filter.FilterEventDto; @@ -540,6 +541,51 @@ void getEventWithoutUser() { verify(eventRepo, never()).findSubscribedAmongEventIds(anyList(), anyLong()); } + @Test + void getEventV2WithoutUserTest() { + Event event = ModelUtils.getEvent(); + EventResponseDto eventResponseDto = ModelUtils.getEventResponseDto(); + + when(eventRepo.findById(anyLong())).thenReturn(Optional.of(event)); + when(modelMapper.map(event, EventResponseDto.class)).thenReturn(eventResponseDto); + + EventResponseDto actual = eventService.getEventV2(1L, null); + + assertEquals(eventResponseDto.getId(), actual.getId()); + assertEquals(eventResponseDto.getAdditionalImages(), actual.getAdditionalImages()); + assertEquals(eventResponseDto.getTitleImage(), actual.getTitleImage()); + assertFalse(actual.isSubscribed()); + assertFalse(actual.isFavorite()); + + verify(eventRepo).findById(1L); + verify(modelMapper).map(event, EventResponseDto.class); + } + + @Test + void getEventV2WithCurrentUserTest() { + Event event = ModelUtils.getEvent(); + EventResponseDto eventResponseDto = ModelUtils.getEventResponseDto(); + Principal principal = ModelUtils.getPrincipal(); + User user = ModelUtils.getUser(); + + event.setEventGrades(List.of(EventGrade.builder().grade(50).user(user).event(event).build())); + + when(modelMapper.map(testUserVo, User.class)).thenReturn(user); + when(restClient.findByEmail(principal.getName())).thenReturn(testUserVo); + when(eventRepo.findById(anyLong())).thenReturn(Optional.of(event)); + when(modelMapper.map(event, EventResponseDto.class)).thenReturn(eventResponseDto); + + EventResponseDto actual = eventService.getEventV2(1L, principal); + + assertFalse(actual.isSubscribed()); + assertFalse(actual.isFavorite()); + assertEquals(50, actual.getCurrentUserGrade()); + + verify(restClient).findByEmail(principal.getName()); + verify(eventRepo).findById(1L); + verify(modelMapper).map(event, EventResponseDto.class); + } + @Test void getEventWithCurrentUser() { Event event = ModelUtils.getEvent(); diff --git a/service/src/test/java/greencity/utils/EventUtilsTest.java b/service/src/test/java/greencity/utils/EventUtilsTest.java new file mode 100644 index 0000000000..04351cd214 --- /dev/null +++ b/service/src/test/java/greencity/utils/EventUtilsTest.java @@ -0,0 +1,63 @@ +package greencity.utils; + +import greencity.entity.event.EventDateLocation; +import greencity.entity.event.EventGrade; +import org.junit.jupiter.api.Test; +import java.time.ZonedDateTime; +import java.util.List; +import static greencity.ModelUtils.createEventDateLocation; +import static org.junit.jupiter.api.Assertions.*; + +class EventUtilsTest { + @Test + void isRelevantFalseWhenDatesListIsNullTest() { + assertFalse(EventUtils.isRelevant(null)); + } + + @Test + void isRelevantFalseWhenDatesListIsEmptyTest() { + assertFalse(EventUtils.isRelevant(List.of())); + } + + @Test + void isRelevantFalseWhenAllEventsAreInPastTest() { + List pastEvents = List.of( + createEventDateLocation(ZonedDateTime.now().minusDays(10), ZonedDateTime.now().minusDays(5)), + createEventDateLocation(ZonedDateTime.now().minusDays(4), ZonedDateTime.now().minusDays(1))); + + assertFalse(EventUtils.isRelevant(pastEvents)); + } + + @Test + void isRelevantTrueWhenLatestEventIsInFutureTest() { + List mixedEvents = List.of( + createEventDateLocation(ZonedDateTime.now().minusDays(10), ZonedDateTime.now().minusDays(5)), + createEventDateLocation(ZonedDateTime.now().plusDays(2), ZonedDateTime.now().plusDays(5))); + + assertTrue(EventUtils.isRelevant(mixedEvents)); + } + + @Test + void isRelevant_shouldReturnTrue_whenLatestEventEndsNowTest() { + List events = List.of( + createEventDateLocation(ZonedDateTime.now().minusDays(10), ZonedDateTime.now().minusDays(5)), + createEventDateLocation(ZonedDateTime.now().minusDays(2), ZonedDateTime.now())); + + assertTrue(EventUtils.isRelevant(events)); + } + + @Test + void calculateEventRateReturnsCorrectAverageTest() { + List grades = List.of( + EventGrade.builder().grade(4).build(), + EventGrade.builder().grade(5).build(), + EventGrade.builder().grade(3).build()); + assertEquals(4.0, EventUtils.calculateEventRate(grades)); + } + + @Test + void calculateEventRateReturnsSingleValueForOneGradeTest() { + List grades = List.of(EventGrade.builder().grade(5).build()); + assertEquals(5.0, EventUtils.calculateEventRate(grades)); + } +} From 41d6e40b3ba7dbc42c1a2f9b0155eb829b9b5802 Mon Sep 17 00:00:00 2001 From: Urio999 Date: Thu, 30 Jan 2025 12:45:35 +0200 Subject: [PATCH 4/9] improved test --- .../greencity/webcontroller/ManagementEventControllerTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java b/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java index 248764a552..a106143137 100644 --- a/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java +++ b/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java @@ -78,6 +78,7 @@ class ManagementEventControllerTest { @BeforeEach void setUp() { + Locale.setDefault(Locale.ENGLISH); this.mockMvc = MockMvcBuilders.standaloneSetup(managementEventController) .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver()) .setValidator(mockValidator) From 145894601712dd875e60527061f0b3d4da32a9ba Mon Sep 17 00:00:00 2001 From: Urio999 Date: Thu, 30 Jan 2025 13:31:19 +0200 Subject: [PATCH 5/9] updated test --- .../src/test/java/greencity/utils/EventUtilsTest.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/service/src/test/java/greencity/utils/EventUtilsTest.java b/service/src/test/java/greencity/utils/EventUtilsTest.java index 04351cd214..ca417d7379 100644 --- a/service/src/test/java/greencity/utils/EventUtilsTest.java +++ b/service/src/test/java/greencity/utils/EventUtilsTest.java @@ -37,15 +37,6 @@ void isRelevantTrueWhenLatestEventIsInFutureTest() { assertTrue(EventUtils.isRelevant(mixedEvents)); } - @Test - void isRelevant_shouldReturnTrue_whenLatestEventEndsNowTest() { - List events = List.of( - createEventDateLocation(ZonedDateTime.now().minusDays(10), ZonedDateTime.now().minusDays(5)), - createEventDateLocation(ZonedDateTime.now().minusDays(2), ZonedDateTime.now())); - - assertTrue(EventUtils.isRelevant(events)); - } - @Test void calculateEventRateReturnsCorrectAverageTest() { List grades = List.of( From 88dabc5b6ffc48c3d3882a2976e242eb6d8ece0a Mon Sep 17 00:00:00 2001 From: Urio999 Date: Thu, 30 Jan 2025 14:08:41 +0200 Subject: [PATCH 6/9] fixed issues --- core/src/test/java/greencity/ModelUtils.java | 2 -- service/src/main/java/greencity/utils/EventUtils.java | 2 ++ .../mapping/events/EventResponseDtoMapperTest.java | 6 ------ 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/core/src/test/java/greencity/ModelUtils.java b/core/src/test/java/greencity/ModelUtils.java index 62097b5d6f..7788845f4a 100644 --- a/core/src/test/java/greencity/ModelUtils.java +++ b/core/src/test/java/greencity/ModelUtils.java @@ -42,7 +42,6 @@ import greencity.dto.location.LocationDto; import greencity.dto.location.MapBoundsDto; import greencity.dto.place.PlaceByBoundsDto; -import greencity.dto.tag.TagDto; import greencity.dto.todolistitem.CustomToDoListItemResponseDto; import greencity.dto.todolistitem.ToDoListItemPostDto; import greencity.dto.todolistitem.ToDoListItemRequestDto; @@ -73,7 +72,6 @@ import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; diff --git a/service/src/main/java/greencity/utils/EventUtils.java b/service/src/main/java/greencity/utils/EventUtils.java index d8461862dd..4d877cd541 100644 --- a/service/src/main/java/greencity/utils/EventUtils.java +++ b/service/src/main/java/greencity/utils/EventUtils.java @@ -2,9 +2,11 @@ import greencity.entity.event.EventDateLocation; import greencity.entity.event.EventGrade; +import lombok.experimental.UtilityClass; import java.time.ZonedDateTime; import java.util.List; +@UtilityClass public class EventUtils { public static boolean isRelevant(List dates) { if (dates == null || dates.isEmpty()) { diff --git a/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java b/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java index 082e419d22..03c4efe883 100644 --- a/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java +++ b/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java @@ -3,20 +3,14 @@ import greencity.ModelUtils; import greencity.dto.event.EventResponseDto; import greencity.entity.event.Event; -import greencity.entity.event.EventDateLocation; -import greencity.entity.event.EventGrade; import greencity.service.CommentService; -import greencity.utils.EventUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.springframework.test.context.junit.jupiter.SpringExtension; -import java.time.ZonedDateTime; import java.util.ArrayList; -import java.util.List; import java.util.Set; - import static greencity.ModelUtils.getEvent; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; From 00112a1652d9ebe646e53d7c8d75e63165a37da2 Mon Sep 17 00:00:00 2001 From: Urio999 Date: Fri, 31 Jan 2025 10:48:43 +0200 Subject: [PATCH 7/9] added improvements according coderabbitai suggestions --- core/src/test/java/greencity/ModelUtils.java | 33 +++++++------- .../ManagementEventControllerTest.java | 9 ++++ .../events/EventResponseDtoMapper.java | 45 ++++++++++--------- .../main/java/greencity/utils/EventUtils.java | 4 ++ .../events/EventResponseDtoMapperTest.java | 12 +++-- .../java/greencity/utils/EventUtilsTest.java | 18 ++++++++ 6 files changed, 77 insertions(+), 44 deletions(-) diff --git a/core/src/test/java/greencity/ModelUtils.java b/core/src/test/java/greencity/ModelUtils.java index 7788845f4a..8df5436808 100644 --- a/core/src/test/java/greencity/ModelUtils.java +++ b/core/src/test/java/greencity/ModelUtils.java @@ -615,22 +615,7 @@ public static EventResponseDto getEventResponseDto() { .startDate(ZonedDateTime.of(2025, 12, 26, 12, 30, 0, 0, ZoneOffset.UTC)) .finishDate(ZonedDateTime.of(2025, 12, 26, 21, 59, 0, 0, ZoneOffset.UTC)) .onlineLink("www.testlink.com") - .coordinates(AddressDto.builder() - .latitude(50.44628775288652) - .longitude(30.49364829378446) - .streetEn("Halytska Square") - .streetUa("Галицька площа") - .houseNumber("1") - .cityEn("Kyiv") - .cityUa("Київ") - .regionEn("Kyiv") - .regionUa("місто Київ") - .countryEn("Ukraine") - .countryUa("Україна") - .formattedAddressEn("Halytska Sq, 1, Kyiv, Ukraine, 02000") - .formattedAddressUa("Галицька пл., 1, Київ, Україна, 02000") - .build()) - .build())) + .coordinates(getAddressDtoCorrect()).build())) .titleImage("https://test.png") .additionalImages(List.of("https://test1.png", "https://test2.png")) .type(EventType.OFFLINE) @@ -645,4 +630,20 @@ public static EventResponseDto getEventResponseDto() { .isOrganizedByFriend(false) .build(); } + + public static AddressDto getAddressDtoCorrect() { + return AddressDto.builder() + .latitude(50.4567236) + .longitude(30.2354469) + .streetUa("Вулиця") + .streetEn("Street") + .houseNumber("1B") + .cityUa("Київ") + .cityEn("Kyiv") + .regionUa("Область") + .regionEn("Oblast") + .countryUa("Країна") + .countryEn("Country") + .build(); + } } diff --git a/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java b/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java index a106143137..8b645b2d9c 100644 --- a/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java +++ b/core/src/test/java/greencity/webcontroller/ManagementEventControllerTest.java @@ -26,6 +26,7 @@ import java.util.Set; import lombok.SneakyThrows; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -75,9 +76,12 @@ class ManagementEventControllerTest { private Principal principal; @Mock private Validator mockValidator; + @Mock + private Locale defaultLocale; @BeforeEach void setUp() { + defaultLocale = Locale.getDefault(); Locale.setDefault(Locale.ENGLISH); this.mockMvc = MockMvcBuilders.standaloneSetup(managementEventController) .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver()) @@ -85,6 +89,11 @@ void setUp() { .build(); } + @AfterEach + void tearDown() { + Locale.setDefault(defaultLocale); + } + @Test @SneakyThrows void getAllEventsWithQuery() { diff --git a/service/src/main/java/greencity/mapping/events/EventResponseDtoMapper.java b/service/src/main/java/greencity/mapping/events/EventResponseDtoMapper.java index 5a1b1cefda..684fa4c048 100644 --- a/service/src/main/java/greencity/mapping/events/EventResponseDtoMapper.java +++ b/service/src/main/java/greencity/mapping/events/EventResponseDtoMapper.java @@ -66,27 +66,30 @@ protected EventResponseDto convert(Event event) { User organizer = event.getOrganizer(); List dateInformation = event.getDates().stream() - .map(date -> EventDateInformationDto.builder() - .id(date.getId()) - .startDate(date.getStartDate()) - .finishDate(date.getFinishDate()) - .onlineLink(date.getOnlineLink()) - .coordinates(AddressDto.builder() - .latitude(date.getAddress().getLatitude()) - .longitude(date.getAddress().getLongitude()) - .streetEn(date.getAddress().getStreetEn()) - .streetUa(date.getAddress().getStreetUa()) - .houseNumber(date.getAddress().getHouseNumber()) - .cityEn(date.getAddress().getCityEn()) - .cityUa(date.getAddress().getCityUa()) - .regionEn(date.getAddress().getRegionEn()) - .regionUa(date.getAddress().getRegionUa()) - .countryEn(date.getAddress().getCountryEn()) - .countryUa(date.getAddress().getCountryUa()) - .formattedAddressEn(date.getAddress().getFormattedAddressEn()) - .formattedAddressUa(date.getAddress().getFormattedAddressUa()) - .build()) - .build()) + .map(date -> { + assert date.getAddress() != null; + return EventDateInformationDto.builder() + .id(date.getId()) + .startDate(date.getStartDate()) + .finishDate(date.getFinishDate()) + .onlineLink(date.getOnlineLink()) + .coordinates(AddressDto.builder() + .latitude(date.getAddress().getLatitude()) + .longitude(date.getAddress().getLongitude()) + .streetEn(date.getAddress().getStreetEn()) + .streetUa(date.getAddress().getStreetUa()) + .houseNumber(date.getAddress().getHouseNumber()) + .cityEn(date.getAddress().getCityEn()) + .cityUa(date.getAddress().getCityUa()) + .regionEn(date.getAddress().getRegionEn()) + .regionUa(date.getAddress().getRegionUa()) + .countryEn(date.getAddress().getCountryEn()) + .countryUa(date.getAddress().getCountryUa()) + .formattedAddressEn(date.getAddress().getFormattedAddressEn()) + .formattedAddressUa(date.getAddress().getFormattedAddressUa()) + .build()) + .build(); + }) .collect(Collectors.toList()); return EventResponseDto.builder() diff --git a/service/src/main/java/greencity/utils/EventUtils.java b/service/src/main/java/greencity/utils/EventUtils.java index 4d877cd541..2a73868d43 100644 --- a/service/src/main/java/greencity/utils/EventUtils.java +++ b/service/src/main/java/greencity/utils/EventUtils.java @@ -17,8 +17,12 @@ public static boolean isRelevant(List dates) { } public static double calculateEventRate(List eventGrades) { + if (eventGrades == null) { + return 0.0; + } return eventGrades.stream() .mapToInt(EventGrade::getGrade) + .filter(grade -> grade > 0) .average() .orElse(0.0); } diff --git a/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java b/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java index 03c4efe883..0424132854 100644 --- a/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java +++ b/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java @@ -13,9 +13,7 @@ import java.util.Set; import static greencity.ModelUtils.getEvent; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; +import static org.junit.jupiter.api.Assertions.assertThrows; @ExtendWith(SpringExtension.class) class EventResponseDtoMapperTest { @@ -39,10 +37,10 @@ void convertTest() { } @Test - void isRelevantFieldTest() { - when(commentService.countCommentsForEvent(any())).thenReturn(0); + void convertHasNullAddressTest() { Event event = getEvent(); - EventResponseDto result = mapper.convert(event); - assertTrue(result.getIsRelevant()); + event.getDates().forEach(date -> date.setAddress(null)); + + assertThrows(AssertionError.class, () -> mapper.convert(event)); } } diff --git a/service/src/test/java/greencity/utils/EventUtilsTest.java b/service/src/test/java/greencity/utils/EventUtilsTest.java index ca417d7379..a8ab0f0955 100644 --- a/service/src/test/java/greencity/utils/EventUtilsTest.java +++ b/service/src/test/java/greencity/utils/EventUtilsTest.java @@ -51,4 +51,22 @@ void calculateEventRateReturnsSingleValueForOneGradeTest() { List grades = List.of(EventGrade.builder().grade(5).build()); assertEquals(5.0, EventUtils.calculateEventRate(grades)); } + + @Test + void calculateEventRateReturnsZeroForEmptyListTest() { + assertEquals(0.0, EventUtils.calculateEventRate(List.of())); + } + + @Test + void calculateEventRateHandlesNullInputTest() { + assertEquals(0.0, EventUtils.calculateEventRate(null)); + } + + @Test + void calculateEventRateHandlesInvalidGradesTest() { + List grades = List.of( + EventGrade.builder().grade(-1).build(), + EventGrade.builder().grade(6).build()); + assertEquals(6.0, EventUtils.calculateEventRate(grades)); + } } From d833238e068031f1682588012b3b913bdf02ad1b Mon Sep 17 00:00:00 2001 From: Urio999 Date: Wed, 5 Feb 2025 22:19:06 +0200 Subject: [PATCH 8/9] converted added dtos to records --- core/src/test/java/greencity/ModelUtils.java | 62 ++++++----- .../dto/event/EventDateInformationDto.java | 22 ++-- .../dto/event/EventInformationDto.java | 18 +-- .../greencity/dto/event/EventResponseDto.java | 66 ++++------- .../events/EventResponseDtoMapper.java | 105 +++++++++--------- .../greencity/service/EventServiceImpl.java | 23 +++- .../src/test/java/greencity/ModelUtils.java | 55 +++++---- .../events/EventResponseDtoMapperTest.java | 11 +- .../service/EventServiceImplTest.java | 8 +- 9 files changed, 179 insertions(+), 191 deletions(-) diff --git a/core/src/test/java/greencity/ModelUtils.java b/core/src/test/java/greencity/ModelUtils.java index 8df5436808..65edfa6d40 100644 --- a/core/src/test/java/greencity/ModelUtils.java +++ b/core/src/test/java/greencity/ModelUtils.java @@ -596,39 +596,41 @@ public static List getPlaceByBoundsDto() { } public static EventResponseDto getEventResponseDto() { - return EventResponseDto.builder() - .id(1L) - .eventInformation(EventInformationDto.builder() - .title("Test Event") - .description("New Test Event") - .tags(List.of(TagUaEnDto.builder() + return new EventResponseDto( + 1L, + new EventInformationDto( + "Test Event", + "New Test Event", + List.of(TagUaEnDto.builder() .id(2L) .nameUa("Соціальний") .nameEn("Social") - .build())) - .build()) - .organizer(EventAuthorDto.builder().id(1L).name("Test").email("test@email.com").build()) - .creationDate(LocalDate.of(2025, 1, 10)) - .isOpen(true) - .dates(List.of( - EventDateInformationDto.builder() - .startDate(ZonedDateTime.of(2025, 12, 26, 12, 30, 0, 0, ZoneOffset.UTC)) - .finishDate(ZonedDateTime.of(2025, 12, 26, 21, 59, 0, 0, ZoneOffset.UTC)) - .onlineLink("www.testlink.com") - .coordinates(getAddressDtoCorrect()).build())) - .titleImage("https://test.png") - .additionalImages(List.of("https://test1.png", "https://test2.png")) - .type(EventType.OFFLINE) - .isRelevant(true) - .likes(3) - .dislikes(1) - .countComments(1) - .eventRate(20.0) - .currentUserGrade(50) - .isSubscribed(false) - .isFavorite(false) - .isOrganizedByFriend(false) - .build(); + .build())), + EventAuthorDto.builder() + .id(1L) + .name("Test") + .email("test@email.com") + .build(), + LocalDate.of(2025, 1, 10), + true, + List.of(new EventDateInformationDto( + null, + getAddressDtoCorrect(), + ZonedDateTime.of(2025, 12, 26, 12, 30, 0, 0, ZoneOffset.UTC), + ZonedDateTime.of(2025, 12, 26, 21, 59, 0, 0, ZoneOffset.UTC), + "www.link.com")), + null, + List.of("image1.jpg", "image2.jpg"), + EventType.OFFLINE, + false, + false, + true, + 10, + 2, + 1, + false, + 20.0, + 50); } public static AddressDto getAddressDtoCorrect() { diff --git a/service-api/src/main/java/greencity/dto/event/EventDateInformationDto.java b/service-api/src/main/java/greencity/dto/event/EventDateInformationDto.java index 4f8bb7cdd8..805e75b236 100644 --- a/service-api/src/main/java/greencity/dto/event/EventDateInformationDto.java +++ b/service-api/src/main/java/greencity/dto/event/EventDateInformationDto.java @@ -1,18 +1,12 @@ package greencity.dto.event; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.experimental.SuperBuilder; +import jakarta.validation.constraints.NotNull; +import java.time.ZonedDateTime; -@SuperBuilder -@NoArgsConstructor -@Getter -@Setter -@EqualsAndHashCode(callSuper = true) -public class EventDateInformationDto extends AbstractEventDateLocationDto { - private Long id; - private EventResponseDto event; - private AddressDto coordinates; +public record EventDateInformationDto( + Long id, + AddressDto coordinates, + @NotNull(message = "Start date must not be null or empty") ZonedDateTime startDate, + @NotNull(message = "Finish date must not be null or empty") ZonedDateTime finishDate, + String onlineLink) { } diff --git a/service-api/src/main/java/greencity/dto/event/EventInformationDto.java b/service-api/src/main/java/greencity/dto/event/EventInformationDto.java index be72ff3a80..8dca5d0cf1 100644 --- a/service-api/src/main/java/greencity/dto/event/EventInformationDto.java +++ b/service-api/src/main/java/greencity/dto/event/EventInformationDto.java @@ -2,19 +2,11 @@ import greencity.dto.tag.TagUaEnDto; import jakarta.validation.constraints.NotEmpty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; +import jakarta.validation.constraints.Size; import java.util.List; -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Data -public class EventInformationDto { - private String title; - private String description; - @NotEmpty - private List tags; +public record EventInformationDto( + @Size(min = 1, max = 255) String title, + @Size(max = 5000) String description, + @NotEmpty List tags) { } diff --git a/service-api/src/main/java/greencity/dto/event/EventResponseDto.java b/service-api/src/main/java/greencity/dto/event/EventResponseDto.java index 37749b3143..32c3c9c2ac 100644 --- a/service-api/src/main/java/greencity/dto/event/EventResponseDto.java +++ b/service-api/src/main/java/greencity/dto/event/EventResponseDto.java @@ -3,55 +3,27 @@ import com.fasterxml.jackson.annotation.JsonProperty; import greencity.enums.EventType; import jakarta.validation.constraints.Max; -import lombok.Builder; -import lombok.Data; import org.springframework.lang.Nullable; import java.time.LocalDate; import java.util.List; -@Data -@Builder -public class EventResponseDto { - private Long id; - - private EventInformationDto eventInformation; - - private EventAuthorDto organizer; - - private LocalDate creationDate; - - private Boolean isOpen; - - @Max(7) - private List dates; - - @Nullable - private String titleImage; - - @Nullable - @Max(4) - private List additionalImages; - - private EventType type; - - @JsonProperty("isSubscribed") - private boolean isSubscribed; - - @JsonProperty("isFavorite") - private boolean isFavorite; - - private Boolean isRelevant; - - private Integer likes; - - private Integer dislikes; - - private Integer countComments; - - @JsonProperty("isOrganizedByFriend") - private boolean isOrganizedByFriend; - - private Double eventRate; - - private Integer currentUserGrade; +public record EventResponseDto( + Long id, + EventInformationDto eventInformation, + EventAuthorDto organizer, + LocalDate creationDate, + Boolean isOpen, + @Max(7) List dates, + @Nullable String titleImage, + @Nullable @Max(4) List additionalImages, + EventType type, + @JsonProperty("isSubscribed") boolean isSubscribed, + @JsonProperty("isFavorite") boolean isFavorite, + Boolean isRelevant, + Integer likes, + Integer dislikes, + Integer countComments, + @JsonProperty("isOrganizedByFriend") boolean isOrganizedByFriend, + Double eventRate, + Integer currentUserGrade) { } diff --git a/service/src/main/java/greencity/mapping/events/EventResponseDtoMapper.java b/service/src/main/java/greencity/mapping/events/EventResponseDtoMapper.java index 684fa4c048..73f3eebacc 100644 --- a/service/src/main/java/greencity/mapping/events/EventResponseDtoMapper.java +++ b/service/src/main/java/greencity/mapping/events/EventResponseDtoMapper.java @@ -17,7 +17,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import java.util.List; -import java.util.stream.Collectors; +import java.util.Optional; /** * Mapper class for converting {@link Event} into {@link EventResponseDto}. @@ -43,10 +43,10 @@ public EventResponseDtoMapper(@Lazy CommentService commentService) { */ @Override protected EventResponseDto convert(Event event) { - EventInformationDto eventInformation = EventInformationDto.builder() - .title(event.getTitle()) - .description(event.getDescription()) - .tags(event.getTags().stream() + EventInformationDto eventInformation = new EventInformationDto( + event.getTitle(), + event.getDescription(), + event.getTags().stream() .map(tag -> TagUaEnDto.builder() .id(tag.getId()) .nameUa(tag.getTagTranslations().stream() @@ -60,61 +60,60 @@ protected EventResponseDto convert(Event event) { .map(TagTranslation::getName) .orElse(null)) .build()) - .toList()) - .build(); + .toList()); User organizer = event.getOrganizer(); List dateInformation = event.getDates().stream() - .map(date -> { - assert date.getAddress() != null; - return EventDateInformationDto.builder() - .id(date.getId()) - .startDate(date.getStartDate()) - .finishDate(date.getFinishDate()) - .onlineLink(date.getOnlineLink()) - .coordinates(AddressDto.builder() - .latitude(date.getAddress().getLatitude()) - .longitude(date.getAddress().getLongitude()) - .streetEn(date.getAddress().getStreetEn()) - .streetUa(date.getAddress().getStreetUa()) - .houseNumber(date.getAddress().getHouseNumber()) - .cityEn(date.getAddress().getCityEn()) - .cityUa(date.getAddress().getCityUa()) - .regionEn(date.getAddress().getRegionEn()) - .regionUa(date.getAddress().getRegionUa()) - .countryEn(date.getAddress().getCountryEn()) - .countryUa(date.getAddress().getCountryUa()) - .formattedAddressEn(date.getAddress().getFormattedAddressEn()) - .formattedAddressUa(date.getAddress().getFormattedAddressUa()) + .map(date -> new EventDateInformationDto( + date.getId(), + Optional.ofNullable(date.getAddress()) + .map(address -> AddressDto.builder() + .latitude(address.getLatitude()) + .longitude(address.getLongitude()) + .streetEn(address.getStreetEn()) + .streetUa(address.getStreetUa()) + .houseNumber(address.getHouseNumber()) + .cityEn(address.getCityEn()) + .cityUa(address.getCityUa()) + .regionEn(address.getRegionEn()) + .regionUa(address.getRegionUa()) + .countryEn(address.getCountryEn()) + .countryUa(address.getCountryUa()) + .formattedAddressEn(address.getFormattedAddressEn()) + .formattedAddressUa(address.getFormattedAddressUa()) .build()) - .build(); - }) - .collect(Collectors.toList()); + .orElse(null), + date.getStartDate(), + date.getFinishDate(), + date.getOnlineLink())) + .toList(); - return EventResponseDto.builder() - .id(event.getId()) - .eventInformation(eventInformation) - .organizer(EventAuthorDto.builder() - .id(organizer.getId()) - .name(organizer.getName()) - .organizerRating(organizer.getEventOrganizerRating()) - .email(organizer.getEmail()) - .build()) - .creationDate(event.getCreationDate()) - .isOpen(event.isOpen()) - .dates(dateInformation) - .titleImage(event.getTitleImage()) - .isRelevant(EventUtils.isRelevant(event.getDates())) - .likes(event.getUsersLikedEvents().size()) - .dislikes(event.getUsersDislikedEvents().size()) - .countComments(commentService.countCommentsForEvent(event.getId())) - .type(event.getType()) - .eventRate(EventUtils.calculateEventRate(event.getEventGrades())) - .additionalImages(event.getAdditionalImages().stream() + return new EventResponseDto( + event.getId(), + eventInformation, + new EventAuthorDto( + organizer.getId(), + organizer.getName(), + organizer.getEventOrganizerRating(), + organizer.getEmail()), + event.getCreationDate(), + event.isOpen(), + dateInformation, + event.getTitleImage(), + event.getAdditionalImages().stream() .map(EventImages::getLink) .limit(MAX_ADDITIONAL_IMAGES) - .toList()) - .build(); + .toList(), + event.getType(), + false, + false, + EventUtils.isRelevant(event.getDates()), + event.getUsersLikedEvents().size(), + event.getUsersDislikedEvents().size(), + commentService.countCommentsForEvent(event.getId()), + false, + EventUtils.calculateEventRate(event.getEventGrades()), + null); } } diff --git a/service/src/main/java/greencity/service/EventServiceImpl.java b/service/src/main/java/greencity/service/EventServiceImpl.java index b82cc6ce93..d842a8cb49 100644 --- a/service/src/main/java/greencity/service/EventServiceImpl.java +++ b/service/src/main/java/greencity/service/EventServiceImpl.java @@ -735,17 +735,36 @@ private void setFollowers(Collection eventDtos, Long userId) { private EventResponseDto buildEventResponseDto(Event event, Long userId) { EventResponseDto eventResponseDto = modelMapper.map(event, EventResponseDto.class); + Integer currentUserGrade = event.getEventGrades() .stream() .filter(g -> g.getUser() != null && g.getUser().getId().equals(userId)) .map(EventGrade::getGrade) .findFirst() .orElse(null); + setFollowers(List.of(), userId); setSubscribes(List.of(), userId); - eventResponseDto.setCurrentUserGrade(currentUserGrade); - return eventResponseDto; + return new EventResponseDto( + eventResponseDto.id(), + eventResponseDto.eventInformation(), + eventResponseDto.organizer(), + eventResponseDto.creationDate(), + eventResponseDto.isOpen(), + eventResponseDto.dates(), + eventResponseDto.titleImage(), + eventResponseDto.additionalImages(), + eventResponseDto.type(), + eventResponseDto.isSubscribed(), + eventResponseDto.isFavorite(), + eventResponseDto.isRelevant(), + eventResponseDto.likes(), + eventResponseDto.dislikes(), + eventResponseDto.countComments(), + eventResponseDto.isOrganizedByFriend(), + eventResponseDto.eventRate(), + currentUserGrade); } private EventDto buildEventDto(Event event, Long userId) { diff --git a/service/src/test/java/greencity/ModelUtils.java b/service/src/test/java/greencity/ModelUtils.java index 6a8e7a6f22..1e89c35c0a 100644 --- a/service/src/test/java/greencity/ModelUtils.java +++ b/service/src/test/java/greencity/ModelUtils.java @@ -3436,33 +3436,40 @@ public static CategoryDto getCategoryDto() { } public static EventResponseDto getEventResponseDto() { - return EventResponseDto.builder() - .id(1L) - .eventInformation(EventInformationDto.builder() - .title("Title") - .description("New Test Event") - .tags(List.of(TagUaEnDto.builder() + return new EventResponseDto( + 1L, + new EventInformationDto( + "Title", + "New Test Event", + List.of(TagUaEnDto.builder() .id(2L) .nameUa("Соціальний") .nameEn("Social") - .build())) - .build()) - .organizer(EventAuthorDto.builder().id(1L).name("Test").build()) - .creationDate(LocalDate.of(2025, 1, 10)) - .isOpen(true) - .dates(List.of( - EventDateInformationDto.builder() - .startDate(ZonedDateTime.of(2025, 12, 26, 12, 30, 0, 0, ZoneOffset.UTC)) - .finishDate(ZonedDateTime.of(2025, 12, 26, 21, 59, 0, 0, ZoneOffset.UTC)) - .onlineLink("www.link.com") - .coordinates(getAddressDtoCorrect()).build())) - .type(EventType.OFFLINE) - .isRelevant(true) - .countComments(1) - .isSubscribed(false) - .isFavorite(false) - .isOrganizedByFriend(false) - .build(); + .build())), + EventAuthorDto.builder() + .id(1L) + .name("Test") + .build(), + LocalDate.of(2025, 1, 10), + true, + List.of(new EventDateInformationDto( + null, + getAddressDtoCorrect(), + ZonedDateTime.of(2025, 12, 26, 12, 30, 0, 0, ZoneOffset.UTC), + ZonedDateTime.of(2025, 12, 26, 21, 59, 0, 0, ZoneOffset.UTC), + "www.link.com")), + null, + List.of("image1.jpg", "image2.jpg"), + EventType.OFFLINE, + false, + false, + true, + 10, + 2, + 1, + false, + 4.5, + null); } public static EventDateLocation createEventDateLocation(ZonedDateTime start, ZonedDateTime finish) { diff --git a/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java b/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java index 0424132854..4c4946f6ba 100644 --- a/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java +++ b/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java @@ -13,7 +13,7 @@ import java.util.Set; import static greencity.ModelUtils.getEvent; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertNull; @ExtendWith(SpringExtension.class) class EventResponseDtoMapperTest { @@ -32,8 +32,8 @@ void convertTest() { EventResponseDto result = mapper.convert(event); - assertEquals(expected.getEventInformation().getTitle(), result.getEventInformation().getTitle()); - assertEquals(event.getUsersLikedEvents().size(), result.getLikes()); + assertEquals(expected.eventInformation().title(), result.eventInformation().title()); + assertEquals(event.getUsersLikedEvents().size(), result.likes()); } @Test @@ -41,6 +41,9 @@ void convertHasNullAddressTest() { Event event = getEvent(); event.getDates().forEach(date -> date.setAddress(null)); - assertThrows(AssertionError.class, () -> mapper.convert(event)); + EventResponseDto result = mapper.convert(event); + + result.dates().forEach(dateInfo -> assertNull(dateInfo.coordinates())); + assertEquals(event.getId(), result.id()); } } diff --git a/service/src/test/java/greencity/service/EventServiceImplTest.java b/service/src/test/java/greencity/service/EventServiceImplTest.java index 8411cec132..1ad22cca96 100644 --- a/service/src/test/java/greencity/service/EventServiceImplTest.java +++ b/service/src/test/java/greencity/service/EventServiceImplTest.java @@ -551,9 +551,9 @@ void getEventV2WithoutUserTest() { EventResponseDto actual = eventService.getEventV2(1L, null); - assertEquals(eventResponseDto.getId(), actual.getId()); - assertEquals(eventResponseDto.getAdditionalImages(), actual.getAdditionalImages()); - assertEquals(eventResponseDto.getTitleImage(), actual.getTitleImage()); + assertEquals(eventResponseDto.id(), actual.id()); + assertEquals(eventResponseDto.additionalImages(), actual.additionalImages()); + assertEquals(eventResponseDto.titleImage(), actual.titleImage()); assertFalse(actual.isSubscribed()); assertFalse(actual.isFavorite()); @@ -579,7 +579,7 @@ void getEventV2WithCurrentUserTest() { assertFalse(actual.isSubscribed()); assertFalse(actual.isFavorite()); - assertEquals(50, actual.getCurrentUserGrade()); + assertEquals(50, actual.currentUserGrade()); verify(restClient).findByEmail(principal.getName()); verify(eventRepo).findById(1L); From 27459ebe8fcb2bfcfab88cad0940406e74090c48 Mon Sep 17 00:00:00 2001 From: Urio999 Date: Wed, 5 Feb 2025 22:40:14 +0200 Subject: [PATCH 9/9] improved test --- .../mapping/events/EventResponseDtoMapperTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java b/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java index 4c4946f6ba..827c96b133 100644 --- a/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java +++ b/service/src/test/java/greencity/mapping/events/EventResponseDtoMapperTest.java @@ -10,10 +10,12 @@ import org.mockito.Mock; import org.springframework.test.context.junit.jupiter.SpringExtension; import java.util.ArrayList; +import java.util.Optional; import java.util.Set; import static greencity.ModelUtils.getEvent; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; @ExtendWith(SpringExtension.class) class EventResponseDtoMapperTest { @@ -45,5 +47,9 @@ void convertHasNullAddressTest() { result.dates().forEach(dateInfo -> assertNull(dateInfo.coordinates())); assertEquals(event.getId(), result.id()); + + result.dates().forEach(dateInfo -> assertTrue(Optional.ofNullable(dateInfo.coordinates()).isEmpty(), + "Coordinates should be empty when address is null")); + assertEquals(event.getId(), result.id(), "Event ID should be preserved even with null address"); } }