Skip to content

Commit

Permalink
DMP-2893 Implement POST /admin/medias/<media_id>/approve-deletion (#2015
Browse files Browse the repository at this point in the history
)
  • Loading branch information
karen-hedges authored Sep 26, 2024
1 parent 5bcf1b3 commit d021403
Show file tree
Hide file tree
Showing 17 changed files with 808 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
package uk.gov.hmcts.darts.audio.controller;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import uk.gov.hmcts.darts.audio.exception.AudioApiError;
import uk.gov.hmcts.darts.audio.model.AdminActionResponse;
import uk.gov.hmcts.darts.audio.model.MediaApproveMarkedForDeletionResponse;
import uk.gov.hmcts.darts.audio.model.Problem;
import uk.gov.hmcts.darts.authorisation.component.UserIdentity;
import uk.gov.hmcts.darts.common.entity.CourtroomEntity;
import uk.gov.hmcts.darts.common.entity.MediaEntity;
import uk.gov.hmcts.darts.common.enums.SecurityRoleEnum;
import uk.gov.hmcts.darts.common.repository.UserAccountRepository;
import uk.gov.hmcts.darts.testutils.IntegrationBase;
import uk.gov.hmcts.darts.testutils.stubs.CourtroomStub;
import uk.gov.hmcts.darts.testutils.stubs.MediaStub;
import uk.gov.hmcts.darts.testutils.stubs.ObjectAdminActionStub;
import uk.gov.hmcts.darts.testutils.stubs.ObjectHiddenReasonStub;
import uk.gov.hmcts.darts.testutils.stubs.SuperAdminUserStub;
import uk.gov.hmcts.darts.testutils.stubs.UserAccountStub;

import java.time.OffsetDateTime;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static wiremock.org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric;

