Skip to content

Commit

Permalink
Merge branch 'develop' into MAT-7083
Browse files Browse the repository at this point in the history
  • Loading branch information
ethankaplan authored Sep 16, 2024
2 parents 65d8e3e + 2fcee87 commit a7447f2
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package cms.gov.madie.measure.config;

import cms.gov.madie.measure.repositories.MeasureRepository;
import gov.cms.madie.models.common.ModelType;
import gov.cms.madie.models.measure.Measure;
import io.mongock.api.annotations.ChangeUnit;
import io.mongock.api.annotations.Execution;
import io.mongock.api.annotations.RollbackExecution;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

@Getter
@Slf4j
@ChangeUnit(id = "remove_qicore_measure_group_stratifications", order = "1", author = "madie_dev")
public class RemoveQICoreMeasureGroupStratificationsChangeUnit {

@Setter private List<Measure> tempMeasures;

@Execution
public void removeQICoreMeasureGroupStratifications(MeasureRepository measureRepository)
throws Exception {
log.info("Removing legacy QI-Core Stratifications.()");

// add all QICore to a list and blank strats
List<Measure> measureList =
new ArrayList<>(measureRepository.findAllByModel(ModelType.QI_CORE.getValue()));
measureList.addAll(measureRepository.findAllByModel(ModelType.QI_CORE_6_0_0.getValue()));

log.info("Modifying [{}] QI-Core measures", measureList.size());

tempMeasures = new ArrayList<>();

measureList.forEach(
measure -> {
if (CollectionUtils.isEmpty(measure.getGroups())) {
return;
}

Measure modifiedMeasure =
measure.toBuilder()
.groups(
measure.getGroups().stream()
.map(
group -> group.toBuilder().stratifications(new ArrayList<>()).build())
.toList())
.build();

tempMeasures.add(modifiedMeasure);
measureRepository.save(modifiedMeasure);
});
}

@RollbackExecution
public void rollbackExecution(MeasureRepository measureRepository) throws Exception {
log.debug("Entering rollbackExecution() ");
if (CollectionUtils.isNotEmpty(tempMeasures)) {
tempMeasures.forEach(measureRepository::save);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,17 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import cms.gov.madie.measure.exceptions.InvalidGroupException;
import gov.cms.madie.models.measure.Group;
import org.springframework.util.CollectionUtils;

@Slf4j
@Service(ServiceConstants.QICORE_VALIDATOR)
public class QiCoreModelValidator extends ModelValidator {

// Groups no longer get validated based on association. Can have 0 to many
@Override
public void validateGroupAssociations(Group group) {
boolean isNotAssociated;

isNotAssociated =
group.getStratifications().stream().anyMatch(map -> map.getAssociation() == null);

if (isNotAssociated) {
throw new InvalidGroupException(
"QI-Core group stratifications should be associated to a valid population type.");
}
log.info("do nothing");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package cms.gov.madie.measure.config;

import cms.gov.madie.measure.repositories.MeasureRepository;
import gov.cms.madie.models.common.ModelType;
import gov.cms.madie.models.measure.Group;
import gov.cms.madie.models.measure.Measure;
import gov.cms.madie.models.measure.Stratification;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;

public class RemoveQICoreMeasureGroupStratificationsChangeUnitTest {

@Mock private MeasureRepository measureRepository;

@InjectMocks
private RemoveQICoreMeasureGroupStratificationsChangeUnit
removeQICoreMeasureGroupStratificationsChangeUnit;

private List<Measure> mockMeasures;

@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);

// Create mock measures for QI-Core v4.1.1 and v6.0.0
Stratification stratification =
Stratification.builder().id(UUID.randomUUID().toString()).build();

Group groupWithStratifications =
Group.builder().stratifications(List.of(stratification)).build();

Measure measureWithStratifications =
Measure.builder()
.id(UUID.randomUUID().toString())
.model(ModelType.QI_CORE.getValue())
.groups(List.of(groupWithStratifications))
.active(true)
.build();

Measure measureWithEmptyStratifications =
Measure.builder()
.id(UUID.randomUUID().toString())
.model(ModelType.QI_CORE_6_0_0.getValue())
.groups(List.of(groupWithStratifications))
.active(true)
.build();

mockMeasures = new ArrayList<>();
mockMeasures.add(measureWithStratifications);
mockMeasures.add(measureWithEmptyStratifications);
}

@Test
public void testRemoveQICoreMeasureGroupStratifications() throws Exception {
when(measureRepository.findAllByModel(ModelType.QI_CORE.getValue()))
.thenReturn(Collections.singletonList(mockMeasures.get(0)));
when(measureRepository.findAllByModel(ModelType.QI_CORE_6_0_0.getValue()))
.thenReturn(Collections.singletonList(mockMeasures.get(1)));

removeQICoreMeasureGroupStratificationsChangeUnit.removeQICoreMeasureGroupStratifications(
measureRepository);

verify(measureRepository, times(2)).save(any(Measure.class));
assertEquals(2, removeQICoreMeasureGroupStratificationsChangeUnit.getTempMeasures().size());
removeQICoreMeasureGroupStratificationsChangeUnit
.getTempMeasures()
.forEach(
measure ->
measure
.getGroups()
.forEach(group -> assertEquals(0, group.getStratifications().size())));
}

@Test
public void testRemoveQICoreMeasureGroupStratificationsNoChange() throws Exception {
Measure measureWithoutGroups =
Measure.builder()
.id(UUID.randomUUID().toString())
.model(ModelType.QI_CORE.getValue())
.groups(new ArrayList<>())
.active(true)
.build();

when(measureRepository.findAllByModel(ModelType.QI_CORE.getValue()))
.thenReturn(Collections.singletonList(measureWithoutGroups));
when(measureRepository.findAllByModel(ModelType.QI_CORE_6_0_0.getValue()))
.thenReturn(Collections.emptyList());

removeQICoreMeasureGroupStratificationsChangeUnit.removeQICoreMeasureGroupStratifications(
measureRepository);

verify(measureRepository, never()).save(any(Measure.class));
assertEquals(0, removeQICoreMeasureGroupStratificationsChangeUnit.getTempMeasures().size());
}

@Test
public void testRollbackExecution() throws Exception {
// Prepare mock measures for rollback
when(measureRepository.findAllByModel(anyString())).thenReturn(mockMeasures);

removeQICoreMeasureGroupStratificationsChangeUnit.setTempMeasures(mockMeasures);

removeQICoreMeasureGroupStratificationsChangeUnit.rollbackExecution(measureRepository);

verify(measureRepository, times(2)).save(any(Measure.class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,9 @@ void useQicoreModelValidatorTestHasInvalidAssociation() {
assertTrue(validator instanceof QiCoreModelValidator);
try {
validator.validateGroupAssociations(group);
fail("Should fail because QICore strat association can't be null");
// Should no longer throw error
} catch (InvalidGroupException e) {
assertEquals(
"QI-Core group stratifications should be associated to a valid population type.",
e.getMessage());
fail("Should not fail because QICore strat association can be null");
}
}

Expand Down

0 comments on commit a7447f2

Please sign in to comment.