Add tests for #877
This commit is contained in:
parent
ca3e7fe38f
commit
55fc20b87e
|
@ -17,9 +17,9 @@ import java.util.*;
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -60,6 +60,9 @@ public class DaoConfig {
|
|||
* update setter javadoc if default changes
|
||||
*/
|
||||
private boolean myAllowExternalReferences = false;
|
||||
/**
|
||||
* update setter javadoc if default changes
|
||||
*/
|
||||
private boolean myAllowContainsSearches = true;
|
||||
|
||||
/**
|
||||
|
@ -137,6 +140,7 @@ public class DaoConfig {
|
|||
myTreatReferencesAsLogical.add(theTreatReferencesAsLogical);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specifies the highest number that a client is permitted to use in a
|
||||
* <code>Cache-Control: nostore, max-results=NNN</code>
|
||||
|
@ -376,9 +380,9 @@ public class DaoConfig {
|
|||
* of higher importance than raw write performance
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that this setting also has an impact on sorting (i.e. using the
|
||||
* <code>_sort</code> parameter on searches): If the server is configured
|
||||
* to not index missing field.
|
||||
* Note that this setting also has an impact on sorting (i.e. using the
|
||||
* <code>_sort</code> parameter on searches): If the server is configured
|
||||
* to not index missing field.
|
||||
* </p>
|
||||
*/
|
||||
public void setIndexMissingFields(IndexEnabledEnum theIndexMissingFields) {
|
||||
|
@ -650,6 +654,26 @@ public class DaoConfig {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If enabled, the server will support the use of :contains searches,
|
||||
* which are helpful but can have adverse effects on performance.
|
||||
*
|
||||
* Default is <code>true</code>
|
||||
*/
|
||||
public boolean isAllowContainsSearches() {
|
||||
return myAllowContainsSearches;
|
||||
}
|
||||
|
||||
/**
|
||||
* If enabled, the server will support the use of :contains searches,
|
||||
* which are helpful but can have adverse effects on performance.
|
||||
*
|
||||
* Default is <code>true</code>
|
||||
*/
|
||||
public void setAllowContainsSearches(boolean theAllowContainsSearches) {
|
||||
this.myAllowContainsSearches = theAllowContainsSearches;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to <code>true</code> (default is <code>false</code>) the server will allow
|
||||
* resources to have references to external servers. For example if this server is
|
||||
|
@ -1099,16 +1123,6 @@ public class DaoConfig {
|
|||
|
||||
}
|
||||
|
||||
public boolean allowContainsSearches() {
|
||||
|
||||
return myAllowContainsSearches;
|
||||
}
|
||||
|
||||
public void setAllowContainsSearches(boolean myAllowContainsSearches) {
|
||||
|
||||
this.myAllowContainsSearches = myAllowContainsSearches;
|
||||
}
|
||||
|
||||
public enum IndexEnabledEnum {
|
||||
ENABLED,
|
||||
DISABLED
|
||||
|
|
|
@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.dao;
|
|||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -28,8 +28,6 @@ import ca.uhn.fhir.jpa.search.JpaRuntimeSearchParam;
|
|||
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
||||
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
|
||||
import ca.uhn.fhir.jpa.util.BaseIterator;
|
||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||
import ca.uhn.fhir.util.StopWatch;
|
||||
import ca.uhn.fhir.model.api.*;
|
||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
|
||||
|
@ -45,7 +43,9 @@ import ca.uhn.fhir.rest.api.SortSpec;
|
|||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.util.StopWatch;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Lists;
|
||||
|
@ -1091,10 +1091,10 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
} else if (theParameter instanceof StringParam) {
|
||||
StringParam id = (StringParam) theParameter;
|
||||
rawSearchTerm = id.getValue();
|
||||
if ((id.isContains()) &&
|
||||
(!myCallingDao.getConfig().allowContainsSearches()))
|
||||
{
|
||||
throw new MethodNotAllowedException(":contains modifier is disabled on this server");
|
||||
if (id.isContains()) {
|
||||
if (!myCallingDao.getConfig().isAllowContainsSearches()) {
|
||||
throw new MethodNotAllowedException(":contains modifier is disabled on this server");
|
||||
}
|
||||
}
|
||||
} else if (theParameter instanceof IPrimitiveDatatype<?>) {
|
||||
IPrimitiveDatatype<?> id = (IPrimitiveDatatype<?>) theParameter;
|
||||
|
@ -1109,18 +1109,11 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
}
|
||||
|
||||
String likeExpression = BaseHapiFhirDao.normalizeString(rawSearchTerm);
|
||||
if (myCallingDao.getConfig().allowContainsSearches()) {
|
||||
if (theParameter instanceof StringParam) {
|
||||
if (((StringParam) theParameter).isContains()) {
|
||||
likeExpression = createLeftAndRightMatchLikeExpression(likeExpression);
|
||||
} else {
|
||||
likeExpression = createLeftMatchLikeExpression(likeExpression);
|
||||
}
|
||||
} else {
|
||||
likeExpression = createLeftMatchLikeExpression(likeExpression);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (theParameter instanceof StringParam &&
|
||||
((StringParam) theParameter).isContains() &&
|
||||
myCallingDao.getConfig().isAllowContainsSearches()) {
|
||||
likeExpression = createLeftAndRightMatchLikeExpression(likeExpression);
|
||||
} else {
|
||||
likeExpression = createLeftMatchLikeExpression(likeExpression);
|
||||
}
|
||||
|
||||
|
@ -2020,14 +2013,14 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
return lastUpdatedPredicates;
|
||||
}
|
||||
|
||||
private static String createLeftMatchLikeExpression(String likeExpression) {
|
||||
return likeExpression.replace("%", "[%]") + "%";
|
||||
}
|
||||
|
||||
private static String createLeftAndRightMatchLikeExpression(String likeExpression) {
|
||||
return "%" + likeExpression.replace("%", "[%]") + "%";
|
||||
}
|
||||
|
||||
private static String createLeftMatchLikeExpression(String likeExpression) {
|
||||
return likeExpression.replace("%", "[%]") + "%";
|
||||
}
|
||||
|
||||
private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, From<?, ? extends ResourceLink> theFrom,
|
||||
String theResourceType) {
|
||||
RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(theResourceType);
|
||||
|
|
|
@ -11,6 +11,7 @@ import ca.uhn.fhir.rest.api.Constants;
|
|||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -54,6 +55,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
public void afterResetSearchSize() {
|
||||
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
|
||||
myDaoConfig.setFetchSizeDefaultMaximum(new DaoConfig().getFetchSizeDefaultMaximum());
|
||||
myDaoConfig.setAllowContainsSearches(new DaoConfig().isAllowContainsSearches());
|
||||
}
|
||||
|
||||
@Before
|
||||
|
@ -1404,43 +1406,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See #819
|
||||
*/
|
||||
@Test
|
||||
public void testSearchTokenWithNotModifier() {
|
||||
String male, female;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
patient.addName().setFamily("Tester").addGiven("Joe");
|
||||
patient.setGender(AdministrativeGender.MALE);
|
||||
male = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
patient.addName().setFamily("Tester").addGiven("Jane");
|
||||
patient.setGender(AdministrativeGender.FEMALE);
|
||||
female = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
|
||||
List<String> patients;
|
||||
SearchParameterMap params;
|
||||
|
||||
params = new SearchParameterMap();
|
||||
params.add(Patient.SP_GENDER, new TokenParam(null, "male"));
|
||||
params.setLoadSynchronous(true);
|
||||
patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
|
||||
assertThat(patients, contains(male));
|
||||
|
||||
params = new SearchParameterMap();
|
||||
params.add(Patient.SP_GENDER, new TokenParam(null, "male").setModifier(TokenParamModifier.NOT));
|
||||
params.setLoadSynchronous(true);
|
||||
patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
|
||||
assertThat(patients, contains(female));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchNumberParam() {
|
||||
ImmunizationRecommendation e1 = new ImmunizationRecommendation();
|
||||
|
@ -2122,6 +2087,43 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See #819
|
||||
*/
|
||||
@Test
|
||||
public void testSearchTokenWithNotModifier() {
|
||||
String male, female;
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("001");
|
||||
patient.addName().setFamily("Tester").addGiven("Joe");
|
||||
patient.setGender(AdministrativeGender.MALE);
|
||||
male = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("002");
|
||||
patient.addName().setFamily("Tester").addGiven("Jane");
|
||||
patient.setGender(AdministrativeGender.FEMALE);
|
||||
female = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
|
||||
}
|
||||
|
||||
List<String> patients;
|
||||
SearchParameterMap params;
|
||||
|
||||
params = new SearchParameterMap();
|
||||
params.add(Patient.SP_GENDER, new TokenParam(null, "male"));
|
||||
params.setLoadSynchronous(true);
|
||||
patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
|
||||
assertThat(patients, contains(male));
|
||||
|
||||
params = new SearchParameterMap();
|
||||
params.add(Patient.SP_GENDER, new TokenParam(null, "male").setModifier(TokenParamModifier.NOT));
|
||||
params.setLoadSynchronous(true);
|
||||
patients = toUnqualifiedVersionlessIdValues(myPatientDao.search(params));
|
||||
assertThat(patients, contains(female));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchTokenWrongParam() {
|
||||
Patient p1 = new Patient();
|
||||
|
@ -2257,6 +2259,67 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithContains() {
|
||||
|
||||
Patient pt1 = new Patient();
|
||||
pt1.addName().setFamily("ABCDEFGHIJK");
|
||||
String pt1id = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
Patient pt2 = new Patient();
|
||||
pt2.addName().setFamily("FGHIJK");
|
||||
String pt2id = myPatientDao.create(pt2).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
Patient pt3 = new Patient();
|
||||
pt3.addName().setFamily("ZZZZZ");
|
||||
myPatientDao.create(pt3).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
|
||||
List<String> ids;
|
||||
SearchParameterMap map;
|
||||
IBundleProvider results;
|
||||
|
||||
// Contains = true
|
||||
map = new SearchParameterMap();
|
||||
map.add(Patient.SP_NAME, new StringParam("FGHIJK").setContains(true));
|
||||
map.setLoadSynchronous(true);
|
||||
results = myPatientDao.search(map);
|
||||
ids = toUnqualifiedVersionlessIdValues(results);
|
||||
assertThat(ids, containsInAnyOrder(pt1id, pt2id));
|
||||
|
||||
// Contains = false
|
||||
map = new SearchParameterMap();
|
||||
map.add(Patient.SP_NAME, new StringParam("FGHIJK").setContains(false));
|
||||
map.setLoadSynchronous(true);
|
||||
results = myPatientDao.search(map);
|
||||
ids = toUnqualifiedVersionlessIdValues(results);
|
||||
assertThat(ids, containsInAnyOrder(pt2id));
|
||||
|
||||
// No contains
|
||||
map = new SearchParameterMap();
|
||||
map.add(Patient.SP_NAME, new StringParam("FGHIJK"));
|
||||
map.setLoadSynchronous(true);
|
||||
results = myPatientDao.search(map);
|
||||
ids = toUnqualifiedVersionlessIdValues(results);
|
||||
assertThat(ids, containsInAnyOrder(pt2id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithContainsDisabled() {
|
||||
myDaoConfig.setAllowContainsSearches(false);
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
map.add(Patient.SP_NAME, new StringParam("FGHIJK").setContains(true));
|
||||
|
||||
try {
|
||||
myPatientDao.search(map);
|
||||
fail();
|
||||
} catch (MethodNotAllowedException e) {
|
||||
assertEquals(":contains modifier is disabled on this server", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithDate() {
|
||||
IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId();
|
||||
|
|
Loading…
Reference in New Issue