Skip to content

Commit

Permalink
merge: Feature/#664 행사 dto의 image url을 s3의 데이터로 대체
Browse files Browse the repository at this point in the history
Feature/#664 행사 dto의 image url을 s3의 데이터로 대체
  • Loading branch information
amaran-th authored Oct 9, 2023
2 parents 8bb0fb2 + 1978ad0 commit ec8aa3e
Show file tree
Hide file tree
Showing 22 changed files with 314 additions and 252 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import com.emmsale.event.application.dto.EventResponse;
import com.emmsale.event.domain.Event;
import com.emmsale.event.domain.EventMode;
import com.emmsale.event.domain.EventStatus;
import com.emmsale.event.domain.EventType;
import com.emmsale.event.domain.PaymentType;
import com.emmsale.tag.TagFixture;
Expand Down Expand Up @@ -72,16 +71,9 @@ class EventApiTest extends MockMvcTestHelper {
fieldWithPath("applyEndDate").type(JsonFieldType.STRING)
.description("신청 종료일자(nullable)"),
fieldWithPath("location").type(JsonFieldType.STRING).description("장소"),
fieldWithPath("status").type(JsonFieldType.STRING).description("진행상태"),
fieldWithPath("applyStatus").type(JsonFieldType.STRING)
.description("행사 신청 기간의 진행 상황"),
fieldWithPath("tags[]").type(JsonFieldType.ARRAY).description("태그들"),
fieldWithPath("imageUrl").type(JsonFieldType.STRING)
.description("이미지 Url(포스터)"),
fieldWithPath("remainingDays").type(JsonFieldType.NUMBER)
.description("시작일로 부터 D-day"),
fieldWithPath("applyRemainingDays").type(JsonFieldType.NUMBER)
.description("행사 신청 시작일까지 남은 일 수"),
fieldWithPath("thumbnailUrl").type(JsonFieldType.STRING)
.description("섬네일 이미지 Url(포스터)"),
fieldWithPath("type").type(JsonFieldType.STRING)
.description("event의 타입"),
fieldWithPath("imageUrls[]").description("이미지 URL들").optional(),
Expand All @@ -98,9 +90,8 @@ void findEvent() throws Exception {
"http://infcon.com", LocalDateTime.of(2023, 8, 15, 12, 0),
LocalDateTime.of(2023, 8, 15, 12, 0), LocalDateTime.of(2023, 8, 1, 12, 0),
LocalDateTime.of(2023, 8, 15, 12, 0), "코엑스",
"UPCOMING",
"ENDED", List.of("코틀린", "백엔드", "안드로이드"),
"https://www.image.com", 2, -12, EventType.COMPETITION.toString(),
List.of("코틀린", "백엔드", "안드로이드"),
"https://www.image.com", EventType.COMPETITION.toString(),
List.of("imageUrl1", "imageUrl2"), "인프런", "유료");

Mockito.when(eventService.findEvent(ArgumentMatchers.anyLong(), any()))
Expand Down Expand Up @@ -143,8 +134,8 @@ void findEvents() throws Exception {
.description("행사 마감일(yyyy:MM:dd:HH:mm:ss)"),
PayloadDocumentation.fieldWithPath("[].tags[]").type(JsonFieldType.ARRAY)
.description("행사 태그 목록"),
PayloadDocumentation.fieldWithPath("[].imageUrl").type(JsonFieldType.STRING)
.description("행사 이미지 URL"),
PayloadDocumentation.fieldWithPath("[].thumbnailUrl").type(JsonFieldType.STRING)
.description("행사 섬네일 이미지 URL"),
PayloadDocumentation.fieldWithPath("[].eventMode").type(JsonFieldType.STRING)
.description("행사 온라인 여부(온라인, 오프라인, 온오프라인)"),
PayloadDocumentation.fieldWithPath("[].paymentType").type(JsonFieldType.STRING)
Expand Down Expand Up @@ -230,18 +221,18 @@ void updateEventTest() throws Exception {
event.getLocation(), event.getInformationUrl(), event.getEventPeriod().getStartDate(),
event.getEventPeriod().getEndDate(),
event.getEventPeriod().getApplyStartDate(), event.getEventPeriod().getApplyEndDate(),
tags, event.getImageUrl(), event.getType(), EventMode.ON_OFFLINE, PaymentType.FREE,
tags, event.getType(), EventMode.ON_OFFLINE, PaymentType.FREE,
"행사기관");

final EventDetailResponse response = new EventDetailResponse(1L, request.getName(),
request.getInformationUrl(), request.getStartDateTime(), request.getEndDateTime(),
request.getApplyStartDateTime(), request.getApplyEndDateTime(),
request.getLocation(), EventStatus.IN_PROGRESS.name(), EventStatus.ENDED.name(),
request.getLocation(),
tags.stream().map(TagRequest::getName).collect(Collectors.toList()),
request.getImageUrl(), 10, 10, request.getType().toString(),
"image1.jpg", request.getType().toString(),
List.of("imageUrl1", "imageUrl2"), "행사기관", "유료");

Mockito.when(eventService.updateEvent(eq(eventId), any(EventDetailRequest.class), any(), any()))
Mockito.when(eventService.updateEvent(eq(eventId), any(EventDetailRequest.class), any()))
.thenReturn(response);

final String contents = objectMapper.writeValueAsString(request);
Expand Down Expand Up @@ -332,18 +323,18 @@ void addEventTest() throws Exception {
event.getLocation(), event.getInformationUrl(), event.getEventPeriod().getStartDate(),
event.getEventPeriod().getEndDate(),
event.getEventPeriod().getApplyStartDate(), event.getEventPeriod().getApplyEndDate(),
tags, event.getImageUrl(), event.getType(), EventMode.ON_OFFLINE, PaymentType.FREE,
tags, event.getType(), EventMode.ON_OFFLINE, PaymentType.FREE,
"행사기관");

final EventDetailResponse response = new EventDetailResponse(1L, request.getName(),
request.getInformationUrl(), request.getStartDateTime(), request.getEndDateTime(),
request.getApplyStartDateTime(), request.getApplyEndDateTime(),
request.getLocation(), EventStatus.IN_PROGRESS.name(), EventStatus.ENDED.name(),
request.getLocation(),
tags.stream().map(TagRequest::getName).collect(Collectors.toList()),
request.getImageUrl(), 10, 10, request.getType().toString(),
"image1.jpg", request.getType().toString(),
List.of("imageUrl1", "imageUrl2"), "행사기관", "무료");

Mockito.when(eventService.addEvent(any(EventDetailRequest.class), any(), any()))
Mockito.when(eventService.addEvent(any(EventDetailRequest.class), any()))
.thenReturn(response);

final String contents = objectMapper.writeValueAsString(request);
Expand Down Expand Up @@ -412,7 +403,7 @@ void addEventWithEmptyNameTest(final String eventName) throws Exception {
eventName, event.getLocation(), event.getInformationUrl(), event.getEventPeriod()
.getStartDate(), event.getEventPeriod().getEndDate(),
event.getEventPeriod().getApplyStartDate(), event.getEventPeriod().getApplyEndDate(),
tags, event.getImageUrl(), event.getType(), event.getEventMode(),
tags, event.getType(), event.getEventMode(),
event.getPaymentType(), event.getOrganization());
final String contents = objectMapper.writeValueAsString(request);
//when & then
Expand Down Expand Up @@ -453,7 +444,7 @@ void addEventWithEmptyLocationTest(final String eventLocation) throws Exception
event.getName(), eventLocation, event.getInformationUrl(), event.getEventPeriod()
.getStartDate(), event.getEventPeriod().getEndDate(),
event.getEventPeriod().getApplyStartDate(), event.getEventPeriod().getApplyEndDate(),
tags, event.getImageUrl(), event.getType(), event.getEventMode(),
tags, event.getType(), event.getEventMode(),
event.getPaymentType(), event.getOrganization());
final String contents = objectMapper.writeValueAsString(request);
//when & then
Expand Down Expand Up @@ -495,7 +486,7 @@ void addEventWithInvalidInformationUrlTest(final String informationUrl) throws E
event.getName(), event.getLocation(), informationUrl, event.getEventPeriod()
.getStartDate(), event.getEventPeriod().getEndDate(),
event.getEventPeriod().getApplyStartDate(), event.getEventPeriod().getApplyEndDate(),
tags, event.getImageUrl(), event.getType(), event.getEventMode(),
tags, event.getType(), event.getEventMode(),
event.getPaymentType(), event.getOrganization());
final String contents = objectMapper.writeValueAsString(request);
//when & then
Expand Down Expand Up @@ -540,7 +531,6 @@ void addEventWithUnformattedStartDateTimeTest(final String startDateTime)
request.put("endDateTime", event.getEventPeriod().getEndDate().toString());
request.put("applyStartDateTime", event.getEventPeriod().getApplyStartDate().toString());
request.put("applyEndDateTime", event.getEventPeriod().getApplyEndDate().toString());
request.put("imageUrl", event.getImageUrl());
request.put("type", event.getType().name());
request.put("eventMode", event.getEventMode().name());
request.put("paymentType", event.getPaymentType().name());
Expand Down Expand Up @@ -588,7 +578,6 @@ void addEventWithUnformattedEndDateTimeTest(final String endDateTime) throws Exc
request.put("endDateTime", endDateTime);
request.put("applyStartDateTime", event.getEventPeriod().getApplyStartDate().toString());
request.put("applyEndDateTime", event.getEventPeriod().getApplyEndDate().toString());
request.put("imageUrl", event.getImageUrl());
request.put("type", event.getType().name());
request.put("eventMode", event.getEventMode().name());
request.put("paymentType", event.getPaymentType().name());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ void findAllScraps() throws Exception {
.description("행사 마감일(yyyy:MM:dd:HH:mm:ss)"),
PayloadDocumentation.fieldWithPath("[].tags[]").type(JsonFieldType.ARRAY)
.description("행사 태그 목록"),
PayloadDocumentation.fieldWithPath("[].imageUrl").type(JsonFieldType.STRING)
.description("행사 이미지 URL"),
PayloadDocumentation.fieldWithPath("[].thumbnailUrl").type(JsonFieldType.STRING)
.description("행사 섬네일 이미지 URL"),
PayloadDocumentation.fieldWithPath("[].eventMode").type(JsonFieldType.STRING)
.description("행사 온라인 여부(온라인, 오프라인, 온오프라인)"),
PayloadDocumentation.fieldWithPath("[].paymentType").type(JsonFieldType.STRING)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ public ResponseEntity<List<EventResponse>> findEvents(
@ResponseStatus(HttpStatus.CREATED)
public EventDetailResponse addEvent(@RequestPart @Valid final EventDetailRequest request,
@RequestPart final List<MultipartFile> images) {
return eventService.addEvent(request, images, LocalDate.now());
return eventService.addEvent(request, images);
}

@PutMapping(path = "/{eventId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseStatus(HttpStatus.OK)
public EventDetailResponse updateEvent(@PathVariable final Long eventId,
@RequestPart @Valid final EventDetailRequest request,
@RequestPart final List<MultipartFile> images) {
return eventService.updateEvent(eventId, request, images, LocalDate.now());
return eventService.updateEvent(eventId, request, images);
}

@DeleteMapping("/{eventId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@
import java.time.LocalDateTime;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -66,8 +70,23 @@ public EventDetailResponse findEvent(final Long id, final LocalDate today) {
.sorted(comparing(Image::getOrder))
.map(Image::getName)
.collect(toList());
final String thumbnailImageUrl = extractThumbnailImage(imageUrls);
final List<String> informationImageUrls = extractInformationImages(imageUrls);
return EventDetailResponse.from(event, thumbnailImageUrl, informationImageUrls);
}

private String extractThumbnailImage(final List<String> imageUrls) {
if (imageUrls.isEmpty()) {
return null;
}
return imageUrls.get(0);
}

return EventDetailResponse.from(event, today, imageUrls);
private List<String> extractInformationImages(final List<String> imageUrls) {
if (imageUrls.size() <= 1) {
return Collections.emptyList();
}
return imageUrls.subList(1, imageUrls.size());
}

@Transactional(readOnly = true)
Expand All @@ -88,10 +107,11 @@ public List<EventResponse> findEvents(final EventType category,
spec = spec.and(EventSpecification.filterByPeriod(startDateTime, endDateTime));
}
final List<Event> events = eventRepository.findAll(spec);

final EnumMap<EventStatus, List<Event>> eventsForEventStatus
= groupByEventStatus(nowDate, events);

return filterByStatuses(statuses, eventsForEventStatus);
return filterByStatuses(statuses, eventsForEventStatus, makeImageUrlPerEventId(events));
}

private boolean isExistTagNames(final List<String> tagNames) {
Expand Down Expand Up @@ -138,6 +158,19 @@ private void validateEndDateAfterDateStart(final LocalDateTime startDate,
}
}

// TODO: 2023/09/27 코드 중복 제거(ScrapService)
private Map<Long, String> makeImageUrlPerEventId(final List<Event> events) {
final List<Long> scrappedEventIds = events.stream()
.map(Event::getId)
.collect(Collectors.toList());
final List<Image> images = imageRepository.findAllThumbnailByEventIdIn(scrappedEventIds);
Map<Long, String> imageUrlPerEventId = new HashMap<>();
for (Image image : images) {
imageUrlPerEventId.put(image.getContentId(), image.getName());
}
return imageUrlPerEventId;
}

private EnumMap<EventStatus, List<Event>> groupByEventStatus(final LocalDate nowDate,
final List<Event> events) {
return events.stream()
Expand All @@ -150,12 +183,13 @@ private EnumMap<EventStatus, List<Event>> groupByEventStatus(final LocalDate now

private List<EventResponse> filterByStatuses(
final List<EventStatus> statuses,
final EnumMap<EventStatus, List<Event>> eventsForEventStatus
final EnumMap<EventStatus, List<Event>> eventsForEventStatus,
final Map<Long, String> imageUrlPerEventId
) {
if (isExistStatusName(statuses)) {
return filterEventResponseByStatuses(statuses, eventsForEventStatus);
return filterEventResponseByStatuses(statuses, eventsForEventStatus, imageUrlPerEventId);
}
return EventResponse.mergeEventResponses(eventsForEventStatus);
return EventResponse.mergeEventResponses(eventsForEventStatus, imageUrlPerEventId);
}

private boolean isExistStatusName(final List<EventStatus> statuses) {
Expand All @@ -164,20 +198,22 @@ private boolean isExistStatusName(final List<EventStatus> statuses) {

private List<EventResponse> filterEventResponseByStatuses(
final List<EventStatus> statuses,
final EnumMap<EventStatus, List<Event>> eventsForEventStatus
final EnumMap<EventStatus, List<Event>> eventsForEventStatus,
final Map<Long, String> imageUrlPerEventId
) {
return eventsForEventStatus.entrySet()
.stream()
.filter(entry -> statuses.contains(entry.getKey()))
.map(entry -> EventResponse.makeEventResponsesByStatus(entry.getValue()))
.map(
entry -> EventResponse.makeEventResponsesByStatus(entry.getValue(), imageUrlPerEventId))
.reduce(new ArrayList<>(), (combinedEvents, eventsToAdd) -> {
combinedEvents.addAll(eventsToAdd);
return combinedEvents;
});
}

public EventDetailResponse addEvent(final EventDetailRequest request,
final List<MultipartFile> images, final LocalDate today) {
final List<MultipartFile> images) {
final Event event = eventRepository.save(request.toEvent());
final List<Tag> tags = findAllPersistTagsOrElseThrow(request.getTags());
event.addAllEventTags(tags);
Expand All @@ -190,12 +226,13 @@ public EventDetailResponse addEvent(final EventDetailRequest request,
.collect(toList());

eventPublisher.publish(event);

return EventDetailResponse.from(event, today, imageUrls);
final String thumbnailImageUrl = extractThumbnailImage(imageUrls);
final List<String> informationImageUrls = extractInformationImages(imageUrls);
return EventDetailResponse.from(event, thumbnailImageUrl, informationImageUrls);
}

public EventDetailResponse updateEvent(final Long eventId, final EventDetailRequest request,
final List<MultipartFile> images, final LocalDate today) {
final List<MultipartFile> images) {
final Event event = eventRepository.findById(eventId)
.orElseThrow(() -> new EventException(NOT_FOUND_EVENT));

Expand All @@ -220,8 +257,9 @@ public EventDetailResponse updateEvent(final Long eventId, final EventDetailRequ
.sorted(comparing(Image::getOrder))
.map(Image::getName)
.collect(toList());

return EventDetailResponse.from(updatedEvent, today, imageUrls);
final String thumbnailImageUrl = extractThumbnailImage(imageUrls);
final List<String> informationImageUrls = extractInformationImages(imageUrls);
return EventDetailResponse.from(updatedEvent, thumbnailImageUrl, informationImageUrls);
}

public void deleteEvent(final Long eventId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ public class EventDetailRequest {
private final LocalDateTime applyEndDateTime;

private final List<TagRequest> tags;

private final String imageUrl;
private final EventType type;

private final EventMode eventMode;
Expand All @@ -62,7 +60,6 @@ public Event toEvent() {
applyEndDateTime,
informationUrl,
type,
imageUrl,
paymentType,
eventMode,
organization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.emmsale.event.domain.EventTag;
import com.emmsale.tag.domain.Tag;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import lombok.Getter;
Expand All @@ -30,20 +29,16 @@ public class EventDetailResponse {
@JsonFormat(pattern = DATE_TIME_FORMAT)
private final LocalDateTime applyEndDate;
private final String location;
private final String status;
private final String applyStatus;
private final List<String> tags;
private final String imageUrl;
private final Integer remainingDays;
private final Integer applyRemainingDays;
private final String thumbnailUrl;
private final String type;
private final List<String> imageUrls;
private final String organization;
private final String paymentType;

public static EventDetailResponse from(
final Event event,
final LocalDate today,
final String thumbnailUrl,
final List<String> imageUrls
) {
final List<String> tagNames = event.getTags().stream()
Expand All @@ -60,12 +55,8 @@ public static EventDetailResponse from(
event.getEventPeriod().getApplyStartDate(),
event.getEventPeriod().getApplyEndDate(),
event.getLocation(),
event.getEventPeriod().calculateEventStatus(today).name(),
event.getEventPeriod().calculateEventApplyStatus(today).name(),
tagNames,
event.getImageUrl(),
event.getEventPeriod().calculateRemainingDays(today),
event.getEventPeriod().calculateApplyRemainingDays(today),
thumbnailUrl,
event.getType().toString(),
imageUrls,
event.getOrganization(),
Expand Down
Loading

0 comments on commit ec8aa3e

Please sign in to comment.