@AutoConfigureMockMvc
class AudioControllerPostAdminApproveMediaMarkedForDeletionIntTest extends IntegrationBase {
private static final String MEDIA_ID_SUBSTITUTION_KEY = "{media_id}";
private static final String ENDPOINT_URL = "/admin/medias/" + MEDIA_ID_SUBSTITUTION_KEY + "/approve-deletion";
private static final OffsetDateTime START_TIME = OffsetDateTime.parse("2024-01-01T10:00:00Z");
private static final OffsetDateTime END_TIME = OffsetDateTime.parse("2024-01-01T00:12:00Z");

@Autowired
private MockMvc mockMvc;

@Autowired
private UserAccountRepository userAccountRepository;

@Autowired
SuperAdminUserStub superAdminUserStub;

@MockBean
UserIdentity userIdentity;

@Autowired
private UserAccountStub userAccountStub;

@Autowired
private CourtroomStub courtroomStub;

@Autowired
private MediaStub mediaStub;

@Autowired
private ObjectAdminActionStub objectAdminActionStub;

@Autowired
private ObjectHiddenReasonStub objectHiddenReasonStub;

private MediaEntity mediaEntity;

private String endpoint;

@BeforeEach
void setUp() {
String courtHouseName = randomAlphanumeric(8);
var courtroomEntity = courtroomStub.createCourtroomUnlessExists(courtHouseName, "Test Courtroom",
userAccountStub.getSystemUserAccountEntity());

// And a media that's marked for deletion, but not yet approved for deletion (not marked for manual deletion)
mediaEntity = createAndSaveMediaEntity(courtroomEntity);

endpoint = ENDPOINT_URL.replace(MEDIA_ID_SUBSTITUTION_KEY, mediaEntity.getId().toString());
}

@Test
void postAdminApproveMediaMarkedForDeletionShouldReturnSuccess() throws Exception {
// given
var superAdminUser = superAdminUserStub.givenUserIsAuthorised(userIdentity);

var testUser = dartsDatabase.getUserAccountStub().getIntegrationTestUserAccountEntity("testuser");
objectAdminActionStub.createAndSave(ObjectAdminActionStub.ObjectAdminActionSpec.builder()
.media(mediaEntity)
.objectHiddenReason(
objectHiddenReasonStub.getAnyWithMarkedForDeletion(true))
.markedForManualDeletion(false)
.markedForManualDelBy(null)
.markedForManualDelDateTime(null)
.hiddenBy(testUser)
.build());

// when
MvcResult mvcResult = mockMvc.perform(post(endpoint))
.andExpect(status().isOk())
.andReturn();

// then
MediaApproveMarkedForDeletionResponse mediaApproveMarkedForDeletionResponse
= objectMapper.readValue(mvcResult.getResponse().getContentAsByteArray(), MediaApproveMarkedForDeletionResponse.class);
AdminActionResponse actionResponse = mediaApproveMarkedForDeletionResponse.getAdminAction();
assertNotNull(actionResponse.getMarkedForManualDeletionAt());
assertEquals(superAdminUser.getId(), actionResponse.getMarkedForManualDeletionById());
assertTrue(actionResponse.getIsMarkedForManualDeletion());

}

@Test
void postAdminApproveMediaMarkedForDeletionWhereCurrentUserMarkedForDeletion() throws Exception {
// given
var superAdminUser = superAdminUserStub.givenUserIsAuthorised(userIdentity);

objectAdminActionStub.createAndSave(ObjectAdminActionStub.ObjectAdminActionSpec.builder()
.media(mediaEntity)
.objectHiddenReason(
objectHiddenReasonStub.getAnyWithMarkedForDeletion(true))
.markedForManualDeletion(false)
.markedForManualDelBy(null)
.markedForManualDelDateTime(null)
.hiddenBy(superAdminUser)
.build());

// when
MvcResult mvcResult = mockMvc.perform(post(endpoint))
.andExpect(status().isBadRequest())
.andReturn();

// then
String actualJson = mvcResult.getResponse().getContentAsString();

Problem problem = objectMapper.readValue(actualJson, Problem.class);
assertEquals(problem.getType(), AudioApiError.USER_CANNOT_APPROVE_THEIR_OWN_DELETION.getType());
assertEquals(problem.getTitle(), AudioApiError.USER_CANNOT_APPROVE_THEIR_OWN_DELETION.getTitle());
}

@Test
void postAdminApproveMediaMarkedForDeletionWhereMediaMarkedForDeletionTwice() throws Exception {
// given
superAdminUserStub.givenUserIsAuthorised(userIdentity);
var testUser = dartsDatabase.getUserAccountStub().getIntegrationTestUserAccountEntity("testuser");

objectAdminActionStub.createAndSave(ObjectAdminActionStub.ObjectAdminActionSpec.builder()
.media(mediaEntity)
.objectHiddenReason(
objectHiddenReasonStub.getAnyWithMarkedForDeletion(true))
.markedForManualDeletion(false)
.markedForManualDelBy(null)
.markedForManualDelDateTime(null)
.hiddenBy(testUser)
.build());

objectAdminActionStub.createAndSave(ObjectAdminActionStub.ObjectAdminActionSpec.builder()
.media(mediaEntity)
.objectHiddenReason(
objectHiddenReasonStub.getAnyWithMarkedForDeletion(true))
.markedForManualDeletion(false)
.markedForManualDelBy(null)
.markedForManualDelDateTime(null)
.hiddenBy(testUser)
.build());

// when
MvcResult mvcResult = mockMvc.perform(post(endpoint))
.andExpect(status().isBadRequest())
.andReturn();

// then
String actualJson = mvcResult.getResponse().getContentAsString();

Problem problem = objectMapper.readValue(actualJson, Problem.class);
assertEquals(problem.getType(), AudioApiError.TOO_MANY_RESULTS.getType());
assertEquals(problem.getTitle(), AudioApiError.TOO_MANY_RESULTS.getTitle());
}

@Test
void postAdminApproveMediaMarkedForDeletionWhereMediaNotMarkedForDeletion() throws Exception {
// given
superAdminUserStub.givenUserIsAuthorised(userIdentity);
var testUser = dartsDatabase.getUserAccountStub().getIntegrationTestUserAccountEntity("testuser");

objectAdminActionStub.createAndSave(ObjectAdminActionStub.ObjectAdminActionSpec.builder()
.media(mediaEntity)
.objectHiddenReason(
objectHiddenReasonStub.getAnyWithMarkedForDeletion(false))
.markedForManualDeletion(false)
.markedForManualDelBy(null)
.markedForManualDelDateTime(null)
.hiddenBy(testUser)
.build());

// when
MvcResult mvcResult = mockMvc.perform(post(endpoint))
.andExpect(status().isBadRequest())
.andReturn();

// then
String actualJson = mvcResult.getResponse().getContentAsString();

Problem problem = objectMapper.readValue(actualJson, Problem.class);
assertEquals(problem.getType(), AudioApiError.MEDIA_MARKED_FOR_DELETION_REASON_NOT_FOUND.getType());
assertEquals(problem.getTitle(), AudioApiError.MEDIA_MARKED_FOR_DELETION_REASON_NOT_FOUND.getTitle());
}

@Test
void postAdminApproveMediaMarkedForDeletionAlreadyApproved() throws Exception {
// given
superAdminUserStub.givenUserIsAuthorised(userIdentity);

var testUser = dartsDatabase.getUserAccountStub().getIntegrationTestUserAccountEntity("testuser");
objectAdminActionStub.createAndSave(ObjectAdminActionStub.ObjectAdminActionSpec.builder()
.media(mediaEntity)
.objectHiddenReason(
objectHiddenReasonStub.getAnyWithMarkedForDeletion(true))
.hiddenBy(testUser)
.build());

// when
MvcResult mvcResult = mockMvc.perform(post(endpoint))
.andExpect(status().isConflict())
.andReturn();

// then
String actualJson = mvcResult.getResponse().getContentAsString();

Problem problem = objectMapper.readValue(actualJson, Problem.class);
assertEquals(problem.getType(), AudioApiError.MEDIA_ALREADY_MARKED_FOR_DELETION.getType());
assertEquals(problem.getTitle(), AudioApiError.MEDIA_ALREADY_MARKED_FOR_DELETION.getTitle());

}

@Test
void postAdminApproveMediaMarkedForDeletionMediaNotMarkedForDeletion() throws Exception {
// given
superAdminUserStub.givenUserIsAuthorised(userIdentity);

// when
MvcResult mvcResult = mockMvc.perform(post(endpoint))
.andExpect(status().isNotFound())
.andReturn();

// then
String actualJson = mvcResult.getResponse().getContentAsString();

Problem problem = objectMapper.readValue(actualJson, Problem.class);
assertEquals(problem.getType(), AudioApiError.ADMIN_MEDIA_MARKED_FOR_DELETION_NOT_FOUND.getType());
assertEquals(problem.getTitle(), AudioApiError.ADMIN_MEDIA_MARKED_FOR_DELETION_NOT_FOUND.getTitle());

}

@ParameterizedTest
@EnumSource(value = SecurityRoleEnum.class, names = {"SUPER_ADMIN"}, mode = EnumSource.Mode.EXCLUDE)
void testForbidden(SecurityRoleEnum role) throws Exception {
// given
superAdminUserStub.givenUserIsAuthorised(userIdentity, role);

// when then
mockMvc.perform(post(endpoint))
.andExpect(status().isForbidden())
.andReturn();

}

private MediaEntity createAndSaveMediaEntity(CourtroomEntity courtroomEntity) {
return mediaStub.createMediaEntity(courtroomEntity.getCourthouse().getCourthouseName(),
courtroomEntity.getName(),
START_TIME,
END_TIME,
1,
"MP2");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,31 @@ void findAllWithAnyDeletionReasonShouldReturnExpectedResultsWhenMediaExistsMedia
Assertions.assertEquals(expectedObjectAdminActionEntity.getId(), result.getFirst().getId());
}

@Test
void findByMediaIdAndMarkedForManualDeletionTrue() {
var media = dartsDatabase.getMediaStub().createAndSaveMedia();
var markedForManualDeletionAction = objectAdminActionStub.createAndSave(ObjectAdminActionStub.ObjectAdminActionSpec.builder()
.media(media)
.objectHiddenReason(
objectHiddenReasonStub.getAnyWithMarkedForDeletion(true))
.markedForManualDeletion(true)
.build());
objectAdminActionStub.createAndSave(ObjectAdminActionStub.ObjectAdminActionSpec.builder()
.media(media)
.objectHiddenReason(
objectHiddenReasonStub.getAnyWithMarkedForDeletion(true))
.markedForManualDeletion(false)
.build());


// When
List<ObjectAdminActionEntity> result = repository.findByMediaIdAndMarkedForManualDeletionTrue(media.getId());

// Then
Assertions.assertEquals(1, result.size());
Assertions.assertEquals(markedForManualDeletionAction.getId(), result.getFirst().getId());
}

private MediaEntity createAndSaveMediaEntity(CourtroomEntity courtroomEntity) {
return mediaStub.createMediaEntity(courtroomEntity.getCourthouse().getCourthouseName(),
courtroomEntity.getName(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import uk.gov.hmcts.darts.audio.model.AudioPreview;
import uk.gov.hmcts.darts.audio.model.GetAdminMediaResponseItem;
import uk.gov.hmcts.darts.audio.model.GetTransformedMediaResponse;
import uk.gov.hmcts.darts.audio.model.MediaApproveMarkedForDeletionResponse;
import uk.gov.hmcts.darts.audio.model.MediaHideRequest;
import uk.gov.hmcts.darts.audio.model.MediaHideResponse;
import uk.gov.hmcts.darts.audio.model.PostAdminMediasMarkedForDeletionItem;
Expand Down Expand Up @@ -139,7 +140,6 @@ public ResponseEntity<List<GetAdminMediaResponseItem>> getAdminMedias(Integer tr
return new ResponseEntity<>(response, HttpStatus.OK);
}


@Override
@SecurityRequirement(name = SECURITY_SCHEMES_BEARER_AUTH)
@Authorisation(contextId = ANY_ENTITY_ID, globalAccessSecurityRoles = {SUPER_ADMIN})
Expand All @@ -148,6 +148,14 @@ public ResponseEntity<MediaHideResponse> postAdminHideMediaId(Integer mediaId, M
return new ResponseEntity<>(audioResponse, HttpStatus.OK);
}

@Override
@SecurityRequirement(name = SECURITY_SCHEMES_BEARER_AUTH)
@Authorisation(contextId = ANY_ENTITY_ID, globalAccessSecurityRoles = {SUPER_ADMIN})
public ResponseEntity<MediaApproveMarkedForDeletionResponse> postAdminApproveMediaMarkedForDeletion(Integer mediaId) {
MediaApproveMarkedForDeletionResponse audioResponse = adminMediaService.adminApproveMediaMarkedForDeletion(mediaId);
return new ResponseEntity<>(audioResponse, HttpStatus.OK);
}

@Override
@SecurityRequirement(name = SECURITY_SCHEMES_BEARER_AUTH)
@Authorisation(contextId = ANY_ENTITY_ID, globalAccessSecurityRoles = {SUPER_USER, SUPER_ADMIN})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,29 @@ public enum AudioApiError implements DartsApiError {
TOO_MANY_RESULTS(
AddAudioErrorCode.TOO_MANY_RESULTS.getValue(),
HttpStatus.BAD_REQUEST,
AddAudioTitleErrors.TOO_MANY_RESULTS.getValue());
AddAudioTitleErrors.TOO_MANY_RESULTS.getValue()
),
MEDIA_ALREADY_MARKED_FOR_DELETION(
AddAudioErrorCode.MEDIA_ALREADY_MARKED_FOR_DELETION.getValue(),
HttpStatus.CONFLICT,
AddAudioTitleErrors.MEDIA_ALREADY_MARKED_FOR_DELETION.getValue()
),
ADMIN_MEDIA_MARKED_FOR_DELETION_NOT_FOUND(
AddAudioErrorCode.ADMIN_MEDIA_MARKED_FOR_DELETION_NOT_FOUND.getValue(),
HttpStatus.NOT_FOUND,
AddAudioTitleErrors.ADMIN_MEDIA_MARKED_FOR_DELETION_NOT_FOUND.getValue()
),
MEDIA_MARKED_FOR_DELETION_REASON_NOT_FOUND(
AddAudioErrorCode.MARKED_FOR_DELETION_REASON_NOT_FOUND.getValue(),
HttpStatus.BAD_REQUEST,
AddAudioTitleErrors.MARKED_FOR_DELETION_REASON_NOT_FOUND.getValue()
),
USER_CANNOT_APPROVE_THEIR_OWN_DELETION(
AddAudioErrorCode.USER_CANT_APPROVE_THEIR_OWN_DELETION.getValue(),
HttpStatus.BAD_REQUEST,
AddAudioTitleErrors.USER_CANT_APPROVE_THEIR_OWN_DELETION.getValue()
);


private static final String ERROR_TYPE_PREFIX = "AUDIO";

Expand Down
Loading

0 comments on commit d021403

Please sign in to comment.