From 4a6ea994c25fa01b246d3ee6b3581edbb004c4a6 Mon Sep 17 00:00:00 2001 From: w0uldy0u Date: Sun, 15 Feb 2026 23:19:02 +0900 Subject: [PATCH 1/2] feat: implement diagnosis delete --- .../episode/diagnosis/DiagnosisController.java | 15 +++++++++++++++ .../episode/diagnosis/DiagnosisRepository.java | 2 ++ .../yat2/episode/diagnosis/DiagnosisService.java | 8 ++++++++ 3 files changed, 25 insertions(+) diff --git a/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisController.java b/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisController.java index f9c2171ab..2e178c7ef 100644 --- a/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisController.java +++ b/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisController.java @@ -8,6 +8,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -80,4 +81,18 @@ public ResponseEntity createDiagnosis( URI location = UriUtil.createLocationUri(resBody.diagnosisId()); return ResponseEntity.created(location).body(resBody); } + + @Operation(summary = "진단 삭제") + @ApiResponses({ @ApiResponse(responseCode = "204", description = "삭제 성공") }) + @ApiErrorCodes({ ErrorCode.INVALID_REQUEST, ErrorCode.DIAGNOSIS_NOT_FOUND, ErrorCode.INTERNAL_ERROR }) + @DeleteMapping("/{diagnosisId}") + public ResponseEntity deleteDiagnosis( + @PathVariable + @Positive(message = "Id는 1 이상의 정수여야 합니다.") + Integer diagnosisId, + @RequestAttribute(USER_ID) Long userId + ) { + diagnosisService.deleteDiagnosis(diagnosisId, userId); + return ResponseEntity.noContent().build(); + } } diff --git a/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisRepository.java b/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisRepository.java index 27e82888d..1e4632f6b 100644 --- a/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisRepository.java +++ b/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisRepository.java @@ -48,4 +48,6 @@ Optional findDetailByIdAndUserId( @Param("diagnosisId") Integer diagnosisId, @Param("userId") Long userId ); + + Optional findByIdAndUser_KakaoId(Integer id, Long kakaoId); } diff --git a/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisService.java b/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisService.java index 2039cacce..e6e84198f 100644 --- a/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisService.java +++ b/backend/api/src/main/java/com/yat2/episode/diagnosis/DiagnosisService.java @@ -74,6 +74,14 @@ public DiagnosisDetailRes getDiagnosisDetailById(Integer diagnosisId, Long userI weaknesses); } + @Transactional + public void deleteDiagnosis(Integer diagnosisId, Long userId) { + DiagnosisResult diagnosis = diagnosisRepository.findByIdAndUser_KakaoId(diagnosisId, userId) + .orElseThrow(() -> new CustomException(ErrorCode.DIAGNOSIS_NOT_FOUND)); + + diagnosisRepository.delete(diagnosis); + } + private void validateUserJob(User user) { if (user.getJob() == null) { throw new CustomException(ErrorCode.JOB_NOT_SELECTED); From 90c87d9e7b8896a57a53fc521a28c75b452161c2 Mon Sep 17 00:00:00 2001 From: w0uldy0u Date: Sun, 15 Feb 2026 23:25:02 +0900 Subject: [PATCH 2/2] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diagnosis/DiagnosisServiceTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/backend/api/src/test/java/com/yat2/episode/diagnosis/DiagnosisServiceTest.java b/backend/api/src/test/java/com/yat2/episode/diagnosis/DiagnosisServiceTest.java index 4ecd0115a..2686db03c 100644 --- a/backend/api/src/test/java/com/yat2/episode/diagnosis/DiagnosisServiceTest.java +++ b/backend/api/src/test/java/com/yat2/episode/diagnosis/DiagnosisServiceTest.java @@ -361,4 +361,40 @@ void getDiagnosisDetail_noWeaknesses() { assertThat(result.weaknesses()).isEmpty(); } } + + @Nested + @DisplayName("deleteDiagnosis") + class DeleteDiagnosisTest { + + @Test + @DisplayName("진단을 성공적으로 삭제한다") + void deleteDiagnosis_success() { + Integer diagnosisId = 1; + Long userId = 1L; + + DiagnosisResult diagnosis = mock(DiagnosisResult.class); + when(diagnosisRepository.findByIdAndUser_KakaoId(diagnosisId, userId)).thenReturn(Optional.of(diagnosis)); + + diagnosisService.deleteDiagnosis(diagnosisId, userId); + + verify(diagnosisRepository).findByIdAndUser_KakaoId(diagnosisId, userId); + verify(diagnosisRepository).delete(diagnosis); + } + + @Test + @DisplayName("진단이 없거나 내 진단이 아니면 DIAGNOSIS_NOT_FOUND 예외가 발생하고 삭제하지 않는다") + void deleteDiagnosis_notFound_throwsException() { + Integer diagnosisId = 999; + Long userId = 1L; + + when(diagnosisRepository.findByIdAndUser_KakaoId(diagnosisId, userId)).thenReturn(Optional.empty()); + + assertThatThrownBy(() -> diagnosisService.deleteDiagnosis(diagnosisId, userId)).isInstanceOf( + CustomException.class).extracting(e -> ((CustomException) e).getErrorCode()) + .isEqualTo(ErrorCode.DIAGNOSIS_NOT_FOUND); + + verify(diagnosisRepository).findByIdAndUser_KakaoId(diagnosisId, userId); + verify(diagnosisRepository, never()).delete(any(DiagnosisResult.class)); + } + } }