Skip to content

Commit

Permalink
Merge pull request #479 from MeasureAuthoringTool/feature/mat-6187-ad…
Browse files Browse the repository at this point in the history
…min-msr-delete

[MAT-6187] Admin API to Hard Delete Measure Instance
  • Loading branch information
jkotanchik-SB authored Oct 18, 2023
2 parents 8c808c2 + 0b2cf81 commit a927fb4
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 5 deletions.
32 changes: 27 additions & 5 deletions src/main/java/cms/gov/madie/measure/resources/AdminController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
import cms.gov.madie.measure.dto.MeasureTestCaseValidationReport;
import cms.gov.madie.measure.dto.MeasureTestCaseValidationReportSummary;
import cms.gov.madie.measure.dto.TestCaseValidationReport;
import cms.gov.madie.measure.exceptions.ResourceNotFoundException;
import cms.gov.madie.measure.repositories.MeasureRepository;
import cms.gov.madie.measure.services.ActionLogService;
import cms.gov.madie.measure.services.MeasureService;
import cms.gov.madie.measure.services.MeasureSetService;
import cms.gov.madie.measure.services.TestCaseService;
import gov.cms.madie.models.common.ActionType;
import gov.cms.madie.models.measure.Measure;
import gov.cms.madie.models.measure.MeasureSet;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,11 +20,7 @@
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.ArrayList;
Expand All @@ -34,6 +35,9 @@ public class AdminController {
private final MeasureService measureService;
private final TestCaseService testCaseService;
private final MeasureSetService measureSetService;
private final ActionLogService actionLogService;

private final MeasureRepository measureRepository;

@Value("${madie.admin.concurrency-limit}")
private int concurrencyLimit;
Expand Down Expand Up @@ -104,6 +108,24 @@ public ResponseEntity<MeasureTestCaseValidationReportSummary> validateAllMeasure
.build());
}

@DeleteMapping("/measures/{id}")
@PreAuthorize("#request.getHeader('api-key') == #apiKey")
public ResponseEntity<Measure> permDeleteMeasure(
HttpServletRequest request,
@Value("${admin-api-key}") String apiKey,
Principal principal,
@RequestHeader("Authorization") String accessToken,
@PathVariable String id) {

Measure measureToDelete = measureService.findMeasureById(id);
if (measureToDelete != null) {
measureRepository.delete(measureToDelete);
actionLogService.logAction(id, Measure.class, ActionType.DELETED, principal.getName());
return ResponseEntity.ok(measureToDelete);
}
throw new ResourceNotFoundException(id);
}

private Callable<MeasureTestCaseValidationReport> buildCallableForMeasureId(
final String measureId, final String accessToken) {
return () -> testCaseService.updateTestCaseValidResourcesWithReport(measureId, accessToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import cms.gov.madie.measure.dto.JobStatus;
import cms.gov.madie.measure.dto.MeasureTestCaseValidationReport;
import cms.gov.madie.measure.dto.TestCaseValidationReport;
import cms.gov.madie.measure.repositories.MeasureRepository;
import cms.gov.madie.measure.services.ActionLogService;
import cms.gov.madie.measure.services.MeasureService;
import cms.gov.madie.measure.services.MeasureSetService;
import cms.gov.madie.measure.services.TestCaseService;
import gov.cms.madie.models.measure.Measure;
import gov.cms.madie.models.measure.MeasureSet;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -20,8 +23,11 @@
import java.util.List;

import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
Expand All @@ -42,6 +48,9 @@ public class AdminControllerMvcTest {
@MockBean private MeasureService measureService;
@MockBean private MeasureSetService measureSetService;
@MockBean private TestCaseService testCaseService;
@MockBean private ActionLogService actionLogService;

@MockBean private MeasureRepository measureRepository;

@Autowired private MockMvc mockMvc;

Expand Down Expand Up @@ -290,4 +299,43 @@ public void testValidateAllMeasureTestCasesOneImpactedMeasureDefaultDraftOnly()
verify(testCaseService, times(1)).updateTestCaseValidResourcesWithReport(eq("M1"), anyString());
verify(testCaseService, times(1)).updateTestCaseValidResourcesWithReport(eq("M2"), anyString());
}

@Test
public void testAdminMeasurePermaDelete() throws Exception {
Measure testMsr = Measure.builder().id("12345").build();
when(measureService.findMeasureById(anyString())).thenReturn(testMsr);
doNothing().when(measureRepository).delete(any(Measure.class));

mockMvc.perform(
MockMvcRequestBuilders.delete("/admin/measures/{id}", "12345")
.with(csrf())
.with(user(TEST_USER_ID))
.header(ADMIN_TEST_API_KEY_HEADER, ADMIN_TEST_API_KEY_HEADER_VALUE)
.header("Authorization", "test-okta"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id", equalTo("12345")));
}

@Test
public void testAdminMeasureDeleteThrowsWhenMeasureNotFound() throws Exception {
when(measureService.findMeasureById(anyString())).thenReturn(null);

mockMvc.perform(
MockMvcRequestBuilders.delete("/admin/measures/{id}", "12345")
.with(csrf())
.with(user(TEST_USER_ID))
.header(ADMIN_TEST_API_KEY_HEADER, ADMIN_TEST_API_KEY_HEADER_VALUE)
.header("Authorization", "test-okta"))
.andExpect(status().isNotFound());
}

@Test
public void testBlocksNonAuthorizedDeleteRequests() throws Exception {
mockMvc.perform(
MockMvcRequestBuilders.delete("/admin/measures/{id}", "12345")
.with(csrf())
.with(user(TEST_USER_ID))
.header("Authorization", "test-okta"))
.andExpect(status().isForbidden());
}
}

0 comments on commit a927fb4

Please sign in to comment.