Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BFD-2720: Fix bug with samhsa matcher class cast in RDA logic #1812

Merged
merged 1 commit into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import com.codahale.metrics.MetricRegistry;
import com.google.common.annotations.VisibleForTesting;
import com.newrelic.api.agent.Trace;
import gov.cms.bfd.model.rda.RdaFissClaim;
import gov.cms.bfd.model.rda.RdaMcsClaim;
import gov.cms.bfd.server.war.commons.AbstractResourceProvider;
import gov.cms.bfd.server.war.commons.OffsetLinkBuilder;
import gov.cms.bfd.server.war.commons.OpenAPIContentProvider;
Expand Down Expand Up @@ -52,7 +50,6 @@
import org.apache.logging.log4j.util.Strings;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Claim;
import org.hl7.fhir.r4.model.ClaimResponse;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Resource;
Expand Down Expand Up @@ -427,7 +424,7 @@ Bundle createBundleFor(

resources.addAll(
entities.stream()
.filter(e -> !bundleOptions.excludeSamhsa || hasNoSamhsaData(e))
.filter(e -> !bundleOptions.excludeSamhsa || samhsaMatcher.hasNoSamhsaData(e))
.map(e -> transformEntity(type, e, bundleOptions.includeTaxNumbers))
.collect(Collectors.toList()));
}
Expand All @@ -453,28 +450,6 @@ Bundle createBundleFor(
return bundle;
}

/**
* Determines if there are no samhsa entries in the claim.
*
* @param entity the claim to check
* @return {@code true} if there are no samhsa entries in the claim
*/
@VisibleForTesting
boolean hasNoSamhsaData(Object entity) {
Claim claim;

if (entity instanceof RdaFissClaim) {
claim = (Claim) fissTransformer.transform(entity, false);
} else if (entity instanceof RdaMcsClaim) {
claim = (Claim) mcsTransformer.transform(entity, false);
} else {
throw new IllegalArgumentException(
"Unsupported entity " + entity.getClass().getCanonicalName() + " for samhsa filtering");
}

return !samhsaMatcher.test(claim);
}

