Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAT-7938: implement CMS id delete endpoint #759

Merged
merged 7 commits into from
Dec 10, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,13 @@ public ResponseEntity<MeasureSet> createCmsId(
.body(measureSetService.createAndUpdateCmsId(measureSetId, principal.getName()));
}

@DeleteMapping("/measures/{measureId}/delete-cms-id")
public ResponseEntity<String> deleteCmsId(
@PathVariable String measureId, @RequestParam(name = "cmsId") Integer cmsId) {
adongare marked this conversation as resolved.
Show resolved Hide resolved
return ResponseEntity.status(HttpStatus.OK)
.body(measureSetService.deleteCmsId(measureId, cmsId));
}

@PutMapping("/measures/cms-id-association")
public ResponseEntity<MeasureSet> associateCmsId(
Principal principal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import cms.gov.madie.measure.exceptions.*;
import cms.gov.madie.measure.repositories.GeneratorRepository;
import cms.gov.madie.measure.repositories.MeasureRepository;
import cms.gov.madie.measure.repositories.MeasureSetRepository;
import gov.cms.madie.models.access.AclOperation;
import gov.cms.madie.models.access.AclSpecification;
Expand All @@ -13,6 +14,7 @@
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

Expand All @@ -21,6 +23,7 @@
@RequiredArgsConstructor
public class MeasureSetService {

private final MeasureRepository measureRepository;
private final MeasureSetRepository measureSetRepository;
private final GeneratorRepository generatorRepository;
private final ActionLogService actionLogService;
Expand Down Expand Up @@ -147,6 +150,49 @@ public MeasureSet createAndUpdateCmsId(String measureSetId, String username) {
return updatedMeasureSet;
}

public String deleteCmsId(String measureId, Integer cmsId) {
Optional<Measure> measure = measureRepository.findById(measureId);

if (measure.isPresent()) {
String measureSetId = measure.get().getMeasureSetId();
Optional<MeasureSet> optionalMeasureSet = measureSetRepository.findByMeasureSetId(measureSetId);

if (optionalMeasureSet.isEmpty()) {
throw new ResourceNotFoundException("No measure set exists for measure with measure set id of "
+ measureSetId);
}

MeasureSet measureSet = optionalMeasureSet.get();

if (measureSet.getCmsId() == null) {
throw new ResourceNotFoundException(String.format("No CMS id of %s exists to be deleted " +
"within measure set with measure set id of %s", cmsId, measureSetId));
}

if (!measureSet.getCmsId().equals(cmsId)) {
throw new InvalidIdException(
String.format("CMS id of %s passed in does not match CMS id of %s within " +
"measure set with measure set id of %s", cmsId,measureSet.getCmsId(), measureSetId));
}

List<Measure> measures = measureRepository.findAllByMeasureSetIdAndActive(measureSetId, true);

if (measures.size() > 1) {
throw new InvalidRequestException(String.format("Measure set with measure set id of %s contains more than 1 measure. " +
"Cannot delete CMS id when measure set has more than 1 version of measure.", measureSetId));
}

measureSet.setCmsId(null);
measureSetRepository.save(measureSet);

return String.format("CMS id of %s was deleted successfully from " +
"measure set with measure set id of %s", cmsId, measureSetId);
} else {
throw new ResourceNotFoundException(
"No measure exists with measure id of " + measureId);
}
}

public MeasureSet findByMeasureSetId(final String measureSetId) {
return measureSetRepository.findByMeasureSetId(measureSetId).orElse(null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,30 @@ void createCmsId() {
verify(measureSetService, times(1)).createAndUpdateCmsId(anyString(), anyString());
}

@Test
void deleteCmsId() {
String measureId = "measureId";

final MeasureSet measureSet =
MeasureSet.builder()
.id("f225481c-921e-4015-9e14-e5046bfac9ff")
.cmsId(6)
.measureSetId("measureSetId")
.owner("owner")
.acls(null)
.build();

String expectedBody = String.format("CMS Id of %s was deleted successfully from measure set with measure set id of %s", measureSet.getCmsId(), measureSet.getMeasureSetId());

when(measureSetService.deleteCmsId(anyString(), anyInt())).thenReturn(expectedBody);

ResponseEntity<String> response = controller.deleteCmsId(measureId, measureSet.getCmsId());

assertThat(response.getBody(), is(notNullValue()));
assertEquals(expectedBody, response.getBody());
verify(measureSetService, times(1)).deleteCmsId(anyString(), anyInt());
}

@Test
void updateMeasureSuccessfullyLogDeleted() {
ArgumentCaptor<Measure> saveMeasureArgCaptor = ArgumentCaptor.forClass(Measure.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package cms.gov.madie.measure.services;

import cms.gov.madie.measure.exceptions.InvalidIdException;
import cms.gov.madie.measure.exceptions.InvalidRequestException;
import cms.gov.madie.measure.exceptions.ResourceNotFoundException;
import cms.gov.madie.measure.repositories.GeneratorRepository;
import cms.gov.madie.measure.repositories.MeasureRepository;
import cms.gov.madie.measure.repositories.MeasureSetRepository;
import gov.cms.madie.models.access.AclOperation;
import gov.cms.madie.models.access.AclSpecification;
import gov.cms.madie.models.access.RoleEnum;
import gov.cms.madie.models.common.ActionType;
import gov.cms.madie.models.common.ModelType;
import gov.cms.madie.models.measure.Measure;
import gov.cms.madie.models.measure.MeasureSet;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -22,14 +25,14 @@
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
public class MeasureSetServiceTest {

@InjectMocks private MeasureSetService measureSetService;
@Mock MeasureRepository measureRepository;
@Mock MeasureSetRepository measureSetRepository;
@Mock GeneratorRepository generatorRepository;
@Mock private ActionLogService actionLogService;
Expand Down Expand Up @@ -256,4 +259,168 @@ public void testCreateCmsIdWhenCmsIdAlreadyExistsInMeasureSet() {
verify(measureSetRepository, times(1)).findByMeasureSetId(anyString());
verify(measureSetRepository, times(0)).save(any(MeasureSet.class));
}

@Test
public void testDeleteCmsId() {
Integer cmsId = 1;
Measure measure =
Measure.builder()
.model(ModelType.QI_CORE.getValue())
.measureSetId("measureSetId1")
.build();

List<Measure> measures = Collections.singletonList(measure);
MeasureSet measureSet = MeasureSet.builder().measureSetId("1").cmsId(1).build();
String measureId = "measureId";

when(measureRepository.findById(anyString())).thenReturn(Optional.of( measure));
when(measureSetRepository.findByMeasureSetId(anyString())).thenReturn(Optional.of(measureSet));
when(measureRepository.findAllByMeasureSetIdAndActive(anyString(), anyBoolean())).thenReturn(measures);
when(measureSetRepository.save(any(MeasureSet.class))).thenReturn(measureSet);

String responseBody = measureSetService.deleteCmsId(measureId, cmsId);

assertEquals(responseBody, String.format("CMS id of %s was deleted successfully from measure set with measure set id of %s", cmsId, measure.getMeasureSetId()));
verify(measureRepository, times(1)).findById(anyString());
verify(measureSetRepository, times(1)).findByMeasureSetId(anyString());
verify(measureRepository, times(1)).findAllByMeasureSetIdAndActive(anyString(), anyBoolean());
verify(measureSetRepository, times(1)).save(any(MeasureSet.class));
}

@Test
public void testDeleteCmsIdWhenMeasureWithMeasureIdIsNotFound() {
String measureId = "measureId";

when(measureRepository.findById(anyString())).thenReturn(Optional.empty());

Exception ex =
assertThrows(
ResourceNotFoundException.class,
() -> measureSetService.deleteCmsId(measureId, 1));

assertTrue(
ex.getMessage()
.contains(String.format("No measure exists with measure id of %s", measureId)));
verify(measureRepository, times(1)).findById(anyString());
verify(measureSetRepository, times(0)).save(any(MeasureSet.class));
verify(measureSetRepository, times(0)).save(any(MeasureSet.class));
}

@Test
public void testDeleteCmsIdWhenMeasureSetIsNotFound() {
Measure measure =
Measure.builder()
.model(ModelType.QI_CORE.getValue())
.measureSetId("measureSetId")
.build();

String measureId = "measureId";

when(measureRepository.findById(anyString())).thenReturn(Optional.of( measure));
when(measureSetRepository.findByMeasureSetId(anyString())).thenReturn(Optional.empty());

Exception ex =
assertThrows(
ResourceNotFoundException.class,
() -> measureSetService.deleteCmsId(measureId, 1));

assertTrue(
ex.getMessage()
.contains(String.format("No measure set exists for measure with measure set id of %s", measure.getMeasureSetId())));
verify(measureRepository, times(1)).findById(anyString());
verify(measureSetRepository, times(1)).findByMeasureSetId(anyString());
verify(measureSetRepository, times(0)).save(any(MeasureSet.class));
}

@Test
public void testDeleteCmsIdWhenCmsIdIsNotFoundInMeasureSet() {
Integer cmsId = 1;
Measure measure =
Measure.builder()
.model(ModelType.QI_CORE.getValue())
.measureSetId("measureSetId")
.build();

MeasureSet measureSet = MeasureSet.builder().measureSetId("1").build();
String measureId = "measureId";

when(measureRepository.findById(anyString())).thenReturn(Optional.of( measure));
when(measureSetRepository.findByMeasureSetId(anyString())).thenReturn(Optional.of(measureSet));

Exception ex =
assertThrows(
ResourceNotFoundException.class,
() -> measureSetService.deleteCmsId(measureId, cmsId));

assertTrue(
ex.getMessage()
.contains(String.format("No CMS id of %s exists to be deleted within measure set with measure set id of %s", cmsId, measure.getMeasureSetId())));
verify(measureRepository, times(1)).findById(anyString());
verify(measureSetRepository, times(1)).findByMeasureSetId(anyString());
verify(measureSetRepository, times(0)).save(any(MeasureSet.class));
}

@Test
public void testDeleteCmsIdWhenCmsIdToDeleteDoesNotMatchCmsIdInMeasureSet() {
Integer cmsId = 1;
Measure measure =
Measure.builder()
.model(ModelType.QI_CORE.getValue())
.measureSetId("measureSetId")
.build();

MeasureSet measureSet = MeasureSet.builder().measureSetId("1").cmsId(2).build();
String measureId = "measureId";

when(measureRepository.findById(anyString())).thenReturn(Optional.of( measure));
when(measureSetRepository.findByMeasureSetId(anyString())).thenReturn(Optional.of(measureSet));

Exception ex =
assertThrows(
InvalidIdException.class,
() -> measureSetService.deleteCmsId(measureId, cmsId));

assertTrue(
ex.getMessage()
.contains(String.format("CMS id of %s passed in does not match CMS id of %s within measure set with measure set id of %s", cmsId, measureSet.getCmsId(), measure.getMeasureSetId())));
verify(measureRepository, times(1)).findById(anyString());
verify(measureSetRepository, times(1)).findByMeasureSetId(anyString());
verify(measureSetRepository, times(0)).save(any(MeasureSet.class));
}
@Test
public void testDeleteCmsIdWhenMeasureHasMultipleVersions() {
Integer cmsId = 1;
Measure measure1 =
Measure.builder()
.model(ModelType.QI_CORE.getValue())
.measureSetId("measureSetId1")
.build();

Measure measure2 =
Measure.builder()
.model(ModelType.QI_CORE.getValue())
.measureSetId("measureSetId2")
.build();

List<Measure> measures = Arrays.asList(measure1, measure2);
MeasureSet measureSet = MeasureSet.builder().measureSetId("1").cmsId(1).build();
String measureId = "measureId";

when(measureRepository.findById(anyString())).thenReturn(Optional.of( measure1));
when(measureSetRepository.findByMeasureSetId(anyString())).thenReturn(Optional.of(measureSet));
when(measureRepository.findAllByMeasureSetIdAndActive(anyString(), anyBoolean())).thenReturn(measures);

Exception ex =
assertThrows(
InvalidRequestException.class,
() -> measureSetService.deleteCmsId(measureId, cmsId));

assertTrue(
ex.getMessage()
.contains(String.format(String.format("Measure set with measure set id of %s contains more than 1 measure. Cannot delete CMS id when measure set has more than 1 version of measure.", measure1.getMeasureSetId()))));
verify(measureRepository, times(1)).findById(anyString());
verify(measureSetRepository, times(1)).findByMeasureSetId(anyString());
verify(measureRepository, times(1)).findAllByMeasureSetIdAndActive(anyString(), anyBoolean());
verify(measureSetRepository, times(0)).save(any(MeasureSet.class));
}
}
Loading