Skip to content

Commit

Permalink
Merge pull request #235 from MeasureAuthoringTool/feature/mat-7156-71…
Browse files Browse the repository at this point in the history
…62-shift-qicore-test-case-dates

[MAT-7156, MAT-7162] Shift QICore Test Case Dates
  • Loading branch information
jkotanchik-SB authored Aug 8, 2024
2 parents 56e629d + 4343b28 commit d9f32f0
Show file tree
Hide file tree
Showing 14 changed files with 389 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package gov.cms.madie.madiefhirservice.resources;

import gov.cms.madie.madiefhirservice.services.TestCaseDateShifterService;
import gov.cms.madie.models.measure.TestCase;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.List;

import static java.util.stream.Collectors.joining;

@Slf4j
@RestController
@RequestMapping(path = "/fhir/")
@Tag(name = "Test-Case-Controller", description = "API for manipulating FHIR Test Cases")
@RequiredArgsConstructor
public class TestCaseController {
private final TestCaseDateShifterService testCaseDateShifterService;

@PutMapping("/test-cases/shift-dates")
public ResponseEntity<List<TestCase>> shiftTestCasesDates(
Principal principal,
@RequestBody List<TestCase> testCases,
@RequestParam(name = "shifted", defaultValue = "0") int shifted) {
log.info(
"User [{}] requested date shift for test cases [{}] of [{}] years",
principal.getName(),
testCases.stream().map(TestCase::getId).collect(joining(", ")),
shifted);
return ResponseEntity.ok(testCaseDateShifterService.shiftDates(testCases, shifted));
}

@PutMapping("/test-case/shift-dates")
public ResponseEntity<TestCase> shiftTestCaseDates(
Principal principal,
@RequestBody TestCase testCase,
@RequestParam(name = "shifted", defaultValue = "0") int shifted) {
log.info(
"User [{}] requested date shift for test case [{}] of [{}] years",
principal.getName(),
testCase.getId(),
shifted);
return ResponseEntity.ok(testCaseDateShifterService.shiftDates(testCase, shifted));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package gov.cms.madie.madiefhirservice.services;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.StrictErrorHandler;
import gov.cms.madie.models.measure.TestCase;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.r4.model.Base;
import org.hl7.fhir.r4.model.BaseDateTimeType;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Property;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;

@Slf4j
@Service
@AllArgsConstructor
public class TestCaseDateShifterService {

private FhirContext fhirContext;

public TestCase shiftDates(TestCase testCase, int shifted) {
if (testCase == null) {
return null;
}
List<TestCase> shiftedTestCases = shiftDates(List.of(testCase), shifted);
if (CollectionUtils.isNotEmpty(shiftedTestCases) && shiftedTestCases.size() == 1) {
return shiftedTestCases.get(0);
}
return null;
}

public List<TestCase> shiftDates(List<TestCase> testCases, int shifted) {
if (CollectionUtils.isEmpty(testCases)) {
return Collections.emptyList();
}
List<TestCase> shiftedTestCases = new ArrayList<>();

IParser parser = getIParser();
for (TestCase testCase : new ArrayList<>(testCases)) {
try {
if (StringUtils.isBlank(testCase.getJson())) {
throw new DataFormatException("Empty test case");
}
// convert test case json to bundle
Bundle bundle = parser.parseResource(Bundle.class, testCase.getJson());
// update the test case dates
bundle.getEntry().forEach(entry -> shiftDates(entry.getResource(), shifted));
// convert the updated bundle to string and assign back to test case.
String json = parser.encodeResourceToString(bundle);
testCase.setJson(json);
shiftedTestCases.add(testCase);
} catch (DataFormatException dfe) {
log.info("skipping the test case with id [{}] as it is empty or invalid", testCase.getId());
}
}
return shiftedTestCases;
}

void shiftDates(Base baseResource, int shifted) {
List<Field> fields = new LinkedList<>();
getAllFields(fields, baseResource.getClass());
for (Field field : fields) {
Property property = baseResource.getNamedProperty(field.getName());
if (property != null) {
List<Base> values = property.getValues();
for (Base value : values) {
if (value.isPrimitive()) {
if (value.isDateTime()) {
BaseDateTimeType dateType = (BaseDateTimeType) value;
dateType.add(1, shifted);
}
} else {
shiftDates(value, shifted);
}
}
}
}
}

private static void getAllFields(List<Field> fields, Class<?> type) {
fields.addAll(List.of(type.getDeclaredFields()));
if (type.getSuperclass() != null) {
getAllFields(fields, type.getSuperclass());
}
}

IParser getIParser() {
return fhirContext
.newJsonParser()
.setParserErrorHandler(new StrictErrorHandler())
.setPrettyPrint(true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ public class MeasureBundleControllerMvcTest implements ResourceFileUtil {

@Test
public void testGetMeasureBundle() throws Exception {
String madieMeasureJson =
getStringFromTestResource("/measures/SimpleFhirMeasureLib/madie_measure.json");
String madieMeasureJson = getStringFromTestResource("/measures/madie_measure.json");
Bundle testBundle = MeasureTestHelper.createTestMeasureBundle();

when(measureBundleService.createMeasureBundle(
Expand All @@ -82,8 +81,7 @@ public void testGetMeasureBundle() throws Exception {

@Test
public void testGetMeasureBundleXml() throws Exception {
String madieMeasureJson =
getStringFromTestResource("/measures/SimpleFhirMeasureLib/madie_measure.json");
String madieMeasureJson = getStringFromTestResource("/measures/madie_measure.json");
Bundle testBundle = MeasureTestHelper.createTestMeasureBundle();

when(measureBundleService.createMeasureBundle(
Expand All @@ -108,8 +106,7 @@ public void testGetMeasureBundleXml() throws Exception {

@Test
public void testExportMeasure() throws Exception {
String madieMeasureJson =
getStringFromTestResource("/measures/SimpleFhirMeasureLib/madie_measure.json");
String madieMeasureJson = getStringFromTestResource("/measures/madie_measure.json");

MvcResult result =
mockMvc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ class TestCaseBundleControllerMvcTest implements ResourceFileUtil {

@BeforeEach
public void setUp() throws JsonProcessingException {
madieMeasureJson =
getStringFromTestResource("/measures/SimpleFhirMeasureLib/madie_measure.json");
madieMeasureJson = getStringFromTestResource("/measures/madie_measure.json");
String testCaseJson = getStringFromTestResource("/testCaseBundles/validTestCase.json");
testCaseBundle = FhirContext.forR4().newJsonParser().parseResource(Bundle.class, testCaseJson);
dto =
Expand Down Expand Up @@ -146,8 +145,7 @@ void getTestCaseExportBundleMultiWithBundleTypeTransaction() throws Exception {
@Test
void getTestCaseExportAllThrowExceptionWhenTestCasesAreNotFoundInMeasure() throws Exception {
var madieMeasureWithNoTestCases =
getStringFromTestResource(
"/measures/SimpleFhirMeasureLib/madie_measure_no_test_cases.json");
getStringFromTestResource("/measures/madie_measure_no_test_cases.json");

ExportDTO dto =
ExportDTO.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,15 @@ public class MeasureBundleServiceTest implements ResourceFileUtil {

@BeforeEach
public void setup() throws JsonProcessingException {
String madieMeasureJson =
getStringFromTestResource("/measures/SimpleFhirMeasureLib/madie_measure.json");
String madieMeasureJson = getStringFromTestResource("/measures/madie_measure.json");
madieMeasure = MeasureTestHelper.createMadieMeasureFromJson(madieMeasureJson);

String fhirMeasureJson =
getStringFromTestResource("/measures/SimpleFhirMeasureLib/fhir_measure.json");
String fhirMeasureJson = getStringFromTestResource("/measures/fhir_measure.json");
measure =
MeasureTestHelper.createFhirResourceFromJson(
fhirMeasureJson, org.hl7.fhir.r4.model.Measure.class);

String fhirLibraryJson =
getStringFromTestResource("/measures/SimpleFhirMeasureLib/fhir_measure_library.json");
String fhirLibraryJson = getStringFromTestResource("/measures/fhir_measure_library.json");
library = MeasureTestHelper.createFhirResourceFromJson(fhirLibraryJson, Library.class);
effectiveDataRequirements =
convertToFhirR5Resource(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,11 @@ public class MeasureTranslatorServiceTest implements ResourceFileUtil {

@BeforeEach
public void setUp() throws JsonProcessingException {
String madieMeasureJson =
getStringFromTestResource("/measures/SimpleFhirMeasureLib/madie_measure.json");
String madieMeasureJson = getStringFromTestResource("/measures/madie_measure.json");
madieMeasure = MeasureTestHelper.createMadieMeasureFromJson(madieMeasureJson);
String madieRatioMeasureJson =
getStringFromTestResource("/measures/SimpleFhirMeasureLib/madie_ratio_measure.json");
String madieRatioMeasureJson = getStringFromTestResource("/measures/madie_ratio_measure.json");
madieRatioMeasure = MeasureTestHelper.createMadieMeasureFromJson(madieRatioMeasureJson);
String cvMeasureJson =
getStringFromTestResource("/measures/SimpleFhirMeasureLib/madie_cv_measure.json");
String cvMeasureJson = getStringFromTestResource("/measures/madie_cv_measure.json");
madieCVMeasure = MeasureTestHelper.createMadieMeasureFromJson(cvMeasureJson);
ReflectionTestUtils.setField(fhirResourceHelpers, "madieUrl", "madie.cms.gov");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ public void setUp() throws JsonProcessingException {
.newJsonParser()
.setParserErrorHandler(new StrictErrorHandler())
.setPrettyPrint(true);
String madieMeasureJson =
getStringFromTestResource("/measures/SimpleFhirMeasureLib/madie_measure.json");
String madieMeasureJson = getStringFromTestResource("/measures/madie_measure.json");
madieMeasure = MeasureTestHelper.createMadieMeasureFromJson(madieMeasureJson);
testCase = Objects.requireNonNull(madieMeasure).getTestCases().get(0);
exportDTO = ExportDTO.builder().bundleType(BundleType.TRANSACTION).build();
Expand Down
Loading

0 comments on commit d9f32f0

Please sign in to comment.