Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/#822 피드 관련 반환값 변경 #828

Merged
merged 3 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 80 additions & 62 deletions backend/emm-sale/src/documentTest/java/com/emmsale/FeedApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.emmsale.feed.application.dto.FeedDetailResponse;
import com.emmsale.feed.application.dto.FeedDetailResponse.WriterProfileResponse;
import com.emmsale.feed.application.dto.FeedListResponse;
import com.emmsale.feed.application.dto.FeedSimpleResponse;
import com.emmsale.feed.application.dto.FeedResponseRefactor;
import com.emmsale.feed.application.dto.FeedUpdateRequest;
import com.emmsale.feed.application.dto.FeedUpdateResponse;
import java.time.LocalDate;
import com.emmsale.member.application.dto.MemberReferenceResponse;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
Expand All @@ -36,34 +32,53 @@

class FeedApiTest extends MockMvcTestHelper {

private static final MemberReferenceResponse MEMBER_REFERENCE_RESPONSE = new MemberReferenceResponse(
2L,
"멤버",
"멤버 설명",
"멤버 이미지url",
"멤버 깃허브 url"
);
private static final ResponseFieldsSnippet FEEDS_RESPONSE_FIELDS = responseFields(
fieldWithPath("[].id").type(JsonFieldType.NUMBER).description("피드 id"),
fieldWithPath("[].eventId").type(JsonFieldType.NUMBER).description("피드가 작성된 부모 이벤트 id"),
fieldWithPath("[].title").type(JsonFieldType.STRING).description("피드 제목"),
fieldWithPath("[].content").type(JsonFieldType.STRING).description("피드 내용"),
fieldWithPath("[].images").type(JsonFieldType.ARRAY).description("피드 이미지 url 리스트"),
fieldWithPath("[].writer.id").type(JsonFieldType.NUMBER).description("writer의 식별자"),
fieldWithPath("[].writer.name").type(JsonFieldType.STRING).description("writer의 이름"),
fieldWithPath("[].writer.description").type(JsonFieldType.STRING)
.description("writer의 한줄 자기소개"),
fieldWithPath("[].writer.imageUrl").type(JsonFieldType.STRING)
.description("writer의 이미지 url"),
fieldWithPath("[].writer.githubUrl").type(JsonFieldType.STRING)
.description("writer의 github Url"),
fieldWithPath("[].commentCount").type(JsonFieldType.NUMBER).description("피드의 댓글 개수"),
fieldWithPath("[].createdAt").type(JsonFieldType.STRING).description("피드 생성 일시"),
fieldWithPath("[].updatedAt").type(JsonFieldType.STRING).description("피드 업데이트 일시")
);

@Test
@DisplayName("이벤트의 피드 목록을 성공적으로 반환하면 200 OK를 반환한다.")
void findAllFeedsTest() throws Exception {
//given
final ResponseFieldsSnippet responseFields = responseFields(
fieldWithPath("eventId").type(JsonFieldType.NUMBER).description("피드가 작성된 부모 이벤트 id"),
fieldWithPath("feeds").type(JsonFieldType.ARRAY).description("피드 리스트"),
fieldWithPath("feeds[].id").type(JsonFieldType.NUMBER).description("피드 id"),
fieldWithPath("feeds[].title").type(JsonFieldType.STRING).description("피드 제목"),
fieldWithPath("feeds[].content").type(JsonFieldType.STRING).description("피드 내용"),
fieldWithPath("feeds[].images").type(JsonFieldType.ARRAY).description("피드 이미지 url 리스트"),
fieldWithPath("feeds[].writerId").type(JsonFieldType.NUMBER).description("피드 작성자 id"),
fieldWithPath("feeds[].commentCount").type(JsonFieldType.NUMBER).description("피드의 댓글 개수"),
fieldWithPath("feeds[].createdAt").type(JsonFieldType.STRING).description("피드 생성 일시"),
fieldWithPath("feeds[].updatedAt").type(JsonFieldType.STRING).description("피드 업데이트 일시")
);

final long eventId = 11L;
final List<FeedSimpleResponse> feeds = List.of(
new FeedSimpleResponse(34L, "피드1 제목", "피드 내용", 23L,
List.of("https://image1.url", "https://image2.url"), 0L,
LocalDateTime.of(LocalDate.of(2023, 7, 13), LocalTime.of(11, 43, 11)),
LocalDateTime.of(LocalDate.of(2023, 7, 13), LocalTime.of(11, 43, 11))),
new FeedSimpleResponse(35L, "피드2 제목", "피드 내용", 43L, Collections.emptyList(), 3L,
LocalDateTime.of(LocalDate.of(2023, 7, 22), LocalTime.of(23, 54, 49)),
LocalDateTime.of(LocalDate.of(2023, 7, 22), LocalTime.of(23, 54, 49)))
final List<FeedResponseRefactor> response = List.of(
new FeedResponseRefactor(
34L, eventId, "피드 1 제목", "피드 1 내용",
MEMBER_REFERENCE_RESPONSE,
Collections.emptyList(),
2L,
LocalDateTime.of(2023, 7, 13, 0, 0), LocalDateTime.of(2023, 7, 13, 0, 0)
),
new FeedResponseRefactor(
35L, eventId, "피드 2 제목", "피드 2 내용",
MEMBER_REFERENCE_RESPONSE,
Collections.emptyList(),
2L,
LocalDateTime.of(2023, 7, 13, 0, 0), LocalDateTime.of(2023, 7, 13, 0, 0)
)
);
final FeedListResponse response = new FeedListResponse(eventId, feeds);

when(feedQueryService.findAllFeeds(any(), any())).thenReturn(response);

Expand All @@ -72,7 +87,7 @@ void findAllFeedsTest() throws Exception {
.param("event-id", String.valueOf(eventId)))
.andExpect(status().isOk())
.andDo(print())
.andDo(document("find-all-feed", responseFields));
.andDo(document("find-all-feed", FEEDS_RESPONSE_FIELDS));
}

@Test
Expand All @@ -81,26 +96,33 @@ void findDetailFeedTest() throws Exception {
//given
final ResponseFieldsSnippet responseFields = responseFields(
fieldWithPath("id").type(JsonFieldType.NUMBER).description("피드 id"),
fieldWithPath("eventId").type(JsonFieldType.NUMBER).description("이벤트 id"),
fieldWithPath("writer").type(JsonFieldType.OBJECT).description("작성자"),
fieldWithPath("writer.memberId").type(JsonFieldType.NUMBER).description("작성자 id"),
fieldWithPath("writer.name").type(JsonFieldType.STRING).description("작성자명"),
fieldWithPath("writer.imageUrl").type(JsonFieldType.STRING).description("작성자 이미지 url"),
fieldWithPath("eventId").type(JsonFieldType.NUMBER).description("피드가 작성된 부모 이벤트 id"),
fieldWithPath("title").type(JsonFieldType.STRING).description("피드 제목"),
fieldWithPath("content").type(JsonFieldType.STRING).description("피드 내용"),
fieldWithPath("images").type(JsonFieldType.ARRAY).description("피드 이미지 url 리스트"),
fieldWithPath("writer.id").type(JsonFieldType.NUMBER).description("writer의 식별자"),
fieldWithPath("writer.name").type(JsonFieldType.STRING).description("writer의 이름"),
fieldWithPath("writer.description").type(JsonFieldType.STRING)
.description("writer의 한줄 자기소개"),
fieldWithPath("writer.imageUrl").type(JsonFieldType.STRING)
.description("writer의 이미지 url"),
fieldWithPath("writer.githubUrl").type(JsonFieldType.STRING)
.description("writer의 github Url"),
fieldWithPath("commentCount").type(JsonFieldType.NUMBER).description("피드의 댓글 개수"),
fieldWithPath("createdAt").type(JsonFieldType.STRING).description("피드 생성 일시"),
fieldWithPath("updatedAt").type(JsonFieldType.STRING).description("피드 업데이트 일시")
);

final long eventId = 11L;
final long feedId = 34L;
final WriterProfileResponse writer = new WriterProfileResponse(8L, "작성자명",
"https://member-image.com");
final FeedDetailResponse response = new FeedDetailResponse(feedId, eventId, writer, "피드 제목",
"피드 상세 내용", List.of("https://image1.url", "https://image2.url"),
LocalDateTime.of(LocalDate.of(2023, 7, 22), LocalTime.of(23, 54, 49)),
LocalDateTime.of(LocalDate.of(2023, 7, 22), LocalTime.of(23, 54, 49)));

final FeedResponseRefactor response =
new FeedResponseRefactor(
34L, eventId, "피드 1 제목", "피드 1 내용",
MEMBER_REFERENCE_RESPONSE,
Collections.emptyList(),
2L,
LocalDateTime.of(2023, 7, 13, 0, 0), LocalDateTime.of(2023, 7, 13, 0, 0)
);

when(feedQueryService.findFeed(any(), any())).thenReturn(response);

Expand All @@ -115,35 +137,31 @@ void findDetailFeedTest() throws Exception {
@DisplayName("자신의 피드 목록을 성공적으로 반환하면 200 OK를 반환한다.")
void findAllMyFeedsTest() throws Exception {
//given
final ResponseFieldsSnippet responseFields = responseFields(
fieldWithPath("[].id").type(JsonFieldType.NUMBER).description("피드 id"),
fieldWithPath("[].title").type(JsonFieldType.STRING).description("피드 제목"),
fieldWithPath("[].content").type(JsonFieldType.STRING).description("피드 내용"),
fieldWithPath("[].images").type(JsonFieldType.ARRAY).description("피드 이미지 url 리스트"),
fieldWithPath("[].writerId").type(JsonFieldType.NUMBER).description("피드 작성자 id"),
fieldWithPath("[].commentCount").type(JsonFieldType.NUMBER).description("피드의 댓글 개수"),
fieldWithPath("[].createdAt").type(JsonFieldType.STRING).description("피드 생성 일시"),
fieldWithPath("[].updatedAt").type(JsonFieldType.STRING).description("피드 업데이트 일시")
);

final List<FeedSimpleResponse> feeds = List.of(
new FeedSimpleResponse(34L, "피드1 제목", "피드 내용", 23L,
List.of("https://image1.url", "https://image2.url"), 0L,
LocalDateTime.of(LocalDate.of(2023, 7, 13), LocalTime.of(11, 43, 11)),
LocalDateTime.of(LocalDate.of(2023, 7, 13), LocalTime.of(11, 43, 11))),
new FeedSimpleResponse(35L, "피드2 제목", "피드 내용", 43L, Collections.emptyList(), 3L,
LocalDateTime.of(LocalDate.of(2023, 7, 22), LocalTime.of(23, 54, 49)),
LocalDateTime.of(LocalDate.of(2023, 7, 22), LocalTime.of(23, 54, 49)))
final List<FeedResponseRefactor> responses = List.of(
new FeedResponseRefactor(
34L, 2L, "피드 1 제목", "피드 1 내용",
MEMBER_REFERENCE_RESPONSE,
Collections.emptyList(),
2L,
LocalDateTime.of(2023, 7, 13, 0, 0), LocalDateTime.of(2023, 7, 13, 0, 0)
),
new FeedResponseRefactor(
35L, 2L, "피드 2 제목", "피드 2 내용",
MEMBER_REFERENCE_RESPONSE,
Collections.emptyList(),
2L,
LocalDateTime.of(2023, 7, 13, 0, 0), LocalDateTime.of(2023, 7, 13, 0, 0)
)
);

when(feedQueryService.findAllMyFeeds(any())).thenReturn(feeds);
when(feedQueryService.findAllMyFeeds(any())).thenReturn(responses);

//when & then
mockMvc.perform(get("/feeds/my")
.header(HttpHeaders.AUTHORIZATION, "Bearer accessToken"))
.andExpect(status().isOk())
.andDo(print())
.andDo(document("find-all-my-feed", responseFields));
.andDo(document("find-all-my-feed", FEEDS_RESPONSE_FIELDS));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.emmsale.feed.application.FeedCommandService;
import com.emmsale.feed.application.FeedQueryService;
import com.emmsale.feed.application.dto.FeedDetailResponse;
import com.emmsale.feed.application.dto.FeedListResponse;
import com.emmsale.feed.application.dto.FeedPostRequest;
import com.emmsale.feed.application.dto.FeedResponseRefactor;
import com.emmsale.feed.application.dto.FeedSimpleResponse;
import com.emmsale.feed.application.dto.FeedUpdateRequest;
import com.emmsale.feed.application.dto.FeedUpdateResponse;
Expand Down Expand Up @@ -34,20 +34,20 @@ public class FeedApi {
private final FeedCommandService feedCommandService;

@GetMapping
public FeedListResponse findAllFeeds(
public List<FeedResponseRefactor> findAllFeeds(
final Member member,
@RequestParam("event-id") final Long eventId
) {
return feedQueryService.findAllFeeds(member, eventId);
}

@GetMapping("/{id}")
public FeedDetailResponse findFeed(final Member member, @PathVariable final Long id) {
public FeedResponseRefactor findFeed(final Member member, @PathVariable final Long id) {
return feedQueryService.findFeed(member, id);
}

@GetMapping("/my")
public List<FeedSimpleResponse> findAllMyFeeds(final Member member) {
public List<FeedResponseRefactor> findAllMyFeeds(final Member member) {
return feedQueryService.findAllMyFeeds(member);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.emmsale.feed.application;

import static java.util.stream.Collectors.toUnmodifiableList;

import com.emmsale.block.domain.Block;
import com.emmsale.block.domain.BlockRepository;
import com.emmsale.comment.infrastructure.persistence.CommentDao;
import com.emmsale.comment.infrastructure.persistence.dto.FeedCommentCount;
import com.emmsale.event.domain.repository.EventRepository;
import com.emmsale.event.exception.EventException;
import com.emmsale.event.exception.EventExceptionType;
import com.emmsale.feed.application.dto.FeedDetailResponse;
import com.emmsale.feed.application.dto.FeedListResponse;
import com.emmsale.feed.application.dto.FeedSimpleResponse;
import com.emmsale.feed.application.dto.FeedResponseRefactor;
import com.emmsale.feed.domain.Feed;
import com.emmsale.feed.domain.repository.FeedRepository;
import com.emmsale.feed.exception.FeedException;
Expand Down Expand Up @@ -40,32 +40,17 @@ public class FeedQueryService {
private final ImageRepository imageRepository;
private final CommentDao commentDao;

public FeedListResponse findAllFeeds(final Member member, final Long eventId) {
public List<FeedResponseRefactor> findAllFeeds(final Member member, final Long eventId) {
validateEvent(eventId);

final List<Feed> feeds = excludeBlockedMembersFeed(member,
feedRepository.findAllByEventIdAndNotDeleted(eventId));
final List<Long> feedIds = feeds.stream()
.map(Feed::getId)
.collect(Collectors.toList());

final Map<Long, Long> feedCommentCounts = getFeedIdCommentCountMap(feedIds);
final Map<Long, List<Image>> feedImages = getFeedImagesMap(feedIds);

final List<FeedSimpleResponse> feedSimpleResponses = feeds.stream()
.map(feed -> {
final List<Image> images = feedImages.getOrDefault(feed.getId(), Collections.emptyList());
final Long commentCount = feedCommentCounts.getOrDefault(feed.getId(),
DEFAULT_COMMENT_COUNT);
return FeedSimpleResponse.from(feed, images, commentCount);
})
.collect(Collectors.toList());

return new FeedListResponse(eventId, feedSimpleResponses);
final List<Feed> feeds = feedRepository.findAllByEventIdAndNotDeleted(eventId);
final List<Feed> filteredFeeds = excludeBlockedMembersFeed(member, feeds);
return createFeedResponses(filteredFeeds);
}

private Map<Long, List<Image>> getFeedImagesMap(final List<Long> feedIds) {
final Map<Long, List<Image>> feedImagesMap = imageRepository.findAllByFeedIdIn(feedIds).stream()
final Map<Long, List<Image>> feedImagesMap = imageRepository.findAllByFeedIdIn(feedIds)
.stream()
.collect(Collectors.groupingBy(
Image::getContentId,
Collectors.mapping(
Expand Down Expand Up @@ -105,16 +90,16 @@ private List<Long> getBlockedMemberIds(final Member member) {
.collect(Collectors.toList());
}

public FeedDetailResponse findFeed(final Member member, final Long id) {
final Feed feed = feedRepository.findById(id)
.orElseThrow(() -> new FeedException(FeedExceptionType.NOT_FOUND_FEED));
public FeedResponseRefactor findFeed(final Member member, final Long id) {
final Feed feed = feedRepository.getByIdOrThrow(id);
final List<Image> images = imageRepository.findAllByFeedId(feed.getId());
images.sort(Comparator.comparing(Image::getOrder));

validateBlockedMemberFeed(member, feed);
validateDeletedFeed(feed);

return FeedDetailResponse.from(feed, images);
//이 부분은 안드분들과 이야기를 해봐야할 듯 실질적으로 쓰지 않는 값
return FeedResponseRefactor.of(feed, images, 0L);
}

private void validateBlockedMemberFeed(final Member member, final Feed feed) {
Expand All @@ -136,9 +121,13 @@ private void validateDeletedFeed(final Feed feed) {
}
}

public List<FeedSimpleResponse> findAllMyFeeds(final Member member) {
public List<FeedResponseRefactor> findAllMyFeeds(final Member member) {
final List<Feed> feeds = feedRepository.findByMember(member);

return createFeedResponses(feeds);
}

private List<FeedResponseRefactor> createFeedResponses(List<Feed> feeds) {
final List<Long> feedIds = feeds.stream()
.map(Feed::getId)
.collect(Collectors.toList());
Expand All @@ -151,8 +140,8 @@ public List<FeedSimpleResponse> findAllMyFeeds(final Member member) {
final List<Image> images = feedImages.getOrDefault(feed.getId(), Collections.emptyList());
final Long commentCount = feedCommentCounts.getOrDefault(feed.getId(),
DEFAULT_COMMENT_COUNT);
return FeedSimpleResponse.from(feed, images, commentCount);
return FeedResponseRefactor.of(feed, images, commentCount);
})
.collect(Collectors.toList());
.collect(toUnmodifiableList());
}
}

This file was deleted.

Loading
Loading