Skip to content

Commit

Permalink
Merge pull request #746 from MeasureAuthoringTool/feature/MAT-7924-qd…
Browse files Browse the repository at this point in the history
…m-improvementnotation-mongock

MAT-7924: add mongock script to migrate non-standard QDM improvement …
  • Loading branch information
nmorasb authored Nov 19, 2024
2 parents fc2bbdc + f585406 commit 94d9000
Show file tree
Hide file tree
Showing 2 changed files with 236 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
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 gov.cms.madie.models.measure.QdmMeasure;
import gov.cms.madie.models.validators.ImprovementNotationValidator;
import io.mongock.api.annotations.ChangeUnit;
import io.mongock.api.annotations.Execution;
import io.mongock.api.annotations.RollbackExecution;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@ChangeUnit(id = "qdm_improvement_notation_standardizer", order = "1", author = "madie_dev")
public class QdmImprovementNotationStandardizationChangeUnit {

@Execution
public void standardizeQdmImprovementNotationField(MeasureRepository measureRepository) {
log.info("QdmImprovementNotationStandardizationChangeUnit started!");
List<Measure> qdmMeasures = measureRepository.findAllByModel(ModelType.QDM_5_6.getValue());
ImprovementNotationValidator validator = new ImprovementNotationValidator();
AtomicInteger counter = new AtomicInteger(0);
if (CollectionUtils.isNotEmpty(qdmMeasures)) {
qdmMeasures.stream()
.filter(
(measure) ->
measure.getMeasureMetaData().isDraft()
&& measure.isActive()
&& StringUtils.isNotBlank(((QdmMeasure) measure).getImprovementNotation())
&& !validator.isValid((QdmMeasure) measure, null))
.forEach(
measure -> {
QdmMeasure qdmMeasure = (QdmMeasure) measure;
log.info(
"Updating draft measure [{}] with invalid improvement notation: {} ",
measure.getId(),
((QdmMeasure) measure).getImprovementNotation());
counter.incrementAndGet();
qdmMeasure.setImprovementNotationDescription(qdmMeasure.getImprovementNotation());
qdmMeasure.setImprovementNotation("Other");
measureRepository.save(measure);
});
}
log.info(
"QdmImprovementNotationStandardizationChangeUnit completed, updated {} measures", counter);
}

@RollbackExecution
public void rollbackExecution(MongoTemplate mongoTemplate) {
// Not able to rollback - not able to differentiate between update
// measures and measures that already had Other + description
// Also, rolling back means these measures will be broken again
log.error("Error detected, but cannot roll back QdmImprovementNotationStandardizationChangeUnit!");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
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.common.Version;
import gov.cms.madie.models.measure.Measure;
import gov.cms.madie.models.measure.MeasureMetaData;
import gov.cms.madie.models.measure.QdmMeasure;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

@ExtendWith(MockitoExtension.class)
class QdmImprovementNotationStandardizationChangeUnitTest {

@Mock private MeasureRepository measureRepository;

@InjectMocks private QdmImprovementNotationStandardizationChangeUnit changeUnit;

@Captor private ArgumentCaptor<Measure> measureArgumentCaptor;

private QdmMeasure qdmDraftMeasureWithNoImprovementNotation;
private QdmMeasure qdmDraftMeasureWithBlankImprovementNotation;
private QdmMeasure qdmDraftMeasureWithInvalidImprovementNotation;
private QdmMeasure qdmDraftMeasureWithOtherImprovementNotation;
private QdmMeasure qdmDraftMeasureWithValidIncreaseImprovementNotation;
private QdmMeasure qdmDraftMeasureWithValidDecreaseImprovementNotation;

private QdmMeasure qdmVersionedMeasureWithInvalidImprovementNotation;

private QdmMeasure qdmInactiveDraftMeasureWithInvalidImprovementNotation;

@BeforeEach
void setup() {
qdmDraftMeasureWithNoImprovementNotation =
QdmMeasure.builder()
.model(ModelType.QDM_5_6.getValue())
.active(true)
.measureMetaData(MeasureMetaData.builder().draft(true).build())
.improvementNotation(null)
.build();
qdmDraftMeasureWithBlankImprovementNotation =
QdmMeasure.builder()
.model(ModelType.QDM_5_6.getValue())
.active(true)
.measureMetaData(MeasureMetaData.builder().draft(true).build())
.improvementNotation("")
.build();
qdmDraftMeasureWithInvalidImprovementNotation =
QdmMeasure.builder()
.model(ModelType.QDM_5_6.getValue())
.active(true)
.measureMetaData(MeasureMetaData.builder().draft(true).build())
.improvementNotation("This is definitely an invalid improvement notation!")
.build();
qdmDraftMeasureWithOtherImprovementNotation =
QdmMeasure.builder()
.model(ModelType.QDM_5_6.getValue())
.active(true)
.measureMetaData(MeasureMetaData.builder().draft(true).build())
.improvementNotation("Other")
.improvementNotationDescription("There's some other content here")
.build();
qdmDraftMeasureWithValidIncreaseImprovementNotation =
QdmMeasure.builder()
.model(ModelType.QDM_5_6.getValue())
.active(true)
.measureMetaData(MeasureMetaData.builder().draft(true).build())
.improvementNotation("Increased score indicates improvement")
.build();
qdmDraftMeasureWithValidDecreaseImprovementNotation =
QdmMeasure.builder()
.model(ModelType.QDM_5_6.getValue())
.active(true)
.measureMetaData(MeasureMetaData.builder().draft(true).build())
.improvementNotation("Decreased score indicates improvement")
.build();
qdmVersionedMeasureWithInvalidImprovementNotation =
QdmMeasure.builder()
.model(ModelType.QDM_5_6.getValue())
.active(true)
.version(Version.parse("1.0.000"))
.measureMetaData(MeasureMetaData.builder().draft(false).build())
.improvementNotation("This is definitely an invalid improvement notation!")
.build();
qdmInactiveDraftMeasureWithInvalidImprovementNotation =
QdmMeasure.builder()
.model(ModelType.QDM_5_6.getValue())
.active(false)
.measureMetaData(MeasureMetaData.builder().draft(true).build())
.improvementNotation("This is definitely an invalid improvement notation!")
.build();
}

@Test
void standardizeQdmImprovementNotationFieldExitsForNoMeasures() throws Exception {
// given
when(measureRepository.findAllByModel(anyString())).thenReturn(List.of());

// when
changeUnit.standardizeQdmImprovementNotationField(measureRepository);

// then
verify(measureRepository, never()).save(any());
}

@Test
void standardizeQdmImprovementNotationFieldDoesNothingForNoMatchingMeasures() throws Exception {
// given
when(measureRepository.findAllByModel(anyString()))
.thenReturn(
List.of(
qdmDraftMeasureWithNoImprovementNotation,
qdmDraftMeasureWithBlankImprovementNotation,
qdmDraftMeasureWithOtherImprovementNotation,
qdmDraftMeasureWithValidIncreaseImprovementNotation,
qdmDraftMeasureWithValidDecreaseImprovementNotation,
qdmVersionedMeasureWithInvalidImprovementNotation,
qdmInactiveDraftMeasureWithInvalidImprovementNotation));

// when
changeUnit.standardizeQdmImprovementNotationField(measureRepository);

// then
verify(measureRepository, never()).save(any());
}

@Test
void standardizeQdmImprovementNotationField() {
// given
when(measureRepository.findAllByModel(anyString()))
.thenReturn(
List.of(
qdmDraftMeasureWithNoImprovementNotation,
qdmDraftMeasureWithBlankImprovementNotation,
qdmDraftMeasureWithOtherImprovementNotation,
qdmDraftMeasureWithInvalidImprovementNotation,
qdmDraftMeasureWithValidIncreaseImprovementNotation,
qdmDraftMeasureWithValidDecreaseImprovementNotation,
qdmVersionedMeasureWithInvalidImprovementNotation,
qdmInactiveDraftMeasureWithInvalidImprovementNotation));

// when
changeUnit.standardizeQdmImprovementNotationField(measureRepository);

// then
verify(measureRepository, times(1)).save(measureArgumentCaptor.capture());
Measure updatedMeasure = measureArgumentCaptor.getValue();
assertThat(updatedMeasure, is(notNullValue()));
assertThat(updatedMeasure.getModel(), is(equalTo(ModelType.QDM_5_6.getValue())));
QdmMeasure qdmMeasure = (QdmMeasure) updatedMeasure;
assertThat(qdmMeasure.getImprovementNotation(), is(equalTo("Other")));
assertThat(
qdmMeasure.getImprovementNotationDescription(),
is(equalTo("This is definitely an invalid improvement notation!")));
}
}

0 comments on commit 94d9000

Please sign in to comment.