diff --git a/src/main/java/com/mr/domain/analysis/dto/res/AnalysisResultResponseDTO.java b/src/main/java/com/mr/domain/analysis/dto/res/AnalysisResultResponseDTO.java index 0a1c2e60..aa59eefb 100644 --- a/src/main/java/com/mr/domain/analysis/dto/res/AnalysisResultResponseDTO.java +++ b/src/main/java/com/mr/domain/analysis/dto/res/AnalysisResultResponseDTO.java @@ -41,7 +41,8 @@ public record AnalysisResultResponseDTO( public static AnalysisResultResponseDTO from( Analysis analysis, AnalysisReport analysisReport, - JsonNode rawResult + JsonNode rawResult, + String recordingFileUrl ) { Playing playing = analysis.getPlaying(); BackingTrack backingTrack = playing.getBackingTrack(); @@ -53,7 +54,7 @@ public static AnalysisResultResponseDTO from( formatKey(backingTrack), playing.getBpm(), playing.getEndedAt(), - playing.getRecordingFileUrl(), + recordingFileUrl, backingTrack != null ? backingTrack.getAudioFileUrl() : null, analysis.getStatus(), analysis.getStartBar(), diff --git a/src/main/java/com/mr/domain/analysis/service/AnalysisService.java b/src/main/java/com/mr/domain/analysis/service/AnalysisService.java index 13d0b7ad..496bd7e5 100644 --- a/src/main/java/com/mr/domain/analysis/service/AnalysisService.java +++ b/src/main/java/com/mr/domain/analysis/service/AnalysisService.java @@ -21,6 +21,7 @@ import com.mr.domain.playing.exception.PlayingErrorStatus; import com.mr.domain.playing.repository.PlayingRepository; import com.mr.global.apipayload.exception.GeneralException; +import com.mr.global.file.s3.service.S3FileService; import java.util.List; import java.util.Objects; import lombok.RequiredArgsConstructor; @@ -41,6 +42,7 @@ public class AnalysisService { private final AnalysisRequestFactory analysisRequestFactory; private final ApplicationEventPublisher eventPublisher; private final ObjectMapper objectMapper; + private final S3FileService s3FileService; @Transactional public AnalysisCreateResponseDTO createAnalysis( @@ -115,10 +117,17 @@ public AnalysisResultResponseDTO getAnalysisResult( analysis.getRawResultJson() ); + String recordingFileUrl = + s3FileService.createPresignedDownload( + userId, + analysis.getPlaying().getRecordingObjectKey() + ); + return AnalysisResultResponseDTO.from( analysis, analysisReport, - rawResult + rawResult, + recordingFileUrl ); } diff --git a/src/main/java/com/mr/domain/history/dto/res/HistoryDetailResponseDTO.java b/src/main/java/com/mr/domain/history/dto/res/HistoryDetailResponseDTO.java index dc3569ee..c346346d 100644 --- a/src/main/java/com/mr/domain/history/dto/res/HistoryDetailResponseDTO.java +++ b/src/main/java/com/mr/domain/history/dto/res/HistoryDetailResponseDTO.java @@ -29,7 +29,7 @@ public record HistoryDetailResponseDTO( List analyses ) { - public static HistoryDetailResponseDTO from(Playing playing, List analyses) { + public static HistoryDetailResponseDTO from(Playing playing, List analyses, String recordingFileUrl) { BackingTrack backingTrack = playing.getBackingTrack(); return new HistoryDetailResponseDTO( @@ -42,7 +42,7 @@ public static HistoryDetailResponseDTO from(Playing playing, List anal playing.getEndedAt(), toDurationMinutes(playing.getDurationSec()), playing.getDurationSec(), - playing.getRecordingFileUrl(), + recordingFileUrl, backingTrack != null ? backingTrack.getAudioFileUrl() : null, playing.getMidiData().stream().map(MidiEvent::from).toList(), backingTrack != null ? backingTrack.getMidiData() : null, diff --git a/src/main/java/com/mr/domain/history/service/HistoryService.java b/src/main/java/com/mr/domain/history/service/HistoryService.java index 91069076..47a1272f 100644 --- a/src/main/java/com/mr/domain/history/service/HistoryService.java +++ b/src/main/java/com/mr/domain/history/service/HistoryService.java @@ -12,6 +12,7 @@ import com.mr.domain.playing.entity.enums.PlayingStatus; import com.mr.domain.playing.repository.PlayingRepository; import com.mr.global.apipayload.exception.GeneralException; +import com.mr.global.file.s3.service.S3FileService; import com.mr.global.util.RelativeDateFormatter; import java.time.LocalDateTime; import java.util.ArrayList; @@ -37,6 +38,7 @@ public class HistoryService { private final PlayingRepository playingRepository; private final AnalysisRepository analysisRepository; + private final S3FileService s3FileService; public HistoryListResponseDTO getHistories(Long userId, int page, int size, HistoryPeriod period) { validatePaging(page, size); @@ -69,7 +71,13 @@ public HistoryDetailResponseDTO getHistoryDetail(Long userId, Long playingId) { List analyses = analysisRepository.findByPlayingIdAndUserIdOrderByStartBarAscIdAsc(playingId, userId); - return HistoryDetailResponseDTO.from(playing, analyses); + String recordingFileUrl = + s3FileService.createPresignedDownload( + userId, + playing.getRecordingObjectKey() + ); + + return HistoryDetailResponseDTO.from(playing, analyses, recordingFileUrl); } private List buildItems( diff --git a/src/main/java/com/mr/domain/playing/dto/res/AnalysisContextResponse.java b/src/main/java/com/mr/domain/playing/dto/res/AnalysisContextResponse.java index 1902f945..c82d40ad 100644 --- a/src/main/java/com/mr/domain/playing/dto/res/AnalysisContextResponse.java +++ b/src/main/java/com/mr/domain/playing/dto/res/AnalysisContextResponse.java @@ -25,7 +25,7 @@ public record AnalysisContextResponse( Integer totalBars ) { - public static AnalysisContextResponse from(Playing playing, int totalBars) { + public static AnalysisContextResponse from(Playing playing, int totalBars, String recordingFileUrl) { BackingTrack backingTrack = playing.getBackingTrack(); return new AnalysisContextResponse( @@ -38,7 +38,7 @@ public static AnalysisContextResponse from(Playing playing, int totalBars) { playing.getEndedAt(), toDurationMinutes(playing.getDurationSec()), playing.getDurationSec(), - playing.getRecordingFileUrl(), + recordingFileUrl, backingTrack.getAudioFileUrl(), playing.getMidiData().stream().map(MidiEvent::from).toList(), backingTrack.getMidiData(), diff --git a/src/main/java/com/mr/domain/playing/dto/res/PlayingDetailResponse.java b/src/main/java/com/mr/domain/playing/dto/res/PlayingDetailResponse.java index 04ee974d..c8533d8d 100644 --- a/src/main/java/com/mr/domain/playing/dto/res/PlayingDetailResponse.java +++ b/src/main/java/com/mr/domain/playing/dto/res/PlayingDetailResponse.java @@ -21,7 +21,7 @@ public record PlayingDetailResponse( BackingTrackInfo backingTrack, LocalDateTime createdAt ) { - public static PlayingDetailResponse from(Playing playing) { + public static PlayingDetailResponse from(Playing playing, String recordingFileUrl) { return new PlayingDetailResponse( playing.getId(), playing.getStatus(), @@ -30,7 +30,7 @@ public static PlayingDetailResponse from(Playing playing) { playing.getEndedAt(), playing.getDurationSec(), playing.getBpm(), - playing.getRecordingFileUrl(), + recordingFileUrl, playing.isPublic(), BackingTrackInfo.from(playing.getBackingTrack()), playing.getCreatedAt() diff --git a/src/main/java/com/mr/domain/playing/entity/Playing.java b/src/main/java/com/mr/domain/playing/entity/Playing.java index ff68e4d3..f2793e0c 100644 --- a/src/main/java/com/mr/domain/playing/entity/Playing.java +++ b/src/main/java/com/mr/domain/playing/entity/Playing.java @@ -94,9 +94,8 @@ public class Playing extends BaseCreatedDeletedEntity { @Column(name = "ended_at") private LocalDateTime endedAt; - // 사용자가 연주한 녹음 파일 URL - @Column(name = "recording_file_url", length = 255) - private String recordingFileUrl; + @Column(name = "recording_object_key", length = 255) + private String recordingObjectKey; @Column(name = "duration_sec") private Integer durationSec; @@ -190,7 +189,7 @@ public static Playing createBackingTrack( // 연주 완료 시 전체 MIDI 데이터를 저장하고 완료 상태로 전환 public void completeWithMidiData( List requestedMidiData, - String recordingFileUrl + String recordingObjectKey ) { validateCompletableStatus(); validateMidiData(requestedMidiData); @@ -200,12 +199,13 @@ public void completeWithMidiData( List normalizedMidiData = normalizeMidiData(requestedMidiData, savedDurationMs); validateNormalizedMidiData(normalizedMidiData); + validateRecordingObjectKey(recordingObjectKey); this.midiData = new ArrayList<>(normalizedMidiData); this.endedAt = this.startedAt.plusNanos(savedDurationMs * 1_000_000L); this.durationSec = Math.toIntExact( Duration.ofMillis(savedDurationMs).toSeconds()); - this.recordingFileUrl = recordingFileUrl; + this.recordingObjectKey = recordingObjectKey; this.status = PlayingStatus.COMPLETED; } @@ -215,6 +215,14 @@ public void validatePlayingOwner(Long userId) { } } + private void validateRecordingObjectKey(String recordingObjectKey) { + if (recordingObjectKey == null || recordingObjectKey.isBlank()) { + throw new GeneralException( + PlayingErrorStatus.INVALID_RECORDING_OBJECT_KEY + ); + } + } + public void validateCompleted() { if (this.status != PlayingStatus.COMPLETED) { throw new GeneralException(PlayingErrorStatus.PLAYING_NOT_COMPLETED); diff --git a/src/main/java/com/mr/domain/playing/exception/PlayingErrorStatus.java b/src/main/java/com/mr/domain/playing/exception/PlayingErrorStatus.java index cbba04bc..3ba74f0d 100644 --- a/src/main/java/com/mr/domain/playing/exception/PlayingErrorStatus.java +++ b/src/main/java/com/mr/domain/playing/exception/PlayingErrorStatus.java @@ -18,6 +18,7 @@ public enum PlayingErrorStatus implements BaseCode { MISSING_PLAYING_STATUS(HttpStatus.BAD_REQUEST, "PLAYING_400_12", "연주 상태는 필수 입력값입니다."), UNSUPPORTED_PLAYING_MODE(HttpStatus.BAD_REQUEST, "PLAYING_400_13", "현재 지원하지 않는 연주 모드입니다."), INVALID_PLAYING_ID(HttpStatus.BAD_REQUEST, "PLAYING_400_14", "연주 ID가 올바르지 않습니다."), + INVALID_RECORDING_OBJECT_KEY(HttpStatus.BAD_REQUEST," PLAYING_400_15", "유효하지 않은 녹음 파일 Object Key입니다."), PLAYING_ACCESS_DENIED(HttpStatus.FORBIDDEN, "PLAYING_403_01", "해당 연주에 대한 접근 권한이 없습니다."), BACKING_TRACK_ACCESS_FORBIDDEN(HttpStatus.FORBIDDEN, "PLAYING_403_02", "해당 백킹트랙으로 연주를 시작할 수 없습니다."), PLAYING_NOT_FOUND(HttpStatus.NOT_FOUND, "PLAYING_404_01", "연주 세션을 찾을 수 없습니다."), diff --git a/src/main/java/com/mr/domain/playing/service/PlayingService.java b/src/main/java/com/mr/domain/playing/service/PlayingService.java index 779a5acf..6db2cc2b 100644 --- a/src/main/java/com/mr/domain/playing/service/PlayingService.java +++ b/src/main/java/com/mr/domain/playing/service/PlayingService.java @@ -124,7 +124,7 @@ public MidiEventSaveResponse saveMidiEvents( playing.completeWithMidiData( midiEvents, - recording.fileUrl() + recording.objectKey() ); publishPracticeMilestoneNotification(userId, playing); @@ -150,7 +150,13 @@ public PlayingDetailResponse getPlayingDetail(Long userId, Long playingId) { playing.validatePlayingOwner(userId); playing.validateCompleted(); - return PlayingDetailResponse.from(playing); + String recordingFileUrl = + s3FileService.createPresignedDownload( + userId, + playing.getRecordingObjectKey() + ); + + return PlayingDetailResponse.from(playing, recordingFileUrl); } @Transactional(readOnly = true) @@ -166,8 +172,14 @@ public AnalysisContextResponse getAnalysisContext(Long userId, Long playingId) { throw new GeneralException(PlayingErrorStatus.BACKING_TRACK_NOT_FOUND); } + String recordingFileUrl = + s3FileService.createPresignedDownload( + userId, + playing.getRecordingObjectKey() + ); + int totalBars = analysisBarCalculator.calculate(playing).totalBars(); - return AnalysisContextResponse.from(playing, totalBars); + return AnalysisContextResponse.from(playing, totalBars, recordingFileUrl); } @Transactional diff --git a/src/main/java/com/mr/global/file/s3/dto/ValidatedFile.java b/src/main/java/com/mr/global/file/s3/dto/ValidatedFile.java index 0a9c46f7..19fe4ca4 100644 --- a/src/main/java/com/mr/global/file/s3/dto/ValidatedFile.java +++ b/src/main/java/com/mr/global/file/s3/dto/ValidatedFile.java @@ -3,7 +3,6 @@ // S3 업로드 완료 검증 결과 public record ValidatedFile( String objectKey, - String fileUrl, Long fileSize, String contentType ) { diff --git a/src/main/java/com/mr/global/file/s3/service/S3FileService.java b/src/main/java/com/mr/global/file/s3/service/S3FileService.java index c34e0ebe..1d7ea5c0 100644 --- a/src/main/java/com/mr/global/file/s3/service/S3FileService.java +++ b/src/main/java/com/mr/global/file/s3/service/S3FileService.java @@ -24,7 +24,6 @@ import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest; import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest; -import java.net.URI; import java.time.Instant; import java.util.Map; @@ -141,7 +140,6 @@ public ValidatedFile validateUploadedFile( return new ValidatedFile( objectKey, - buildFileUrl(objectKey), headObject.contentLength(), normalizedContentType ); @@ -218,43 +216,6 @@ public void deleteObject(String objectKey) { } } - public String extractObjectKey( - String storedFileValue - ) { - if (storedFileValue == null - || storedFileValue.isBlank()) { - throw new GeneralException( - S3ErrorStatus.INVALID_OBJECT_KEY - ); - } - - if (!storedFileValue.startsWith("http://") - && !storedFileValue.startsWith("https://")) { - return storedFileValue; - } - - try { - String path = - URI.create(storedFileValue) - .getPath(); - - if (path == null || path.isBlank()) { - throw new GeneralException( - S3ErrorStatus.INVALID_OBJECT_KEY - ); - } - - return path.startsWith("/") - ? path.substring(1) - : path; - - } catch (IllegalArgumentException exception) { - throw new GeneralException( - S3ErrorStatus.INVALID_OBJECT_KEY - ); - } - } - private HeadObjectResponse getHeadObject(String objectKey) { HeadObjectRequest request = HeadObjectRequest.builder() .bucket(s3Properties.bucket()) @@ -346,12 +307,4 @@ private void validateObjectKey( throw new GeneralException(S3ErrorStatus.INVALID_OBJECT_KEY); } } - - private String buildFileUrl(String objectKey) { - return s3Client.utilities() - .getUrl(builder -> builder - .bucket(s3Properties.bucket()) - .key(objectKey)) - .toString(); - } } diff --git a/src/main/resources/db/migration/V5__migrate_recording_file_url_to_object_key.sql b/src/main/resources/db/migration/V5__migrate_recording_file_url_to_object_key.sql new file mode 100644 index 00000000..e780fadc --- /dev/null +++ b/src/main/resources/db/migration/V5__migrate_recording_file_url_to_object_key.sql @@ -0,0 +1,32 @@ +-- 1. 컬럼명 변경 +ALTER TABLE playing + RENAME COLUMN recording_file_url TO recording_object_key; + +-- 2. URL에서 S3 Object Key만 추출 +UPDATE playing +SET recording_object_key = regexp_replace( + recording_object_key, + '^(https?://[^/]+/)?([^?#]*).*$', + '\2' + ) +WHERE recording_object_key IS NOT NULL + AND btrim(recording_object_key) <> ''; + +-- 3. 검증: 실패 시 예외 발생 → Flyway가 트랜잭션 롤백 처리 +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 + FROM playing + WHERE recording_object_key IS NOT NULL + AND ( + recording_object_key LIKE '%?%' + OR recording_object_key LIKE 'http%' + OR recording_object_key LIKE '%X-Amz%' + OR btrim(recording_object_key) = '' + ) + ) THEN + RAISE EXCEPTION 'recording_object_key migration validation failed'; + END IF; +END +$$; \ No newline at end of file diff --git a/src/test/java/com/mr/domain/analysis/service/AnalysisServiceTest.java b/src/test/java/com/mr/domain/analysis/service/AnalysisServiceTest.java index a32ea22e..c66bc5f8 100644 --- a/src/test/java/com/mr/domain/analysis/service/AnalysisServiceTest.java +++ b/src/test/java/com/mr/domain/analysis/service/AnalysisServiceTest.java @@ -32,6 +32,7 @@ import com.mr.domain.playing.repository.PlayingRepository; import com.mr.domain.user.entity.User; import com.mr.global.apipayload.exception.GeneralException; +import com.mr.global.file.s3.service.S3FileService; import com.mr.global.client.ai.AiAnalysisRequest; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -51,6 +52,9 @@ @ExtendWith(MockitoExtension.class) class AnalysisServiceTest { + private static final String RECORDING_OBJECT_KEY = "recordings/1/2026-08-06/120000_abcdef.webm"; + private static final String RECORDING_FILE_URL = "https://example.com/presigned-recording.webm"; + @Mock private AnalysisRepository analysisRepository; @@ -66,12 +70,15 @@ class AnalysisServiceTest { @Mock private ApplicationEventPublisher eventPublisher; + @Mock + private S3FileService s3FileService; + private AnalysisService analysisService; @BeforeEach void setUp() { analysisService = new AnalysisService(analysisRepository, analysisReportRepository, playingRepository, - analysisRequestFactory, eventPublisher, new ObjectMapper()); + analysisRequestFactory, eventPublisher, new ObjectMapper(), s3FileService); } private Analysis completedAnalysis(Long userId) { @@ -88,7 +95,7 @@ private Analysis completedAnalysis(Long userId, ScaleType scaleType) { lenient().when(playing.getUser()).thenReturn(user); lenient().when(playing.getBackingTrack()).thenReturn(backingTrack); lenient().when(playing.getBpm()).thenReturn(120); - lenient().when(playing.getRecordingFileUrl()).thenReturn("https://example.com/recording.webm"); + lenient().when(playing.getRecordingObjectKey()).thenReturn(RECORDING_OBJECT_KEY); lenient().when(backingTrack.getTitle()).thenReturn("테스트 트랙"); lenient().when(backingTrack.getGenre()).thenReturn("jazz"); lenient().when(backingTrack.getKeySignature()).thenReturn("C"); @@ -142,12 +149,14 @@ void getAnalysisResult_success_returnsLatestSuccessReport() { given(analysisRepository.findById(analysisId)).willReturn(Optional.of(analysis)); given(analysisReportRepository.findFirstByAnalysisIdAndLlmStatusOrderByCreatedAtDesc(anyLong(), any())) .willReturn(Optional.of(report)); + given(s3FileService.createPresignedDownload(userId, RECORDING_OBJECT_KEY)).willReturn(RECORDING_FILE_URL); AnalysisResultResponseDTO response = analysisService.getAnalysisResult(userId, analysisId); ArgumentCaptor llmStatusCaptor = ArgumentCaptor.forClass(LlmStatus.class); verify(analysisReportRepository) .findFirstByAnalysisIdAndLlmStatusOrderByCreatedAtDesc(eq(analysisId), llmStatusCaptor.capture()); + verify(s3FileService).createPresignedDownload(userId, RECORDING_OBJECT_KEY); assertThat(llmStatusCaptor.getValue()).isEqualTo(LlmStatus.SUCCESS); assertThat(response.report()).isNotNull(); @@ -155,7 +164,7 @@ void getAnalysisResult_success_returnsLatestSuccessReport() { assertThat(response.report().llmStatus()).isEqualTo(LlmStatus.SUCCESS); assertThat(response.title()).isEqualTo("테스트 트랙"); assertThat(response.key()).isEqualTo("C Major"); - assertThat(response.recordingFileUrl()).isEqualTo("https://example.com/recording.webm"); + assertThat(response.recordingFileUrl()).isEqualTo(RECORDING_FILE_URL); assertThat(response.backingTrackAudioFileUrl()).isEqualTo("https://example.com/backing-track.mp3"); } diff --git a/src/test/java/com/mr/domain/history/service/HistoryServiceTest.java b/src/test/java/com/mr/domain/history/service/HistoryServiceTest.java index bc2c6e75..2a0d201b 100644 --- a/src/test/java/com/mr/domain/history/service/HistoryServiceTest.java +++ b/src/test/java/com/mr/domain/history/service/HistoryServiceTest.java @@ -26,6 +26,7 @@ import com.mr.domain.playing.repository.PlayingRepository; import com.mr.domain.user.entity.User; import com.mr.global.apipayload.exception.GeneralException; +import com.mr.global.file.s3.service.S3FileService; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -49,11 +50,14 @@ class HistoryServiceTest { @Mock private AnalysisRepository analysisRepository; + @Mock + private S3FileService s3FileService; + private HistoryService historyService; @BeforeEach void setUp() { - historyService = new HistoryService(playingRepository, analysisRepository); + historyService = new HistoryService(playingRepository, analysisRepository, s3FileService); } private Playing mockPlaying(Long playingId, Long userId, PlayingStatus status, LocalDateTime endedAt) { @@ -271,9 +275,11 @@ void getHistoryDetail_notCompleted_throws409() { void getHistoryDetail_success_returnsAllAnalysesRegardlessOfStatus() { Playing playing = mockPlaying(1L, 1L, PlayingStatus.COMPLETED, LocalDateTime.now()); BackingTrack backingTrack = mock(BackingTrack.class); - String recordingFileUrl = playing.toString(); + String recordingObjectKey = "recordings/1/2026-08-06/test.webm"; + String recordingFileUrl = "https://example.com/presigned-recording.webm"; String backingTrackAudioFileUrl = backingTrack.toString(); - given(playing.getRecordingFileUrl()).willReturn(recordingFileUrl); + given(playing.getRecordingObjectKey()).willReturn(recordingObjectKey); + given(s3FileService.createPresignedDownload(1L, recordingObjectKey)).willReturn(recordingFileUrl); given(playing.getBackingTrack()).willReturn(backingTrack); given(backingTrack.getAudioFileUrl()).willReturn(backingTrackAudioFileUrl); given(playingRepository.findByIdWithBackingTrack(1L)).willReturn(Optional.of(playing)); @@ -288,6 +294,8 @@ void getHistoryDetail_success_returnsAllAnalysesRegardlessOfStatus() { HistoryDetailResponseDTO response = historyService.getHistoryDetail(1L, 1L); + verify(s3FileService).createPresignedDownload(1L, recordingObjectKey); + assertThat(response.recordingFileUrl()).isEqualTo(recordingFileUrl); assertThat(response.backingTrackAudioFileUrl()).isEqualTo(backingTrackAudioFileUrl); assertThat(response.analyses()).hasSize(2); diff --git a/src/test/java/com/mr/domain/playing/entity/PlayingTest.java b/src/test/java/com/mr/domain/playing/entity/PlayingTest.java index eeb5c02d..e17f6723 100644 --- a/src/test/java/com/mr/domain/playing/entity/PlayingTest.java +++ b/src/test/java/com/mr/domain/playing/entity/PlayingTest.java @@ -677,8 +677,8 @@ void createBackingTrackPlaying_success() { } @Test - @DisplayName("진행 중인 연주에 MIDI 데이터와 녹음 파일 URL을 저장하면 완료 상태로 변경된다") - void completeWithMidiDataAndRecordingFileUrl() { + @DisplayName("진행 중인 연주에 MIDI 데이터와 녹음 파일 Object Key를 저장하면 완료 상태로 변경된다") + void completeWithMidiDataAndRecordingObjectKey() { // given Playing playing = createInProgressPlaying(); @@ -691,15 +691,15 @@ void completeWithMidiDataAndRecordingFileUrl() { // when playing.completeWithMidiData( midiData, - RECORDING_FILE_URL + RECORDING_OBJECT_KEY ); // then assertThat(playing.getMidiData()) .hasSize(3); - assertThat(playing.getRecordingFileUrl()) - .isEqualTo(RECORDING_FILE_URL); + assertThat(playing.getRecordingObjectKey()) + .isEqualTo(RECORDING_OBJECT_KEY); assertThat(playing.getEndedAt()) .isNotNull(); diff --git a/src/test/java/com/mr/domain/playing/service/PlayingServiceTest.java b/src/test/java/com/mr/domain/playing/service/PlayingServiceTest.java index 23adc4d8..20786b4c 100644 --- a/src/test/java/com/mr/domain/playing/service/PlayingServiceTest.java +++ b/src/test/java/com/mr/domain/playing/service/PlayingServiceTest.java @@ -119,7 +119,6 @@ class PlayingServiceTest { ValidatedFile recordingResponse = new ValidatedFile( RECORDING_OBJECT_KEY, - RECORDING_FILE_URL, 1_157_632L, "audio/mpeg" ); @@ -171,7 +170,7 @@ void saveMidiEvents_success() { .thenReturn(midiEvents); return null; - }).when(playing).completeWithMidiData(anyList(), eq(RECORDING_FILE_URL)); + }).when(playing).completeWithMidiData(anyList(), eq(RECORDING_OBJECT_KEY)); // when MidiEventSaveResponse response = @@ -201,7 +200,7 @@ void saveMidiEvents_success() { ); verify(playing) - .completeWithMidiData(anyList(), eq(RECORDING_FILE_URL)); + .completeWithMidiData(anyList(), eq(RECORDING_OBJECT_KEY)); ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(Object.class); @@ -335,7 +334,7 @@ void saveMidiEvents_convertsRequestToEntity() { .thenReturn(midiEvents); return null; - }).when(playing).completeWithMidiData(anyList(), anyString()); + }).when(playing).completeWithMidiData(anyList(), eq(RECORDING_OBJECT_KEY)); // when playingService.saveMidiEvents( @@ -360,7 +359,7 @@ void saveMidiEvents_convertsRequestToEntity() { verify(playing) .completeWithMidiData( anyList(), - eq(RECORDING_FILE_URL) + eq(RECORDING_OBJECT_KEY) ); verify(eventPublisher) diff --git a/src/test/java/com/mr/global/file/s3/service/RecordingObjectKeyGeneratorTest.java b/src/test/java/com/mr/global/file/s3/service/RecordingObjectKeyGeneratorTest.java index d6ddb97a..4c1174c3 100644 --- a/src/test/java/com/mr/global/file/s3/service/RecordingObjectKeyGeneratorTest.java +++ b/src/test/java/com/mr/global/file/s3/service/RecordingObjectKeyGeneratorTest.java @@ -192,7 +192,7 @@ void generateUnsupportedFileExtension() { objectKeyGenerator.generate( 1L, "recording.m4a", - "audio/mp4" + "audio/mpeg" ) ) .isInstanceOf(GeneralException.class) diff --git a/src/test/java/com/mr/global/file/s3/service/S3FileServiceTest.java b/src/test/java/com/mr/global/file/s3/service/S3FileServiceTest.java index 29d2aa61..8f523605 100644 --- a/src/test/java/com/mr/global/file/s3/service/S3FileServiceTest.java +++ b/src/test/java/com/mr/global/file/s3/service/S3FileServiceTest.java @@ -519,8 +519,6 @@ void validateUploadedFile_success() throws Exception { any(HeadObjectRequest.class) )).thenReturn(headObjectResponse); - mockFileUrl(); - // when ValidatedFile response = s3FileService.validateUploadedFile( @@ -584,8 +582,6 @@ void validateUploadedFile_normalizesContentType() any(HeadObjectRequest.class) )).thenReturn(headObjectResponse); - mockFileUrl(); - // when ValidatedFile response = s3FileService.validateUploadedFile( @@ -1069,21 +1065,6 @@ void createPresignedDownload_sdkException() { } } - private void mockFileUrl() throws Exception { - S3Utilities s3Utilities = - mock(S3Utilities.class); - - when(s3Client.utilities()) - .thenReturn(s3Utilities); - - when(s3Utilities.getUrl( - org.mockito.ArgumentMatchers - .>any() - )).thenReturn( - URI.create(FILE_URL).toURL() - ); - } - private void verifyDeleteObject() { ArgumentCaptor captor = ArgumentCaptor.forClass(