Skip to content

Commit

Permalink
feat: 채팅 조회
Browse files Browse the repository at this point in the history
  • Loading branch information
Leehunil committed Dec 4, 2024
1 parent f53c123 commit 7e5d5e8
Show file tree
Hide file tree
Showing 3 changed files with 331 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.palettee.chat.controller.dto.response;

import com.palettee.chat.domain.Chat;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class ChatCustomResponse {
private List<ChatResponse> chats;

private boolean hasNext;

private LocalDateTime lastSendAt;

public static ChatCustomResponse toResponseFromEntity(List<Chat> chats, boolean hasNext,
LocalDateTime nextChatTimeStamp) {
return new ChatCustomResponse(
chats.stream()
.map(ChatResponse::toResponseFromEntity)
.toList(),
hasNext,
nextChatTimeStamp
);
}

public static ChatCustomResponse toResponseFromDto(List<ChatResponse> chats, boolean hasNext,
LocalDateTime nextChatTimeStamp) {
return new ChatCustomResponse(
chats,
hasNext,
nextChatTimeStamp
);
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package com.palettee.chat_room.controller;

import com.palettee.chat.controller.dto.response.ChatCustomResponse;
import com.palettee.chat.service.ChatRedisService;
import com.palettee.chat_room.controller.dto.request.ChatRoomCreateRequest;
import com.palettee.chat_room.controller.dto.response.ChatRoomResponse;
import com.palettee.chat_room.service.ChatRoomService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;

@RestController
@RequiredArgsConstructor
@RequestMapping("/chat-room")
public class ChatRoomController {
private final ChatRoomService chatRoomService;
private final ChatRedisService chatRedisService;

// 채팅방 생성
@PostMapping
Expand All @@ -32,4 +37,11 @@ public void participateChatRoom(@PathVariable Long chatRoomId, @PathVariable Lon
public void leaveChatRoom(@PathVariable Long chatRoomId, @PathVariable Long userId) {
chatRoomService.leave(chatRoomId, userId);
}

@GetMapping("/chats/{chatRoomId}")
public ChatCustomResponse getChats(@PathVariable Long chatRoomId,
@RequestParam(value = "size") int size,
@RequestParam(value = "lastSendAt", required = false) LocalDateTime lastSendAt) {
return chatRedisService.getChats(chatRoomId, size, lastSendAt);
}
}
279 changes: 279 additions & 0 deletions src/test/java/com/palettee/chat/ChatRedisServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
package com.palettee.chat;

import com.palettee.chat.controller.dto.request.ChatRequest;
import com.palettee.chat.controller.dto.response.ChatCustomResponse;
import com.palettee.chat.controller.dto.response.ChatImgUrl;
import com.palettee.chat.controller.dto.response.ChatResponse;
import com.palettee.chat.domain.Chat;
import com.palettee.chat.repository.ChatRepository;
import com.palettee.chat.service.ChatRedisService;
import com.palettee.chat_room.domain.ChatCategory;
import com.palettee.chat_room.domain.ChatRoom;
import com.palettee.chat_room.repository.ChatRoomRepository;
import com.palettee.global.redis.utils.TypeConverter;
import com.palettee.user.domain.MajorJobGroup;
import com.palettee.user.domain.MinorJobGroup;
import com.palettee.user.domain.User;
import com.palettee.user.repository.UserRepository;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static org.assertj.core.api.Assertions.*;

@SpringBootTest
@Transactional
public class ChatRedisServiceTest {

@Autowired UserRepository userRepository;
@Autowired ChatRoomRepository chatRoomRepository;
@Autowired ChatRepository chatRepository;
@Autowired ChatRedisService chatRedisService;
@Qualifier("chatRedisTemplate") @Autowired RedisTemplate<String, ChatResponse> redisTemplate;

private ZSetOperations<String, ChatResponse> zSetOperations;
private User savedUser;
private ChatRoom savedChatRoom;

@BeforeEach
void beforeEach() {
zSetOperations = redisTemplate.opsForZSet();

savedUser = userRepository.save(new User("email", "imageUrl","name", "briefIntro", MajorJobGroup.DEVELOPER, MinorJobGroup.BACKEND));
savedChatRoom = chatRoomRepository.save(new ChatRoom(ChatCategory.COFFEE_CHAT));
}

@AfterEach
void afterEach() {
userRepository.deleteAll();
chatRoomRepository.deleteAll();
chatRepository.deleteAll();

redisTemplate.delete(String.valueOf(savedChatRoom.getId()));
}

@Test
@DisplayName("채팅 저장")
void saveChat() {
// given
String userEmail = savedUser.getEmail();
Long chatRoomId = savedChatRoom.getId();
List<ChatImgUrl> urls = new ArrayList<>();
ChatRequest chatRequest = new ChatRequest("Hi", urls);

// when
ChatResponse chatResponse = chatRedisService.addChat(userEmail, chatRoomId, chatRequest);
Double sendAt = TypeConverter.LocalDateTimeToDouble(TypeConverter.StringToLocalDateTime(chatResponse.getSendAt()));
List<ChatResponse> results = zSetOperations.rangeByScore(String.valueOf(chatResponse.getChatRoomId()), sendAt, sendAt).stream().toList();

// then
assertThat(results.size()).isEqualTo(1);
assertThat(results.get(0).getContent()).isEqualTo("Hi");
}

@Test
@DisplayName("redis에서 조회 && DB에 데이터 X")
void getChatsSituation1() {
//given
String userEmail = savedUser.getEmail();
Long chatRoomId = savedChatRoom.getId();

List<ChatImgUrl> urls1 = new ArrayList<>();
List<ChatImgUrl> urls2 = new ArrayList<>();
List<ChatImgUrl> urls3 = new ArrayList<>();

ChatRequest chatRequest1 = new ChatRequest("Hi1", urls1);
ChatRequest chatRequest2 = new ChatRequest("Hi2", urls2);
ChatRequest chatRequest3 = new ChatRequest("Hi3", urls3);

chatRedisService.addChat(userEmail, chatRoomId, chatRequest1);
chatRedisService.addChat(userEmail, chatRoomId, chatRequest2);
chatRedisService.addChat(userEmail, chatRoomId, chatRequest3);

//when
ChatCustomResponse chatCustomResponse = chatRedisService.getChats(chatRoomId, 3, null);

//then
assertThat(chatCustomResponse.getChats().size()).isEqualTo(3);
assertThat(chatCustomResponse.isHasNext()).isFalse();
assertThat(chatCustomResponse.getLastSendAt()).isNull();
}

@Test
@DisplayName("redis에 전혀 없고 DB에만 있을 때")
void getChatsSituation2() {
//given
Chat chat1 = Chat.builder()
.id(UUID.randomUUID().toString())
.user(savedUser)
.chatRoom(savedChatRoom)
.sendAt(LocalDateTime.of(2024, 12, 4, 11, 10, 12, 123_123_000))
.content("Hi1")
.build();

Chat chat2 = Chat.builder()
.id(UUID.randomUUID().toString())
.user(savedUser)
.chatRoom(savedChatRoom)
.sendAt(LocalDateTime.of(2024, 12, 4, 11, 10, 13, 123_123_000))
.content("Hi2")
.build();

Chat chat3 = Chat.builder()
.id(UUID.randomUUID().toString())
.user(savedUser)
.chatRoom(savedChatRoom)
.sendAt(LocalDateTime.of(2024, 12, 4, 11, 10, 14, 123_123_000))
.content("Hi3")
.build();

List<Chat> chats = new ArrayList<>();
chats.add(chat1);
chats.add(chat2);
chats.add(chat3);

chatRepository.saveAll(chats);

//when
ChatCustomResponse chatCustomResponse = chatRedisService.getChats(savedChatRoom.getId(), 3, null);

//then
assertThat(chatCustomResponse.getChats().size()).isEqualTo(3);
assertThat(chatCustomResponse.isHasNext()).isFalse();
assertThat(chatCustomResponse.getLastSendAt()).isNull();
}

@Test
@DisplayName("redis에 1개 DB에 2개 있을 때")
void getChatsSituation3() {
//given
Chat chat1 = Chat.builder()
.id(UUID.randomUUID().toString())
.user(savedUser)
.chatRoom(savedChatRoom)
.sendAt(LocalDateTime.of(2024, 12, 4, 11, 10, 12, 123_123_000))
.content("Hi1")
.build();

Chat chat2 = Chat.builder()
.id(UUID.randomUUID().toString())
.user(savedUser)
.chatRoom(savedChatRoom)
.sendAt(LocalDateTime.of(2024, 12, 4, 11, 10, 13, 123_123_000))
.content("Hi2")
.build();


List<Chat> chats = new ArrayList<>();
chats.add(chat1);
chats.add(chat2);

chatRepository.saveAll(chats);

List<ChatImgUrl> urls1 = new ArrayList<>();
ChatRequest chatRequest1 = new ChatRequest("Hi", urls1);

chatRedisService.addChat(savedUser.getEmail(), savedChatRoom.getId(), chatRequest1);

//when
ChatCustomResponse chatCustomResponse = chatRedisService.getChats(savedChatRoom.getId(), 3, null);

//then
assertThat(chatCustomResponse.getChats().size()).isEqualTo(3);
assertThat(chatCustomResponse.isHasNext()).isFalse();
assertThat(chatCustomResponse.getLastSendAt()).isNull();
}

@Test
@DisplayName("redis에 1개 DB에 3개 있을 때")
void getChatsSituation4() {
//given
Chat chat1 = Chat.builder()
.id(UUID.randomUUID().toString())
.user(savedUser)
.chatRoom(savedChatRoom)
.sendAt(LocalDateTime.of(2024, 12, 4, 11, 10, 12, 123_123_000))
.content("Hi1")
.build();

Chat chat2 = Chat.builder()
.id(UUID.randomUUID().toString())
.user(savedUser)
.chatRoom(savedChatRoom)
.sendAt(LocalDateTime.of(2024, 12, 4, 11, 10, 13, 123_123_000))
.content("Hi2")
.build();

Chat chat3 = Chat.builder()
.id(UUID.randomUUID().toString())
.user(savedUser)
.chatRoom(savedChatRoom)
.sendAt(LocalDateTime.of(2024, 12, 4, 11, 10, 14, 123_123_000))
.content("Hi3")
.build();


List<Chat> chats = new ArrayList<>();
chats.add(chat1);
chats.add(chat2);
chats.add(chat3);

chatRepository.saveAll(chats);

List<ChatImgUrl> urls1 = new ArrayList<>();
ChatRequest chatRequest1 = new ChatRequest("Hi", urls1);

chatRedisService.addChat(savedUser.getEmail(), savedChatRoom.getId(), chatRequest1);

//when
ChatCustomResponse chatCustomResponse = chatRedisService.getChats(savedChatRoom.getId(), 3, null);

//then
assertThat(chatCustomResponse.getChats().size()).isEqualTo(3);
assertThat(chatCustomResponse.isHasNext()).isTrue();
assertThat(chatCustomResponse.getLastSendAt()).isEqualTo(chat2.getSendAt());
}

@Test
@DisplayName("redis 데이터 4개")
void getChatsSituation5() {
//given
String userEmail = savedUser.getEmail();
Long chatRoomId = savedChatRoom.getId();

List<ChatImgUrl> urls1 = new ArrayList<>();
List<ChatImgUrl> urls2 = new ArrayList<>();
List<ChatImgUrl> urls3 = new ArrayList<>();
List<ChatImgUrl> urls4 = new ArrayList<>();

ChatRequest chatRequest1 = new ChatRequest("Hi1", urls1);
ChatRequest chatRequest2 = new ChatRequest("Hi2", urls2);
ChatRequest chatRequest3 = new ChatRequest("Hi3", urls3);
ChatRequest chatRequest4 = new ChatRequest("Hi4", urls4);

chatRedisService.addChat(userEmail, chatRoomId, chatRequest1);
ChatResponse chatResponse = chatRedisService.addChat(userEmail, chatRoomId, chatRequest2);
chatRedisService.addChat(userEmail, chatRoomId, chatRequest3);
chatRedisService.addChat(userEmail, chatRoomId, chatRequest4);

//when
ChatCustomResponse chatCustomResponse = chatRedisService.getChats(chatRoomId, 3, null);

//then
assertThat(chatCustomResponse.getChats().size()).isEqualTo(3);
assertThat(chatCustomResponse.isHasNext()).isTrue();
assertThat(chatCustomResponse.getLastSendAt()).isEqualTo(chatResponse.getSendAt());
}
}

0 comments on commit 7e5d5e8

Please sign in to comment.