From c5f7cfdbe5b7f7eb7b779781bbe1247431c82e24 Mon Sep 17 00:00:00 2001 From: Rwolfe-Nava <87499456+Rwolfe-Nava@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:08:45 -0400 Subject: [PATCH] [AB2D-6101] Address Critical Code Smell - Reduce cognitive method compleixty (#403) * update tests and address codesmells * update tests * parameterize generic * bump fhirVersion * update based on review feedback * fix test method name * add setup methods in test to reduce code duplication * remove redundant variables * remove more redundant variables * fix generic so sonar is happy --- .../gov/cms/ab2d/fhir/IdentifierUtils.java | 67 +++--- .../ab2d/fhir/PatientIdentifierUtilsTest.java | 196 +++++++++++++++++- build.gradle | 2 +- 3 files changed, 239 insertions(+), 26 deletions(-) diff --git a/ab2d-fhir/src/main/java/gov/cms/ab2d/fhir/IdentifierUtils.java b/ab2d-fhir/src/main/java/gov/cms/ab2d/fhir/IdentifierUtils.java index a535209c..0731307e 100644 --- a/ab2d-fhir/src/main/java/gov/cms/ab2d/fhir/IdentifierUtils.java +++ b/ab2d-fhir/src/main/java/gov/cms/ab2d/fhir/IdentifierUtils.java @@ -5,6 +5,7 @@ import org.hl7.fhir.instance.model.api.IBaseExtension; import org.hl7.fhir.instance.model.api.ICompositeType; import org.hl7.fhir.instance.model.api.IDomainResource; +import org.hl7.fhir.dstu3.model.Coding; import java.util.ArrayList; import java.util.Date; @@ -206,41 +207,59 @@ private static PatientIdentifier.Currency getCurrencyMbiStandard(ICompositeType return getCurrencyFromTypeCodingExtension(identifier); } - private static PatientIdentifier.Currency getCurrencyFromTypeCodingExtension(ICompositeType identifier) { + public static PatientIdentifier.Currency getCurrencyFromTypeCodingExtension(ICompositeType identifier) { Object type = Versions.invokeGetMethod(identifier, "getType"); - if (type == null) { - return PatientIdentifier.Currency.UNKNOWN; - } - List vals = (List) Versions.invokeGetMethod(type, "getCoding"); - if (vals == null || vals.isEmpty()) { + List vals = (List) Versions.invokeGetMethod(type, "getCoding"); + + if (checkTypeAndCodingNotExists(type, vals)) { return PatientIdentifier.Currency.UNKNOWN; } + Object val = vals.get(0); String codeSystem = (String) Versions.invokeGetMethod(val, GET_SYSTEM); String codeValue = (String) Versions.invokeGetMethod(val, GET_CODE); - if (codeSystem != null && codeSystem.equalsIgnoreCase(MBI_ID_R4) && ("MB".equalsIgnoreCase(codeValue) || "MC".equalsIgnoreCase(codeValue))) { - List extensions = (List) Versions.invokeGetMethod(val, "getExtension"); - if (extensions != null && extensions.size() > 0) { - Object extension = extensions.get(0); - String url = (String) Versions.invokeGetMethod(extension, "getUrl"); - if (url != null && url.equalsIgnoreCase(CURRENCY_IDENTIFIER)) { - Object currValue = Versions.invokeGetMethod(extension, GET_VALUE); - String extValueSystem = (String) Versions.invokeGetMethod(currValue, GET_SYSTEM); - if (CURRENCY_IDENTIFIER.equalsIgnoreCase(extValueSystem)) { - String currValueCode = (String) Versions.invokeGetMethod(currValue, GET_CODE); - if (CURRENT_MBI.equalsIgnoreCase(currValueCode)) { - return PatientIdentifier.Currency.CURRENT; - } - if (HISTORIC_MBI.equalsIgnoreCase(currValueCode)) { - return PatientIdentifier.Currency.HISTORIC; - } - } - } + + List extensions = (List) Versions.invokeGetMethod(val, "getExtension"); + if (checkCodingIsNotValid(codeSystem, codeValue) || checkExtensionsNotExists(extensions)) { + return PatientIdentifier.Currency.UNKNOWN; + } + + Object extension = extensions.get(0); + String url = (String) Versions.invokeGetMethod(extension, "getUrl"); + if (checkCurrencyUrlIsNotValid(url)) { + return PatientIdentifier.Currency.UNKNOWN; + } + + Object currValue = Versions.invokeGetMethod(extension, GET_VALUE); + String extValueSystem = (String) Versions.invokeGetMethod(currValue, GET_SYSTEM); + if (CURRENCY_IDENTIFIER.equalsIgnoreCase(extValueSystem)) { + String currValueCode = (String) Versions.invokeGetMethod(currValue, GET_CODE); + if (CURRENT_MBI.equalsIgnoreCase(currValueCode)) { + return PatientIdentifier.Currency.CURRENT; + } + if (HISTORIC_MBI.equalsIgnoreCase(currValueCode)) { + return PatientIdentifier.Currency.HISTORIC; } } return PatientIdentifier.Currency.UNKNOWN; } + public static boolean checkTypeAndCodingNotExists(Object type, List vals) { + return (type == null || vals == null || vals.isEmpty()); + } + + public static boolean checkCodingIsNotValid(String codeSystem, String codeValue) { + return (codeSystem == null || !codeSystem.equalsIgnoreCase(MBI_ID_R4)) || (!codeValue.equalsIgnoreCase("MB") && !codeValue.equalsIgnoreCase("MC")); + } + + public static boolean checkExtensionsNotExists(List extensions) { + return (extensions == null || extensions.isEmpty()); + } + + public static boolean checkCurrencyUrlIsNotValid(String url) { + return (url == null || !url.equalsIgnoreCase(CURRENCY_IDENTIFIER)); + } + /** * If the period has a value for the identifier, return the information from that, otherwise UNKNOWN * diff --git a/ab2d-fhir/src/test/java/gov/cms/ab2d/fhir/PatientIdentifierUtilsTest.java b/ab2d-fhir/src/test/java/gov/cms/ab2d/fhir/PatientIdentifierUtilsTest.java index af4cdd93..997440f9 100644 --- a/ab2d-fhir/src/test/java/gov/cms/ab2d/fhir/PatientIdentifierUtilsTest.java +++ b/ab2d-fhir/src/test/java/gov/cms/ab2d/fhir/PatientIdentifierUtilsTest.java @@ -2,9 +2,10 @@ import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.dstu3.model.Coding; -import org.hl7.fhir.dstu3.model.Extension; import org.hl7.fhir.dstu3.model.Identifier; import org.hl7.fhir.dstu3.model.Patient; +import org.hl7.fhir.dstu3.model.Extension; +import org.hl7.fhir.instance.model.api.IBaseExtension; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.ICompositeType; import org.junit.jupiter.api.Test; @@ -13,6 +14,7 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.ArrayList; import java.util.Set; import static gov.cms.ab2d.fhir.PatientIdentifier.CURRENT_MBI; @@ -20,6 +22,7 @@ import static gov.cms.ab2d.fhir.PatientIdentifier.Currency.HISTORIC; import static gov.cms.ab2d.fhir.PatientIdentifier.HISTORIC_MBI; import static gov.cms.ab2d.fhir.PatientIdentifier.MBI_ID; +import static gov.cms.ab2d.fhir.PatientIdentifier.MBI_ID_R4; import static gov.cms.ab2d.fhir.IdentifierUtils.CURRENCY_IDENTIFIER; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; @@ -177,6 +180,161 @@ void testGetCurrentMbiWrongType() { assertNull(IdentifierUtils.getCurrentMbi(List.of(patientIdentifier))); } + @Test + void testGetCurrentMbiTypeNotExists() { + PatientIdentifier patientIdentifier = new PatientIdentifier(); + patientIdentifier.setType(null); + patientIdentifier.setValue("test-1"); + assertNull(IdentifierUtils.getCurrentMbi(List.of(patientIdentifier))); + } + + @Test + void testGetCurrencyFromTypeCodingExtensionReturnsCurrent() { + Coding coding = setupCodingForTestingCurrencyTypeCode(MBI_ID_R4, "MB"); + + Coding extCoding = setupCodingForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, CURRENT_MBI); + Extension extension = setupExtensionForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, extCoding); + + Identifier identifier = setupIdentifierForTestingCurrencyTypeCode(coding, extension); + Patient patient = setupPatientForTestingCurrencyTypeCode(identifier); + + assertEquals(PatientIdentifier.Currency.CURRENT, IdentifierUtils.getCurrencyFromTypeCodingExtension(patient.getIdentifier().get(0))); + } + + @Test + void testGetCurrencyFromTypeCodingExtensionReturnsHistoric() { + Coding coding = setupCodingForTestingCurrencyTypeCode(MBI_ID_R4, "MB"); + + Coding extCoding = setupCodingForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, HISTORIC_MBI); + Extension extension = setupExtensionForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, extCoding); + + Identifier identifier = setupIdentifierForTestingCurrencyTypeCode(coding, extension); + Patient patient = setupPatientForTestingCurrencyTypeCode(identifier); + + assertEquals(PatientIdentifier.Currency.HISTORIC, IdentifierUtils.getCurrencyFromTypeCodingExtension(patient.getIdentifier().get(0))); + } + + @Test + void testGetCurrencyFromTypeCodingExtensionReturnsUnknown() { + Coding coding = setupCodingForTestingCurrencyTypeCode(MBI_ID_R4, "MB"); + + Coding extCoding = setupCodingForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, "unknown"); + Extension extension = setupExtensionForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, extCoding); + + Identifier identifier = setupIdentifierForTestingCurrencyTypeCode(coding, extension); + Patient patient = setupPatientForTestingCurrencyTypeCode(identifier); + + assertEquals(PatientIdentifier.Currency.UNKNOWN, IdentifierUtils.getCurrencyFromTypeCodingExtension(patient.getIdentifier().get(0))); + } + + @Test + void testGetCurrencyFromTypeCodingExtensionReturnsUnknownWhenCodingEmpty() { + Identifier identifier = setupIdentifierForTestingCurrencyTypeCode(null, null); + Patient patient = setupPatientForTestingCurrencyTypeCode(identifier); + + assertEquals(PatientIdentifier.Currency.UNKNOWN, IdentifierUtils.getCurrencyFromTypeCodingExtension(patient.getIdentifier().get(0))); + } + + @Test + void testGetCurrencyFromTypeCodingExtensionReturnsUnknownWhenCodingSystemInvalid() { + Coding coding = setupCodingForTestingCurrencyTypeCode("invalid_system", "MB"); + + Coding extCoding = setupCodingForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, CURRENT_MBI); + Extension extension = setupExtensionForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, extCoding); + + Identifier identifier = setupIdentifierForTestingCurrencyTypeCode(coding, extension); + Patient patient = setupPatientForTestingCurrencyTypeCode(identifier); + + assertEquals(PatientIdentifier.Currency.UNKNOWN, IdentifierUtils.getCurrencyFromTypeCodingExtension(patient.getIdentifier().get(0))); + + } + + @Test + void testGetCurrencyFromTypeCodingExtensionReturnsUnknownWhenCodingCodeInvalid() { + Coding coding = setupCodingForTestingCurrencyTypeCode(MBI_ID_R4, "invalid_code"); + + Coding extCoding = setupCodingForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, CURRENT_MBI); + Extension extension = setupExtensionForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, extCoding); + + Identifier identifier = setupIdentifierForTestingCurrencyTypeCode(coding, extension); + Patient patient = setupPatientForTestingCurrencyTypeCode(identifier); + + assertEquals(PatientIdentifier.Currency.UNKNOWN, IdentifierUtils.getCurrencyFromTypeCodingExtension(patient.getIdentifier().get(0))); + + } + + @Test + void testGetCurrencyFromTypeCodingExtensionReturnsUnknownWhenUrlNull() { + Coding coding = setupCodingForTestingCurrencyTypeCode(MBI_ID_R4, "MB"); + + Coding extCoding = setupCodingForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, CURRENT_MBI); + Extension extension = setupExtensionForTestingCurrencyTypeCode(null, extCoding); + + Identifier identifier = setupIdentifierForTestingCurrencyTypeCode(coding, extension); + Patient patient = setupPatientForTestingCurrencyTypeCode(identifier); + + assertEquals(PatientIdentifier.Currency.UNKNOWN, IdentifierUtils.getCurrencyFromTypeCodingExtension(patient.getIdentifier().get(0))); + } + + @Test + void testGetCurrencyFromTypeCodingExtensionReturnsUnknownWhenUrlInvalid() { + Coding coding = setupCodingForTestingCurrencyTypeCode(MBI_ID_R4, "MB"); + + Coding extCoding = setupCodingForTestingCurrencyTypeCode(CURRENCY_IDENTIFIER, CURRENT_MBI); + Extension extension = setupExtensionForTestingCurrencyTypeCode("invalid_url", extCoding); + + Identifier identifier = setupIdentifierForTestingCurrencyTypeCode(coding, extension); + Patient patient = setupPatientForTestingCurrencyTypeCode(identifier); + + assertEquals(PatientIdentifier.Currency.UNKNOWN, IdentifierUtils.getCurrencyFromTypeCodingExtension(patient.getIdentifier().get(0))); + } + + @Test + void testReturnsTrueIfCodingNotExist() { + PatientIdentifier patientIdentifier = new PatientIdentifier(); + patientIdentifier.setType(PatientIdentifier.Type.MBI); + patientIdentifier.setValue("test-1"); + + Object type = Versions.invokeGetMethod(patientIdentifier, "getType"); + List vals = (List) Versions.invokeGetMethod(type, "getCode"); + + assertTrue(IdentifierUtils.checkTypeAndCodingNotExists(type, vals)); + } + + @Test + void testReturnsTrueIfCodingNotValid() { + assertTrue(IdentifierUtils.checkCodingIsNotValid("invalid_system", "invalid_value")); + } + + @Test + void testReturnsFalseIfCodingValid() { + assertFalse(IdentifierUtils.checkCodingIsNotValid(MBI_ID_R4, "MB")); + assertFalse(IdentifierUtils.checkCodingIsNotValid(MBI_ID_R4, "MC")); + } + + @Test + void testReturnsTrueIfExtensionsNotExists() { + assertTrue(IdentifierUtils.checkExtensionsNotExists(new ArrayList<>())); + } + + @Test + void testReturnsFalseIfExtensionsExists() { + List extensions = new ArrayList<>(); + Extension extension = new Extension(); + extensions.add(extension); + assertFalse(IdentifierUtils.checkExtensionsNotExists(extensions)); + } + + @Test + void testReturnsFalseIfURLValid() { + assertFalse(IdentifierUtils.checkCurrencyUrlIsNotValid(IdentifierUtils.CURRENCY_IDENTIFIER)); + } + + @Test + void testReturnsTrueIfURLInvalid() { + assertTrue(IdentifierUtils.checkCurrencyUrlIsNotValid("invalid_url")); + } + @Test void testR4ExtractIds() throws IOException { List beneIds = List.of("-19990000001101", "-19990000001102", "-19990000001103"); @@ -212,6 +370,42 @@ void testR4ExtractIds() throws IOException { } } + Extension setupExtensionForTestingCurrencyTypeCode(String url, Coding extCoding) { + Extension extension = new Extension(); + extension.setUrl(url); + + if (extCoding != null) { + extension.setValue(extCoding); + } + return extension; + } + + Coding setupCodingForTestingCurrencyTypeCode(String system, String code) { + Coding coding = new Coding(); + coding.setSystem(system); + coding.setCode(code); + return coding; + } + + Identifier setupIdentifierForTestingCurrencyTypeCode(Coding coding, Extension extension) { + Identifier identifier = new Identifier(); + identifier.setSystem(MBI_ID); + identifier.setValue("mbi-1"); + if (coding != null) { + identifier.getType().addCoding(coding); + } + if (extension != null) { + identifier.getType().getCoding().get(0).addExtension(extension); + } + return identifier; + } + + Patient setupPatientForTestingCurrencyTypeCode(Identifier identifier) { + Patient patient = new Patient(); + patient.setIdentifier(List.of(identifier)); + return patient; + } + IBaseResource extractBundle(FhirVersion version, String fileName) throws IOException { return version.getJsonParser().parseResource(getRawJson(fileName)); } diff --git a/build.gradle b/build.gradle index 06110c4f..2f77dcd9 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ ext { : System.getenv()['ARTIFACTORY_PASSWORD'] // AB2D libraries - fhirVersion='1.2.6' + fhirVersion='1.2.7' bfdVersion='2.2.2' aggregatorVersion='1.3.4' filtersVersion='1.9.4'