diff --git a/src/main/kotlin/com/ctrlhub/core/router/request/FilterExpression.kt b/src/main/kotlin/com/ctrlhub/core/router/request/FilterExpression.kt index a70ed0f..1f9a716 100644 --- a/src/main/kotlin/com/ctrlhub/core/router/request/FilterExpression.kt +++ b/src/main/kotlin/com/ctrlhub/core/router/request/FilterExpression.kt @@ -4,8 +4,22 @@ sealed interface FilterOption { fun format(): String } -class FieldFilterExpression(val field: String, val value: String) : FilterOption { - override fun format(): String = "${field}('$value')" +class FieldFilterExpression(val field: String, val value: T) : FilterOption { + private fun quoteIfNeeded(v: Any?): String = when (v) { + is String -> "'${v.replace("'", "\\'")}'" + null -> "''" + else -> v.toString() + } + + override fun format(): String { + return when (value) { + is List<*> -> { + val inner = value.joinToString(",") { quoteIfNeeded(it) } + "$field($inner)" + } + else -> "$field(${quoteIfNeeded(value)})" + } + } } class ValueFilterExpression(val value: String) : FilterOption { @@ -16,6 +30,7 @@ class AndExpression(val parts: List) : FilterOption { override fun format(): String = "and(${parts.joinToString(",") { it.format() }})" } +@Suppress("unused") class OrExpression(val parts: List) : FilterOption { override fun format(): String = "or(${parts.joinToString(",") { it.format() }})" } \ No newline at end of file diff --git a/src/test/kotlin/com/ctrlhub/core/router/request/RequestParametersFiltersTest.kt b/src/test/kotlin/com/ctrlhub/core/router/request/RequestParametersFiltersTest.kt index e0b94ef..fffdd07 100644 --- a/src/test/kotlin/com/ctrlhub/core/router/request/RequestParametersFiltersTest.kt +++ b/src/test/kotlin/com/ctrlhub/core/router/request/RequestParametersFiltersTest.kt @@ -49,5 +49,45 @@ class RequestParametersFiltersTest { assertEquals("and(status('active'),is_latest())", map["filter"]) } -} + @Test + fun `field list formats correctly`() { + val ids = listOf( + "06e55d1c-f816-48b2-b11b-debdb3115b2f", + "5f43b904-8d5b-4b81-9258-b14aafe858d4", + "9b31bdd1-2785-4419-b1b3-36ccd35d22c6" + ) + + val expr = FieldFilterExpression("payload_operations", ids) + val params = RequestParameters(filters = listOf(expr)) + val map = params.toMap() + + assertEquals( + "payload_operations('06e55d1c-f816-48b2-b11b-debdb3115b2f','5f43b904-8d5b-4b81-9258-b14aafe858d4','9b31bdd1-2785-4419-b1b3-36ccd35d22c6')", + map["filter"] + ) + } + + @Test + fun `or of field list and single field formats correctly`() { + val ids = listOf( + "06e55d1c-f816-48b2-b11b-debdb3115b2f", + "5f43b904-8d5b-4b81-9258-b14aafe858d4" + ) + + val expr = OrExpression( + listOf( + FieldFilterExpression("payload_operations", ids), + FieldFilterExpression("category", "updates") + ) + ) + + val params = RequestParameters(filters = listOf(expr)) + val map = params.toMap() + + assertEquals( + "or(payload_operations('06e55d1c-f816-48b2-b11b-debdb3115b2f','5f43b904-8d5b-4b81-9258-b14aafe858d4'),category('updates'))", + map["filter"] + ) + } +}