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/#821 메시지 관련 api 명세 수정 #836

Merged
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
107 changes: 67 additions & 40 deletions backend/emm-sale/src/documentTest/java/com/emmsale/RoomApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,38 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.emmsale.member.application.dto.MemberReferenceResponse;
import com.emmsale.member.domain.Member;
import com.emmsale.message_room.api.RoomApi;
import com.emmsale.message_room.application.dto.MessageResponse;
import com.emmsale.message_room.application.dto.RoomResponse;
import com.emmsale.message_room.domain.Message;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.HttpHeaders;
import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.restdocs.payload.ResponseFieldsSnippet;
import org.springframework.restdocs.request.PathParametersSnippet;
import org.springframework.restdocs.request.RequestParametersSnippet;

@WebMvcTest(RoomApi.class)
class RoomApiTest extends MockMvcTestHelper {

private String accessToken = "Bearer AccessToken";
private static final ResponseFieldsSnippet MESSAGES_RESPONSE_FIELDS = responseFields(
fieldWithPath("[].id").description("메시지의 ID"),
fieldWithPath("[].sender.id").description("메시지를 보낸 사람 ID"),
fieldWithPath("[].sender.name").description("메시지를 보낸 사람의 이름"),
fieldWithPath("[].sender.description").description("메시지를 보낸 사람의 한 줄 자기소개"),
fieldWithPath("[].sender.imageUrl").description("메시지를 보낸 사람의 프로필 이미지 URL"),
fieldWithPath("[].sender.githubUrl").description("메시지를 보낸 사람의 Github ID"),
fieldWithPath("[].content").description("메시지 내용"),
fieldWithPath("[].createdAt").description("메시지 보낸 시간")
);
private static final String accessToken = "Bearer AccessToken";

@Test
@DisplayName("findAllRoom() : 사용자의 쪽지함을 성공적으로 조회하면 200 OK를 반환할 수 있다.")
Expand All @@ -42,20 +56,47 @@ void test_findAllRoom() throws Exception {

final ResponseFieldsSnippet responseFields = responseFields(
fieldWithPath("[].roomId").description("Room Id(String 타입의 UUID입니다)"),
fieldWithPath("[].interlocutorId").description("쪽지를 주고받는 상대방 ID"),
fieldWithPath("[].interlocutorName").description("쪽지를 주고받는 상대방의 이름"),
fieldWithPath("[].interlocutorProfile").description("쪽지를 주고받는 상대방 이미지 URL"),
fieldWithPath("[].recentlyMessage").description("최근 메시지 내용"),
fieldWithPath("[].recentlyMessageTime").description("최근 메시지 시간")
fieldWithPath("[].interlocutor.id").type(JsonFieldType.NUMBER)
.description("메세지를 주고받는 member의 식별자"),
fieldWithPath("[].interlocutor.name").type(JsonFieldType.STRING)
.description("메세지를 주고받는 member의 이름"),
fieldWithPath("[].interlocutor.description").type(JsonFieldType.STRING)
.description("메세지를 주고받는 member의 한줄 자기소개"),
fieldWithPath("[].interlocutor.imageUrl").type(JsonFieldType.STRING)
.description("메세지를 주고받는 member의 이미지 url"),
fieldWithPath("[].interlocutor.githubUrl").type(JsonFieldType.STRING)
.description("메세지를 주고받는 member의 github Url"),
fieldWithPath("[].recentlyMessage.id").description("최근 메시지 내용"),
fieldWithPath("[].recentlyMessage.content").description("최근 메시지 내용"),
fieldWithPath("[].recentlyMessage.sender.id").type(JsonFieldType.NUMBER)
.description("최근 메세지를 전송한 member의 식별자"),
fieldWithPath("[].recentlyMessage.sender.name").type(JsonFieldType.STRING)
.description("최근 메세지를 전송한 member의 이름"),
fieldWithPath("[].recentlyMessage.sender.description").type(JsonFieldType.STRING)
.description("최근 메세지를 전송한 member의 한줄 자기소개"),
fieldWithPath("[].recentlyMessage.sender.imageUrl").type(JsonFieldType.STRING)
.description("최근 메세지를 전송한 member의 이미지 url"),
fieldWithPath("[].recentlyMessage.sender.githubUrl").type(JsonFieldType.STRING)
.description("최근 메세지를 전송한 member의 github Url"),
fieldWithPath("[].recentlyMessage.createdAt").description("최근 메시지 시간")
);

final Member member1 = new Member(1L, 3L, "https://github.image", "receiver1", "amaran-th");
final Member member2 = new Member(2L, 4L, "https://github.image2", "receiver2", "amaran-th2");
final Member member3 = new Member(3L, 8L, "https://github.image2", "receiver3", "amaran-th3");
final Message message1 = new Message(1L, "최근 메시지1", member1, "ROOMID1111", LocalDateTime.now());
final Message message2 = new Message(2L, "최근 메시지2", member2, "ROOMID2222",
LocalDateTime.now().minusDays(2));
final Message message3 = new Message(3L, "최근 메시지3", member3, "ROOMID3333",
LocalDateTime.now().minusDays(3));

final List<RoomResponse> roomResponses = List.of(
new RoomResponse(UUID.randomUUID().toString(), 1L, "receiver1", "imageUrl1", "최근 메시지1",
LocalDateTime.now()),
new RoomResponse(UUID.randomUUID().toString(), 2L, "receiver2", "imageUrl2", "최근 메시지2",
LocalDateTime.now().minusDays(2)),
new RoomResponse(UUID.randomUUID().toString(), 1L, "receiver3", "imageUrl3", "최근 메시지3",
LocalDateTime.now().minusDays(3))
new RoomResponse(UUID.randomUUID().toString(), MemberReferenceResponse.from(member1),
MessageResponse.from(message1)),
new RoomResponse(UUID.randomUUID().toString(), MemberReferenceResponse.from(member2),
MessageResponse.from(message2)),
new RoomResponse(UUID.randomUUID().toString(), MemberReferenceResponse.from(member3),
MessageResponse.from(message3))
);

when(roomQueryService.findAll(any(), anyLong()))
Expand All @@ -74,69 +115,55 @@ void test_findAllRoom() throws Exception {
@DisplayName("findByRoomId() : Room Id로 쪽지방을 성공적으로 조회하면 200 OK를 반환할 수 있다.")
void test_findByRoomId() throws Exception {
//given
final RequestParametersSnippet requestParam = requestParameters(
parameterWithName("member-id").description("로그인 한 사용자 ID")
);

final ResponseFieldsSnippet responseFields = responseFields(
fieldWithPath("[].senderId").description("메시지를 보낸 사람 ID"),
fieldWithPath("[].content").description("메시지 내용"),
fieldWithPath("[].createdAt").description("메시지 보낸 시간")
);

final PathParametersSnippet pathParams = pathParameters(
parameterWithName("room-id").description("조회할 Room UUID")
);

final Member member1 = new Member(1L, 3L, "https://github.image", "sender", "amaran-th");
final Member member2 = new Member(2L, 4L, "https://github.image", "receiver", "amaran-th");
final List<MessageResponse> messageResponses = List.of(
new MessageResponse(1L, "내용1", LocalDateTime.now()),
new MessageResponse(2L, "내용2", LocalDateTime.now()),
new MessageResponse(1L, "내용3", LocalDateTime.now())
new MessageResponse(1L, MemberReferenceResponse.from(member1), "내용1", LocalDateTime.now()),
new MessageResponse(2L, MemberReferenceResponse.from(member2), "내용2", LocalDateTime.now()),
new MessageResponse(3L, MemberReferenceResponse.from(member1), "내용3", LocalDateTime.now())
);

when(roomQueryService.findByRoomId(any(), any(), anyLong()))
when(roomQueryService.findByRoomId(any(), any()))
.thenReturn(messageResponses);

//when & then
mockMvc.perform(get("/rooms/{room-id}", 1L)
.queryParam("member-id", "1")
.header(HttpHeaders.AUTHORIZATION, accessToken))
.andExpect(status().isOk())
.andDo(print())
.andDo(document("get-rooms-roomId", requestParam, responseFields, pathParams));
.andDo(document("get-rooms-roomId", MESSAGES_RESPONSE_FIELDS, pathParams));
}

@Test
@DisplayName("findByInterlocutorIds() : 쪽지방 참여자들의 ID를 통해 Room을 성공적으로 조회하면 200 OK를 반환할 수 있다.")
void test_findByInterlocutorIds() throws Exception {
//given
final RequestParametersSnippet requestParam = requestParameters(
parameterWithName("member-id").description("로그인 한 사용자 ID"),
parameterWithName("receiver-id").description("쪽지방 참여 상대방 ID")
);

final ResponseFieldsSnippet responseFields = responseFields(
fieldWithPath("[].senderId").description("메시지를 보낸 사람 ID"),
fieldWithPath("[].content").description("메시지 내용"),
fieldWithPath("[].createdAt").description("메시지 보낸 시간")
);
final Member member1 = new Member(1L, 3L, "https://github.image", "sender", "amaran-th");
final Member member2 = new Member(2L, 4L, "https://github.image", "receiver", "amaran-th");

final List<MessageResponse> messageResponses = List.of(
new MessageResponse(1L, "내용1", LocalDateTime.now()),
new MessageResponse(2L, "내용2", LocalDateTime.now()),
new MessageResponse(1L, "내용3", LocalDateTime.now())
new MessageResponse(1L, MemberReferenceResponse.from(member1), "내용1", LocalDateTime.now()),
new MessageResponse(2L, MemberReferenceResponse.from(member2), "내용2", LocalDateTime.now()),
new MessageResponse(3L, MemberReferenceResponse.from(member1), "내용3", LocalDateTime.now())
);

when(roomQueryService.findByInterlocutorIds(anyLong(), anyLong(), any()))
when(roomQueryService.findByInterlocutorIds(anyLong(), any()))
.thenReturn(messageResponses);

//when & then
mockMvc.perform(get("/rooms")
.queryParam("member-id", "1")
.queryParam("receiver-id", "1")
.header(HttpHeaders.AUTHORIZATION, accessToken))
.andExpect(status().isOk())
.andDo(print())
.andDo(document("get-rooms-interlocutorId", requestParam, responseFields));
.andDo(document("get-rooms-interlocutorId", requestParam, MESSAGES_RESPONSE_FIELDS));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.emmsale;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
Expand Down Expand Up @@ -32,6 +31,31 @@
@WebMvcTest(ScrapApi.class)
class ScrapApiTest extends MockMvcTestHelper {

final ResponseFieldsSnippet SCRAPPED_EVENT_RESPONSE_FIELDS = PayloadDocumentation.responseFields(
fieldWithPath("id").type(JsonFieldType.NUMBER).description("행사 식별자"),
fieldWithPath("name").type(JsonFieldType.STRING)
.description("행사 이름"),
fieldWithPath("informationUrl").type(JsonFieldType.STRING)
.description("행사 상세정보 url"),
fieldWithPath("startDate").type(JsonFieldType.STRING)
.description("행사 시작 일자"),
fieldWithPath("endDate").type(JsonFieldType.STRING).description("행사 종료 일자"),
fieldWithPath("applyStartDate").type(JsonFieldType.STRING)
.description("행사 신청 시작 일자(nullable)"),
fieldWithPath("applyEndDate").type(JsonFieldType.STRING)
.description("행사 신청 종료 일자(nullable)"),
fieldWithPath("location").type(JsonFieldType.STRING).description("행사 장소"),
fieldWithPath("tags[]").type(JsonFieldType.ARRAY).description("행사 태그들"),
fieldWithPath("thumbnailUrl").type(JsonFieldType.STRING)
.description("행사 섬네일 이미지 Url(포스터)"),
fieldWithPath("type").type(JsonFieldType.STRING)
.description("행사의 분류"),
fieldWithPath("imageUrls[]").description("행사의 상세 정보 이미지 URL들").optional(),
fieldWithPath("organization").description("행사 주최기관"),
fieldWithPath("paymentType").description("행사의 유무료 여부(유료,무료,유무료)"),
fieldWithPath("eventMode").description("행사의 온/오프라인 여부(온라인,오프라인,온오프라인)")
);

@Test
@DisplayName("스크랩 목록을 성공적으로 조회하면 200 OK를 반환한다.")
void findAllScraps() throws Exception {
Expand Down Expand Up @@ -127,38 +151,70 @@ void findAllScraps() throws Exception {
void append() throws Exception {
//given
final long eventId = 1L;

final ScrapRequest request = new ScrapRequest(eventId);

final EventResponse expectedScrapResponse = new EventResponse(
1L,
"인프콘 2023",
"https://aaa",
LocalDateTime.parse("2023-06-03T12:00:00"),
LocalDateTime.parse("2023-09-03T12:00:00"),
LocalDateTime.parse("2023-09-01T00:00:00"),
LocalDateTime.parse("2023-09-02T23:59:59"),
"코엑스",
List.of("백엔드", "프론트엔드", "안드로이드", "IOS", "AI"),
"image0.jpg",
EventType.CONFERENCE.name(),
List.of("image1.jpg", "image2.jpg", "image3.jpg"),
"인프런",
PaymentType.PAID.getValue(),
EventMode.ONLINE.getValue()
);
final RequestFieldsSnippet requestFields = requestFields(
fieldWithPath("eventId").description("스크랩할 이벤트 id")
);

//when
doNothing().when(scrapCommandService).append(any(), any());
when(scrapCommandService.append(any(), any())).thenReturn(expectedScrapResponse);

//then
mockMvc.perform(post("/scraps")
.header(HttpHeaders.AUTHORIZATION, "Bearer AccessToken")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isCreated())
.andDo(document("append-scrap", requestFields));
.andDo(document("append-scrap", requestFields, SCRAPPED_EVENT_RESPONSE_FIELDS));
}

@Test
@DisplayName("스크랩을 성공적으로 삭제하면 204 NO_CONTENT를 반환한다.")
void deleteScrap() throws Exception {
//given
final long eventId = 1L;
final EventResponse expectedScrapResponse = new EventResponse(
1L,
"인프콘 2023",
"https://aaa",
LocalDateTime.parse("2023-06-03T12:00:00"),
LocalDateTime.parse("2023-09-03T12:00:00"),
LocalDateTime.parse("2023-09-01T00:00:00"),
LocalDateTime.parse("2023-09-02T23:59:59"),
"코엑스",
List.of("백엔드", "프론트엔드", "안드로이드", "IOS", "AI"),
"image0.jpg",
EventType.CONFERENCE.name(),
List.of("image1.jpg", "image2.jpg", "image3.jpg"),
"인프런",
PaymentType.PAID.getValue(),
EventMode.ONLINE.getValue()
);

//when
doNothing().when(scrapCommandService).deleteScrap(any(), any());
when(scrapCommandService.deleteScrap(any(), any())).thenReturn(expectedScrapResponse);

//then
mockMvc.perform(delete("/scraps?event-id={eventId}", eventId)
.header(HttpHeaders.AUTHORIZATION, "Bearer AccessToken"))
.andExpect(status().isNoContent())
.andDo(document("delete-scrap"));
.andExpect(status().isOk())
.andDo(document("delete-scrap", SCRAPPED_EVENT_RESPONSE_FIELDS));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static MessageNotificationEvent of(final Message message, final Long rece
return new MessageNotificationEvent(
message.getRoomId(),
message.getContent(),
message.getSenderId(),
message.getSender().getId(),
receiverId,
message.getCreatedAt()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,23 @@ public class Member extends BaseEntity {
private String githubUsername;

public Member(final Long id, final Long githubId, final String imageUrl, final String name,
final String description,
final String githubUsername) {
this.id = id;
this.githubId = githubId;
this.imageUrl = imageUrl;
this.name = name;
this.description = DEFAULT_DESCRIPTION;
this.description = description;
this.githubUsername = githubUsername;
}

public Member(final Long id, final Long githubId, final String imageUrl, final String name,
final String githubUsername) {
this(id, githubId, imageUrl, name, DEFAULT_DESCRIPTION, githubUsername);
}

public Member(final Long githubId, final String imageUrl, final String githubUsername) {
this.githubId = githubId;
this.imageUrl = imageUrl;
this.description = DEFAULT_DESCRIPTION;
this.githubUsername = githubUsername;
this(null, githubId, imageUrl, null, DEFAULT_DESCRIPTION, githubUsername);
}

public void updateName(final String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,16 @@ public List<RoomResponse> findAllRoom(
@GetMapping("/rooms/{room-id}")
public List<MessageResponse> findByRoomId(
final Member member,
@PathVariable("room-id") final String roomId,
@RequestParam("member-id") final Long memberId
@PathVariable("room-id") final String roomId
) {
return roomQueryService.findByRoomId(member, roomId, memberId);
return roomQueryService.findByRoomId(member, roomId);
}

@GetMapping("/rooms")
public List<MessageResponse> findByInterlocutorIds(
@RequestParam("receiver-id") final Long receiverId,
@RequestParam("member-id") final Long memberId,
final Member loginMember
) {
return roomQueryService.findByInterlocutorIds(receiverId, memberId, loginMember);
return roomQueryService.findByInterlocutorIds(receiverId, loginMember);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public MessageSendResponse sendMessage(final MessageSendRequest request, final M
.map(room -> room.getRoomId().getUuid())
.orElseGet(() -> saveRooms(request));

final Message message = new Message(request.getContent(), request.getSenderId(),
final Message message = new Message(request.getContent(), member,
roomId, LocalDateTime.now());

messageRepository.save(message);
Expand Down
Loading
Loading