From e4a123f1df8a9ef1612707edafcdd01a7b110aa8 Mon Sep 17 00:00:00 2001 From: Hyun Date: Wed, 15 May 2024 18:36:48 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=EC=9D=98=20?= =?UTF-8?q?=ED=9E=88=EC=8A=A4=ED=86=A0=EB=A6=AC=20=EA=B8=B8=EC=9D=B4=20?= =?UTF-8?q?=EC=A0=9C=ED=95=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../room/application/RoomService.java | 5 +- src/main/java/site/youtogether/user/User.java | 16 +++++ .../site/youtogether/util/AppConstants.java | 1 + .../room/application/RoomServiceTest.java | 44 +++++++++++++ .../java/site/youtogether/user/UserTest.java | 63 +++++++++++++++++++ 5 files changed, 126 insertions(+), 3 deletions(-) diff --git a/src/main/java/site/youtogether/room/application/RoomService.java b/src/main/java/site/youtogether/room/application/RoomService.java index fe51b08..16a558a 100644 --- a/src/main/java/site/youtogether/room/application/RoomService.java +++ b/src/main/java/site/youtogether/room/application/RoomService.java @@ -6,14 +6,13 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; -import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import lombok.RequiredArgsConstructor; import site.youtogether.exception.room.RoomNoExistenceException; import site.youtogether.exception.user.UserNoExistenceException; import site.youtogether.message.AlarmMessage; -import site.youtogether.message.ChatHistory; import site.youtogether.message.application.MessageService; import site.youtogether.playlist.Playlist; import site.youtogether.playlist.infrastructure.PlaylistStorage; @@ -37,7 +36,7 @@ public class RoomService { private final PlaylistStorage playlistStorage; private final UserStorage userStorage; private final MessageService messageService; - private final RedisTemplate chatRedisTemplate; + private final StringRedisTemplate redisTemplate; public NewRoom create(Long userId, RoomSettings roomSettings, LocalDateTime now) { String roomCode = RandomUtil.generateRandomCode(ROOM_CODE_LENGTH); diff --git a/src/main/java/site/youtogether/user/User.java b/src/main/java/site/youtogether/user/User.java index b4101be..bcd0d91 100644 --- a/src/main/java/site/youtogether/user/User.java +++ b/src/main/java/site/youtogether/user/User.java @@ -1,8 +1,12 @@ package site.youtogether.user; +import static site.youtogether.util.AppConstants.*; + +import java.util.ArrayDeque; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.Queue; import org.springframework.data.annotation.Id; @@ -36,6 +40,7 @@ public class User { private String nickname; private Map history = new HashMap<>(); + private Queue roomCodeQueue = new ArrayDeque<>(); @Builder private User(Long id, String nickname, String currentRoomCode, boolean activate) { @@ -103,7 +108,13 @@ public void changeOtherUserRole(User targetUser, Role newUserRole) { public void enterRoom(String roomCode) { if (isFirstTimeEntering(roomCode)) { history.put(roomCode, Role.GUEST); + if (roomCodeQueue.size() >= USER_HISTORY_LENGTH) { + removeOldestRoomCode(); + } + } else { + roomCodeQueue.remove(roomCode); } + roomCodeQueue.offer(roomCode); currentRoomCode = roomCode; activate = true; } @@ -133,6 +144,11 @@ private boolean isFirstTimeEntering(String roomCode) { return !history.containsKey(roomCode); } + private void removeOldestRoomCode() { + String deletedRoomCode = roomCodeQueue.poll(); + history.remove(deletedRoomCode); + } + private boolean isInSameRoom(User user, User targetUser) { return user.getCurrentRoomCode().equals(targetUser.getCurrentRoomCode()); } diff --git a/src/main/java/site/youtogether/util/AppConstants.java b/src/main/java/site/youtogether/util/AppConstants.java index fefb2c3..fcf6134 100644 --- a/src/main/java/site/youtogether/util/AppConstants.java +++ b/src/main/java/site/youtogether/util/AppConstants.java @@ -7,6 +7,7 @@ public final class AppConstants { public static final int ROOM_CODE_LENGTH = 10; + public static final int USER_HISTORY_LENGTH = 10; public static final String STOMP_ENDPOINT = "/stomp"; public static final String USER_ID = "userId"; public static final String ROOM_CODE = "roomCode"; diff --git a/src/test/java/site/youtogether/room/application/RoomServiceTest.java b/src/test/java/site/youtogether/room/application/RoomServiceTest.java index f46b126..3f52553 100644 --- a/src/test/java/site/youtogether/room/application/RoomServiceTest.java +++ b/src/test/java/site/youtogether/room/application/RoomServiceTest.java @@ -253,6 +253,50 @@ void changeRoom() throws Exception { assertThat(savedRoom.getTitle()).isEqualTo(updateTitle); } + @Test + @DisplayName("유저가 입장한 방 기록은 최대 10개만 방문 순서대로 유지된다") + void userHistory() throws Exception { + // given + User user = createUser(1L); + + // when + for (int i = 0; i < 100; i++) { + Room room = createRoom(LocalDateTime.now(), "roomCode" + i); + roomService.enter(room.getCode(), user.getId(), null); + } + + // then + User savedUser = userStorage.findById(user.getId()).get(); + assertThat(savedUser.getHistory().size()).isEqualTo(10); + } + + @Test + @DisplayName("방을 재입장하는 경우, 방 기록 순서는 갱신된다") + void userHistoryUpdate() throws Exception { + // given + User user = createUser(1L); + + Room firstRoom = createRoom(LocalDateTime.now(), "firstRoomCode"); + roomService.enter(firstRoom.getCode(), user.getId(), null); + + Room room1 = createRoom(LocalDateTime.now(), "room1"); + roomService.enter(room1.getCode(), user.getId(), null); + + Room room2 = createRoom(LocalDateTime.now(), "room2"); + roomService.enter(room2.getCode(), user.getId(), null); + + Room room3 = createRoom(LocalDateTime.now(), "room3"); + roomService.enter(room3.getCode(), user.getId(), null); + + // when + roomService.enter(firstRoom.getCode(), user.getId(), null); + + // then + User savedUser = userStorage.findById(user.getId()).get(); + assertThat(savedUser.getHistory().size()).isEqualTo(4); + assertThat(savedUser.getRoomCodeQueue()).containsExactly(room1.getCode(), room2.getCode(), room3.getCode(), firstRoom.getCode()); + } + private User createUser(Long userId) { User user = User.builder() .id(userId) diff --git a/src/test/java/site/youtogether/user/UserTest.java b/src/test/java/site/youtogether/user/UserTest.java index f405e2d..08f280c 100644 --- a/src/test/java/site/youtogether/user/UserTest.java +++ b/src/test/java/site/youtogether/user/UserTest.java @@ -167,4 +167,67 @@ void changeNicknameNoEnterRoom() throws Exception { assertThat(user.getNickname()).isEqualTo(updateNickname); } + @Test + @DisplayName("방 참여 기록은 최대 10개까지 저장된다") + void historyLength() throws Exception { + // given + User user = User.builder() + .id(1L) + .nickname("황똥땡") + .build(); + + // when + for (int i = 0; i < 10; i++) { + user.enterRoom("roomCode" + i); + } + + // then + assertThat(user.getHistory().size()).isEqualTo(10); + } + + @Test + @DisplayName("방 참여 기록이 10개를 넘어가면, 가장 오래전에 방문한 방의 기록부터 제거한다") + void historyLimitExceed() throws Exception { + // given + User user = User.builder() + .id(1L) + .nickname("황똥땡") + .build(); + + String firstRoomCode = "firstRoomCode"; + user.enterRoom(firstRoomCode); + + // when + for (int i = 0; i < 10; i++) { + user.enterRoom("roomCode" + i); + } + + // then + assertThat(user.getHistory().size()).isEqualTo(10); + assertThat(user.getHistory()).doesNotContainKey(firstRoomCode); + } + + @Test + @DisplayName("방을 재입장 한 경우, 방문 순서가 갱신된다") + void historyUpdate() throws Exception { + // given + User user = User.builder() + .id(1L) + .nickname("황똥땡") + .build(); + + String firstRoomCode = "firstRoomCode"; + user.enterRoom(firstRoomCode); + + // when + for (int i = 0; i < 3; i++) { + user.enterRoom("roomCode" + i); + } + user.enterRoom(firstRoomCode); + + // then + assertThat(user.getHistory().size()).isEqualTo(4); + assertThat(user.getRoomCodeQueue()).containsExactly("roomCode0", "roomCode1", "roomCode2", "firstRoomCode"); + } + } From dfb565f6ebac92b59e8fab42aff19cf983c9feda Mon Sep 17 00:00:00 2001 From: yeonise Date: Wed, 15 May 2024 19:28:20 +0900 Subject: [PATCH 2/2] =?UTF-8?q?modify:=20chatHistory=EC=97=90=EB=8F=84=20c?= =?UTF-8?q?hatId=EB=A5=BC=20=ED=8F=AC=ED=95=A8=ED=95=98=EB=8F=84=EB=A1=9D?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/site/youtogether/message/ChatHistory.java | 3 +++ .../youtogether/room/presentation/RoomControllerTest.java | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/site/youtogether/message/ChatHistory.java b/src/main/java/site/youtogether/message/ChatHistory.java index 44fd415..5bc6e99 100644 --- a/src/main/java/site/youtogether/message/ChatHistory.java +++ b/src/main/java/site/youtogether/message/ChatHistory.java @@ -11,12 +11,14 @@ public class ChatHistory { private MessageType messageType; + private Long chatId; private Long userId; private String content; private String createdAt; public ChatHistory(ChatMessage chatMessage) { this.messageType = chatMessage.getMessageType(); + this.chatId = chatMessage.getChatId(); this.userId = chatMessage.getUserId(); this.content = chatMessage.getContent(); this.createdAt = chatMessage.getCreatedAt(); @@ -24,6 +26,7 @@ public ChatHistory(ChatMessage chatMessage) { public ChatHistory(AlarmMessage alarmMessage) { this.messageType = alarmMessage.getMessageType(); + this.chatId = alarmMessage.getChatId(); this.userId = null; this.content = alarmMessage.getContent(); this.createdAt = alarmMessage.getCreatedAt(); diff --git a/src/test/java/site/youtogether/room/presentation/RoomControllerTest.java b/src/test/java/site/youtogether/room/presentation/RoomControllerTest.java index 5ff6804..3173b7c 100644 --- a/src/test/java/site/youtogether/room/presentation/RoomControllerTest.java +++ b/src/test/java/site/youtogether/room/presentation/RoomControllerTest.java @@ -779,10 +779,10 @@ private List generateRooms(int count) { private List createChatHistory(String roomCode) { return List.of( - new ChatHistory(MessageType.CHAT, 1L, "안녕하세요", LocalDateTime.now().toString()), - new ChatHistory(MessageType.ALARM, null, "yeon님이 입장하셨습니다.", LocalDateTime.now().toString()), - new ChatHistory(MessageType.CHAT, 2L, "방가방가 햄토리", LocalDateTime.now().toString()), - new ChatHistory(MessageType.CHAT, 1L, "ㄷㄷ", LocalDateTime.now().toString()) + new ChatHistory(MessageType.CHAT, 123L, 1L, "안녕하세요", LocalDateTime.now().toString()), + new ChatHistory(MessageType.ALARM, 124L, null, "yeon님이 입장하셨습니다.", LocalDateTime.now().toString()), + new ChatHistory(MessageType.CHAT, 125L, 2L, "방가방가 햄토리", LocalDateTime.now().toString()), + new ChatHistory(MessageType.CHAT, 126L, 1L, "ㄷㄷ", LocalDateTime.now().toString()) ); }