diff --git a/api/expression-parser.api b/api/expression-parser.api index eeb4e0e..759b6b2 100644 --- a/api/expression-parser.api +++ b/api/expression-parser.api @@ -116,6 +116,7 @@ public final class org/hisp/dhis/lib/expression/ast/NamedFunction : java/lang/En public static final field d2_hasUserRole Lorg/hisp/dhis/lib/expression/ast/NamedFunction; public static final field d2_hasValue Lorg/hisp/dhis/lib/expression/ast/NamedFunction; public static final field d2_inOrgUnitGroup Lorg/hisp/dhis/lib/expression/ast/NamedFunction; + public static final field d2_inUserGroup Lorg/hisp/dhis/lib/expression/ast/NamedFunction; public static final field d2_lastEventDate Lorg/hisp/dhis/lib/expression/ast/NamedFunction; public static final field d2_left Lorg/hisp/dhis/lib/expression/ast/NamedFunction; public static final field d2_length Lorg/hisp/dhis/lib/expression/ast/NamedFunction; @@ -1383,6 +1384,7 @@ public abstract interface class org/hisp/dhis/lib/expression/spi/ExpressionFunct public abstract fun d2_hasUserRole (Ljava/lang/String;Ljava/util/List;)Z public abstract fun d2_hasValue (Lorg/hisp/dhis/lib/expression/spi/VariableValue;)Z public abstract fun d2_inOrgUnitGroup (Ljava/lang/String;Lorg/hisp/dhis/lib/expression/spi/VariableValue;Ljava/util/Map;)Z + public abstract fun d2_inUserGroup (Ljava/lang/String;Ljava/util/List;)Z public abstract fun d2_lastEventDate (Lorg/hisp/dhis/lib/expression/spi/VariableValue;)Lkotlinx/datetime/LocalDate; public abstract fun d2_left (Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/String; public abstract fun d2_length (Ljava/lang/String;)I @@ -1444,6 +1446,7 @@ public final class org/hisp/dhis/lib/expression/spi/ExpressionFunctions$DefaultI public static fun d2_hasUserRole (Lorg/hisp/dhis/lib/expression/spi/ExpressionFunctions;Ljava/lang/String;Ljava/util/List;)Z public static fun d2_hasValue (Lorg/hisp/dhis/lib/expression/spi/ExpressionFunctions;Lorg/hisp/dhis/lib/expression/spi/VariableValue;)Z public static fun d2_inOrgUnitGroup (Lorg/hisp/dhis/lib/expression/spi/ExpressionFunctions;Ljava/lang/String;Lorg/hisp/dhis/lib/expression/spi/VariableValue;Ljava/util/Map;)Z + public static fun d2_inUserGroup (Lorg/hisp/dhis/lib/expression/spi/ExpressionFunctions;Ljava/lang/String;Ljava/util/List;)Z public static fun d2_lastEventDate (Lorg/hisp/dhis/lib/expression/spi/ExpressionFunctions;Lorg/hisp/dhis/lib/expression/spi/VariableValue;)Lkotlinx/datetime/LocalDate; public static fun d2_left (Lorg/hisp/dhis/lib/expression/spi/ExpressionFunctions;Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/String; public static fun d2_length (Lorg/hisp/dhis/lib/expression/spi/ExpressionFunctions;Ljava/lang/String;)I diff --git a/build.gradle.kts b/build.gradle.kts index 57df513..7bf746e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ repositories { mavenCentral() } -version = "1.1.11-SNAPSHOT" +version = "1.1.12-SNAPSHOT" group = "org.hisp.dhis.lib.expression" if (project.hasProperty("removeSnapshotSuffix")) { diff --git a/src/commonMain/kotlin/org/hisp/dhis/lib/expression/ast/NamedFunction.kt b/src/commonMain/kotlin/org/hisp/dhis/lib/expression/ast/NamedFunction.kt index 4de803d..014a8e9 100644 --- a/src/commonMain/kotlin/org/hisp/dhis/lib/expression/ast/NamedFunction.kt +++ b/src/commonMain/kotlin/org/hisp/dhis/lib/expression/ast/NamedFunction.kt @@ -58,6 +58,7 @@ enum class NamedFunction( d2_extractDataMatrixValue("d2:extractDataMatrixValue", ValueType.STRING, ValueType.STRING, ValueType.STRING), d2_floor("d2:floor", ValueType.NUMBER, ValueType.NUMBER), d2_hasUserRole("d2:hasUserRole", ValueType.BOOLEAN, ValueType.STRING), + d2_inUserGroup("d2:inUserGroup", ValueType.BOOLEAN, ValueType.STRING), d2_hasValue("d2:hasValue", ValueType.BOOLEAN, ValueType.MIXED), d2_inOrgUnitGroup("d2:inOrgUnitGroup", ValueType.BOOLEAN, ValueType.STRING), d2_lastEventDate("d2:lastEventDate", ValueType.DATE, ValueType.STRING), diff --git a/src/commonMain/kotlin/org/hisp/dhis/lib/expression/eval/Calculator.kt b/src/commonMain/kotlin/org/hisp/dhis/lib/expression/eval/Calculator.kt index cd682c0..d5494cd 100644 --- a/src/commonMain/kotlin/org/hisp/dhis/lib/expression/eval/Calculator.kt +++ b/src/commonMain/kotlin/org/hisp/dhis/lib/expression/eval/Calculator.kt @@ -92,7 +92,10 @@ internal class Calculator( NamedFunction.d2_floor -> functions.d2_floor(evalToNumber(fn.child(0))) NamedFunction.d2_hasUserRole -> functions.d2_hasUserRole( evalToString(fn.child(0)), - data.supplementaryValues["USER"]) + data.supplementaryValues["USER_ROLES"]) + NamedFunction.d2_inUserGroup -> functions.d2_inUserGroup( + evalToString(fn.child(0)), + data.supplementaryValues["USER_GROUPS"]) NamedFunction.d2_hasValue -> try { functions.d2_hasValue(evalToVar(fn.child(0))) } catch (e: IllegalExpressionException) { diff --git a/src/commonMain/kotlin/org/hisp/dhis/lib/expression/spi/ExpressionFunctions.kt b/src/commonMain/kotlin/org/hisp/dhis/lib/expression/spi/ExpressionFunctions.kt index 4fbd7d0..5fb4fa7 100644 --- a/src/commonMain/kotlin/org/hisp/dhis/lib/expression/spi/ExpressionFunctions.kt +++ b/src/commonMain/kotlin/org/hisp/dhis/lib/expression/spi/ExpressionFunctions.kt @@ -221,6 +221,11 @@ fun interface ExpressionFunctions { return roles.contains(role) } + fun d2_inUserGroup(userGroup: String?, userGroups: List?): Boolean { + if (userGroups == null) throw IllegalExpressionException("Supplementary data for user needs to be provided") + return userGroups.contains(userGroup) + } + fun d2_hasValue(value: VariableValue?): Boolean { return value?.value != null } diff --git a/src/commonMain/kotlin/org/hisp/dhis/lib/expression/syntax/ExpressionGrammar.kt b/src/commonMain/kotlin/org/hisp/dhis/lib/expression/syntax/ExpressionGrammar.kt index 9d1e348..77206ac 100644 --- a/src/commonMain/kotlin/org/hisp/dhis/lib/expression/syntax/ExpressionGrammar.kt +++ b/src/commonMain/kotlin/org/hisp/dhis/lib/expression/syntax/ExpressionGrammar.kt @@ -116,6 +116,7 @@ object ExpressionGrammar { fn(NamedFunction.d2_extractDataMatrixValue, expr, expr), fn(NamedFunction.d2_floor, expr), fn(NamedFunction.d2_hasUserRole, expr), + fn(NamedFunction.d2_inUserGroup, expr), fn(NamedFunction.d2_inOrgUnitGroup, expr), fn(NamedFunction.d2_lastEventDate, expr), fn(NamedFunction.d2_left, expr, expr), diff --git a/src/commonTest/kotlin/org/hisp/dhis/lib/expression/function/HasUserRoleTest.kt b/src/commonTest/kotlin/org/hisp/dhis/lib/expression/function/HasUserRoleTest.kt index e894c3e..c9ae64b 100644 --- a/src/commonTest/kotlin/org/hisp/dhis/lib/expression/function/HasUserRoleTest.kt +++ b/src/commonTest/kotlin/org/hisp/dhis/lib/expression/function/HasUserRoleTest.kt @@ -15,7 +15,7 @@ internal class HasUserRoleTest { @Test fun testHasUserRole_Null() { - assertFalse(evaluate("d2:hasUserRole(null)", mapOf("USER" to listOf("admin")))) + assertFalse(evaluate("d2:hasUserRole(null)", mapOf("USER_ROLES" to listOf("admin")))) } @Test @@ -26,9 +26,9 @@ internal class HasUserRoleTest { @Test fun testHasUserRole() { - assertTrue(evaluate("d2:hasUserRole(\"admin\")", mapOf("USER" to listOf("admin")))) - assertFalse(evaluate("d2:hasUserRole(\"admin\")", mapOf("USER" to listOf("guest")))) - assertTrue(evaluate("d2:hasUserRole(\"admin\")", mapOf("USER" to listOf("foo","admin")))) + assertTrue(evaluate("d2:hasUserRole(\"admin\")", mapOf("USER_ROLES" to listOf("admin")))) + assertFalse(evaluate("d2:hasUserRole(\"admin\")", mapOf("USER_ROLES" to listOf("guest")))) + assertTrue(evaluate("d2:hasUserRole(\"admin\")", mapOf("USER_ROLES" to listOf("foo","admin")))) } private fun evaluate(expression: String, supplementaryValues: Map>): Boolean { diff --git a/src/commonTest/kotlin/org/hisp/dhis/lib/expression/function/InUserGroupTest.kt b/src/commonTest/kotlin/org/hisp/dhis/lib/expression/function/InUserGroupTest.kt new file mode 100644 index 0000000..87275aa --- /dev/null +++ b/src/commonTest/kotlin/org/hisp/dhis/lib/expression/function/InUserGroupTest.kt @@ -0,0 +1,37 @@ +package org.hisp.dhis.lib.expression.function + +import org.hisp.dhis.lib.expression.Expression +import org.hisp.dhis.lib.expression.ExpressionMode +import org.hisp.dhis.lib.expression.spi.ExpressionData +import org.hisp.dhis.lib.expression.spi.IllegalExpressionException +import kotlin.test.* + +/** + * Test of the `d2:inUserGroup` function. + * + * @author Zubair Asghar + */ +internal class InUserGroupTest { + + @Test + fun testInUserGroup_Null() { + assertFalse(evaluate("d2:inUserGroup(null)", mapOf("USER_GROUPS" to listOf("uidusgroup0")))) + } + + @Test + fun testInUserGroup_NoData() { + val ex = assertFailsWith(IllegalExpressionException::class) { evaluate("d2:inUserGroup(\"uidougroup1\")", mapOf()) } + assertEquals("Supplementary data for user needs to be provided", ex.message) + } + + @Test + fun testInUserGroup() { + assertTrue(evaluate("d2:inUserGroup(\"uidusgroup0\")", mapOf("USER_GROUPS" to listOf("uidusgroup0")))) + assertFalse(evaluate("d2:inUserGroup(\"uidusgroup0\")", mapOf("USER_GROUPS" to listOf("uidusgroup1")))) + } + + private fun evaluate(expression: String, supplementaryValues: Map>): Boolean { + val data: ExpressionData = ExpressionData().copy(supplementaryValues = supplementaryValues) + return Expression(expression, ExpressionMode.RULE_ENGINE_ACTION).evaluate( { _: String -> null }, data) as Boolean + } +} \ No newline at end of file