3470 ne date search (#3471)

* fix mongo date search with the NOT_EQUALS prefix

* add test & changelog

* add some unit tests

* rename unit test names to be more clear

Co-authored-by: olivia-you <olivia.you@smilecdr.com>
This commit is contained in:
Olivia You 2022-03-25 17:51:17 -04:00 committed by GitHub
parent 1dcc64ee44
commit 625ed936e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 106 additions and 37 deletions

View File

@ -89,6 +89,7 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
setRangeFromDatesInclusive(theDateParam.getValueAsString(), theDateParam.getValueAsString());
} else {
switch (theDateParam.getPrefix()) {
case NOT_EQUAL:
case EQUAL:
setRangeFromDatesInclusive(theDateParam.getValueAsString(), theDateParam.getValueAsString());
break;
@ -161,41 +162,42 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
}
private void addParam(DateParam theParsed) throws InvalidRequestException {
if (theParsed.getPrefix() == null || theParsed.getPrefix() == EQUAL) {
if (myLowerBound != null || myUpperBound != null) {
throw new InvalidRequestException(Msg.code(1922) + "Can not have multiple date range parameters for the same param without a qualifier");
}
if (theParsed.getMissing() != null) {
myLowerBound = theParsed;
myUpperBound = theParsed;
} else {
myLowerBound = new DateParam(EQUAL, theParsed.getValueAsString());
myUpperBound = new DateParam(EQUAL, theParsed.getValueAsString());
}
} else {
switch (theParsed.getPrefix()) {
case GREATERTHAN:
case GREATERTHAN_OR_EQUALS:
if (myLowerBound != null) {
throw new InvalidRequestException(Msg.code(1923) + "Can not have multiple date range parameters for the same param that specify a lower bound");
}
myLowerBound = theParsed;
break;
case LESSTHAN:
case LESSTHAN_OR_EQUALS:
if (myUpperBound != null) {
throw new InvalidRequestException(Msg.code(1924) + "Can not have multiple date range parameters for the same param that specify an upper bound");
}
myUpperBound = theParsed;
break;
default:
throw new InvalidRequestException(Msg.code(1925) + "Unknown comparator: " + theParsed.getPrefix());
}
if (theParsed.getPrefix() == null){
theParsed.setPrefix(EQUAL);
}
switch (theParsed.getPrefix()) {
case NOT_EQUAL:
case EQUAL:
if (myLowerBound != null || myUpperBound != null) {
throw new InvalidRequestException(Msg.code(1922) + "Can not have multiple date range parameters for the same param without a qualifier");
}
if (theParsed.getMissing() != null) {
myLowerBound = theParsed;
myUpperBound = theParsed;
} else {
myLowerBound = new DateParam(theParsed.getPrefix(), theParsed.getValueAsString());
myUpperBound = new DateParam(theParsed.getPrefix(), theParsed.getValueAsString());
}
break;
case GREATERTHAN:
case GREATERTHAN_OR_EQUALS:
if (myLowerBound != null) {
throw new InvalidRequestException(Msg.code(1923) + "Can not have multiple date range parameters for the same param that specify a lower bound");
}
myLowerBound = theParsed;
break;
case LESSTHAN:
case LESSTHAN_OR_EQUALS:
if (myUpperBound != null) {
throw new InvalidRequestException(Msg.code(1924) + "Can not have multiple date range parameters for the same param that specify an upper bound");
}
myUpperBound = theParsed;
break;
default:
throw new InvalidRequestException(Msg.code(1925) + "Unknown comparator: " + theParsed.getPrefix());
}
}
@Override

View File

@ -10,6 +10,7 @@ import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@ -25,7 +26,7 @@ public class DateRangeParamTest {
* Can happen e.g. when the query parameter for {@code _lastUpdated} is left empty.
*/
@Test
public void testParamWithoutPrefixAndWithoutValue() {
public void testParamWithoutPrefixAndWithoutValue_dateRangeParamRemainsEmpty() {
QualifiedParamList qualifiedParamList = new QualifiedParamList(1);
qualifiedParamList.add("");
@ -41,7 +42,7 @@ public class DateRangeParamTest {
* Can happen e.g. when the query parameter for {@code _lastUpdated} is given as {@code lt} without any value.
*/
@Test
public void testUpperBoundWithPrefixWithoutValue() {
public void testUpperBoundWithPrefixWithoutValue_throwsDateFormatException() {
QualifiedParamList qualifiedParamList = new QualifiedParamList(1);
qualifiedParamList.add("lt");
@ -60,7 +61,7 @@ public class DateRangeParamTest {
* Can happen e.g. when the query parameter for {@code _lastUpdated} is given as {@code gt} without any value.
*/
@Test
public void testLowerBoundWithPrefixWithoutValue() {
public void testLowerBoundWithPrefixWithoutValue_throwsDateFormatException() {
QualifiedParamList qualifiedParamList = new QualifiedParamList(1);
qualifiedParamList.add("gt");
@ -74,4 +75,52 @@ public class DateRangeParamTest {
// good
}
}
@Test
public void testSetValueAsQueryTokens_neYear_setsUpperAndLowerBounds() {
QualifiedParamList qualifiedParamList = new QualifiedParamList(1);
qualifiedParamList.add("ne1965");
List<QualifiedParamList> params = new ArrayList<>(1);
params.add(qualifiedParamList);
DateRangeParam dateRangeParam = new DateRangeParam();
dateRangeParam.setValuesAsQueryTokens(fhirContext, "_lastUpdated", params);
assertEquals("1965", dateRangeParam.getLowerBound().getValueAsString());
assertEquals("1965", dateRangeParam.getUpperBound().getValueAsString());
assertEquals(ParamPrefixEnum.NOT_EQUAL, dateRangeParam.getLowerBound().getPrefix());
assertEquals(ParamPrefixEnum.NOT_EQUAL, dateRangeParam.getUpperBound().getPrefix());
}
@Test
public void testSetValueAsQueryTokens_neMonth_setsUpperAndLowerBounds() {
QualifiedParamList qualifiedParamList = new QualifiedParamList(1);
qualifiedParamList.add("ne1965-11");
List<QualifiedParamList> params = new ArrayList<>(1);
params.add(qualifiedParamList);
DateRangeParam dateRangeParam = new DateRangeParam();
dateRangeParam.setValuesAsQueryTokens(fhirContext, "_lastUpdated", params);
assertEquals("1965-11", dateRangeParam.getLowerBound().getValueAsString());
assertEquals("1965-11", dateRangeParam.getUpperBound().getValueAsString());
assertEquals(ParamPrefixEnum.NOT_EQUAL, dateRangeParam.getLowerBound().getPrefix());
assertEquals(ParamPrefixEnum.NOT_EQUAL, dateRangeParam.getUpperBound().getPrefix());
}
@Test
public void testSetValueAsQueryTokens_neDay_setsUpperAndLowerBounds() {
QualifiedParamList qualifiedParamList = new QualifiedParamList(1);
qualifiedParamList.add("ne1965-11-23");
List<QualifiedParamList> params = new ArrayList<>(1);
params.add(qualifiedParamList);
DateRangeParam dateRangeParam = new DateRangeParam();
dateRangeParam.setValuesAsQueryTokens(fhirContext, "_lastUpdated", params);
assertEquals("1965-11-23", dateRangeParam.getLowerBound().getValueAsString());
assertEquals("1965-11-23", dateRangeParam.getUpperBound().getValueAsString());
assertEquals(ParamPrefixEnum.NOT_EQUAL, dateRangeParam.getLowerBound().getPrefix());
assertEquals(ParamPrefixEnum.NOT_EQUAL, dateRangeParam.getUpperBound().getPrefix());
}
}

View File

@ -0,0 +1,4 @@
---
type: add
issue: 3470
title: "The server now supports date searches with the NOT_EQUALS (`ne`) prefix."

View File

@ -195,6 +195,20 @@ public class DateRangeParamR4Test {
assertEquals(ParamPrefixEnum.LESSTHAN_OR_EQUALS, ourLastDateRange.getUpperBound().getPrefix());
}
@Test
public void testSearchForOneQualifiedDateNe() throws Exception {
HttpGet httpGet = new HttpGet(ourBaseUrl + "?birthdate=ne2012-01-01");
CloseableHttpResponse status = ourClient.execute(httpGet);
consumeResponse(status);
assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals("2012-01-01", ourLastDateRange.getLowerBound().getValueAsString());
assertEquals("2012-01-01", ourLastDateRange.getUpperBound().getValueAsString());
assertEquals(ParamPrefixEnum.NOT_EQUAL, ourLastDateRange.getLowerBound().getPrefix());
assertEquals(ParamPrefixEnum.NOT_EQUAL, ourLastDateRange.getUpperBound().getPrefix());
}
@Test
public void testRangeWithDatePrecision() throws Exception {
HttpGet httpGet = new HttpGet(ourBaseUrl + "?birthdate=gt2012-01-01&birthdate=lt2012-01-03");