From 6ec4c45b88df9256ccb90fc259c0ee627c228332 Mon Sep 17 00:00:00 2001 From: benedwards Date: Tue, 25 Feb 2025 13:23:05 +0000 Subject: [PATCH 1/6] Main Implementation + Unit tests --- .../audio/controller/AudioController.java | 8 + .../mapper/GetAdminMediaResponseMapper.java | 61 ++++++-- .../audio/service/AdminMediaService.java | 3 + .../service/impl/AdminMediaServiceImpl.java | 23 ++- src/main/resources/openapi/audio.yaml | 71 ++++++++- .../GetAdminMediaResponseMapperTest.java | 147 ++++++++++++++++++ .../impl/AdminMediaServiceImplTest.java | 71 +++++++++ 7 files changed, 369 insertions(+), 15 deletions(-) create mode 100644 src/test/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapperTest.java diff --git a/src/main/java/uk/gov/hmcts/darts/audio/controller/AudioController.java b/src/main/java/uk/gov/hmcts/darts/audio/controller/AudioController.java index 0fab69eecc..18c43962dd 100644 --- a/src/main/java/uk/gov/hmcts/darts/audio/controller/AudioController.java +++ b/src/main/java/uk/gov/hmcts/darts/audio/controller/AudioController.java @@ -17,6 +17,7 @@ import uk.gov.hmcts.darts.audio.mapper.TransformedMediaMapper; import uk.gov.hmcts.darts.audio.model.AddAudioMetadataRequestWithStorageGUID; import uk.gov.hmcts.darts.audio.model.AdminMediaResponse; +import uk.gov.hmcts.darts.audio.model.AdminVersionedMediaResponse; import uk.gov.hmcts.darts.audio.model.AudioMetadata; import uk.gov.hmcts.darts.audio.model.AudioPreview; import uk.gov.hmcts.darts.audio.model.GetAdminMediaResponseItem; @@ -164,6 +165,13 @@ public ResponseEntity getAdminMediasById(Integer id) { return new ResponseEntity<>(adminMediaService.getMediasById(id), HttpStatus.OK); } + @Override + @SecurityRequirement(name = SECURITY_SCHEMES_BEARER_AUTH) + @Authorisation(contextId = ANY_ENTITY_ID, globalAccessSecurityRoles = {SUPER_USER, SUPER_ADMIN}) + public ResponseEntity getAdminMediaVersionsById(Integer id) { + return new ResponseEntity<>(adminMediaService.getMediaVersionsById(id), HttpStatus.OK); + } + @Override @SecurityRequirement(name = SECURITY_SCHEMES_BEARER_AUTH) @Authorisation(contextId = ANY_ENTITY_ID, globalAccessSecurityRoles = {SUPER_USER, SUPER_ADMIN}) diff --git a/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java b/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java index bee6e750cd..a786de30c9 100644 --- a/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java +++ b/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java @@ -1,8 +1,10 @@ package uk.gov.hmcts.darts.audio.mapper; -import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; import uk.gov.hmcts.darts.audio.model.AdminActionResponse; +import uk.gov.hmcts.darts.audio.model.AdminMediaVersionResponse; +import uk.gov.hmcts.darts.audio.model.AdminVersionedMediaResponse; import uk.gov.hmcts.darts.audio.model.GetAdminMediaResponseCase; import uk.gov.hmcts.darts.audio.model.GetAdminMediaResponseCourthouse; import uk.gov.hmcts.darts.audio.model.GetAdminMediaResponseCourtroom; @@ -19,13 +21,17 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; @Slf4j -@UtilityClass +@Component public class GetAdminMediaResponseMapper { - public List createResponseItemList(List mediaEntities, HearingEntity hearing) { + private CourtroomMapper courtroomMapper; + private CourthouseMapper courthouseMapper; + + public static List createResponseItemList(List mediaEntities, HearingEntity hearing) { List responseList = new ArrayList<>(); for (MediaEntity mediaEntity : mediaEntities) { responseList.add(createResponseItem(mediaEntity, hearing)); @@ -33,7 +39,7 @@ public List createResponseItemList(List return responseList; } - public GetAdminMediaResponseItem createResponseItem(MediaEntity mediaEntity, HearingEntity hearing) { + public static GetAdminMediaResponseItem createResponseItem(MediaEntity mediaEntity, HearingEntity hearing) { GetAdminMediaResponseItem responseItem = new GetAdminMediaResponseItem(); responseItem.setId(mediaEntity.getId()); responseItem.setChannel(mediaEntity.getChannel()); @@ -48,21 +54,21 @@ public GetAdminMediaResponseItem createResponseItem(MediaEntity mediaEntity, Hea return responseItem; } - private GetAdminMediaResponseCase createResponseCase(CourtCaseEntity courtCaseEntity) { + private static GetAdminMediaResponseCase createResponseCase(CourtCaseEntity courtCaseEntity) { GetAdminMediaResponseCase responseCase = new GetAdminMediaResponseCase(); responseCase.setId(courtCaseEntity.getId()); responseCase.setCaseNumber(courtCaseEntity.getCaseNumber()); return responseCase; } - private GetAdminMediaResponseHearing createResponseHearing(HearingEntity hearingEntity) { + private static GetAdminMediaResponseHearing createResponseHearing(HearingEntity hearingEntity) { GetAdminMediaResponseHearing responseHearing = new GetAdminMediaResponseHearing(); responseHearing.setId(hearingEntity.getId()); responseHearing.setHearingDate(hearingEntity.getHearingDate()); return responseHearing; } - private GetAdminMediaResponseCourthouse createResponseCourthouse(HearingEntity hearingEntity) { + private static GetAdminMediaResponseCourthouse createResponseCourthouse(HearingEntity hearingEntity) { CourthouseEntity courthouse = hearingEntity.getCourtroom().getCourthouse(); GetAdminMediaResponseCourthouse responseCourthouse = new GetAdminMediaResponseCourthouse(); responseCourthouse.setId(courthouse.getId()); @@ -70,7 +76,7 @@ private GetAdminMediaResponseCourthouse createResponseCourthouse(HearingEntity h return responseCourthouse; } - private GetAdminMediaResponseCourtroom createResponseCourtroom(HearingEntity hearingEntity) { + private static GetAdminMediaResponseCourtroom createResponseCourtroom(HearingEntity hearingEntity) { CourtroomEntity courtroom = hearingEntity.getCourtroom(); GetAdminMediaResponseCourtroom responseCourthouse = new GetAdminMediaResponseCourtroom(); responseCourthouse.setId(courtroom.getId()); @@ -78,7 +84,7 @@ private GetAdminMediaResponseCourtroom createResponseCourtroom(HearingEntity hea return responseCourthouse; } - public MediaHideResponse mapHideOrShowResponse(MediaEntity entity, ObjectAdminActionEntity objectAdminActionEntity) { + public static MediaHideResponse mapHideOrShowResponse(MediaEntity entity, ObjectAdminActionEntity objectAdminActionEntity) { MediaHideResponse response = new MediaHideResponse(); response.setId(entity.getId()); response.setIsHidden(entity.isHidden()); @@ -107,7 +113,8 @@ private static AdminActionResponse buildAdminActionResponse(ObjectAdminActionEnt return aaResponse; } - public MediaApproveMarkedForDeletionResponse mapMediaApproveMarkedForDeletionResponse(MediaEntity entity, ObjectAdminActionEntity objectAdminActionEntity) { + public static MediaApproveMarkedForDeletionResponse mapMediaApproveMarkedForDeletionResponse(MediaEntity entity, + ObjectAdminActionEntity objectAdminActionEntity) { MediaApproveMarkedForDeletionResponse response = new MediaApproveMarkedForDeletionResponse(); response.setId(entity.getId()); response.setIsHidden(entity.isHidden()); @@ -119,4 +126,38 @@ public MediaApproveMarkedForDeletionResponse mapMediaApproveMarkedForDeletionRes return response; } + + public AdminVersionedMediaResponse mapAdminVersionedMediaResponse(MediaEntity mediaEntity, List mediaVersions) { + AdminVersionedMediaResponse response = new AdminVersionedMediaResponse(); + response.setMediaObjectId(mediaEntity.getLegacyObjectId()); + response.setCurrentVersion(mapAdminMediaVersionResponse(mediaEntity)); + response.setPreviousVersions( + mediaVersions.stream() + .map(this::mapAdminMediaVersionResponse) + .filter(adminMediaVersionResponse -> adminMediaVersionResponse != null) + .toList() + ); + return response; + } + + AdminMediaVersionResponse mapAdminMediaVersionResponse(MediaEntity mediaEntity) { + if (mediaEntity == null) { + return null; + } + AdminMediaVersionResponse response = new AdminMediaVersionResponse(); + response.setId(mediaEntity.getId()); + response.setCourtroom(courtroomMapper.toApiModel(mediaEntity.getCourtroom())); + response.setCourthouse(courthouseMapper.toApiModel( + Optional.ofNullable(mediaEntity.getCourtroom()) + .map(courtroomEntity -> courtroomEntity.getCourthouse()) + .orElse(null))); + response.setStartAt(mediaEntity.getStart()); + response.setEndAt(mediaEntity.getEnd()); + response.setChannel(mediaEntity.getChannel()); + response.setChronicleId(mediaEntity.getChronicleId()); + response.setAntecedentId(mediaEntity.getAntecedentId()); + response.setIsCurrent(mediaEntity.getIsCurrent()); + response.setCreatedAt(mediaEntity.getCreatedDateTime()); + return response; + } } \ No newline at end of file diff --git a/src/main/java/uk/gov/hmcts/darts/audio/service/AdminMediaService.java b/src/main/java/uk/gov/hmcts/darts/audio/service/AdminMediaService.java index 13ba0e2afa..54b8c78179 100644 --- a/src/main/java/uk/gov/hmcts/darts/audio/service/AdminMediaService.java +++ b/src/main/java/uk/gov/hmcts/darts/audio/service/AdminMediaService.java @@ -1,6 +1,7 @@ package uk.gov.hmcts.darts.audio.service; import uk.gov.hmcts.darts.audio.model.AdminMediaResponse; +import uk.gov.hmcts.darts.audio.model.AdminVersionedMediaResponse; import uk.gov.hmcts.darts.audio.model.GetAdminMediaResponseItem; import uk.gov.hmcts.darts.audio.model.GetAdminMediasMarkedForDeletionItem; import uk.gov.hmcts.darts.audio.model.MediaApproveMarkedForDeletionResponse; @@ -30,4 +31,6 @@ default List filterMediasWithTransformedMediaId(Integ List getMediasMarkedForDeletion(); MediaApproveMarkedForDeletionResponse adminApproveMediaMarkedForDeletion(Integer mediaId); + + AdminVersionedMediaResponse getMediaVersionsById(Integer id); } \ No newline at end of file diff --git a/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java b/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java index cdbba18915..b8ffd7c5af 100644 --- a/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java +++ b/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java @@ -21,6 +21,7 @@ import uk.gov.hmcts.darts.audio.mapper.PostAdminMediaSearchResponseMapper; import uk.gov.hmcts.darts.audio.model.AdminActionRequest; import uk.gov.hmcts.darts.audio.model.AdminMediaResponse; +import uk.gov.hmcts.darts.audio.model.AdminVersionedMediaResponse; import uk.gov.hmcts.darts.audio.model.GetAdminMediaResponseItem; import uk.gov.hmcts.darts.audio.model.GetAdminMediasMarkedForDeletionAdminAction; import uk.gov.hmcts.darts.audio.model.GetAdminMediasMarkedForDeletionItem; @@ -79,6 +80,7 @@ public class AdminMediaServiceImpl implements AdminMediaService { private final CourthouseMapper courthouseMapper; private final CourtroomMapper courtroomMapper; private final ObjectActionMapper objectActionMapper; + private final GetAdminMediaResponseMapper getAdminMediaResponseMapper; private final MediaRepository mediaRepository; private final TransformedMediaRepository transformedMediaRepository; @@ -95,8 +97,7 @@ public class AdminMediaServiceImpl implements AdminMediaService { @Override public AdminMediaResponse getMediasById(Integer id) { - var mediaEntity = mediaRepository.findById(id) - .orElseThrow(() -> new DartsApiException(AudioApiError.MEDIA_NOT_FOUND)); + var mediaEntity = getMediaEntityById(id); AdminMediaResponse adminMediaResponse = adminMediaMapper.toApiModel(mediaEntity); adminMediaResponse.getCases().sort((o1, o2) -> o2.getCaseNumber().compareTo(o1.getCaseNumber())); @@ -104,6 +105,11 @@ public AdminMediaResponse getMediasById(Integer id) { return adminMediaResponse; } + MediaEntity getMediaEntityById(Integer id) { + return mediaRepository.findById(id) + .orElseThrow(() -> new DartsApiException(AudioApiError.MEDIA_NOT_FOUND)); + } + @Override public List performAdminMediasSearchPost(PostAdminMediasSearchRequest adminMediasSearchRequest) { List matchingMedia = postAdminMediasSearchHelper.getMatchingMedia(adminMediasSearchRequest); @@ -262,7 +268,18 @@ public MediaApproveMarkedForDeletionResponse adminApproveMediaMarkedForDeletion( auditApi.record(AuditActivity.MANUAL_DELETION, currentUser, objectAdminActionEntity.getId().toString()); - return GetAdminMediaResponseMapper.mapMediaApproveMarkedForDeletionResponse(mediaEntity, objectAdminActionEntity); + return getAdminMediaResponseMapper.mapMediaApproveMarkedForDeletionResponse(mediaEntity, objectAdminActionEntity); + } + + @Override + public AdminVersionedMediaResponse getMediaVersionsById(Integer id) { + MediaEntity mediaEntity = getMediaEntityById(id); + List mediaVersions = new ArrayList<>(); + //Only fetch versions if the media is part of a chronicle + if (mediaEntity.getChronicleId() != null) { + mediaVersions.addAll(mediaRepository.findAllByChronicleId(mediaEntity.getChronicleId())); + } + return getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(mediaEntity, mediaVersions); } private ApplyAdminActionComponent.AdminActionProperties mapToAdminActionProperties(AdminActionRequest adminActionRequest) { diff --git a/src/main/resources/openapi/audio.yaml b/src/main/resources/openapi/audio.yaml index 8f55d2821a..8559284ede 100644 --- a/src/main/resources/openapi/audio.yaml +++ b/src/main/resources/openapi/audio.yaml @@ -276,7 +276,6 @@ paths: type: "AUTHORISATION_100" title: "User is not authorised for the associated courthouse" status: 401 - /admin/medias/{id}: get: tags: @@ -296,7 +295,41 @@ paths: application/json: schema: $ref: '#/components/schemas/AdminMediaResponse' - + /admin/medias/{id}/versions: + get: + tags: + - Audio + operationId: getAdminMediaVersionsById + description: Returns a representation of a media record and associated versions + parameters: + - in: path + name: id + required: true + schema: + $ref: '#/components/schemas/MediaId' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AdminVersionedMediaResponse' + '401': + description: Unauthorised Error + '403': + description: Forbidden Error + content: + application/json+problem: + schema: + allOf: + - $ref: './problem.yaml' + '404': + description: Not Found Error + content: + application/json+problem: + schema: + allOf: + - $ref: './problem.yaml' /admin/medias/{media_id}/hide: post: tags: @@ -567,6 +600,40 @@ components: $ref: '#/components/schemas/AdminMediaCourtroomResponse' admin_action: $ref: '#/components/schemas/AdminActionResponse' + AdminVersionedMediaResponse: + type: object + properties: + media_object_id: + type: string + current_version: + $ref: '#/components/schemas/AdminMediaVersionResponse' + previous_versions: + type: array + items: + $ref: '#/components/schemas/AdminMediaVersionResponse' + AdminMediaVersionResponse: + type: object + properties: + id: + $ref: '#/components/schemas/MediaId' + courthouse: + $ref: '#/components/schemas/AdminMediaCourthouseResponse' + courtroom: + $ref: '#/components/schemas/AdminMediaCourtroomResponse' + start_at: + $ref: '#/components/schemas/StartAt' + end_at: + $ref: '#/components/schemas/EndAt' + channel: + $ref: '#/components/schemas/Channel' + chronicle_id: + $ref: '#/components/schemas/ChronicleId' + antecedent_id: + $ref: '#/components/schemas/AntecedentId' + is_current: + $ref: '#/components/schemas/IsCurrent' + created_at: + $ref: '#/components/schemas/CreatedAt' AdminMediaResponse: type: object properties: diff --git a/src/test/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapperTest.java b/src/test/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapperTest.java new file mode 100644 index 0000000000..4a5ac6a765 --- /dev/null +++ b/src/test/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapperTest.java @@ -0,0 +1,147 @@ +package uk.gov.hmcts.darts.audio.mapper; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; +import uk.gov.hmcts.darts.audio.model.AdminMediaCourthouseResponse; +import uk.gov.hmcts.darts.audio.model.AdminMediaCourtroomResponse; +import uk.gov.hmcts.darts.audio.model.AdminMediaVersionResponse; +import uk.gov.hmcts.darts.audio.model.AdminVersionedMediaResponse; +import uk.gov.hmcts.darts.common.entity.CourthouseEntity; +import uk.gov.hmcts.darts.common.entity.CourtroomEntity; +import uk.gov.hmcts.darts.common.entity.MediaEntity; + +import java.time.OffsetDateTime; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class GetAdminMediaResponseMapperTest { + + + @Mock + private CourtroomMapper courtroomMapper; + @Mock + private CourthouseMapper courthouseMapper; + + @InjectMocks + @Spy + private GetAdminMediaResponseMapper getAdminMediaResponseMapper; + + @Test + void mapAdminVersionedMediaResponse_shouldMapAdminVersionedMediaResponse() { + final String legacyObjectId = "legacyObjectId"; + MediaEntity mediaEntity = mock(MediaEntity.class); + when(mediaEntity.getLegacyObjectId()).thenReturn(legacyObjectId); + + MediaEntity versioendMediaEntity1 = mock(MediaEntity.class); + MediaEntity versioendMediaEntity2 = mock(MediaEntity.class); + MediaEntity versioendMediaEntity3 = mock(MediaEntity.class); + List versionedMediaEntities = List.of(versioendMediaEntity1, versioendMediaEntity2, versioendMediaEntity3); + + AdminMediaVersionResponse mediaEntityVersionedResponse = mock(AdminMediaVersionResponse.class); + AdminMediaVersionResponse versionedMediaEntityVersionedResponse1 = mock(AdminMediaVersionResponse.class); + AdminMediaVersionResponse versionedMediaEntityVersionedResponse3 = mock(AdminMediaVersionResponse.class); + + doReturn(mediaEntityVersionedResponse).when(getAdminMediaResponseMapper).mapAdminMediaVersionResponse(mediaEntity); + doReturn(versionedMediaEntityVersionedResponse1).when(getAdminMediaResponseMapper).mapAdminMediaVersionResponse(versioendMediaEntity1); + doReturn(null).when(getAdminMediaResponseMapper).mapAdminMediaVersionResponse(versioendMediaEntity2); + doReturn(versionedMediaEntityVersionedResponse3).when(getAdminMediaResponseMapper).mapAdminMediaVersionResponse(versioendMediaEntity3); + + + AdminVersionedMediaResponse adminVersionedMediaResponse = getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(mediaEntity, + versionedMediaEntities); + assertThat(adminVersionedMediaResponse).isNotNull(); + assertThat(adminVersionedMediaResponse.getMediaObjectId()).isEqualTo(legacyObjectId); + assertThat(adminVersionedMediaResponse.getCurrentVersion()).isEqualTo(mediaEntityVersionedResponse); + //versionedMediaEntityVersionedResponse2 should be excluded as it is null + assertThat(adminVersionedMediaResponse.getPreviousVersions()) + .containsExactly(versionedMediaEntityVersionedResponse1, + versionedMediaEntityVersionedResponse3); + } + + @Test + void mapAdminMediaVersionResponse_courtRoomDoesNotExist_shouldMapAdminMediaVersionResponse() { + MediaEntity media = new MediaEntity(); + media.setId(321); + media.setStart(OffsetDateTime.now()); + media.setEnd(OffsetDateTime.now().plusDays(1)); + media.setChannel(2); + media.setLegacyObjectId("legacyObjectId2"); + media.setChronicleId("chronicleId2"); + media.setAntecedentId("antecedentId2"); + media.setIsCurrent(false); + media.setCreatedDateTime(OffsetDateTime.now().plusDays(3)); + + AdminMediaVersionResponse response = getAdminMediaResponseMapper.mapAdminMediaVersionResponse(media); + + assertThat(response).isNotNull(); + assertThat(response.getId()).isEqualTo(media.getId()); + assertThat(response.getCourtroom()).isNull(); + assertThat(response.getCourthouse()).isNull(); + assertThat(response.getStartAt()).isEqualTo(media.getStart()); + assertThat(response.getEndAt()).isEqualTo(media.getEnd()); + + assertThat(response.getChannel()).isEqualTo(media.getChannel()); + assertThat(response.getChronicleId()).isEqualTo(media.getChronicleId()); + assertThat(response.getAntecedentId()).isEqualTo(media.getAntecedentId()); + assertThat(response.getIsCurrent()).isEqualTo(media.getIsCurrent()); + assertThat(response.getCreatedAt()).isEqualTo(media.getCreatedDateTime()); + } + + @Test + void mapAdminMediaVersionResponse_shouldMapAdminMediaVersionResponse() { + CourtroomEntity courtroomEntity = mock(CourtroomEntity.class); + AdminMediaCourtroomResponse courtroom = mock(AdminMediaCourtroomResponse.class); + when(courtroomMapper.toApiModel(courtroomEntity)).thenReturn(courtroom); + + CourthouseEntity courthouseEntity = mock(CourthouseEntity.class); + AdminMediaCourthouseResponse courthouse = mock(AdminMediaCourthouseResponse.class); + when(courthouseMapper.toApiModel(courthouseEntity)).thenReturn(courthouse); + when(courtroomEntity.getCourthouse()).thenReturn(courthouseEntity); + + MediaEntity media = new MediaEntity(); + media.setId(123); + media.setCourtroom(courtroomEntity); + media.setStart(OffsetDateTime.now()); + media.setEnd(OffsetDateTime.now().plusDays(1)); + media.setChannel(1); + media.setLegacyObjectId("legacyObjectId"); + media.setChronicleId("chronicleId"); + media.setAntecedentId("antecedentId"); + media.setIsCurrent(true); + media.setCreatedDateTime(OffsetDateTime.now().plusDays(3)); + + AdminMediaVersionResponse response = getAdminMediaResponseMapper.mapAdminMediaVersionResponse(media); + + assertThat(response).isNotNull(); + assertThat(response.getId()).isEqualTo(media.getId()); + assertThat(response.getCourtroom()).isEqualTo(courtroom); + assertThat(response.getCourthouse()).isEqualTo(courthouse); + assertThat(response.getStartAt()).isEqualTo(media.getStart()); + assertThat(response.getEndAt()).isEqualTo(media.getEnd()); + + assertThat(response.getChannel()).isEqualTo(media.getChannel()); + assertThat(response.getChronicleId()).isEqualTo(media.getChronicleId()); + assertThat(response.getAntecedentId()).isEqualTo(media.getAntecedentId()); + assertThat(response.getIsCurrent()).isEqualTo(media.getIsCurrent()); + assertThat(response.getCreatedAt()).isEqualTo(media.getCreatedDateTime()); + + verify(courtroomMapper).toApiModel(courtroomEntity); + verify(courtroomEntity).getCourthouse(); + verify(courthouseMapper).toApiModel(courthouseEntity); + } + + @Test + void mapAdminMediaVersionResponse_ifMediaEntityIsNull_nullShouldBeReturned() { + assertThat(getAdminMediaResponseMapper.mapAdminMediaVersionResponse(null)).isNull(); + } +} diff --git a/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java b/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java index e2211c1319..fc455f2c87 100644 --- a/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java +++ b/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java @@ -5,6 +5,7 @@ import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -21,6 +22,7 @@ import uk.gov.hmcts.darts.audio.component.impl.ApplyAdminActionComponent; import uk.gov.hmcts.darts.audio.component.impl.RemoveAdminActionComponent; import uk.gov.hmcts.darts.audio.entity.MediaRequestEntity; +import uk.gov.hmcts.darts.audio.exception.AudioApiError; import uk.gov.hmcts.darts.audio.mapper.AdminMarkedForDeletionMapper; import uk.gov.hmcts.darts.audio.mapper.AdminMarkedForDeletionMapperImpl; import uk.gov.hmcts.darts.audio.mapper.CourthouseMapper; @@ -33,6 +35,7 @@ import uk.gov.hmcts.darts.audio.model.AdminActionRequest; import uk.gov.hmcts.darts.audio.model.AdminMediaCourthouseResponse; import uk.gov.hmcts.darts.audio.model.AdminMediaCourtroomResponse; +import uk.gov.hmcts.darts.audio.model.AdminVersionedMediaResponse; import uk.gov.hmcts.darts.audio.model.GetAdminMediaResponseItem; import uk.gov.hmcts.darts.audio.model.GetAdminMediasMarkedForDeletionAdminAction; import uk.gov.hmcts.darts.audio.model.GetAdminMediasMarkedForDeletionItem; @@ -102,6 +105,8 @@ class AdminMediaServiceImplTest { private RemoveAdminActionComponent removeAdminActionComponent; @Mock private ObjectHiddenReasonRepository hiddenReasonRepository; + @Mock + private GetAdminMediaResponseMapper getAdminMediaResponseMapper; private ObjectMapper objectMapper; @@ -568,6 +573,72 @@ void filterMedias_shouldReturnSingleMediaForHearingsAndStartEndTimes_whenMediaIs JSONAssert.assertEquals(expectedString, responseString, JSONCompareMode.NON_EXTENSIBLE); } + @Test + void getMediaEntityById_shouldReutrnMediaEntity_ifOneExists() { + MediaEntity mediaEntity = mock(MediaEntity.class); + when(mediaRepository.findById(1)).thenReturn(Optional.of(mediaEntity)); + + assertThat(mediaRequestService.getMediaEntityById(1)) + .isEqualTo(mediaEntity); + verify(mediaRepository).findById(1); + } + + @Test + void getMediaEntityById_shouldThrowException_ifNoMediaEntityExists() { + when(mediaRepository.findById(1)).thenReturn(Optional.empty()); + + DartsApiException exception = assertThrows(DartsApiException.class, () -> mediaRequestService.getMediaEntityById(1)); + + assertThat(exception.getError()).isEqualTo(AudioApiError.MEDIA_NOT_FOUND); + } + + + @Nested + @DisplayName("AdminVersionedMediaResponse getMediaVersionsById(Integer id)") + class GetMediaVersionsById { + @Test + void getMediaVersionsById_shouldFetchMediaVersions_whenChronicleIdIsNotNull() { + MediaEntity mediaEntity = mock(MediaEntity.class); + doReturn(mediaEntity).when(mediaRequestService).getMediaEntityById(123); + when(mediaEntity.getChronicleId()).thenReturn("chronicleId1"); + List versionedMedias = List.of(mock(MediaEntity.class), mock(MediaEntity.class)); + + when(mediaRepository.findAllByChronicleId("chronicleId1")).thenReturn(versionedMedias); + + AdminVersionedMediaResponse response = mock(AdminVersionedMediaResponse.class); + when(getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(mediaEntity, versionedMedias)) + .thenReturn(response); + + assertThat(mediaRequestService.getMediaVersionsById(123)) + .isEqualTo(response); + verify(getAdminMediaResponseMapper).mapAdminVersionedMediaResponse(mediaEntity, versionedMedias); + + verify(mediaRequestService).getMediaEntityById(123); + verify(mediaRepository).findAllByChronicleId("chronicleId1"); + } + + @Test + void getMediaVersionsById_shouldNotFetchMediaVersions_whenChronicleIdIsNull() { + MediaEntity mediaEntity = mock(MediaEntity.class); + doReturn(mediaEntity).when(mediaRequestService).getMediaEntityById(123); + when(mediaEntity.getChronicleId()).thenReturn(null); + + AdminVersionedMediaResponse response = mock(AdminVersionedMediaResponse.class); + when(getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(mediaEntity, new ArrayList<>())) + .thenReturn(response); + + assertThat(mediaRequestService.getMediaVersionsById(123)) + .isEqualTo(response); + verify(getAdminMediaResponseMapper).mapAdminVersionedMediaResponse(mediaEntity, new ArrayList<>()); + + + verify(mediaRequestService).getMediaEntityById(123); + verifyNoInteractions(mediaRepository); + } + + } + + @NotNull private static HearingEntity createHearing() { CourthouseEntity courthouse = new CourthouseEntity(); From ea7d204d69cc7b83214cad11faf6f009113e01d4 Mon Sep 17 00:00:00 2001 From: benedwards Date: Tue, 25 Feb 2025 15:48:25 +0000 Subject: [PATCH 2/6] Added remaining tests + Rejigged some current version logic --- ...ollerGetAdminMediaVersionsByIdIntTest.java | 220 ++++++++++++++++++ .../expectedResponseNoVersions.json | 22 ++ .../expectedResponseTypical.json | 59 +++++ .../mapper/GetAdminMediaResponseMapper.java | 7 +- .../service/impl/AdminMediaServiceImpl.java | 44 +++- .../common/exception/CommonApiError.java | 5 + src/main/resources/openapi/common.yaml | 6 +- .../impl/AdminMediaServiceImplTest.java | 114 +++++++-- 8 files changed, 452 insertions(+), 25 deletions(-) create mode 100644 src/integrationTest/java/uk/gov/hmcts/darts/audio/controller/AudioControllerGetAdminMediaVersionsByIdIntTest.java create mode 100644 src/integrationTest/resources/tests/audio/AudioControllerGetAdminMediaVersionsByIdIntTest/expectedResponseNoVersions.json create mode 100644 src/integrationTest/resources/tests/audio/AudioControllerGetAdminMediaVersionsByIdIntTest/expectedResponseTypical.json diff --git a/src/integrationTest/java/uk/gov/hmcts/darts/audio/controller/AudioControllerGetAdminMediaVersionsByIdIntTest.java b/src/integrationTest/java/uk/gov/hmcts/darts/audio/controller/AudioControllerGetAdminMediaVersionsByIdIntTest.java new file mode 100644 index 0000000000..6d698996c5 --- /dev/null +++ b/src/integrationTest/java/uk/gov/hmcts/darts/audio/controller/AudioControllerGetAdminMediaVersionsByIdIntTest.java @@ -0,0 +1,220 @@ +package uk.gov.hmcts.darts.audio.controller; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.skyscreamer.jsonassert.JSONAssert; +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import uk.gov.hmcts.darts.common.entity.MediaEntity; +import uk.gov.hmcts.darts.common.enums.SecurityRoleEnum; +import uk.gov.hmcts.darts.testutils.GivenBuilder; +import uk.gov.hmcts.darts.testutils.IntegrationBase; +import uk.gov.hmcts.darts.testutils.stubs.DartsDatabaseStub; + +import java.time.Duration; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; + +import static org.junit.jupiter.params.provider.EnumSource.Mode.EXCLUDE; +import static org.junit.jupiter.params.provider.EnumSource.Mode.INCLUDE; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static uk.gov.hmcts.darts.test.common.TestUtils.getContentsFromFile; + +@AutoConfigureMockMvc +class AudioControllerGetAdminMediaVersionsByIdIntTest extends IntegrationBase { + @Autowired + private GivenBuilder given; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private DartsDatabaseStub databaseStub; + + private static final String ENDPOINT_URL = "/admin/medias/{id}/versions"; + private static final String COURTHOUSE_NAME = "TESTCOURTHOUSE"; + private static final String COURTROOM_NAME = "TESTCOURTROOM"; + private static final OffsetDateTime HEARING_START_AT = OffsetDateTime.parse("2024-01-01T12:10:10Z"); + private static final OffsetDateTime MEDIA_START_AT = HEARING_START_AT; + private static final OffsetDateTime MEDIA_END_AT = MEDIA_START_AT.plusHours(1); + private static final String RETAIN_UNTIL = "2200-02-01T00:00:00Z"; + + + @ParameterizedTest + @EnumSource(value = SecurityRoleEnum.class, names = {"SUPER_USER", "SUPER_ADMIN"}, mode = INCLUDE) + void shouldReturn200_whenChronicleIdHasBothCurrentAndNonCurrentVersions(SecurityRoleEnum role) throws Exception { + final String chronicleId = "chronicleId"; + MediaEntity currentMediaEntity = createAndSaveMediaEntity(true, chronicleId, Duration.ofDays(3)); + MediaEntity versionedMediaEntity1 = createAndSaveMediaEntity(false, chronicleId, Duration.ofDays(2)); + MediaEntity versionedMediaEntity2 = createAndSaveMediaEntity(false, chronicleId, Duration.ofDays(1)); + //Craeted unrelated media to ensure not returned + createAndSaveMediaEntity(true, "unrealted"); + + given.anAuthenticatedUserWithGlobalAccessAndRole(role); + + // When + MvcResult mvcResult = mockMvc.perform(get(ENDPOINT_URL, currentMediaEntity.getId())) + .andExpect(status().isOk()) + .andReturn(); + + String expectedResponse = getContentsFromFile( + "tests/audio/AudioControllerGetAdminMediaVersionsByIdIntTest/expectedResponseTypical.json") + .replace("", currentMediaEntity.getCreatedDateTime().format(DateTimeFormatter.ISO_DATE_TIME)) + .replace("", versionedMediaEntity2.getCreatedDateTime().format(DateTimeFormatter.ISO_DATE_TIME)) + .replace("", versionedMediaEntity1.getCreatedDateTime().format(DateTimeFormatter.ISO_DATE_TIME)); + JSONAssert.assertEquals(expectedResponse, mvcResult.getResponse().getContentAsString(), JSONCompareMode.STRICT); + } + + @Test + void shouldReturn200_whenMediaIdPassedIsNotCurrent_shouldReturnTheCorrectCorrentVersion() throws Exception { + final String chronicleId = "chronicleId"; + MediaEntity currentMediaEntity = createAndSaveMediaEntity(true, chronicleId, Duration.ofDays(3)); + MediaEntity versionedMediaEntity1 = createAndSaveMediaEntity(false, chronicleId, Duration.ofDays(2)); + MediaEntity versionedMediaEntity2 = createAndSaveMediaEntity(false, chronicleId, Duration.ofDays(1)); + //Craeted unrelated media to ensure not returned + createAndSaveMediaEntity(true, "unrealted"); + + given.anAuthenticatedUserWithGlobalAccessAndRole(SecurityRoleEnum.SUPER_ADMIN); + + // When + MvcResult mvcResult = mockMvc.perform(get(ENDPOINT_URL, versionedMediaEntity1.getId())) + .andExpect(status().isOk()) + .andReturn(); + + String expectedResponse = getContentsFromFile( + "tests/audio/AudioControllerGetAdminMediaVersionsByIdIntTest/expectedResponseTypical.json") + .replace("", currentMediaEntity.getCreatedDateTime().format(DateTimeFormatter.ISO_DATE_TIME)) + .replace("", versionedMediaEntity2.getCreatedDateTime().format(DateTimeFormatter.ISO_DATE_TIME)) + .replace("", versionedMediaEntity1.getCreatedDateTime().format(DateTimeFormatter.ISO_DATE_TIME)); + JSONAssert.assertEquals(expectedResponse, mvcResult.getResponse().getContentAsString(), JSONCompareMode.STRICT); + } + + @Test + void shouldReturn200_whenChronicleIdHasOnlyCurrentAndNoVersions() throws Exception { + final String chronicleId = "chronicleId"; + MediaEntity currentMediaEntity = createAndSaveMediaEntity(true, chronicleId, Duration.ofDays(3)); + //Craeted unrelated media to ensure not returned + createAndSaveMediaEntity(true, "unrealted"); + + given.anAuthenticatedUserWithGlobalAccessAndRole(SecurityRoleEnum.SUPER_ADMIN); + + // When + MvcResult mvcResult = mockMvc.perform(get(ENDPOINT_URL, currentMediaEntity.getId())) + .andExpect(status().isOk()) + .andReturn(); + + String expectedResponse = getContentsFromFile( + "tests/audio/AudioControllerGetAdminMediaVersionsByIdIntTest/expectedResponseNoVersions.json") + .replace("", currentMediaEntity.getCreatedDateTime().format(DateTimeFormatter.ISO_DATE_TIME)); + JSONAssert.assertEquals(expectedResponse, mvcResult.getResponse().getContentAsString(), JSONCompareMode.STRICT); + } + + @ParameterizedTest + @EnumSource(value = SecurityRoleEnum.class, names = {"SUPER_USER", "SUPER_ADMIN"}, mode = INCLUDE) + void shouldReturn404_WhenMediaRecordDoesNotExist(SecurityRoleEnum role) throws Exception { + // Given + given.anAuthenticatedUserWithGlobalAccessAndRole(role); + + // When + MvcResult mvcResult = mockMvc.perform(get(ENDPOINT_URL, "123456789")) + .andExpect(status().isNotFound()) + .andReturn(); + + // Then + var jsonString = mvcResult.getResponse().getContentAsString(); + JSONAssert.assertEquals(""" + { + "type": "AUDIO_102", + "title": "The requested media cannot be found", + "status": 404 + } + """, jsonString, JSONCompareMode.STRICT); + } + + @ParameterizedTest + @EnumSource(value = SecurityRoleEnum.class, names = {"SUPER_USER", "SUPER_ADMIN"}, mode = INCLUDE) + void shouldReturn404_WhenMediaRecordIsDeleted(SecurityRoleEnum role) throws Exception { + // Given + given.anAuthenticatedUserWithGlobalAccessAndRole(role); + + + var mediaEntity = createAndSaveMediaEntity(true, true, "chronicleId", Duration.ofMillis(0)); + // When + MvcResult mvcResult = mockMvc.perform(get(ENDPOINT_URL, String.valueOf(mediaEntity.getId()))) + .andExpect(status().isNotFound()) + .andReturn(); + + // Then + var jsonString = mvcResult.getResponse().getContentAsString(); + JSONAssert.assertEquals(""" + { + "type": "AUDIO_102", + "title": "The requested media cannot be found", + "status": 404 + } + """, jsonString, JSONCompareMode.STRICT); + + } + + @ParameterizedTest + @EnumSource(value = SecurityRoleEnum.class, names = {"SUPER_USER", "SUPER_ADMIN"}, mode = EXCLUDE) + void shouldDenyAccess_whenNotAuthorised(SecurityRoleEnum role) throws Exception { + // Given + given.anAuthenticatedUserWithGlobalAccessAndRole(role); + + // When + MvcResult mvcResult = mockMvc.perform(get(ENDPOINT_URL, "123456789")) + .andExpect(status().isForbidden()) + .andReturn(); + + // Then + var jsonString = mvcResult.getResponse().getContentAsString(); + JSONAssert.assertEquals(""" + { + "type": "AUTHORISATION_109", + "title": "User is not authorised for this endpoint", + "status": 403 + } + """, jsonString, JSONCompareMode.STRICT); + } + + private MediaEntity createAndSaveMediaEntity(boolean isCurrent, String chronicleId) { + return createAndSaveMediaEntity(false, isCurrent, chronicleId, Duration.ofMillis(0)); + } + + private MediaEntity createAndSaveMediaEntity(boolean isCurrent, String chronicleId, Duration timeOffset) { + return createAndSaveMediaEntity(false, isCurrent, chronicleId, timeOffset); + } + + private MediaEntity createAndSaveMediaEntity(boolean isDeleted, boolean isCurrent, String chronicleId, Duration timeOffset) { + MediaEntity mediaEntity = databaseStub.createMediaEntity(COURTHOUSE_NAME, + COURTROOM_NAME, + MEDIA_START_AT.plus(timeOffset), + MEDIA_END_AT.plus(timeOffset), + 2); + var userAccountEntity = databaseStub.getUserAccountRepository().findAll().stream() + .findFirst() + .orElseThrow(); + mediaEntity.setLegacyObjectId("object-id-value"); + mediaEntity.setContentObjectId("content-id-value"); + mediaEntity.setClipId("clip-id-value"); + mediaEntity.setMediaStatus("media-status-value"); + mediaEntity.setHidden(true); + mediaEntity.setDeleted(isDeleted); + mediaEntity.setLegacyVersionLabel("version-label-value"); + mediaEntity.setChronicleId(chronicleId); + mediaEntity.setAntecedentId("antecedent-value"); + mediaEntity.setRetainUntilTs(OffsetDateTime.parse(RETAIN_UNTIL)); + mediaEntity.setCreatedBy(userAccountEntity); + mediaEntity.setLastModifiedBy(userAccountEntity); + mediaEntity.setIsCurrent(isCurrent); + + return databaseStub.getMediaRepository() + .saveAndFlush(mediaEntity); + } +} diff --git a/src/integrationTest/resources/tests/audio/AudioControllerGetAdminMediaVersionsByIdIntTest/expectedResponseNoVersions.json b/src/integrationTest/resources/tests/audio/AudioControllerGetAdminMediaVersionsByIdIntTest/expectedResponseNoVersions.json new file mode 100644 index 0000000000..ca45beb8ad --- /dev/null +++ b/src/integrationTest/resources/tests/audio/AudioControllerGetAdminMediaVersionsByIdIntTest/expectedResponseNoVersions.json @@ -0,0 +1,22 @@ +{ + "media_object_id": "object-id-value", + "current_version": { + "id": 1, + "courthouse": { + "id": 1, + "display_name": "TESTCOURTHOUSE" + }, + "courtroom": { + "id": 1, + "name": "TESTCOURTROOM" + }, + "start_at": "2024-01-04T12:10:10Z", + "end_at": "2024-01-04T13:10:10Z", + "channel": 2, + "chronicle_id": "chronicleId", + "antecedent_id": "antecedent-value", + "is_current": true, + "created_at": "" + }, + "previous_versions": [] +} \ No newline at end of file diff --git a/src/integrationTest/resources/tests/audio/AudioControllerGetAdminMediaVersionsByIdIntTest/expectedResponseTypical.json b/src/integrationTest/resources/tests/audio/AudioControllerGetAdminMediaVersionsByIdIntTest/expectedResponseTypical.json new file mode 100644 index 0000000000..7883035ef8 --- /dev/null +++ b/src/integrationTest/resources/tests/audio/AudioControllerGetAdminMediaVersionsByIdIntTest/expectedResponseTypical.json @@ -0,0 +1,59 @@ +{ + "media_object_id": "object-id-value", + "current_version": { + "id": 1, + "courthouse": { + "id": 1, + "display_name": "TESTCOURTHOUSE" + }, + "courtroom": { + "id": 1, + "name": "TESTCOURTROOM" + }, + "start_at": "2024-01-04T12:10:10Z", + "end_at": "2024-01-04T13:10:10Z", + "channel": 2, + "chronicle_id": "chronicleId", + "antecedent_id": "antecedent-value", + "is_current": true, + "created_at": "" + }, + "previous_versions": [ + { + "id": 3, + "courthouse": { + "id": 1, + "display_name": "TESTCOURTHOUSE" + }, + "courtroom": { + "id": 1, + "name": "TESTCOURTROOM" + }, + "start_at": "2024-01-02T12:10:10Z", + "end_at": "2024-01-02T13:10:10Z", + "channel": 2, + "chronicle_id": "chronicleId", + "antecedent_id": "antecedent-value", + "is_current": false, + "created_at": "" + }, + { + "id": 2, + "courthouse": { + "id": 1, + "display_name": "TESTCOURTHOUSE" + }, + "courtroom": { + "id": 1, + "name": "TESTCOURTROOM" + }, + "start_at": "2024-01-03T12:10:10Z", + "end_at": "2024-01-03T13:10:10Z", + "channel": 2, + "chronicle_id": "chronicleId", + "antecedent_id": "antecedent-value", + "is_current": false, + "created_at": "" + } + ] +} \ No newline at end of file diff --git a/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java b/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java index a786de30c9..95c9fe96e2 100644 --- a/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java +++ b/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java @@ -1,6 +1,8 @@ package uk.gov.hmcts.darts.audio.mapper; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import uk.gov.hmcts.darts.audio.model.AdminActionResponse; import uk.gov.hmcts.darts.audio.model.AdminMediaVersionResponse; @@ -26,10 +28,11 @@ @Slf4j @Component +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class GetAdminMediaResponseMapper { - private CourtroomMapper courtroomMapper; - private CourthouseMapper courthouseMapper; + private final CourtroomMapper courtroomMapper; + private final CourthouseMapper courthouseMapper; public static List createResponseItemList(List mediaEntities, HearingEntity hearing) { List responseList = new ArrayList<>(); diff --git a/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java b/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java index b8ffd7c5af..5847cd54fa 100644 --- a/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java +++ b/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java @@ -3,6 +3,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -63,6 +64,7 @@ @Service @RequiredArgsConstructor +@Slf4j public class AdminMediaServiceImpl implements AdminMediaService { private final SearchMediaValidator searchMediaValidator; @@ -273,13 +275,43 @@ public MediaApproveMarkedForDeletionResponse adminApproveMediaMarkedForDeletion( @Override public AdminVersionedMediaResponse getMediaVersionsById(Integer id) { - MediaEntity mediaEntity = getMediaEntityById(id); - List mediaVersions = new ArrayList<>(); - //Only fetch versions if the media is part of a chronicle - if (mediaEntity.getChronicleId() != null) { - mediaVersions.addAll(mediaRepository.findAllByChronicleId(mediaEntity.getChronicleId())); + MediaEntity mediaEntityFromRequest = getMediaEntityById(id); + + if (mediaEntityFromRequest.getChronicleId() == null) { + throw new DartsApiException(CommonApiError.INTERNAL_SERVER_ERROR, + "Media " + id + " has a Chronicle Id that is null. As such we can not ensure accurate results are returned"); + } + List mediaVersions = mediaRepository.findAllByChronicleId(mediaEntityFromRequest.getChronicleId()); + + + List currentMediaVersions = mediaVersions.stream() + .filter(mediaEntity -> mediaEntity.getIsCurrent() != null) + .filter(media -> media.getIsCurrent()) + .sorted((o1, o2) -> o1.getCreatedDateTime().compareTo(o2.getCreatedDateTime())) + .collect(Collectors.toCollection(ArrayList::new)); + + List versionedMedia = mediaVersions.stream() + .filter(media -> media.getIsCurrent() == null || !media.getIsCurrent()) + .sorted((o1, o2) -> o2.getCreatedDateTime().compareTo(o1.getCreatedDateTime())) + .collect(Collectors.toCollection(ArrayList::new)); + + MediaEntity currentVersion; + if (currentMediaVersions.size() == 1) { + currentVersion = currentMediaVersions.getLast(); + } else if (currentMediaVersions.size() == 0) { + currentVersion = null; + log.info("Media with id {} has {} current versions", id, currentMediaVersions.size()); + } else { + log.warn("Media with id {} has {} current versions we only expect one", id, currentMediaVersions.size()); + currentVersion = currentMediaVersions.getLast(); + //Add any extra current events to top of versionedMedia so they still get displayed + currentMediaVersions.removeLast(); + currentMediaVersions + .forEach(mediaEntity -> { + versionedMedia.addFirst(mediaEntity); + }); } - return getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(mediaEntity, mediaVersions); + return getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(currentVersion, versionedMedia); } private ApplyAdminActionComponent.AdminActionProperties mapToAdminActionProperties(AdminActionRequest adminActionRequest) { diff --git a/src/main/java/uk/gov/hmcts/darts/common/exception/CommonApiError.java b/src/main/java/uk/gov/hmcts/darts/common/exception/CommonApiError.java index f7fa6e330f..4bdc1fa823 100644 --- a/src/main/java/uk/gov/hmcts/darts/common/exception/CommonApiError.java +++ b/src/main/java/uk/gov/hmcts/darts/common/exception/CommonApiError.java @@ -24,6 +24,11 @@ public enum CommonApiError implements DartsApiError { CommonErrorCode.NOT_FOUND.getValue(), HttpStatus.NOT_FOUND, CommonTitleErrors.NOT_FOUND.getValue() + ), + INTERNAL_SERVER_ERROR( + CommonErrorCode.INTERNAL_SERVER_ERROR.getValue(), + HttpStatus.INTERNAL_SERVER_ERROR, + CommonTitleErrors.INTERNAL_SERVER_ERROR.getValue() ); private static final String ERROR_TYPE_PREFIX = "COMMON"; diff --git a/src/main/resources/openapi/common.yaml b/src/main/resources/openapi/common.yaml index 99e3ac1ad4..6de458c48d 100644 --- a/src/main/resources/openapi/common.yaml +++ b/src/main/resources/openapi/common.yaml @@ -174,9 +174,10 @@ components: - "COMMON_100" - "COMMON_101" - "COMMON_102" + - "COMMON_103" x-enum-varnames: [ COURTHOUSE_PROVIDED_DOES_NOT_EXIST, FEATURE_FLAG_NOT_ENABLED, - NOT_FOUND ] + NOT_FOUND, INTERNAL_SERVER_ERROR ] CommonTitleErrors: type: string @@ -184,7 +185,8 @@ components: - "Provided courthouse does not exist" - "Feature flag not enabled" - "Resource not found" + - "Internal server error" x-enum-varnames: [ COURTHOUSE_PROVIDED_DOES_NOT_EXIST , FEATURE_FLAG_NOT_ENABLED, - NOT_FOUND + NOT_FOUND, INTERNAL_SERVER_ERROR ] \ No newline at end of file diff --git a/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java b/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java index fc455f2c87..841cfb4b47 100644 --- a/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java +++ b/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java @@ -76,10 +76,10 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; @SuppressWarnings("PMD.CouplingBetweenObjects") @@ -597,45 +597,129 @@ void getMediaEntityById_shouldThrowException_ifNoMediaEntityExists() { @DisplayName("AdminVersionedMediaResponse getMediaVersionsById(Integer id)") class GetMediaVersionsById { @Test - void getMediaVersionsById_shouldFetchMediaVersions_whenChronicleIdIsNotNull() { + void getMediaVersionsById_shouldThrowException_whenChronicleIdIsNull() { MediaEntity mediaEntity = mock(MediaEntity.class); + mediaEntity.setChronicleId(null); doReturn(mediaEntity).when(mediaRequestService).getMediaEntityById(123); - when(mediaEntity.getChronicleId()).thenReturn("chronicleId1"); - List versionedMedias = List.of(mock(MediaEntity.class), mock(MediaEntity.class)); - when(mediaRepository.findAllByChronicleId("chronicleId1")).thenReturn(versionedMedias); + DartsApiException exception = assertThrows(DartsApiException.class, () -> mediaRequestService.getMediaVersionsById(123)); + assertThat(exception.getError()).isEqualTo(CommonApiError.INTERNAL_SERVER_ERROR); + assertThat(exception.getMessage()) + .isEqualTo("Internal server error. Media 123 has a Chronicle Id that is null. As such we can not ensure accurate results are returned"); + } + + @Test + void getMediaVersionsById_shouldReturnEmptyVersionList_whenNoMediaVersionsExist() { + final String chronicleId = "someChronicleId"; + MediaEntity mediaEntity = mockMediaEntity(true, chronicleId, OffsetDateTime.now()); + doReturn(mediaEntity).when(mediaRequestService).getMediaEntityById(123); + when(mediaRepository.findAllByChronicleId(chronicleId)).thenReturn(List.of(mediaEntity)); + + AdminVersionedMediaResponse response = mock(AdminVersionedMediaResponse.class); + when(getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(mediaEntity, List.of())).thenReturn(response); + + assertThat(mediaRequestService.getMediaVersionsById(123)) + .isEqualTo(response); + + verify(mediaRepository).findAllByChronicleId(chronicleId); + verify(getAdminMediaResponseMapper).mapAdminVersionedMediaResponse(mediaEntity, List.of()); + verify(mediaRequestService).getMediaEntityById(123); + } + + @Test + void getMediaVersionsById_shouldReturnVersionsAndCurrentMedia_whenVersionsExist() { + final String chronicleId = "someChronicleId"; + OffsetDateTime now = OffsetDateTime.now(); + MediaEntity currentMediaEntity = mockMediaEntity(true, chronicleId, now); + MediaEntity versionedMediaEntity1 = mockMediaEntity(null, chronicleId, now.plusMinutes(2)); + MediaEntity versionedMediaEntity2 = mockMediaEntity(false, chronicleId, now.plusMinutes(1)); + + doReturn(currentMediaEntity).when(mediaRequestService).getMediaEntityById(123); + when(mediaRepository.findAllByChronicleId(chronicleId)) + .thenReturn(List.of(currentMediaEntity, versionedMediaEntity2, versionedMediaEntity1)); AdminVersionedMediaResponse response = mock(AdminVersionedMediaResponse.class); - when(getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(mediaEntity, versionedMedias)) + + List expectedVersioendMedia = List.of(versionedMediaEntity1, versionedMediaEntity2); + when(getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(currentMediaEntity, expectedVersioendMedia)) .thenReturn(response); assertThat(mediaRequestService.getMediaVersionsById(123)) .isEqualTo(response); - verify(getAdminMediaResponseMapper).mapAdminVersionedMediaResponse(mediaEntity, versionedMedias); + verify(mediaRepository).findAllByChronicleId(chronicleId); + verify(getAdminMediaResponseMapper).mapAdminVersionedMediaResponse(currentMediaEntity, expectedVersioendMedia); verify(mediaRequestService).getMediaEntityById(123); - verify(mediaRepository).findAllByChronicleId("chronicleId1"); } + @Test - void getMediaVersionsById_shouldNotFetchMediaVersions_whenChronicleIdIsNull() { - MediaEntity mediaEntity = mock(MediaEntity.class); - doReturn(mediaEntity).when(mediaRequestService).getMediaEntityById(123); - when(mediaEntity.getChronicleId()).thenReturn(null); + void getMediaVersionsById_shouldReturnNullCurrentVersion_ifAllMediaIsCurrentFlase() { + final String chronicleId = "someChronicleId"; + OffsetDateTime now = OffsetDateTime.now(); + MediaEntity versionedMediaEntity1 = mockMediaEntity(null, chronicleId, now.plusMinutes(2)); + MediaEntity versionedMediaEntity2 = mockMediaEntity(false, chronicleId, now.plusMinutes(1)); + + doReturn(versionedMediaEntity1).when(mediaRequestService).getMediaEntityById(123); + + + when(mediaRepository.findAllByChronicleId(chronicleId)) + .thenReturn(List.of(versionedMediaEntity2, versionedMediaEntity1)); AdminVersionedMediaResponse response = mock(AdminVersionedMediaResponse.class); - when(getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(mediaEntity, new ArrayList<>())) + + List expectedVersioendMedia = List.of(versionedMediaEntity1, versionedMediaEntity2); + when(getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(null, expectedVersioendMedia)) .thenReturn(response); assertThat(mediaRequestService.getMediaVersionsById(123)) .isEqualTo(response); - verify(getAdminMediaResponseMapper).mapAdminVersionedMediaResponse(mediaEntity, new ArrayList<>()); + + verify(mediaRepository).findAllByChronicleId(chronicleId); + verify(getAdminMediaResponseMapper).mapAdminVersionedMediaResponse(null, expectedVersioendMedia); + verify(mediaRequestService).getMediaEntityById(123); + + } + + @Test + void getMediaVersionsById_shouldReturnLastCreatedMedia_ifMultipleIsCurrentTrueExist() { + final String chronicleId = "someChronicleId"; + OffsetDateTime now = OffsetDateTime.now(); + MediaEntity currentMediaEntity1 = mockMediaEntity(true, chronicleId, now.plusMinutes(2)); + MediaEntity currentMediaEntity2 = mockMediaEntity(true, chronicleId, now); + MediaEntity currentMediaEntity3 = mockMediaEntity(true, chronicleId, now.plusMinutes(1)); + + MediaEntity versionedMediaEntity1 = mockMediaEntity(null, chronicleId, now.plusMinutes(2)); + MediaEntity versionedMediaEntity2 = mockMediaEntity(false, chronicleId, now.plusMinutes(1)); + + doReturn(currentMediaEntity1).when(mediaRequestService).getMediaEntityById(123); + when(mediaRepository.findAllByChronicleId(chronicleId)) + .thenReturn(List.of(currentMediaEntity1, currentMediaEntity2, currentMediaEntity3, versionedMediaEntity2, versionedMediaEntity1)); + AdminVersionedMediaResponse response = mock(AdminVersionedMediaResponse.class); + List expectedVersioendMedia = List.of(currentMediaEntity3, currentMediaEntity2, versionedMediaEntity1, versionedMediaEntity2); + when(getAdminMediaResponseMapper.mapAdminVersionedMediaResponse(currentMediaEntity1, expectedVersioendMedia)) + .thenReturn(response); + + assertThat(mediaRequestService.getMediaVersionsById(123)) + .isEqualTo(response); + + verify(mediaRepository).findAllByChronicleId(chronicleId); + verify(getAdminMediaResponseMapper).mapAdminVersionedMediaResponse(currentMediaEntity1, expectedVersioendMedia); verify(mediaRequestService).getMediaEntityById(123); - verifyNoInteractions(mediaRepository); + } + private MediaEntity mockMediaEntity(Boolean isCurrent, String chronicleId, OffsetDateTime offsetDateTime) { + MediaEntity mediaEntity = mock(MediaEntity.class); + lenient().when(mediaEntity.getChronicleId()).thenReturn(chronicleId); + lenient().when(mediaEntity.getIsCurrent()).thenReturn(isCurrent); + lenient().when(mediaEntity.getCreatedDateTime()).thenReturn(offsetDateTime); + return mediaEntity; + } + + } From c004ca2959682eb0c0888e4c0b911412c992fb14 Mon Sep 17 00:00:00 2001 From: benedwards Date: Thu, 27 Feb 2025 14:53:02 +0000 Subject: [PATCH 3/6] Fixed merge issues --- .../darts/audio/service/impl/AdminMediaServiceImplTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java b/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java index 841cfb4b47..aad29c422c 100644 --- a/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java +++ b/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java @@ -80,6 +80,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; @SuppressWarnings("PMD.CouplingBetweenObjects") @@ -983,7 +984,7 @@ void shouldThrowException_whenNoMediaIsFound() { // When IllegalStateException exception = assertThrows(IllegalStateException.class, - () -> mediaRequestService.adminHideOrShowMediaById(1, mediaHideRequest)); + () -> mediaRequestService.adminHideOrShowMediaById(1, mediaHideRequest)); // Then assertEquals(exception.getMessage(), "Media not found, expected this to be pre-validated"); From 3b0e887dfbc5c95aa4f8faf7b02c60730b999aa6 Mon Sep 17 00:00:00 2001 From: benedwards Date: Thu, 27 Feb 2025 17:07:00 +0000 Subject: [PATCH 4/6] Review comments --- .../audio/mapper/GetAdminMediaResponseMapper.java | 3 ++- .../audio/service/impl/AdminMediaServiceImpl.java | 12 +++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java b/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java index 95c9fe96e2..91baa53d58 100644 --- a/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java +++ b/src/main/java/uk/gov/hmcts/darts/audio/mapper/GetAdminMediaResponseMapper.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; @@ -137,7 +138,7 @@ public AdminVersionedMediaResponse mapAdminVersionedMediaResponse(MediaEntity me response.setPreviousVersions( mediaVersions.stream() .map(this::mapAdminMediaVersionResponse) - .filter(adminMediaVersionResponse -> adminMediaVersionResponse != null) + .filter(Objects::nonNull) .toList() ); return response; diff --git a/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java b/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java index 5847cd54fa..98e291dc1f 100644 --- a/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java +++ b/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java @@ -45,6 +45,7 @@ import uk.gov.hmcts.darts.common.entity.ObjectAdminActionEntity; import uk.gov.hmcts.darts.common.entity.ObjectHiddenReasonEntity; import uk.gov.hmcts.darts.common.entity.TransformedMediaEntity; +import uk.gov.hmcts.darts.common.entity.base.CreatedBaseEntity; import uk.gov.hmcts.darts.common.exception.CommonApiError; import uk.gov.hmcts.darts.common.exception.DartsApiException; import uk.gov.hmcts.darts.common.helper.CurrentTimeHelper; @@ -56,6 +57,7 @@ import java.time.OffsetDateTime; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Optional; @@ -287,25 +289,25 @@ public AdminVersionedMediaResponse getMediaVersionsById(Integer id) { List currentMediaVersions = mediaVersions.stream() .filter(mediaEntity -> mediaEntity.getIsCurrent() != null) .filter(media -> media.getIsCurrent()) - .sorted((o1, o2) -> o1.getCreatedDateTime().compareTo(o2.getCreatedDateTime())) + .sorted(Comparator.comparing(CreatedBaseEntity::getCreatedDateTime).reversed()) .collect(Collectors.toCollection(ArrayList::new)); List versionedMedia = mediaVersions.stream() .filter(media -> media.getIsCurrent() == null || !media.getIsCurrent()) - .sorted((o1, o2) -> o2.getCreatedDateTime().compareTo(o1.getCreatedDateTime())) + .sorted(Comparator.comparing(CreatedBaseEntity::getCreatedDateTime).reversed()) .collect(Collectors.toCollection(ArrayList::new)); MediaEntity currentVersion; if (currentMediaVersions.size() == 1) { currentVersion = currentMediaVersions.getLast(); - } else if (currentMediaVersions.size() == 0) { + } else if (currentMediaVersions.isEmpty()) { currentVersion = null; - log.info("Media with id {} has {} current versions", id, currentMediaVersions.size()); + log.info("Media with id {} has no current versions", id); } else { log.warn("Media with id {} has {} current versions we only expect one", id, currentMediaVersions.size()); currentVersion = currentMediaVersions.getLast(); //Add any extra current events to top of versionedMedia so they still get displayed - currentMediaVersions.removeLast(); + currentMediaVersions.removeFirst(); currentMediaVersions .forEach(mediaEntity -> { versionedMedia.addFirst(mediaEntity); From 09470f5639e68379c8e85032a532c5f006178e90 Mon Sep 17 00:00:00 2001 From: benedwards Date: Thu, 27 Feb 2025 17:28:16 +0000 Subject: [PATCH 5/6] Fixed issue where incorrect currentVersion was being grabbed --- .../hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java b/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java index 98e291dc1f..91db364879 100644 --- a/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java +++ b/src/main/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImpl.java @@ -289,7 +289,7 @@ public AdminVersionedMediaResponse getMediaVersionsById(Integer id) { List currentMediaVersions = mediaVersions.stream() .filter(mediaEntity -> mediaEntity.getIsCurrent() != null) .filter(media -> media.getIsCurrent()) - .sorted(Comparator.comparing(CreatedBaseEntity::getCreatedDateTime).reversed()) + .sorted(Comparator.comparing(CreatedBaseEntity::getCreatedDateTime)) .collect(Collectors.toCollection(ArrayList::new)); List versionedMedia = mediaVersions.stream() @@ -307,7 +307,7 @@ public AdminVersionedMediaResponse getMediaVersionsById(Integer id) { log.warn("Media with id {} has {} current versions we only expect one", id, currentMediaVersions.size()); currentVersion = currentMediaVersions.getLast(); //Add any extra current events to top of versionedMedia so they still get displayed - currentMediaVersions.removeFirst(); + currentMediaVersions.removeLast(); currentMediaVersions .forEach(mediaEntity -> { versionedMedia.addFirst(mediaEntity); From b5d835218d6971a786a2f15c28acb73690c9dff2 Mon Sep 17 00:00:00 2001 From: benedwards Date: Fri, 28 Feb 2025 13:37:09 +0000 Subject: [PATCH 6/6] Updated unit tests --- .../impl/AdminMediaServiceImplTest.java | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java b/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java index aad29c422c..3e026aab40 100644 --- a/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java +++ b/src/test/java/uk/gov/hmcts/darts/audio/service/impl/AdminMediaServiceImplTest.java @@ -76,7 +76,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -612,7 +611,7 @@ void getMediaVersionsById_shouldThrowException_whenChronicleIdIsNull() { @Test void getMediaVersionsById_shouldReturnEmptyVersionList_whenNoMediaVersionsExist() { final String chronicleId = "someChronicleId"; - MediaEntity mediaEntity = mockMediaEntity(true, chronicleId, OffsetDateTime.now()); + MediaEntity mediaEntity = createMediaEntity(true, chronicleId, OffsetDateTime.now()); doReturn(mediaEntity).when(mediaRequestService).getMediaEntityById(123); when(mediaRepository.findAllByChronicleId(chronicleId)).thenReturn(List.of(mediaEntity)); @@ -631,9 +630,9 @@ void getMediaVersionsById_shouldReturnEmptyVersionList_whenNoMediaVersionsExist( void getMediaVersionsById_shouldReturnVersionsAndCurrentMedia_whenVersionsExist() { final String chronicleId = "someChronicleId"; OffsetDateTime now = OffsetDateTime.now(); - MediaEntity currentMediaEntity = mockMediaEntity(true, chronicleId, now); - MediaEntity versionedMediaEntity1 = mockMediaEntity(null, chronicleId, now.plusMinutes(2)); - MediaEntity versionedMediaEntity2 = mockMediaEntity(false, chronicleId, now.plusMinutes(1)); + MediaEntity currentMediaEntity = createMediaEntity(true, chronicleId, now); + MediaEntity versionedMediaEntity1 = createMediaEntity(null, chronicleId, now.plusMinutes(2)); + MediaEntity versionedMediaEntity2 = createMediaEntity(false, chronicleId, now.plusMinutes(1)); doReturn(currentMediaEntity).when(mediaRequestService).getMediaEntityById(123); when(mediaRepository.findAllByChronicleId(chronicleId)) @@ -658,8 +657,8 @@ void getMediaVersionsById_shouldReturnVersionsAndCurrentMedia_whenVersionsExist( void getMediaVersionsById_shouldReturnNullCurrentVersion_ifAllMediaIsCurrentFlase() { final String chronicleId = "someChronicleId"; OffsetDateTime now = OffsetDateTime.now(); - MediaEntity versionedMediaEntity1 = mockMediaEntity(null, chronicleId, now.plusMinutes(2)); - MediaEntity versionedMediaEntity2 = mockMediaEntity(false, chronicleId, now.plusMinutes(1)); + MediaEntity versionedMediaEntity1 = createMediaEntity(null, chronicleId, now.plusMinutes(2)); + MediaEntity versionedMediaEntity2 = createMediaEntity(false, chronicleId, now.plusMinutes(1)); doReturn(versionedMediaEntity1).when(mediaRequestService).getMediaEntityById(123); @@ -686,12 +685,12 @@ void getMediaVersionsById_shouldReturnNullCurrentVersion_ifAllMediaIsCurrentFlas void getMediaVersionsById_shouldReturnLastCreatedMedia_ifMultipleIsCurrentTrueExist() { final String chronicleId = "someChronicleId"; OffsetDateTime now = OffsetDateTime.now(); - MediaEntity currentMediaEntity1 = mockMediaEntity(true, chronicleId, now.plusMinutes(2)); - MediaEntity currentMediaEntity2 = mockMediaEntity(true, chronicleId, now); - MediaEntity currentMediaEntity3 = mockMediaEntity(true, chronicleId, now.plusMinutes(1)); + MediaEntity currentMediaEntity1 = createMediaEntity(true, chronicleId, now.plusMinutes(2)); + MediaEntity currentMediaEntity2 = createMediaEntity(true, chronicleId, now); + MediaEntity currentMediaEntity3 = createMediaEntity(true, chronicleId, now.plusMinutes(1)); - MediaEntity versionedMediaEntity1 = mockMediaEntity(null, chronicleId, now.plusMinutes(2)); - MediaEntity versionedMediaEntity2 = mockMediaEntity(false, chronicleId, now.plusMinutes(1)); + MediaEntity versionedMediaEntity1 = createMediaEntity(null, chronicleId, now.plusMinutes(2)); + MediaEntity versionedMediaEntity2 = createMediaEntity(false, chronicleId, now.plusMinutes(1)); doReturn(currentMediaEntity1).when(mediaRequestService).getMediaEntityById(123); when(mediaRepository.findAllByChronicleId(chronicleId)) @@ -712,15 +711,14 @@ void getMediaVersionsById_shouldReturnLastCreatedMedia_ifMultipleIsCurrentTrueEx } - private MediaEntity mockMediaEntity(Boolean isCurrent, String chronicleId, OffsetDateTime offsetDateTime) { - MediaEntity mediaEntity = mock(MediaEntity.class); - lenient().when(mediaEntity.getChronicleId()).thenReturn(chronicleId); - lenient().when(mediaEntity.getIsCurrent()).thenReturn(isCurrent); - lenient().when(mediaEntity.getCreatedDateTime()).thenReturn(offsetDateTime); - return mediaEntity; + private MediaEntity createMediaEntity(Boolean isCurrent, String chronicleId, OffsetDateTime offsetDateTime) { + return PersistableFactory.getMediaTestData().someMinimalBuilder() + .chronicleId(chronicleId) + .isCurrent(isCurrent) + .createdDateTime(offsetDateTime) + .build() + .getEntity(); } - - }