Skip to content

Commit f4aa214

Browse files
committed
feat: 메시지 읽음 표시 쿼리 구현
Related to: #136
1 parent b16c1ca commit f4aa214

File tree

2 files changed

+64
-17
lines changed

2 files changed

+64
-17
lines changed

src/main/java/com/hf/healthfriend/domain/chat/repository/ChatMessageRepository.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.springframework.data.domain.Page;
66
import org.springframework.data.domain.Pageable;
77
import org.springframework.data.jpa.repository.JpaRepository;
8+
import org.springframework.data.jpa.repository.Modifying;
89
import org.springframework.data.jpa.repository.Query;
910
import org.springframework.data.repository.query.Param;
1011

@@ -18,4 +19,12 @@ public interface ChatMessageRepository extends JpaRepository<ChatMessage, Long>,
1819
ORDER BY cm.creationTime DESC
1920
""")
2021
Page<ChatMessage> findByChatroomId(@Param("chatroomId") Long chatroomId, Pageable page);
22+
23+
@Modifying(clearAutomatically = true)
24+
@Query("""
25+
UPDATE ChatMessage
26+
SET readByOpponent = TRUE
27+
WHERE chatroom.chatroomId = :chatroomId
28+
""")
29+
void readMessagesInChatroomByOpponent(@Param("chatroomId") Long chatroomId);
2130
}

src/test/java/com/hf/healthfriend/domain/chat/repository/TestChatMessageRepository.java

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.hf.healthfriend.domain.chat.repository;
22

3-
import com.hf.healthfriend.domain.chat.constant.ChatMessageType;
43
import com.hf.healthfriend.domain.chat.entity.Chatroom;
54
import com.hf.healthfriend.domain.chat.entity.chatmessage.ChatMessage;
65
import com.hf.healthfriend.domain.chat.entity.chatmessage.ImageChatMessage;
@@ -10,8 +9,8 @@
109
import com.hf.healthfriend.testutil.MysqlTestcontainerConfig;
1110
import com.hf.healthfriend.testutil.SampleEntityGenerator;
1211
import com.hf.healthfriend.testutil.TestConfig;
12+
import jakarta.persistence.EntityManager;
1313
import lombok.extern.slf4j.Slf4j;
14-
import org.assertj.core.api.Assertions;
1514
import org.junit.jupiter.api.DisplayName;
1615
import org.junit.jupiter.api.Test;
1716
import org.junit.jupiter.params.ParameterizedTest;
@@ -52,6 +51,9 @@ class TestChatMessageRepository {
5251
@Autowired
5352
ChatParticipationRepository chatParticipationRepository;
5453

54+
@Autowired
55+
EntityManager em;
56+
5557
@Test
5658
@DisplayName("save() - 이미지 메시지 저장 성공")
5759
void saveImageMessage_success() {
@@ -91,7 +93,7 @@ void saveImageMessage_success() {
9193
@DisplayName("findByChatroomId() - Pagination을 적용한 채팅 메시지 목록 불러오기 테스트")
9294
void findByChatroomId_success_fetchWithPagination(int page, int pageSize) {
9395
// Given
94-
int index = page - 1;
96+
int zeroBasedPage = page - 1;
9597
Member participant1 = SampleEntityGenerator.generateSampleMember("[email protected]", "part1");
9698
Member participant2 = SampleEntityGenerator.generateSampleMember("[email protected]", "part2");
9799
this.memberRepository.save(participant1);
@@ -108,35 +110,44 @@ void findByChatroomId_success_fetchWithPagination(int page, int pageSize) {
108110
}
109111

110112
// When
113+
PageRequest pageObj = PageRequest.of(zeroBasedPage, pageSize);
114+
log.info("pageObj={}", pageObj);
111115
Page<ChatMessage> result = this.chatMessageRepository.findByChatroomId(chatroom.getChatroomId(),
112-
PageRequest.of(index, pageSize));
116+
pageObj);
113117

114118
// Then
115-
List<ChatMessage> expected = getSubList(messages, index, pageSize);
119+
List<ChatMessage> expected = getSubList(messages, zeroBasedPage, pageSize);
116120

117-
log.info("message.size()={}", messages.size());
118-
log.info("messages.size() / pageSize = {}", messages.size() / pageSize);
119121
assertThat(result.getTotalElements()).isEqualTo(messages.size());
120122
assertThat(result.getTotalPages())
121123
.isEqualTo(messages.size() / pageSize + (messages.size() % pageSize > 0 ? 1 : 0));
122124

125+
Long[] resultIds = result.getContent().stream().map(ChatMessage::getChatMessageId).toArray(Long[]::new);
126+
log.info("resultIds={}", Arrays.toString(resultIds));
127+
log.info("expected={}", expected.stream().map(ChatMessage::getChatMessageId).toList());
123128
// 순서 보장
124129
assertThat(expected.stream().map(ChatMessage::getChatMessageId))
125-
.containsExactly(result.getContent().stream().map(ChatMessage::getChatMessageId).toArray(Long[]::new));
130+
.containsExactly(resultIds);
126131
}
127132

128133
private List<ChatMessage> inputSampleChatMessages(Chatroom chatroom, Member participant1, Member participant2) {
129134
final int DUMMY_COUNT = 100;
130135
List<ChatMessage> chatMessages = new ArrayList<>();
131136
LocalDateTime now = LocalDateTime.now();
132137

138+
Set<Integer> usedRandomValue = new HashSet<>();
133139
for (int i = 0; i < DUMMY_COUNT; i++) {
134140
int num = i + 1;
135141
Random random = new Random();
136-
int randomValue = random.nextInt(DUMMY_COUNT * 100);
137-
log.info("DUMMY_COUNT * 100 = {}", DUMMY_COUNT * 100);
138-
log.info("randomValue={}", randomValue);
139-
LocalDateTime randomCreationTime = now.minus(randomValue, ChronoUnit.SECONDS);
142+
int randomValue;
143+
while (true) {
144+
randomValue = random.nextInt();
145+
if (!usedRandomValue.contains(randomValue)) {
146+
usedRandomValue.add(randomValue);
147+
break;
148+
}
149+
}
150+
LocalDateTime randomCreationTime = now.minus(randomValue, ChronoUnit.MILLIS);
140151
TextChatMessage message = new TextChatMessage(chatroom, num % 2 == 0 ? participant1 : participant2, "text" + num);
141152
ReflectionTestUtils.setField(message, "creationTime", randomCreationTime);
142153
ReflectionTestUtils.setField(message, "lastModified", randomCreationTime);
@@ -158,13 +169,40 @@ private List<ChatMessage> inputSampleChatMessages(Chatroom chatroom, Member part
158169
return chatMessages;
159170
}
160171

161-
private List<ChatMessage> getSubList(List<ChatMessage> original, int index, int pageSize) {
162-
int fromIndex = index * pageSize;
163-
int toIndex = (index + 1) * pageSize;
164-
if (fromIndex >= original.size()) {
172+
private List<ChatMessage> getSubList(List<ChatMessage> original, int zeroBasedPage, int pageSize) {
173+
int originalSize = original.size();
174+
int fromIndex = zeroBasedPage * pageSize;
175+
int toIndex = Math.min((zeroBasedPage + 1) * pageSize, originalSize);
176+
if (fromIndex >= originalSize) {
165177
return new ArrayList<>();
166178
}
167179

168-
return original.subList(fromIndex, Math.min(toIndex, pageSize));
180+
return original.subList(fromIndex, toIndex);
181+
}
182+
183+
@Test
184+
@DisplayName("readMessagesInChatroomByOpponent() - success")
185+
void readByChatroomId_success() {
186+
// Given
187+
Member participant1 = SampleEntityGenerator.generateSampleMember("[email protected]", "part1");
188+
Member participant2 = SampleEntityGenerator.generateSampleMember("[email protected]", "part2");
189+
this.memberRepository.save(participant1);
190+
this.memberRepository.save(participant2);
191+
192+
Chatroom chatroom = SampleEntityGenerator.generateSampleChatroom(participant1, participant2);
193+
this.chatroomRepository.save(chatroom);
194+
195+
List<ChatMessage> chatMessages = inputSampleChatMessages(chatroom, participant1, participant2);
196+
int chatMessageCount = chatMessages.size();
197+
198+
// When
199+
this.chatMessageRepository.readMessagesInChatroomByOpponent(chatroom.getChatroomId());
200+
201+
// Then
202+
List<ChatMessage> found =
203+
this.chatMessageRepository.findByChatroomId(chatroom.getChatroomId(), PageRequest.of(0, chatMessageCount))
204+
.getContent();
205+
206+
found.forEach((f) -> assertThat(f.isReadByOpponent()).isTrue());
169207
}
170208
}

0 commit comments

Comments
 (0)