-
Notifications
You must be signed in to change notification settings - Fork 2
✨ Feat: 펫 디바이스 ID 중복 확인 기능 구현 #152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -514,6 +514,39 @@ public ResponseEntity<PetDeviceUpdateResponse> updateDevice( | |
| return ResponseEntity.ok(response); | ||
| } | ||
|
|
||
| /** | ||
| * 디바이스 ID 중복 여부를 확인합니다. | ||
| * | ||
| * @param request 확인할 디바이스 ID | ||
| * @param userDetails 인증된 사용자 정보 | ||
| * @return 디바이스 ID 사용 가능 여부 응답 | ||
| */ | ||
| @Operation(summary = "디바이스 ID 중복 확인", description = "펫 등록 전에 디바이스 ID가 이미 다른 반려동물에 등록되어 있는지 확인합니다.") | ||
| @ApiResponses(value = { | ||
| @ApiResponse(responseCode = "200", description = "디바이스 ID 중복 확인 결과", | ||
| content = @Content(schema = @Schema(implementation = PetDeviceCheckResponse.class))), | ||
| @ApiResponse(responseCode = "400", description = "잘못된 요청입니다.", | ||
| content = @Content(mediaType = "application/json", | ||
| schema = @Schema(implementation = ErrorResponse.class), | ||
| examples = @ExampleObject(name = "400 Bad Request", value = "{\"status\": 400, \"message\": \"잘못된 요청입니다.\"}"))), | ||
| @ApiResponse(responseCode = "401", description = "로그인이 필요한 기능입니다.", | ||
| content = @Content(mediaType = "application/json", | ||
| schema = @Schema(implementation = ErrorResponse.class), | ||
| examples = @ExampleObject(name = "401 Unauthorized", value = "{\"status\": 401, \"message\": \"로그인이 필요한 기능입니다.\"}"))), | ||
| @ApiResponse(responseCode = "500", description = "서버 내부 오류가 발생했습니다.", | ||
| content = @Content(mediaType = "application/json", | ||
| schema = @Schema(implementation = ErrorResponse.class), | ||
| examples = @ExampleObject(name = "500 Internal Server Error", value = "{\"status\": 500, \"message\": \"서버 내부 오류가 발생했습니다.\"}"))) | ||
| }) | ||
| @PostMapping("/device/check") | ||
| public ResponseEntity<PetDeviceCheckResponse> checkDeviceId( | ||
| @Valid @RequestBody PetDeviceCheckRequest request) { | ||
|
|
||
| log.info("디바이스 ID 중복 확인 요청 - DeviceId: {}", request.getDeviceId()); | ||
|
|
||
| return ResponseEntity.ok(petService.checkDeviceIdAvailability(request)); | ||
| } | ||
|
Comment on lines
+542
to
+548
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 만약 이 API가 로그인 여부와 상관없이 디바이스 ID의 중복 여부만 확인하는 퍼블릭 API라면, |
||
|
|
||
| /** | ||
| * 반려동물 상세 정보를 조회합니다. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |||||||||||||||||||||||||||||
| import com.dodo.backend.activityhistory.entity.ActivityHistory; | ||||||||||||||||||||||||||||||
| import com.dodo.backend.activityhistory.repository.ActivityHistoryRepository; | ||||||||||||||||||||||||||||||
| import com.dodo.backend.imagefile.service.ImageFileService; | ||||||||||||||||||||||||||||||
| import com.dodo.backend.pet.dto.request.PetRequest.PetDeviceCheckRequest; | ||||||||||||||||||||||||||||||
| import com.dodo.backend.pet.dto.request.PetRequest.PetDeviceUpdateRequest; | ||||||||||||||||||||||||||||||
| import com.dodo.backend.pet.dto.request.PetRequest.PetFamilyJoinRequest; | ||||||||||||||||||||||||||||||
| import com.dodo.backend.pet.dto.request.PetRequest.PetRegisterRequest; | ||||||||||||||||||||||||||||||
|
|
@@ -87,6 +88,10 @@ public PetRegisterResponse registerPet(UUID userId, PetRegisterRequest request) | |||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if (petRepository.existsByDeviceId(request.getDeviceId())) { | ||||||||||||||||||||||||||||||
| throw new PetException(DEVICE_ID_DUPLICATED); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| Pet pet = request.toEntity(); | ||||||||||||||||||||||||||||||
| Pet savedPet = petRepository.save(pet); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
@@ -519,6 +524,22 @@ public PetDeviceUpdateResponse updateDevice(UUID userId, Long petId, PetDeviceUp | |||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||
| * 디바이스 ID 중복 여부를 확인합니다. | ||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||
| * @param request 확인할 디바이스 ID가 포함된 요청 DTO | ||||||||||||||||||||||||||||||
| * @return 디바이스 ID 사용 가능 여부 응답 | ||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||
| @Transactional(readOnly = true) | ||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||
| public PetDeviceCheckResponse checkDeviceIdAvailability(PetDeviceCheckRequest request) { | ||||||||||||||||||||||||||||||
| if (petRepository.existsByDeviceId(request.getDeviceId())) { | ||||||||||||||||||||||||||||||
| return PetDeviceCheckResponse.toDto("이미 다른 반려동물에 등록된 디바이스 ID입니다.", false); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| return PetDeviceCheckResponse.toDto("사용 가능한 디바이스 ID입니다.", true); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
Comment on lines
+535
to
+541
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 중복 확인(Check) API는 예외를 던지기보다 200 OK 응답과 함께
Suggested change
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||
| * 반려동물 특이사항을 생성합니다. | ||||||||||||||||||||||||||||||
| * <p> | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -173,6 +173,37 @@ void registerPet_Fail_DuplicateRegistrationNumber() { | |
| log.info("등록번호 중복 실패 테스트가 통과되었습니다."); | ||
| } | ||
|
|
||
| /** | ||
| * 이미 등록된 디바이스 ID로 펫 등록을 시도할 때 예외 발생을 테스트합니다. | ||
| */ | ||
| @Test | ||
| @DisplayName("펫 등록 실패: 이미 다른 펫이 사용 중인 디바이스 ID면 예외가 발생한다.") | ||
| void registerPet_Fail_DuplicateDeviceId() { | ||
| log.info("디바이스 ID 중복으로 인한 펫 등록 실패 테스트를 시작합니다."); | ||
| // given | ||
| UUID userId = UUID.randomUUID(); | ||
| String duplicateDeviceId = "DUPLICATE_DEV"; | ||
| PetRequest.PetRegisterRequest request = PetRequest.PetRegisterRequest.builder() | ||
| .deviceId(duplicateDeviceId) | ||
| .build(); | ||
|
|
||
| log.info("사용자는 존재하고 디바이스 ID가 이미 등록된 상황을 설정합니다."); | ||
| given(userPetService.existsUser(userId)).willReturn(true); | ||
| given(petRepository.existsByDeviceId(duplicateDeviceId)).willReturn(true); | ||
|
|
||
| // when | ||
| log.info("중복된 디바이스 ID로 펫 등록 요청 시 예외가 발생하는지 확인합니다."); | ||
| PetException exception = assertThrows(PetException.class, () -> | ||
| petService.registerPet(userId, request) | ||
| ); | ||
|
|
||
| // then | ||
| log.info("발생한 예외 코드가 DEVICE_ID_DUPLICATED인지 검증합니다."); | ||
| assertEquals(PetErrorCode.DEVICE_ID_DUPLICATED, exception.getErrorCode()); | ||
| verify(petRepository, times(0)).save(any(Pet.class)); | ||
| log.info("디바이스 ID 중복 펫 등록 실패 테스트가 통과되었습니다."); | ||
| } | ||
|
|
||
| /** | ||
| * 반려동물 정보 수정 성공 시나리오를 테스트합니다. | ||
| */ | ||
|
|
@@ -569,6 +600,62 @@ void updateDevice_Fail_DuplicateDeviceId() { | |
| log.info("ID 중복 재등록 실패 테스트가 통과되었습니다."); | ||
| } | ||
|
|
||
| /** | ||
| * 디바이스 ID 중복 확인 성공 시나리오를 테스트합니다. | ||
| */ | ||
| @Test | ||
| @DisplayName("디바이스 ID 중복 확인 성공: 사용 가능한 ID면 true를 반환한다.") | ||
| void checkDeviceIdAvailability_Success() { | ||
| log.info("디바이스 ID 중복 확인 성공 테스트를 시작합니다."); | ||
| // given | ||
| String deviceId = "AVAILABLE_DEV"; | ||
| PetRequest.PetDeviceCheckRequest request = PetRequest.PetDeviceCheckRequest.builder() | ||
| .deviceId(deviceId) | ||
| .build(); | ||
|
|
||
| log.info("요청한 디바이스 ID가 존재하지 않는 상황을 설정합니다."); | ||
| given(petRepository.existsByDeviceId(deviceId)).willReturn(false); | ||
|
|
||
| // when | ||
| log.info("디바이스 ID 중복 확인 서비스 로직을 호출합니다."); | ||
| PetResponse.PetDeviceCheckResponse response = petService.checkDeviceIdAvailability(request); | ||
|
|
||
| // then | ||
| log.info("사용 가능 여부와 메시지를 검증합니다."); | ||
| assertNotNull(response); | ||
| assertTrue(response.isAvailable()); | ||
| assertEquals("사용 가능한 디바이스 ID입니다.", response.getMessage()); | ||
| log.info("디바이스 ID 중복 확인 성공 테스트가 통과되었습니다."); | ||
| } | ||
|
|
||
| /** | ||
| * 디바이스 ID 중복 확인 실패 시나리오를 테스트합니다. | ||
| */ | ||
| @Test | ||
| @DisplayName("디바이스 ID 중복 확인 실패: 이미 사용 중인 ID면 false를 반환한다.") | ||
| void checkDeviceIdAvailability_Fail_DuplicateDeviceId() { | ||
| log.info("디바이스 ID 중복 확인 실패 테스트를 시작합니다."); | ||
| // given | ||
| String duplicateDeviceId = "DUPLICATE_DEV"; | ||
| PetRequest.PetDeviceCheckRequest request = PetRequest.PetDeviceCheckRequest.builder() | ||
| .deviceId(duplicateDeviceId) | ||
| .build(); | ||
|
|
||
| log.info("요청한 디바이스 ID가 이미 존재한다고 설정합니다."); | ||
| given(petRepository.existsByDeviceId(duplicateDeviceId)).willReturn(true); | ||
|
|
||
| // when | ||
| log.info("디바이스 ID 중복 확인 서비스 로직을 호출합니다."); | ||
| PetResponse.PetDeviceCheckResponse response = petService.checkDeviceIdAvailability(request); | ||
|
|
||
| // then | ||
| log.info("사용 가능 여부가 false이고 적절한 메시지가 반환되었는지 검증합니다."); | ||
| assertNotNull(response); | ||
| assertFalse(response.isAvailable()); | ||
| assertEquals("이미 다른 반려동물에 등록된 디바이스 ID입니다.", response.getMessage()); | ||
| log.info("디바이스 ID 중복 확인 실패 테스트가 통과되었습니다."); | ||
| } | ||
|
Comment on lines
+634
to
+657
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@Test
@DisplayName("디바이스 ID 중복 확인 실패: 이미 사용 중인 ID면 false를 반환한다.")
void checkDeviceIdAvailability_Fail_DuplicateDeviceId() {
log.info("디바이스 ID 중복 확인 실패 테스트를 시작합니다.");
// given
String duplicateDeviceId = "DUPLICATE_DEV";
PetRequest.PetDeviceCheckRequest request = PetRequest.PetDeviceCheckRequest.builder()
.deviceId(duplicateDeviceId)
.build();
log.info("요청한 디바이스 ID가 이미 존재한다고 설정합니다.");
given(petRepository.existsByDeviceId(duplicateDeviceId)).willReturn(true);
// when
log.info("디바이스 ID 중복 확인 서비스 로직을 호출합니다.");
PetResponse.PetDeviceCheckResponse response = petService.checkDeviceIdAvailability(request);
// then
log.info("사용 가능 여부가 false이고 적절한 메시지가 반환되었는지 검증합니다.");
assertNotNull(response);
assertFalse(response.isAvailable());
assertEquals("이미 다른 반려동물에 등록된 디바이스 ID입니다.", response.getMessage());
log.info("디바이스 ID 중복 확인 실패 테스트가 통과되었습니다.");
} |
||
|
|
||
| /** | ||
| * 펫 특이사항 생성 성공 시나리오를 테스트합니다. | ||
| */ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
서비스 레이어(
PetServiceImpl)에서 중복된 디바이스 ID에 대해 예외를 던지는 대신available: false를 포함한 200 OK 응답을 반환하도록 변경할 경우, 컨트롤러의 Swagger 문서에서도 409 Conflict 응답 정의를 제거하고 200 OK 응답 설명을 그에 맞게 수정해야 합니다.