Skip to content

Commit 13d3e86

Browse files
committed
fix: allow use of a list of values for field filtering, and format according
1 parent 4e9005c commit 13d3e86

File tree

2 files changed

+58
-3
lines changed

2 files changed

+58
-3
lines changed

src/main/kotlin/com/ctrlhub/core/router/request/FilterExpression.kt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,22 @@ sealed interface FilterOption {
44
fun format(): String
55
}
66

7-
class FieldFilterExpression(val field: String, val value: String) : FilterOption {
8-
override fun format(): String = "${field}('$value')"
7+
class FieldFilterExpression<T>(val field: String, val value: T) : FilterOption {
8+
private fun quoteIfNeeded(v: Any?): String = when (v) {
9+
is String -> "'${v.replace("'", "\\'")}'"
10+
null -> "''"
11+
else -> v.toString()
12+
}
13+
14+
override fun format(): String {
15+
return when (value) {
16+
is List<*> -> {
17+
val inner = value.joinToString(",") { quoteIfNeeded(it) }
18+
"$field($inner)"
19+
}
20+
else -> "$field(${quoteIfNeeded(value)})"
21+
}
22+
}
923
}
1024

1125
class ValueFilterExpression(val value: String) : FilterOption {
@@ -16,6 +30,7 @@ class AndExpression(val parts: List<FilterOption>) : FilterOption {
1630
override fun format(): String = "and(${parts.joinToString(",") { it.format() }})"
1731
}
1832

33+
@Suppress("unused")
1934
class OrExpression(val parts: List<FilterOption>) : FilterOption {
2035
override fun format(): String = "or(${parts.joinToString(",") { it.format() }})"
2136
}

src/test/kotlin/com/ctrlhub/core/router/request/RequestParametersFiltersTest.kt

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,45 @@ class RequestParametersFiltersTest {
4949

5050
assertEquals("and(status('active'),is_latest())", map["filter"])
5151
}
52-
}
5352

53+
@Test
54+
fun `field list formats correctly`() {
55+
val ids = listOf(
56+
"06e55d1c-f816-48b2-b11b-debdb3115b2f",
57+
"5f43b904-8d5b-4b81-9258-b14aafe858d4",
58+
"9b31bdd1-2785-4419-b1b3-36ccd35d22c6"
59+
)
60+
61+
val expr = FieldFilterExpression("payload_operations", ids)
62+
val params = RequestParameters(filters = listOf(expr))
63+
val map = params.toMap()
64+
65+
assertEquals(
66+
"payload_operations('06e55d1c-f816-48b2-b11b-debdb3115b2f','5f43b904-8d5b-4b81-9258-b14aafe858d4','9b31bdd1-2785-4419-b1b3-36ccd35d22c6')",
67+
map["filter"]
68+
)
69+
}
70+
71+
@Test
72+
fun `or of field list and single field formats correctly`() {
73+
val ids = listOf(
74+
"06e55d1c-f816-48b2-b11b-debdb3115b2f",
75+
"5f43b904-8d5b-4b81-9258-b14aafe858d4"
76+
)
77+
78+
val expr = OrExpression(
79+
listOf(
80+
FieldFilterExpression("payload_operations", ids),
81+
FieldFilterExpression("category", "updates")
82+
)
83+
)
84+
85+
val params = RequestParameters(filters = listOf(expr))
86+
val map = params.toMap()
87+
88+
assertEquals(
89+
"or(payload_operations('06e55d1c-f816-48b2-b11b-debdb3115b2f','5f43b904-8d5b-4b81-9258-b14aafe858d4'),category('updates'))",
90+
map["filter"]
91+
)
92+
}
93+
}

0 commit comments

Comments
 (0)