Skip to content

Commit e9e83dd

Browse files
authored
[refactor] 알림 조회 api 요청시 20개의 데이터만 프론트로 전달 (#235)
* [refactoring] : 알림조회시 최신 20개만 전달 * [refactoring] : 테스트코드 수정
1 parent a0ac7fb commit e9e83dd

6 files changed

Lines changed: 101 additions & 35 deletions

File tree

backend/src/main/java/com/back/api/notification/controller/NotificationApi.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,19 @@
22

33
import java.util.List;
44

5-
import org.springframework.security.core.annotation.AuthenticationPrincipal;
65
import org.springframework.web.bind.annotation.PathVariable;
76

87
import com.back.api.notification.dto.NotificationResponseDto;
98
import com.back.api.notification.dto.UnreadCountResponseDto;
109
import com.back.global.config.swagger.ApiErrorCode;
1110
import com.back.global.response.ApiResponse;
12-
import com.back.global.security.SecurityUser;
1311

1412
import io.swagger.v3.oas.annotations.Operation;
1513
import io.swagger.v3.oas.annotations.tags.Tag;
1614

1715
@Tag(name = "Notification API", description = "알림 API")
1816
public interface NotificationApi {
19-
@Operation(summary = "알림 조회", description = "웹소켓이 연결되기 전 발생한 알림들을 조회할 수 있습니다(초기 데이터 로딩). 웹소켓이 연결되면 새로운 알림은 웹소켓으로 전달됩니다 ")
17+
@Operation(summary = "알림 조회 (최신 20개)", description = "웹소켓이 연결되기 전 발생한 알림들을 조회할 수 있습니다(초기 데이터 로딩). 웹소켓이 연결되면 새로운 알림은 웹소켓으로 전달됩니다 ")
2018
@ApiErrorCode({
2119
"NOTIFICATION_NOT_FOUND",
2220
"NOTIFICATION_ACCESS_DENIED"

backend/src/main/java/com/back/api/notification/service/NotificationService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class NotificationService {
1919

2020
public List<NotificationResponseDto> getNotifications(Long userId) {
2121
List<Notification> notifications = notificationRepository
22-
.findByUserIdOrderByCreateAtDesc(userId);
22+
.findTop20ByUserIdOrderByCreateAtDesc(userId);
2323

2424
return notifications.stream()
2525
.map(NotificationResponseDto::from)

backend/src/main/java/com/back/domain/notification/repository/NotificationRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
public interface NotificationRepository extends JpaRepository<Notification, Long> {
1111

12-
List<Notification> findByUserIdOrderByCreateAtDesc(Long userId);
12+
List<Notification> findTop20ByUserIdOrderByCreateAtDesc(Long userId);
1313

1414
long countByUserIdAndIsReadFalse(Long userId);
1515

backend/src/main/java/com/back/global/init/NotificationDataInit.java

Lines changed: 80 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ public void run(ApplicationArguments args) {
6464
}
6565

6666
User user1 = user1Opt.get();
67-
User user2 = user2Opt.get();
6867
Event event = eventOpt.get();
6968
String eventName = event.getTitle();
7069

@@ -88,27 +87,95 @@ public void run(ApplicationArguments args) {
8887
notifications.add(createNotificationFromMessage(user1,
8988
new OrderFailedMessage(user1.getId(), 154000L, 51L, eventName), true));
9089

91-
// ===== 유저 2번 알림 (총 5개) =====
90+
// ===== 유저 1번 알림 (총 5개) =====
91+
// 안읽은 알림 3개
92+
notifications.add(createNotificationFromMessage(user1,
93+
new PreRegisterDoneMessage(user1.getId(), 202L, eventName), false));
94+
95+
notifications.add(createNotificationFromMessage(user1,
96+
new QueueEntriesMessage(user1.getId(), 102L, eventName), false));
97+
98+
notifications.add(createNotificationFromMessage(user1,
99+
new OrdersSuccessMessage(user1.getId(), 2L, 154000L, eventName), false));
100+
101+
// 읽은 알림 2개
102+
notifications.add(createNotificationFromMessage(user1,
103+
new OrderFailedMessage(user1.getId(), 99000L, 52L, eventName), true));
104+
105+
notifications.add(createNotificationFromMessage(user1,
106+
new TicketGetMessage(user1.getId(), DomainName.ORDERS, 302L, eventName), true));
107+
108+
notifications.add(createNotificationFromMessage(user1,
109+
new OrdersSuccessMessage(user1.getId(), 1L, 99000L, eventName), false));
110+
111+
notifications.add(createNotificationFromMessage(user1,
112+
new QueueEntriesMessage(user1.getId(), 101L, eventName), false));
113+
114+
notifications.add(createNotificationFromMessage(user1,
115+
new PreRegisterDoneMessage(user1.getId(), 201L, eventName), false));
116+
117+
// 읽은 알림 2개
118+
notifications.add(createNotificationFromMessage(user1,
119+
new TicketGetMessage(user1.getId(), DomainName.ORDERS, 301L, eventName), true));
120+
121+
notifications.add(createNotificationFromMessage(user1,
122+
new OrderFailedMessage(user1.getId(), 154000L, 51L, eventName), true));
123+
124+
// ===== 유저 1번 알림 (총 5개) =====
125+
// 안읽은 알림 3개
126+
notifications.add(createNotificationFromMessage(user1,
127+
new PreRegisterDoneMessage(user1.getId(), 202L, eventName), false));
128+
129+
notifications.add(createNotificationFromMessage(user1,
130+
new QueueEntriesMessage(user1.getId(), 102L, eventName), false));
131+
132+
notifications.add(createNotificationFromMessage(user1,
133+
new OrdersSuccessMessage(user1.getId(), 2L, 154000L, eventName), false));
134+
135+
// 읽은 알림 2개
136+
notifications.add(createNotificationFromMessage(user1,
137+
new OrderFailedMessage(user1.getId(), 99000L, 52L, eventName), true));
138+
139+
notifications.add(createNotificationFromMessage(user1,
140+
new TicketGetMessage(user1.getId(), DomainName.ORDERS, 302L, eventName), true));
141+
142+
notifications.add(createNotificationFromMessage(user1,
143+
new OrdersSuccessMessage(user1.getId(), 1L, 99000L, eventName), false));
144+
145+
notifications.add(createNotificationFromMessage(user1,
146+
new QueueEntriesMessage(user1.getId(), 101L, eventName), false));
147+
148+
notifications.add(createNotificationFromMessage(user1,
149+
new PreRegisterDoneMessage(user1.getId(), 201L, eventName), false));
150+
151+
// 읽은 알림 2개
152+
notifications.add(createNotificationFromMessage(user1,
153+
new TicketGetMessage(user1.getId(), DomainName.ORDERS, 301L, eventName), true));
154+
155+
notifications.add(createNotificationFromMessage(user1,
156+
new OrderFailedMessage(user1.getId(), 154000L, 51L, eventName), true));
157+
158+
// ===== 유저 1번 알림 (총 5개) =====
92159
// 안읽은 알림 3개
93-
notifications.add(createNotificationFromMessage(user2,
94-
new PreRegisterDoneMessage(user2.getId(), 202L, eventName), false));
160+
notifications.add(createNotificationFromMessage(user1,
161+
new PreRegisterDoneMessage(user1.getId(), 202L, eventName), false));
95162

96-
notifications.add(createNotificationFromMessage(user2,
97-
new QueueEntriesMessage(user2.getId(), 102L, eventName), false));
163+
notifications.add(createNotificationFromMessage(user1,
164+
new QueueEntriesMessage(user1.getId(), 102L, eventName), false));
98165

99-
notifications.add(createNotificationFromMessage(user2,
100-
new OrdersSuccessMessage(user2.getId(), 2L, 154000L, eventName), false));
166+
notifications.add(createNotificationFromMessage(user1,
167+
new OrdersSuccessMessage(user1.getId(), 2L, 154000L, eventName), false));
101168

102169
// 읽은 알림 2개
103-
notifications.add(createNotificationFromMessage(user2,
104-
new OrderFailedMessage(user2.getId(), 99000L, 52L, eventName), true));
170+
notifications.add(createNotificationFromMessage(user1,
171+
new OrderFailedMessage(user1.getId(), 99000L, 52L, eventName), true));
105172

106-
notifications.add(createNotificationFromMessage(user2,
107-
new TicketGetMessage(user2.getId(), DomainName.ORDERS, 302L, eventName), true));
173+
notifications.add(createNotificationFromMessage(user1,
174+
new TicketGetMessage(user1.getId(), DomainName.ORDERS, 302L, eventName), true));
108175

109176
notificationRepository.saveAll(notifications);
110177

111-
log.info("Notification 초기 데이터 {}개가 생성되었습니다. (유저1: 5개, 유저2: 5개)", notifications.size());
178+
log.info("Notification 초기 데이터 {}개가 생성되었습니다.", notifications.size());
112179
}
113180

114181
/**

backend/src/test/java/com/back/api/notification/listener/NotificationEventListenerTest.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ void publishOrdersSuccessMessage_UserOnline_SavesAndSendsWebSocket() {
132132
await().atMost(5, SECONDS).untilAsserted(() -> {
133133
// DB 저장 확인
134134
List<Notification> notifications = notificationRepository
135-
.findByUserIdOrderByCreateAtDesc(testUser.getId());
135+
.findTop20ByUserIdOrderByCreateAtDesc(testUser.getId());
136136
assertThat(notifications).hasSize(1);
137137

138138
Notification saved = notifications.get(0);
@@ -173,7 +173,7 @@ void publishOrdersSuccessMessage_UserOffline_SavesOnlyWithoutWebSocket() {
173173
await().atMost(3, SECONDS).untilAsserted(() -> {
174174
// DB 저장 확인
175175
List<Notification> notifications = notificationRepository
176-
.findByUserIdOrderByCreateAtDesc(testUser.getId());
176+
.findTop20ByUserIdOrderByCreateAtDesc(testUser.getId());
177177
assertThat(notifications).hasSize(1);
178178

179179
// 웹소켓 미전송 확인
@@ -184,6 +184,7 @@ void publishOrdersSuccessMessage_UserOffline_SavesOnlyWithoutWebSocket() {
184184
);
185185
});
186186
}
187+
187188
@Test
188189
@DisplayName("알림 타입 및 상세 정보 검증")
189190
void publishOrdersSuccessMessage_VerifyNotificationTypeDetails() {
@@ -204,7 +205,7 @@ void publishOrdersSuccessMessage_VerifyNotificationTypeDetails() {
204205
// then
205206
await().atMost(3, SECONDS).untilAsserted(() -> {
206207
List<Notification> notifications = notificationRepository
207-
.findByUserIdOrderByCreateAtDesc(testUser.getId());
208+
.findTop20ByUserIdOrderByCreateAtDesc(testUser.getId());
208209

209210
Notification saved = notifications.get(0);
210211
assertThat(saved.getType()).isEqualTo(NotificationTypes.PAYMENT);
@@ -239,7 +240,7 @@ void publishOrderFailedMessage_UserOnline_SavesAndSendsWebSocket() {
239240
// then
240241
await().atMost(3, SECONDS).untilAsserted(() -> {
241242
List<Notification> notifications = notificationRepository
242-
.findByUserIdOrderByCreateAtDesc(testUser.getId());
243+
.findTop20ByUserIdOrderByCreateAtDesc(testUser.getId());
243244
assertThat(notifications).hasSize(1);
244245

245246
Notification saved = notifications.get(0);
@@ -274,7 +275,7 @@ void publishOrderFailedMessage_VerifyFailedType() {
274275
// then
275276
await().atMost(3, SECONDS).untilAsserted(() -> {
276277
List<Notification> notifications = notificationRepository
277-
.findByUserIdOrderByCreateAtDesc(testUser.getId());
278+
.findTop20ByUserIdOrderByCreateAtDesc(testUser.getId());
278279

279280
Notification saved = notifications.get(0);
280281
assertThat(saved.getType()).isEqualTo(NotificationTypes.PAYMENT);
@@ -307,7 +308,7 @@ void publishPreRegisterDoneMessage_UserOnline_SavesAndSendsWebSocket() {
307308
// then
308309
await().atMost(3, SECONDS).untilAsserted(() -> {
309310
List<Notification> notifications = notificationRepository
310-
.findByUserIdOrderByCreateAtDesc(testUser.getId());
311+
.findTop20ByUserIdOrderByCreateAtDesc(testUser.getId());
311312
assertThat(notifications).hasSize(1);
312313

313314
Notification saved = notifications.get(0);
@@ -341,7 +342,7 @@ void publishPreRegisterDoneMessage_VerifyType() {
341342
// then
342343
await().atMost(3, SECONDS).untilAsserted(() -> {
343344
List<Notification> notifications = notificationRepository
344-
.findByUserIdOrderByCreateAtDesc(testUser.getId());
345+
.findTop20ByUserIdOrderByCreateAtDesc(testUser.getId());
345346

346347
Notification saved = notifications.get(0);
347348
assertThat(saved.getType()).isEqualTo(NotificationTypes.PRE_REGISTER);
@@ -374,7 +375,7 @@ void publishQueueEntriesMessage_UserOnline_SavesAndSendsWebSocket() {
374375
// then
375376
await().atMost(3, SECONDS).untilAsserted(() -> {
376377
List<Notification> notifications = notificationRepository
377-
.findByUserIdOrderByCreateAtDesc(testUser.getId());
378+
.findTop20ByUserIdOrderByCreateAtDesc(testUser.getId());
378379
assertThat(notifications).hasSize(1);
379380

380381
Notification saved = notifications.get(0);
@@ -408,7 +409,7 @@ void publishQueueEntriesMessage_VerifyType() {
408409
// then
409410
await().atMost(3, SECONDS).untilAsserted(() -> {
410411
List<Notification> notifications = notificationRepository
411-
.findByUserIdOrderByCreateAtDesc(testUser.getId());
412+
.findTop20ByUserIdOrderByCreateAtDesc(testUser.getId());
412413

413414
Notification saved = notifications.get(0);
414415
assertThat(saved.getType()).isEqualTo(NotificationTypes.QUEUE_ENTRIES);
@@ -443,7 +444,7 @@ void publishMessage_NonExistentUser_DoesNotSaveNotification() {
443444
// then: 알림이 생성되지 않음
444445
await().atMost(3, SECONDS).untilAsserted(() -> {
445446
List<Notification> notifications = notificationRepository
446-
.findByUserIdOrderByCreateAtDesc(nonExistentUserId);
447+
.findTop20ByUserIdOrderByCreateAtDesc(nonExistentUserId);
447448
assertThat(notifications).isEmpty();
448449

449450
// 웹소켓도 전송되지 않음
@@ -481,7 +482,7 @@ void publishMessage_WebSocketFails_StillSavesNotification() {
481482
// then: DB에는 저장됨 (웹소켓 실패가 DB 저장에 영향 없음)
482483
await().atMost(3, SECONDS).untilAsserted(() -> {
483484
List<Notification> notifications = notificationRepository
484-
.findByUserIdOrderByCreateAtDesc(testUser.getId());
485+
.findTop20ByUserIdOrderByCreateAtDesc(testUser.getId());
485486
assertThat(notifications).hasSize(1);
486487

487488
// 웹소켓 전송 시도는 있었음
@@ -514,7 +515,7 @@ void publishMultipleMessages_AllProcessedSuccessfully() {
514515
// then: 4개 모두 저장됨
515516
await().atMost(5, SECONDS).untilAsserted(() -> {
516517
List<Notification> notifications = notificationRepository
517-
.findByUserIdOrderByCreateAtDesc(testUser.getId());
518+
.findTop20ByUserIdOrderByCreateAtDesc(testUser.getId());
518519
assertThat(notifications).hasSize(4);
519520

520521
// 각 타입별 확인

backend/src/test/java/com/back/api/notification/service/NotificationServiceTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ class GetNotificationsTest {
135135
@DisplayName("알림 목록 조회 성공 - 5개 반환")
136136
void getNotifications_Success() {
137137
// given
138-
given(notificationRepository.findByUserIdOrderByCreateAtDesc(USER_ID))
138+
given(notificationRepository.findTop20ByUserIdOrderByCreateAtDesc(USER_ID))
139139
.willReturn(testNotifications);
140140

141141
// when
@@ -146,14 +146,14 @@ void getNotifications_Success() {
146146
assertThat(result).extracting("title")
147147
.containsExactly("알림 제목 1", "알림 제목 2", "알림 제목 3", "알림 제목 4", "알림 제목 5");
148148
verify(notificationRepository, times(1))
149-
.findByUserIdOrderByCreateAtDesc(USER_ID);
149+
.findTop20ByUserIdOrderByCreateAtDesc(USER_ID);
150150
}
151151

152152
@Test
153153
@DisplayName("알림이 없는 경우 - 빈 리스트 반환")
154154
void getNotifications_EmptyList() {
155155
// given
156-
given(notificationRepository.findByUserIdOrderByCreateAtDesc(USER_ID))
156+
given(notificationRepository.findTop20ByUserIdOrderByCreateAtDesc(USER_ID))
157157
.willReturn(List.of());
158158

159159
// when
@@ -162,15 +162,15 @@ void getNotifications_EmptyList() {
162162
// then
163163
assertThat(result).isEmpty();
164164
verify(notificationRepository, times(1))
165-
.findByUserIdOrderByCreateAtDesc(USER_ID);
165+
.findTop20ByUserIdOrderByCreateAtDesc(USER_ID);
166166
}
167167

168168
@Test
169169
@DisplayName("알림 내용 검증 - DTO 변환 정확성")
170170
void getNotifications_DtoMapping() {
171171
// given
172172
Notification notification = testNotifications.get(0);
173-
given(notificationRepository.findByUserIdOrderByCreateAtDesc(USER_ID))
173+
given(notificationRepository.findTop20ByUserIdOrderByCreateAtDesc(USER_ID))
174174
.willReturn(List.of(notification));
175175

176176
// when

0 commit comments

Comments
 (0)