/** Helper class for passing bundle result options. */
private static class BundleOptions {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package gov.cms.bfd.server.war.r4.providers.pac;

import gov.cms.bfd.model.rda.RdaFissClaim;
import gov.cms.bfd.model.rda.RdaMcsClaim;
import gov.cms.bfd.server.war.adapters.CodeableConcept;
import gov.cms.bfd.server.war.adapters.r4.ClaimAdapter;
import gov.cms.bfd.server.war.commons.AbstractSamhsaMatcher;
Expand All @@ -21,6 +23,47 @@
@Component
public final class R4ClaimSamhsaMatcher extends AbstractSamhsaMatcher<Claim> {

/** The fiss claim transformer, used for converting resources to check for samhsa data. */
private final FissClaimTransformerV2 fissTransformer;

/** The mcs claim transformer, used for converting resources to check for samhsa data. */
private final McsClaimTransformerV2 mcsTransformer;

/**
* Instantiates a new samhsa matcher.
*
* <p>Resources should be instantiated by Spring, so this should only be directly called by tests.
*
* @param fissClaimTransformer the fiss claim transformer
* @param mcsClaimTransformer the mcs claim transformer
*/
public R4ClaimSamhsaMatcher(
FissClaimTransformerV2 fissClaimTransformer, McsClaimTransformerV2 mcsClaimTransformer) {
this.mcsTransformer = mcsClaimTransformer;
this.fissTransformer = fissClaimTransformer;
}

/**
* Determines if there are no samhsa entries in the claim.
*
* @param entity the claim to check
* @return {@code true} if there are no samhsa entries in the claim
*/
public boolean hasNoSamhsaData(Object entity) {
Claim claim;

if (entity instanceof RdaFissClaim) {
claim = fissTransformer.transform(entity, false);
} else if (entity instanceof RdaMcsClaim) {
claim = mcsTransformer.transform(entity, false);
} else {
throw new IllegalArgumentException(
"Unsupported entity " + entity.getClass().getCanonicalName() + " for samhsa filtering");
}

return !test(claim);
}
lsmitchell marked this conversation as resolved.
Show resolved Hide resolved

/** {@inheritDoc} */
@Override
public boolean test(Claim claim) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package gov.cms.bfd.server.war.r4.providers.pac;

import static org.junit.jupiter.api.Assertions.assertNotNull;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.param.DateParam;
Expand Down Expand Up @@ -115,6 +117,33 @@ void shouldGetCorrectClaimResponseResourcesByMbiHash() {
AssertUtils.assertJsonEquals(expected, actual, ignorePatterns);
}

/**
* Tests to see if the correct response is given when a search is done for {@link ClaimResponse}s
* using given mbi and excludeSAMHSA=true, since this does an extra check for samhsa data.
*/
@Test
void shouldGetClaimResponseResourcesByMbiHashWithExcludeSamhsaTrue() {
IGenericClient fhirClient = ServerTestUtils.get().createFhirClientV2();

Bundle claimResult =
fhirClient
.search()
.forResource(ClaimResponse.class)
.where(
Map.of(
"mbi",
Collections.singletonList(new ReferenceParam(RDATestUtils.MBI_OLD_HASH)),
"service-date",
Arrays.asList(new DateParam("gt1970-07-18"), new DateParam("lt1970-07-25")),
"excludeSAMHSA",
Collections.singletonList(new ReferenceParam("true"))))
.returnBundle(Bundle.class)
.execute();

// Ensure we got a result and not an exception
assertNotNull(claimResult);
lsmitchell marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Tests to see if the correct paginated response is given when a search is done for {@link
* ClaimResponse}s using given mbi and service-date range. In this test case the query finds the
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package gov.cms.bfd.server.war.r4.providers.pac;

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import gov.cms.bfd.model.rda.RdaFissClaim;
import gov.cms.bfd.model.rda.RdaMcsClaim;
import java.util.ArrayList;
import java.util.List;
import org.hl7.fhir.r4.model.Claim;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;

/** Tests the methods of the {@link R4ClaimSamhsaMatcher}. */
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
public class R4ClaimSamhsaMatcherTest {

/** The class under test. */
private R4ClaimSamhsaMatcher samhsaMatcher;

/** The fiss claim transformer. */
@Mock private FissClaimTransformerV2 mockFissTransformer;

/** The mock mcs claim transformer. */
@Mock private McsClaimTransformerV2 mockMcsTransformer;

/** The mock claim returned by the transformers. */
@Mock private Claim mockClaim;

/** Sets up the class under test and dependencies. */
@BeforeEach
public void setup() {
samhsaMatcher = new R4ClaimSamhsaMatcher(mockFissTransformer, mockMcsTransformer);
when(mockFissTransformer.transform(any(), anyBoolean())).thenReturn(mockClaim);
when(mockMcsTransformer.transform(any(), anyBoolean())).thenReturn(mockClaim);
List<Claim.ProcedureComponent> procedureComponentList = new ArrayList<>();
when(mockClaim.getProcedure()).thenReturn(procedureComponentList);
}

/**
* Tests that the samhsa checker is invoked and returns true when a mcs claim with no data is
* passed, as the matches should have nothing to match as a positive samhsa result.
*/
@Test
public void testHasNoSamhsaDataWhenMcsClaimResponseWithNoDataExpectTrue() {

RdaMcsClaim mcsClaim = mock(RdaMcsClaim.class);

boolean hasNoSamhsa = samhsaMatcher.hasNoSamhsaData(mcsClaim);

assertTrue(hasNoSamhsa);
}

/**
* Tests that the samhsa checker is invoked and returns true when a fiss claim with no data is
* passed, as the matches should have nothing to match as a positive samhsa result.
*/
@Test
public void testHasNoSamhsaDataWhenFissClaimResponseWithNoDataExpectTrue() {

RdaFissClaim fissClaim = mock(RdaFissClaim.class);

boolean hasNoSamhsa = samhsaMatcher.hasNoSamhsaData(fissClaim);

assertTrue(hasNoSamhsa);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,12 @@ public void fissTest(

FissClaimTransformerV2 fissClaimTransformerV2 =
new FissClaimTransformerV2(new MetricRegistry());
McsClaimTransformerV2 mcsClaimTransformerV2 = new McsClaimTransformerV2(new MetricRegistry());

Claim claim = fissClaimTransformerV2.transform(entity, true);

R4ClaimSamhsaMatcher matcher = new R4ClaimSamhsaMatcher();
R4ClaimSamhsaMatcher matcher =
new R4ClaimSamhsaMatcher(fissClaimTransformerV2, mcsClaimTransformerV2);

assertEquals(expectedResult, matcher.test(claim), testName + " " + errorMessagePostFix);
}
Expand Down Expand Up @@ -283,11 +285,14 @@ public void mcsTest(

entity.setDetails(procedures);

FissClaimTransformerV2 fissClaimTransformerV2 =
new FissClaimTransformerV2(new MetricRegistry());
McsClaimTransformerV2 mcsClaimTransformerV2 = new McsClaimTransformerV2(new MetricRegistry());

Claim claim = mcsClaimTransformerV2.transform(entity, true);

R4ClaimSamhsaMatcher matcher = new R4ClaimSamhsaMatcher();
R4ClaimSamhsaMatcher matcher =
new R4ClaimSamhsaMatcher(fissClaimTransformerV2, mcsClaimTransformerV2);

assertEquals(expectedResult, matcher.test(claim), testName + " " + errorMessagePostFix);
}
Expand Down