Skip to content

Commit

Permalink
[AB2D-6101] Address Critical Code Smell - Reduce cognitive method com…
Browse files Browse the repository at this point in the history
…pleixty (#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
  • Loading branch information
Rwolfe-Nava authored Jul 22, 2024
1 parent 50f2e43 commit c5f7cfd
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 26 deletions.
67 changes: 43 additions & 24 deletions ab2d-fhir/src/main/java/gov/cms/ab2d/fhir/IdentifierUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Coding> 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<IBaseExtension> 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<Coding> 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<IBaseExtension> 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
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -13,13 +14,15 @@
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;
import static gov.cms.ab2d.fhir.PatientIdentifier.Currency.CURRENT;
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;
Expand Down Expand Up @@ -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<Coding> 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<IBaseExtension> 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<String> beneIds = List.of("-19990000001101", "-19990000001102", "-19990000001103");
Expand Down Expand Up @@ -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));
}
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down

0 comments on commit c5f7cfd

Please sign in to comment.