Skip to content

Commit

Permalink
MATE-101 : [TEST] 굿즈거래 채팅 관련 기능들 테스트 코드 작성 (#99)
Browse files Browse the repository at this point in the history
* MATE-101 : [TEST] 굿즈거래 채팅방 상세 조회 테스트 코드 작성

* MATE-101 : [TEST] 굿즈거래 내 채팅방 목록 조회 테스트 코드 작성

* MATE-101 : [TEST] 굿즈거래 채팅방 채팅내역 조회 테스트 코드 작성

* MATE-101 : [TEST] 굿즈거래 채팅방 나가기 및 삭제 기능 테스트 코드 작성

* MATE-101 : [TEST] 굿즈거래 채팅방 인원 조회 테스트 코드 작성

* MATE-101 : [TEST] 굿즈거래 채팅 전송 기능 테스트 코드 작성

* MATE-101 : [REFACTOR] 굿즈거래 채팅 전송 로직 수정
  • Loading branch information
hongjeZZ authored Dec 7, 2024
1 parent 48045f0 commit 92a2df8
Show file tree
Hide file tree
Showing 7 changed files with 1,168 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.example.mate.domain.constant.MessageType;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class GoodsChatMessageRequest {

@NotNull(message = "채팅방 ID는 필수 입력 값입니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

@Entity
@Table(name = "goods_chat_message")
Expand All @@ -38,6 +40,7 @@ public class GoodsChatMessage {
@JoinColumn(name = "member_id", referencedColumnName = "member_id"),
@JoinColumn(name = "chat_room_id", referencedColumnName = "chat_room_id")
})
@OnDelete(action = OnDeleteAction.CASCADE)
private GoodsChatPart goodsChatPart;

@Column(name = "content", nullable = false, columnDefinition = "TEXT")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void sendMessage(GoodsChatMessageRequest message) {

// DB에 메시지 저장
GoodsChatMessage chatMessage
= messageRepository.save(createChatMessage(message.getMessage(), chatPart, MessageType.TALK));
= messageRepository.save(createChatMessage(message.getMessage(), chatPart, message.getType()));
chatRoom.updateLastChat(chatMessage.getContent(), chatMessage.getSentAt());

GoodsChatMessageResponse response = GoodsChatMessageResponse.of(chatMessage);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package com.example.mate.domain.goodsChat.controller;

import static org.mockito.BDDMockito.willDoNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.example.mate.common.error.CustomException;
import com.example.mate.common.error.ErrorCode;
import com.example.mate.common.response.PageResponse;
import com.example.mate.common.security.util.JwtUtil;
import com.example.mate.config.WithAuthMember;
import com.example.mate.domain.goodsChat.dto.response.GoodsChatMessageResponse;
import com.example.mate.common.security.util.JwtUtil;
import com.example.mate.domain.goodsChat.dto.response.GoodsChatRoomResponse;
import com.example.mate.domain.goodsChat.dto.response.GoodsChatRoomSummaryResponse;
import com.example.mate.domain.goodsChat.service.GoodsChatService;
import com.example.mate.domain.member.dto.response.MemberSummaryResponse;
import java.time.LocalDateTime;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
Expand All @@ -23,6 +29,7 @@
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext;
import org.springframework.test.web.servlet.MockMvc;

Expand Down Expand Up @@ -164,4 +171,215 @@ void getMessagesForChatRoom_should_return_messages() throws Exception {
verify(goodsChatService).getMessagesForChatRoom(chatRoomId, memberId, pageable);
}

@Test
@DisplayName("굿즈거래 채팅방 상세 조회 성공")
void getGoodsChatRoomInfo_should_return_chatroom_info_and_latest_message() throws Exception {
// given
Long chatRoomId = 1L;
Long memberId = 1L;
Long goodsPostId = 1L;

GoodsChatMessageResponse firstMessage = GoodsChatMessageResponse.builder()
.chatMessageId(1L)
.message("first message")
.senderId(memberId)
.sentAt(LocalDateTime.now().minusMinutes(10))
.build();

GoodsChatMessageResponse secondMessage = GoodsChatMessageResponse.builder()
.chatMessageId(2L)
.message("second message")
.senderId(memberId)
.sentAt(LocalDateTime.now())
.build();

List<GoodsChatMessageResponse> message = List.of(secondMessage, firstMessage);

GoodsChatRoomResponse existingChatRoomResponse = GoodsChatRoomResponse.builder()
.chatRoomId(1L)
.goodsPostId(goodsPostId)
.teamName("test team")
.title("test title")
.category("ACCESSORY")
.price(10000)
.postStatus("OPEN")
.imageUrl("/images/test.jpg")
.initialMessages(PageResponse.from(new PageImpl<>(List.of(message)), message))
.build();

when(goodsChatService.getGoodsChatRoomInfo(memberId, chatRoomId)).thenReturn(existingChatRoomResponse);

mockMvc.perform(get("/api/goods/chat/{chatRoomId}", chatRoomId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("SUCCESS"))
.andExpect(jsonPath("$.code").value(200))
.andExpect(jsonPath("$.data.chatRoomId").value(chatRoomId))
.andExpect(jsonPath("$.data.goodsPostId").value(goodsPostId))
.andExpect(jsonPath("$.data.initialMessages.content").isArray())
.andExpect(jsonPath("$.data.initialMessages.content[0].chatMessageId").value(secondMessage.getChatMessageId()))
.andExpect(jsonPath("$.data.initialMessages.content[0].message").value(secondMessage.getMessage()))
.andExpect(jsonPath("$.data.initialMessages.content[1].chatMessageId").value(firstMessage.getChatMessageId()))
.andExpect(jsonPath("$.data.initialMessages.content[1].message").value(firstMessage.getMessage()));
}

@Test
@DisplayName("굿즈거래 채팅방 목록 조회 성공")
void getGoodsChatRooms_should_return_chat_room_list() throws Exception {
// given
Long memberId = 1L;
Pageable pageable = PageRequest.of(0, 10);

GoodsChatRoomSummaryResponse chatRoom = GoodsChatRoomSummaryResponse.builder()
.chatRoomId(1L)
.opponentNickname("Opponent1")
.lastChatContent("First message")
.lastChatSentAt(LocalDateTime.now().minusMinutes(10))
.placeName("Test Place")
.goodsMainImageUrl("/images/goods1.jpg")
.opponentImageUrl("/images/opponent1.jpg")
.build();

PageResponse<GoodsChatRoomSummaryResponse> pageResponse = PageResponse.from(
new PageImpl<>(List.of(chatRoom), pageable, 1), List.of(chatRoom));

when(goodsChatService.getGoodsChatRooms(memberId, pageable)).thenReturn(pageResponse);

// when & then
mockMvc.perform(get("/api/goods/chat")
.param("page", "0")
.param("size", "10"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("SUCCESS"))
.andExpect(jsonPath("$.code").value(200))
.andExpect(jsonPath("$.data.content").isArray())
.andExpect(jsonPath("$.data.content[0].chatRoomId").value(chatRoom.getChatRoomId()))
.andExpect(jsonPath("$.data.content[0].opponentNickname").value(chatRoom.getOpponentNickname()))
.andExpect(jsonPath("$.data.content[0].lastChatContent").value(chatRoom.getLastChatContent()))
.andExpect(jsonPath("$.data.content[0].lastChatSentAt").isNotEmpty())
.andExpect(jsonPath("$.data.content[0].placeName").value(chatRoom.getPlaceName()))
.andExpect(jsonPath("$.data.content[0].goodsMainImageUrl").value(chatRoom.getGoodsMainImageUrl()))
.andExpect(jsonPath("$.data.content[0].opponentImageUrl").value(chatRoom.getOpponentImageUrl()));

verify(goodsChatService).getGoodsChatRooms(memberId, pageable);
}

@Test
@DisplayName("굿즈거래 채팅방 메시지 조회 성공")
void getGoodsChatRoomMessages_should_return_messages() throws Exception {
// given
Long chatRoomId = 1L;
Long memberId = 1L;
PageRequest pageable = PageRequest.of(0, 20);

GoodsChatMessageResponse firstMessage = GoodsChatMessageResponse.builder()
.chatMessageId(1L)
.message("First message")
.senderId(memberId)
.sentAt(LocalDateTime.now().minusMinutes(10))
.build();

GoodsChatMessageResponse secondMessage = GoodsChatMessageResponse.builder()
.chatMessageId(2L)
.message("Second message")
.senderId(memberId)
.sentAt(LocalDateTime.now())
.build();

PageResponse<GoodsChatMessageResponse> pageResponse = PageResponse.from(
new PageImpl<>(List.of(secondMessage, firstMessage), pageable, 2),
List.of(secondMessage, firstMessage)
);

when(goodsChatService.getMessagesForChatRoom(chatRoomId, memberId, pageable)).thenReturn(pageResponse);

// when & then
mockMvc.perform(get("/api/goods/chat/{chatRoomId}/message", chatRoomId)
.param("page", "0")
.param("size", "20"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("SUCCESS"))
.andExpect(jsonPath("$.code").value(200))
.andExpect(jsonPath("$.data.content").isArray())
.andExpect(jsonPath("$.data.content[0].chatMessageId").value(secondMessage.getChatMessageId()))
.andExpect(jsonPath("$.data.content[0].message").value(secondMessage.getMessage()))
.andExpect(jsonPath("$.data.content[1].chatMessageId").value(firstMessage.getChatMessageId()))
.andExpect(jsonPath("$.data.content[1].message").value(firstMessage.getMessage()));

verify(goodsChatService).getMessagesForChatRoom(chatRoomId, memberId, pageable);
}

@Test
@DisplayName("굿즈거래 채팅방 나가기 성공")
void leaveGoodsChatRoom_should_deactivate_chat_part_and_return_no_content() throws Exception {
// given
Long memberId = 1L;
Long chatRoomId = 1L;

willDoNothing().given(goodsChatService).deactivateGoodsChatPart(memberId, chatRoomId);

// when & then
mockMvc.perform(delete("/api/goods/chat/{chatRoomId}", chatRoomId))
.andExpect(status().isNoContent());

verify(goodsChatService).deactivateGoodsChatPart(memberId, chatRoomId);
}

@Test
@DisplayName("굿즈거래 채팅방 참여자 목록 조회 성공")
void getGoodsChatRoomMembers_should_return_list_of_chat_members() throws Exception {
// given
Long memberId = 1L;
Long chatRoomId = 1L;

MemberSummaryResponse member = MemberSummaryResponse.builder()
.memberId(memberId)
.nickname("member1")
.imageUrl("/images/member1.jpg")
.build();

MemberSummaryResponse anotherMember = MemberSummaryResponse.builder()
.memberId(2L)
.nickname("member2")
.imageUrl("/images/member2.jpg")
.build();

List<MemberSummaryResponse> memberList = List.of(member, anotherMember);

when(goodsChatService.getChatRoomMembers(memberId, chatRoomId)).thenReturn(memberList);

// when & then
mockMvc.perform(get("/api/goods/chat/{chatRoomId}/members", chatRoomId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("SUCCESS"))
.andExpect(jsonPath("$.code").value(200))
.andExpect(jsonPath("$.data").isArray())
.andExpect(jsonPath("$.data[0].memberId").value(member.getMemberId()))
.andExpect(jsonPath("$.data[0].nickname").value(member.getNickname()))
.andExpect(jsonPath("$.data[0].imageUrl").value(member.getImageUrl()))
.andExpect(jsonPath("$.data[1].memberId").value(anotherMember.getMemberId()))
.andExpect(jsonPath("$.data[1].nickname").value(anotherMember.getNickname()))
.andExpect(jsonPath("$.data[1].imageUrl").value(anotherMember.getImageUrl()));

verify(goodsChatService).getChatRoomMembers(memberId, chatRoomId);
}

@Test
@DisplayName("굿즈거래 채팅방 참여자 목록 조회 실패 - 참여하지 않은 사용자가 조회할 경우 예외 발생")
void getGoodsChatRoomMembers_should_throw_exception_when_user_is_not_a_member() throws Exception {
// given
Long memberId = 1L;
Long chatRoomId = 2L;

when(goodsChatService.getChatRoomMembers(memberId, chatRoomId))
.thenThrow(new CustomException(ErrorCode.GOODS_CHAT_NOT_FOUND_CHAT_PART));

// when & then
mockMvc.perform(get("/api/goods/chat/{chatRoomId}/members", chatRoomId))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.status").value("ERROR"))
.andExpect(jsonPath("$.code").value(ErrorCode.GOODS_CHAT_NOT_FOUND_CHAT_PART.getStatus().value()))
.andExpect(jsonPath("$.message").value(ErrorCode.GOODS_CHAT_NOT_FOUND_CHAT_PART.getMessage()));

verify(goodsChatService).getChatRoomMembers(memberId, chatRoomId);
}
}
Loading

0 comments on commit 92a2df8

Please sign in to comment.