Skip to content

Commit 9f86860

Browse files
authored
[feat] 알림: 전체 삭제 기능 추가 #292 (#302)
* Revert "chore: initData용 이미지 추가" This reverts commit ef30eef. * . * chore: 수정사항 없음 * feat: MyHistoryPostItemDto에 상세 정보 필드 추가 및 매핑 로직 업데이트 * refactor: 게시글 좋아요 알림 메시지에 게시글 제목 추가 * chore: 수정사항 없음 * feat: NotificationRepository에 사용자별 알림 전체 삭제 기능 추가 * feat: NotificationService에 사용자 모든 알림 삭제 기능 추가 * feat: NotificationController에 모든 알림을 삭제하는 DELETE /me/notifications 엔드포인트 구현 * test: NotificationControllerTest에 알림 전체 삭제 테스트 케이스 구현
1 parent aa5405a commit 9f86860

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

src/main/java/com/back/domain/notification/controller/NotificationController.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import jakarta.validation.Valid;
1313
import jakarta.validation.constraints.Max;
1414
import jakarta.validation.constraints.Min;
15+
import java.time.LocalDateTime;
1516
import lombok.RequiredArgsConstructor;
1617
import org.springframework.format.annotation.DateTimeFormat;
1718
import org.springframework.security.access.prepost.PreAuthorize;
@@ -20,8 +21,6 @@
2021
import org.springframework.web.bind.annotation.*;
2122
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
2223

23-
import java.time.LocalDateTime;
24-
2524
@RestController
2625
@RequestMapping("/me")
2726
@RequiredArgsConstructor
@@ -120,7 +119,17 @@ public RsData<NotificationGoResponseDto> goPostLink(
120119
@PathVariable("id") Long notificationId
121120
) {
122121
Long userId = principal.getId();
123-
var body = notificationService.markAsReadAndGetPostLink(userId, notificationId);
122+
NotificationGoResponseDto body = notificationService.markAsReadAndGetPostLink(userId, notificationId);
124123
return RsData.successOf(body);
125124
}
125+
126+
@DeleteMapping("/notifications")
127+
@Operation(summary = "Delete all notifications", description = "Remove every notification belonging to the authenticated user")
128+
public RsData<Void> deleteNotifications(
129+
@AuthenticationPrincipal SecurityUser principal
130+
) {
131+
Long userId = principal.getId();
132+
notificationService.deleteAll(userId);
133+
return RsData.of(200, "cleared");
134+
}
126135
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.back.domain.notification.entity.Notification;
44
import org.springframework.data.domain.Pageable;
55
import org.springframework.data.jpa.repository.JpaRepository;
6+
import org.springframework.data.jpa.repository.Modifying;
67
import org.springframework.data.jpa.repository.Query;
78
import org.springframework.data.repository.query.Param;
89
import org.springframework.stereotype.Repository;
@@ -37,4 +38,8 @@ List<Notification> findMyNotificationsAfter(@Param("userId") Long userId,
3738
where n.id = :id and n.user.id = :userId
3839
""")
3940
Notification findByIdAndUserId(@Param("id") Long id, @Param("userId") Long userId);
41+
42+
@Modifying(clearAutomatically = true, flushAutomatically = true)
43+
long deleteByUser_Id(Long userId);
44+
4045
}

src/main/java/com/back/domain/notification/service/NotificationService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,9 @@ public void sendNotification(User user, Post post, NotificationType type, String
115115
}
116116
}
117117
}
118+
119+
@Transactional
120+
public void deleteAll(Long userId) {
121+
notificationRepository.deleteByUser_Id(userId);
122+
}
118123
}

src/test/java/com/back/domain/notification/controller/NotificationControllerTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@
3737

3838
import static org.mockito.ArgumentMatchers.eq;
3939
import static org.mockito.BDDMockito.given;
40+
import static org.mockito.BDDMockito.willDoNothing;
4041
import static org.mockito.Mockito.verify;
4142
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
43+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
4244
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
4345
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
4446
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
@@ -249,4 +251,21 @@ void goPostLink() throws Exception {
249251

250252
verify(notificationService).markAsReadAndGetPostLink(principal.getId(), 999L);
251253
}
254+
@Test
255+
@DisplayName("Delete notifications")
256+
void deleteNotifications() throws Exception {
257+
SecurityUser principal = createPrincipal(17L);
258+
259+
willDoNothing().given(notificationService).deleteAll(principal.getId());
260+
261+
mockMvc.perform(delete("/me/notifications")
262+
.with(withPrincipal(principal))
263+
.accept(MediaType.APPLICATION_JSON))
264+
.andExpect(status().isOk())
265+
.andExpect(jsonPath("$.code").value(200))
266+
.andExpect(jsonPath("$.message").value("cleared"))
267+
.andExpect(jsonPath("$.data").doesNotExist());
268+
269+
verify(notificationService).deleteAll(principal.getId());
270+
}
252271
}

0 commit comments

Comments
 (0)