From 0f1724ac0a28632e49a169866fc3bc21114e744f Mon Sep 17 00:00:00 2001 From: jamesagnew Date: Mon, 30 Jul 2018 05:48:38 -0400 Subject: [PATCH] Credit and a unit test for #912 --- .../fhir/rest/gclient/StringClientParam.java | 32 +++++++------- .../fhir/rest/client/GenericClientTest.java | 44 +++++++++++++++++++ src/changes/changes.xml | 5 +++ 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/StringClientParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/StringClientParam.java index 47d79cd1bea..5d0a463bbfe 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/StringClientParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/StringClientParam.java @@ -20,12 +20,12 @@ package ca.uhn.fhir.rest.gclient; * #L% */ +import ca.uhn.fhir.rest.api.Constants; +import org.hl7.fhir.instance.model.api.IPrimitiveType; + import java.util.Arrays; import java.util.List; -import ca.uhn.fhir.model.primitive.StringDt; -import ca.uhn.fhir.rest.api.Constants; - /** * * @author james @@ -83,7 +83,7 @@ public class StringClientParam extends BaseClientParam implements IParam { /** * Requests that resources be returned which match the given value */ - ICriterion value(StringDt theValue); + ICriterion value(IPrimitiveType theValue); /** * Requests that resources be returned which match ANY of the given values (this is an OR search, not an AND search). Note that to @@ -97,17 +97,17 @@ public class StringClientParam extends BaseClientParam implements IParam { private class StringExactly implements IStringMatch { @Override public ICriterion value(String theValue) { - return new StringCriterion(getParamName() + Constants.PARAMQUALIFIER_STRING_EXACT, theValue); + return new StringCriterion<>(getParamName() + Constants.PARAMQUALIFIER_STRING_EXACT, theValue); } @Override - public ICriterion value(StringDt theValue) { - return new StringCriterion(getParamName() + Constants.PARAMQUALIFIER_STRING_EXACT, theValue.getValue()); + public ICriterion value(IPrimitiveType theValue) { + return new StringCriterion<>(getParamName() + Constants.PARAMQUALIFIER_STRING_EXACT, theValue.getValue()); } @Override public ICriterion values(List theValue) { - return new StringCriterion(getParamName() + Constants.PARAMQUALIFIER_STRING_EXACT, theValue); + return new StringCriterion<>(getParamName() + Constants.PARAMQUALIFIER_STRING_EXACT, theValue); } @Override @@ -119,17 +119,17 @@ public class StringClientParam extends BaseClientParam implements IParam { private class StringContains implements IStringMatch { @Override public ICriterion value(String theValue) { - return new StringCriterion(getParamName() + Constants.PARAMQUALIFIER_STRING_CONTAINS, theValue); + return new StringCriterion<>(getParamName() + Constants.PARAMQUALIFIER_STRING_CONTAINS, theValue); } @Override - public ICriterion value(StringDt theValue) { - return new StringCriterion(getParamName() + Constants.PARAMQUALIFIER_STRING_CONTAINS, theValue.getValue()); + public ICriterion value(IPrimitiveType theValue) { + return new StringCriterion<>(getParamName() + Constants.PARAMQUALIFIER_STRING_CONTAINS, theValue.getValue()); } @Override public ICriterion values(List theValue) { - return new StringCriterion(getParamName() + Constants.PARAMQUALIFIER_STRING_CONTAINS, theValue); + return new StringCriterion<>(getParamName() + Constants.PARAMQUALIFIER_STRING_CONTAINS, theValue); } @Override @@ -141,17 +141,17 @@ public class StringClientParam extends BaseClientParam implements IParam { private class StringMatches implements IStringMatch { @Override public ICriterion value(String theValue) { - return new StringCriterion(getParamName(), theValue); + return new StringCriterion<>(getParamName(), theValue); } @Override - public ICriterion value(StringDt theValue) { - return new StringCriterion(getParamName(), theValue.getValue()); + public ICriterion value(IPrimitiveType theValue) { + return new StringCriterion<>(getParamName(), theValue.getValue()); } @Override public ICriterion values(List theValue) { - return new StringCriterion(getParamName(), theValue); + return new StringCriterion<>(getParamName(), theValue); } @Override diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/GenericClientTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/GenericClientTest.java index 1acbbc3cc5e..e69852ead58 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/GenericClientTest.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/client/GenericClientTest.java @@ -43,6 +43,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.nio.charset.Charset; +import java.util.Arrays; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.startsWith; @@ -1059,6 +1060,49 @@ public class GenericClientTest { } + @SuppressWarnings("unused") + @Test + public void testSearchByStringContains() throws Exception { + + String msg = getPatientFeedWithOneResult(); + + ArgumentCaptor capt = ArgumentCaptor.forClass(HttpUriRequest.class); + when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse); + when(myHttpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK")); + when(myHttpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8")); + when(myHttpResponse.getEntity().getContent()).thenAnswer(t-> new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8"))); + + IGenericClient client = ourCtx.newRestfulGenericClient("http://example.com/fhir"); + + Bundle response = client.search() + .forResource("Patient") + .where(Patient.NAME.contains().value("FOO")) + .returnBundle(Bundle.class) + .execute(); + assertEquals("http://example.com/fhir/Patient?name%3Acontains=FOO", capt.getValue().getURI().toString()); + + response = client.search() + .forResource("Patient") + .where(Patient.NAME.contains().values("FOO", "BAR")) + .returnBundle(Bundle.class) + .execute(); + assertEquals("http://example.com/fhir/Patient?name%3Acontains=FOO%2CBAR", capt.getValue().getURI().toString()); + + response = client.search() + .forResource("Patient") + .where(Patient.NAME.contains().values(Arrays.asList("FOO", "BAR"))) + .returnBundle(Bundle.class) + .execute(); + assertEquals("http://example.com/fhir/Patient?name%3Acontains=FOO%2CBAR", capt.getValue().getURI().toString()); + + response = client.search() + .forResource("Patient") + .where(Patient.NAME.contains().value(new StringType("FOO"))) + .returnBundle(Bundle.class) + .execute(); + assertEquals("http://example.com/fhir/Patient?name%3Acontains=FOO", capt.getValue().getURI().toString()); + } + @SuppressWarnings("unused") @Test public void testSearchByStringExact() throws Exception { diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 995fb40d82e..9b136a848e3 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -150,6 +150,11 @@ in order to prevent HTML injection attacks via maliciously crafted URLs. + + The generic/fluent client now supports the :contains modifier on + string search params. Thanks to Clayton Bodendein for the pull + request! +