From f1c30ac1dee8377bdc599eb618656f89c8dbe276 Mon Sep 17 00:00:00 2001 From: "kai [they]" Date: Mon, 10 Jun 2024 17:17:57 -0700 Subject: [PATCH] [AB2D-6149] increase `ab2d-filters` test coverage (#388) * linter autofixes * git restore * linter * restore to main * cleanups * more EOBLoadUtilitiesTest * testReaderEOB * docs * docs * EobUtilsTest * testInvokeGetMethod * add more test data * remove npe check * cleanup --- .../cms/ab2d/filter/EOBLoadUtilitiesTest.java | 113 +++++++++++++----- .../gov/cms/ab2d/filter/EobUtilsTest.java | 57 +++++++++ 2 files changed, 137 insertions(+), 33 deletions(-) create mode 100644 ab2d-filters/src/test/java/gov/cms/ab2d/filter/EobUtilsTest.java diff --git a/ab2d-filters/src/test/java/gov/cms/ab2d/filter/EOBLoadUtilitiesTest.java b/ab2d-filters/src/test/java/gov/cms/ab2d/filter/EOBLoadUtilitiesTest.java index fc8ae1cf..cf84fe29 100644 --- a/ab2d-filters/src/test/java/gov/cms/ab2d/filter/EOBLoadUtilitiesTest.java +++ b/ab2d-filters/src/test/java/gov/cms/ab2d/filter/EOBLoadUtilitiesTest.java @@ -1,6 +1,9 @@ package gov.cms.ab2d.filter; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.FhirVersionEnum; +import ca.uhn.fhir.model.api.IFhirVersion; + import org.hl7.fhir.dstu3.model.ExplanationOfBenefit; import org.hl7.fhir.instance.model.api.IBaseResource; import org.junit.jupiter.api.Test; @@ -19,18 +22,34 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -public class EOBLoadUtilitiesTest { +class EOBLoadUtilitiesTest { private static IBaseResource eobC; private static IBaseResource eobS; - private static FhirContext context = FhirContext.forDstu3(); static { eobC = ExplanationOfBenefitTrimmerSTU3.getBenefit(EOBLoadUtilities.getSTU3EOBFromFileInClassPath("eobdata/EOB-for-Carrier-Claims.json")); eobS = ExplanationOfBenefitTrimmerSTU3.getBenefit(EOBLoadUtilities.getSTU3EOBFromFileInClassPath("eobdata/EOB-for-SNF-Claims.json")); } + // Our mock FhirVersion class is used to test the switch case statement inside of EOBLoadUtilities.getEOBFromReader. + // We need to extend from a FhirVersionEnum that is actually on our classpath, so we extend from the R4 version. + // We then override the getVersion method to return a version that is not supported by the switch case statement. + // Choosing `FhirVersionEnum.R5` as the version to return here was an arbitrary choice. If we ever add support + // for R5, this test will need to be updated. + class MockFhirVersion extends org.hl7.fhir.r4.hapi.ctx.FhirR4{ + public FhirVersionEnum getVersion() { + return FhirVersionEnum.R5; + } + } + class MockFhirContext extends FhirContext { + @Override + public IFhirVersion getVersion() { + return new MockFhirVersion(); + } + } + @Test - public void testType() { + void testType() { ExplanationOfBenefit eobCarrier = (ExplanationOfBenefit) eobC; List coding = eobCarrier.getType().getCoding(); assertEquals(4, coding.size()); @@ -42,13 +61,13 @@ public void testType() { } @Test - public void testResourceType() { + void testResourceType() { ExplanationOfBenefit eobCarrier = (ExplanationOfBenefit) eobC; assertEquals(org.hl7.fhir.dstu3.model.ResourceType.ExplanationOfBenefit, eobCarrier.getResourceType()); } @Test - public void testDiagnosis() { + void testDiagnosis() { ExplanationOfBenefit eobCarrier = (ExplanationOfBenefit) eobC; List diagnoses = eobCarrier.getDiagnosis(); assertNotNull(diagnoses); @@ -61,7 +80,7 @@ public void testDiagnosis() { } @Test - public void testProcedure() throws ParseException { + void testProcedure() throws ParseException { ExplanationOfBenefit eobSNF = (ExplanationOfBenefit) eobS; List procedures = eobSNF.getProcedure(); assertNotNull(procedures); @@ -77,7 +96,7 @@ public void testProcedure() throws ParseException { } @Test - public void testProvider() { + void testProvider() { ExplanationOfBenefit eobSNF = (ExplanationOfBenefit) eobS; org.hl7.fhir.dstu3.model.Reference ref = eobSNF.getProvider(); assertNotNull(ref); @@ -87,7 +106,7 @@ public void testProvider() { } @Test - public void testOrganization() { + void testOrganization() { ExplanationOfBenefit eobSNF = (ExplanationOfBenefit) eobS; org.hl7.fhir.dstu3.model.Reference ref = eobSNF.getOrganization(); assertNotNull(ref); @@ -97,7 +116,7 @@ public void testOrganization() { } @Test - public void testFacility() { + void testFacility() { ExplanationOfBenefit eobSNF = (ExplanationOfBenefit) eobS; org.hl7.fhir.dstu3.model.Reference ref = eobSNF.getFacility(); assertNotNull(ref); @@ -107,11 +126,11 @@ public void testFacility() { } @Test - public void testIdentifier() { + void testIdentifier() { ExplanationOfBenefit eobSNF = (ExplanationOfBenefit) eobS; List ids = eobSNF.getIdentifier(); assertNotNull(ids); - assertEquals(ids.size(), 2); + assertEquals(2, ids.size()); org.hl7.fhir.dstu3.model.Identifier id = ids.stream() .filter(c -> c.getValue().equalsIgnoreCase("900")) .findFirst().orElse(null); @@ -120,11 +139,11 @@ public void testIdentifier() { } @Test - public void testCareTeam() { + void testCareTeam() { ExplanationOfBenefit eobSNF = (ExplanationOfBenefit) eobS; List careTeamComponents = eobSNF.getCareTeam(); assertNotNull(careTeamComponents); - assertEquals(careTeamComponents.size(), 4); + assertEquals(4, careTeamComponents.size()); ExplanationOfBenefit.CareTeamComponent comp = careTeamComponents.stream() .filter(c -> c.getSequence() == 2).findFirst().orElse(null); assertNotNull(comp); @@ -136,11 +155,11 @@ public void testCareTeam() { } @Test - public void testItems() throws ParseException { + void testItems() throws ParseException { ExplanationOfBenefit eobCarrier = (ExplanationOfBenefit) eobC; List components = eobCarrier.getItem(); assertNotNull(components); - assertEquals(components.size(), 1); + assertEquals(1, components.size()); assertEquals(2, components.get(0).getCareTeamLinkId().get(0).getValue()); assertEquals("1", components.get(0).getQuantity().getValue().toString()); assertEquals(6, components.get(0).getSequence()); @@ -167,27 +186,55 @@ public void testItems() throws ParseException { @Test void testReaderEOB() throws IOException { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - try (InputStream inputStream = classLoader.getResourceAsStream("eobdata/EOB-for-Carrier-Claims.json")) { - try (Reader reader = new java.io.InputStreamReader(inputStream, StandardCharsets.UTF_8)) { - assertNull(EOBLoadUtilities.getEOBFromReader((Reader) null, context)); - // STU3 - ExplanationOfBenefit benefit = (ExplanationOfBenefit) EOBLoadUtilities.getEOBFromReader(reader, context); - assertNotNull(benefit); - assertEquals("Patient/-199900000022040", benefit.getPatient().getReference()); - } catch (Exception e) { - e.printStackTrace(); - } - } catch (Exception ex) { - ex.printStackTrace(); - } + + // DSTU3 + InputStream inputStream = classLoader.getResourceAsStream("eobdata/EOB-for-Carrier-Claims.json"); + Reader reader = new java.io.InputStreamReader(inputStream, StandardCharsets.UTF_8); + assertNull(EOBLoadUtilities.getEOBFromReader((Reader) null, FhirContext.forDstu3())); + ExplanationOfBenefit benefit = (ExplanationOfBenefit) EOBLoadUtilities.getEOBFromReader(reader, FhirContext.forDstu3()); + assertNotNull(benefit); + assertEquals("Patient/-199900000022040", benefit.getPatient().getReference()); + + // R4 + inputStream = classLoader.getResourceAsStream("eobdata/EOB-for-Carrier-R4.json"); + reader = new java.io.InputStreamReader(inputStream, StandardCharsets.UTF_8); + assertNull(EOBLoadUtilities.getEOBFromReader((Reader) null, FhirContext.forR4())); + org.hl7.fhir.r4.model.ExplanationOfBenefit benefitR4 = (org.hl7.fhir.r4.model.ExplanationOfBenefit) EOBLoadUtilities.getEOBFromReader(reader, FhirContext.forR4()); + assertNotNull(benefitR4); + assertEquals("Patient/567834", benefitR4.getPatient().getReference()); + + // invalid context + inputStream = classLoader.getResourceAsStream("eobdata/EOB-for-Carrier-R4.json"); + reader = new java.io.InputStreamReader(inputStream, StandardCharsets.UTF_8); + assertNull(EOBLoadUtilities.getEOBFromReader(null, new MockFhirContext())); + assertNull(EOBLoadUtilities.getEOBFromReader(reader, new MockFhirContext())); + } + + @Test + void testGetSTU3EOB() { + // null tests + assertNull(EOBLoadUtilities.getSTU3EOBFromFileInClassPath("")); + assertNull(EOBLoadUtilities.getSTU3EOBFromFileInClassPath("does-not-exist.json")); + + // not null tests + var jsonParser = FhirContext.forDstu3().newJsonParser(); + org.hl7.fhir.dstu3.model.ExplanationOfBenefit eob = EOBLoadUtilities.getSTU3EOBFromFileInClassPath("eobdata/EOB-for-Carrier-Claims.json"); + org.hl7.fhir.dstu3.model.ExplanationOfBenefit eobNew = (org.hl7.fhir.dstu3.model.ExplanationOfBenefit) ExplanationOfBenefitTrimmer.getBenefit((IBaseResource) eob); + String payload = jsonParser.encodeResourceToString(eobNew) + System.lineSeparator(); + assertNotNull(payload); } @Test - void testToJson() { - var jsonParser = context.newJsonParser(); - ExplanationOfBenefit eob = EOBLoadUtilities.getSTU3EOBFromFileInClassPath("eobdata/EOB-for-Carrier-Claims.json"); - ExplanationOfBenefit eobNew = (ExplanationOfBenefit) ExplanationOfBenefitTrimmerSTU3.getBenefit((IBaseResource) eob); + void testGetR4EOB() { + // null tests + assertNull(EOBLoadUtilities.getR4EOBFromFileInClassPath("")); + assertNull(EOBLoadUtilities.getR4EOBFromFileInClassPath("does-not-exist.json")); + + // not null tests + var jsonParser = FhirContext.forR4().newJsonParser(); + org.hl7.fhir.r4.model.ExplanationOfBenefit eob = EOBLoadUtilities.getR4EOBFromFileInClassPath("eobdata/EOB-for-Carrier-R4.json"); + org.hl7.fhir.r4.model.ExplanationOfBenefit eobNew = (org.hl7.fhir.r4.model.ExplanationOfBenefit) ExplanationOfBenefitTrimmer.getBenefit((IBaseResource) eob); String payload = jsonParser.encodeResourceToString(eobNew) + System.lineSeparator(); assertNotNull(payload); } -} \ No newline at end of file +} diff --git a/ab2d-filters/src/test/java/gov/cms/ab2d/filter/EobUtilsTest.java b/ab2d-filters/src/test/java/gov/cms/ab2d/filter/EobUtilsTest.java new file mode 100644 index 00000000..ce20fa0e --- /dev/null +++ b/ab2d-filters/src/test/java/gov/cms/ab2d/filter/EobUtilsTest.java @@ -0,0 +1,57 @@ +package gov.cms.ab2d.filter; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.hl7.fhir.dstu3.model.ExplanationOfBenefit; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.junit.jupiter.api.Test; + +class EobUtilsTest { + + class MockEOB extends ExplanationOfBenefit { + @Override + public String fhirType() { + return "mock"; + } + } + + IBaseResource eob1 = ExplanationOfBenefitTrimmerSTU3.getBenefit(EOBLoadUtilities.getSTU3EOBFromFileInClassPath("eobdata/EOB-for-Part-D-Claims.json")); + IBaseResource eob2 = ExplanationOfBenefitTrimmerSTU3.getBenefit(EOBLoadUtilities.getSTU3EOBFromFileInClassPath("eobdata/EOB-for-Carrier-Claims.json")); + IBaseResource eob3 = new MockEOB(); + + @Test + void testInvokeGetMethod() { + assertNotNull(EobUtils.invokeGetMethod(eob1, "getBillablePeriod")); + assertNotNull(EobUtils.invokeGetMethod(eob2, "getBillablePeriod")); + + assertNull(EobUtils.invokeGetMethod(eob1, "fake")); + assertNull(EobUtils.invokeGetMethod(eob2, "fake")); + } + + @Test + void testGetStartDate() { + assertNull(EobUtils.getStartDate(eob1)); + assertNotNull(EobUtils.getStartDate(eob2)); + assertNull(EobUtils.getStartDate(eob3)); + assertNull(EobUtils.getStartDate((ExplanationOfBenefit) null)); + } + + @Test + void testGetEndDate() { + assertNull(EobUtils.getEndDate(eob1)); + assertNotNull(EobUtils.getEndDate(eob2)); + assertNull(EobUtils.getEndDate(eob3)); + assertNull(EobUtils.getEndDate((ExplanationOfBenefit) null)); + } + + @Test + void testIsPartD() { + assertTrue(EobUtils.isPartD(eob1)); + assertFalse(EobUtils.isPartD(eob2)); + assertFalse(EobUtils.isPartD(eob3)); + assertFalse(EobUtils.isPartD((ExplanationOfBenefit) null)); + } +}