From 7556f6f272f82964f8b21b1a51a1e94010490042 Mon Sep 17 00:00:00 2001 From: Giuseppe Nespolino Date: Wed, 8 Nov 2023 13:08:36 +0100 Subject: [PATCH] feat: add supports for !eq in dimension endpoint [DHIS2-13779] --- .../webapi/dimension/DimensionFilters.java | 18 ++++---- .../dimension/DimensionFiltersTest.java | 44 +++++++++++-------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/dimension/DimensionFilters.java b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/dimension/DimensionFilters.java index 7909ef951ac8..94b2eaedf995 100644 --- a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/dimension/DimensionFilters.java +++ b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/dimension/DimensionFilters.java @@ -34,10 +34,9 @@ import java.util.Objects; import java.util.Optional; import java.util.StringTokenizer; -import java.util.function.BiFunction; +import java.util.function.BiPredicate; import java.util.function.Function; import java.util.function.Predicate; -import java.util.stream.Collectors; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; @@ -67,7 +66,7 @@ public static DimensionFilters of(Collection filterStrings) { .map(String::trim) .map(SingleFilter::of) .filter(Objects::nonNull) - .collect(Collectors.toList()); + .toList(); if (filters.isEmpty()) { return EMPTY_DATA_DIMENSION_FILTER; @@ -94,28 +93,27 @@ private static class SingleFilter implements Predicate { "displayName", DimensionResponse::getDisplayName, "displayShortName", DimensionResponse::getDisplayShortName); - private static final Map> OPERATOR_MAP = - new HashMap<>(); + private static final Map> OPERATOR_MAP = new HashMap<>(); static { putOperator("startsWith", String::startsWith, true); putOperator("endsWith", String::endsWith, true); - putOperator("eq", String::equals); + putOperator("eq", String::equals, true); putOperator("ieq", String::equalsIgnoreCase); putOperator("ne", (fv, v) -> !fv.equals(v)); putOperator("like", String::contains, true); putOperator("ilike", (fv, v) -> fv.toLowerCase().contains(v.toLowerCase()), true); } - private static void putOperator(String operator, BiFunction function) { + private static void putOperator(String operator, BiPredicate function) { putOperator(operator, function, false); } private static void putOperator( - String operator, BiFunction function, boolean negateAlso) { + String operator, BiPredicate function, boolean negateAlso) { OPERATOR_MAP.put(operator, function); if (negateAlso) { - OPERATOR_MAP.put("!" + operator, (s, s2) -> !function.apply(s, s2)); + OPERATOR_MAP.put("!" + operator, (s, s2) -> !function.test(s, s2)); } } @@ -153,7 +151,7 @@ public boolean test(DimensionResponse dimension) { private boolean applyOperator(String fieldValue) { return Optional.ofNullable(OPERATOR_MAP.get(operator)) - .map(operation -> operation.apply(fieldValue, value)) + .map(operation -> operation.test(fieldValue, value)) .orElse(false); } } diff --git a/dhis-2/dhis-web-api/src/test/java/org/hisp/dhis/analytics/dimension/DimensionFiltersTest.java b/dhis-2/dhis-web-api/src/test/java/org/hisp/dhis/analytics/dimension/DimensionFiltersTest.java index 6ba5de2f192a..3dbf385b89b3 100644 --- a/dhis-2/dhis-web-api/src/test/java/org/hisp/dhis/analytics/dimension/DimensionFiltersTest.java +++ b/dhis-2/dhis-web-api/src/test/java/org/hisp/dhis/analytics/dimension/DimensionFiltersTest.java @@ -27,6 +27,7 @@ */ package org.hisp.dhis.analytics.dimension; +import static org.apache.commons.lang3.tuple.Pair.of; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; @@ -47,6 +48,10 @@ class DimensionFiltersTest { + /** + * A map of all the fields in {@link DimensionResponse} and a function that creates a {@link DimensionResponse} + * with that field set to the given value. + */ private static final Map> BUILDER_MAP = Map.of( "id", s -> DimensionResponse.builder().id(s).build(), @@ -58,33 +63,35 @@ class DimensionFiltersTest { "displayName", s -> DimensionResponse.builder().displayName(s).build(), "displayShortName", s -> DimensionResponse.builder().displayShortName(s).build()); + public static final String STRING_TO_TEST_FILTER_ON = "TeSt"; + + /** + * A map of all the operators and the expected result of applying them to the {@link DimensionResponse} created + * by the corresponding {@link Function} in {@link #BUILDER_MAP} with the given {@link #STRING_TO_TEST_FILTER_ON}. + * The left value is the value to test for positive assertion, the right value is the value to test for negative. + */ private static final Map> OPERATORS = Stream.concat( Map.of( - "startsWith", Pair.of("Te", "eS"), - "!startsWith", Pair.of("eS", "Te"), - "endsWith", Pair.of("St", "eS"), - "!endsWith", Pair.of("eS", "St"), - "eq", Pair.of("TeSt", "tEsT"), - "ieq", Pair.of("test", "random")) + "startsWith", of("Te", "eS"), + "!startsWith", of("eS", "Te"), + "endsWith", of("St", "eS"), + "!endsWith", of("eS", "St"), + "eq", of("TeSt", "tEsT"), + "!eq", of("whatever", "TeSt"), + "ieq", of("test", "random")) .entrySet() .stream(), Map.of( - "ne", - Pair.of("random", "TeSt"), - "like", - Pair.of("eS", "es"), - "!like", - Pair.of("es", "eS"), - "ilike", - Pair.of("es", "et"), - "!ilike", - Pair.of("et", "es")) + "ne", of("random", "TeSt"), + "like", of("eS", "es"), + "!like", of("es", "eS"), + "ilike", of("es", "et"), + "!ilike", of("et", "es")) .entrySet() .stream()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - public static final String TEST_STRING = "TeSt"; @Test void testDimensionFilterConstructor() { @@ -133,7 +140,8 @@ void testOperators() { @Test void testFieldsAndOperators() { - BUILDER_MAP.forEach((s, builder) -> assertAllOpsOnField(s, builder.apply(TEST_STRING))); + BUILDER_MAP.forEach((s, builder) -> assertAllOpsOnField(s, builder.apply( + STRING_TO_TEST_FILTER_ON))); } private void assertAllOpsOnField(String fieldName, DimensionResponse response) {