Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ enum class FormSchemaIncludes(val value: String) : JsonApiIncludes {
class FormSchemaRequestParameters(
offset: Int = 0,
limit: Int = 100,
filterOptions: List<FilterOption> = emptyList(),
filters: List<FilterOption> = emptyList(),
includes: List<FormSchemaIncludes> = emptyList()
) : RequestParametersWithIncludes<FormSchemaIncludes>(
offset = offset,
limit = limit,
filterOptions = filterOptions,
filters = filters,
includes = includes,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ enum class FormSubmissionVersionIncludes(val key: String) : JsonApiIncludes {
class FormSubmissionVersionRequestParameters(
offset: Int = 0,
limit: Int = 100,
filterOptions: List<FilterOption> = emptyList(),
filters: List<FilterOption> = emptyList(),
includes: List<FormSubmissionVersionIncludes> = emptyList()
) : RequestParametersWithIncludes<FormSubmissionVersionIncludes>(
offset = offset,
limit = limit,
filterOptions = filterOptions,
filters = filters,
includes = includes,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class FormSubmissionsRouter(httpClient: HttpClient) : Router(httpClient) {
suspend fun all(organisationId: String, formId: String): PaginatedList<FormSubmission> {
return fetchPaginatedJsonApiResources(
"/v3/orgs/$organisationId/data-capture/forms/$formId/submissions",
queryParameters = emptyMap<String, String>(),
queryParameters = emptyMap(),
FormSubmission::class.java,
User::class.java,
Form::class.java,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.ctrlhub.core.router.request

sealed interface FilterOption {
fun format(): String
}

class FieldFilterExpression(val field: String, val values: List<String>) : FilterOption {
override fun format(): String {
val quoted = values.joinToString(",") { "'${it}'" }
return "${field}($quoted)"
}
}

class ValueFilterExpression(val value: String) : FilterOption {
override fun format(): String = value
}

class AndExpression(val parts: List<FilterOption>) : FilterOption {
override fun format(): String = "and(${parts.joinToString(",") { it.format() }})"
}

class OrExpression(val parts: List<FilterOption>) : FilterOption {
override fun format(): String = "or(${parts.joinToString(",") { it.format() }})"
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package com.ctrlhub.core.router.request

data class FilterOption(
val field: String,
val value: String
)

abstract class AbstractRequestParameters(
val offset: Int? = null,
val limit: Int? = null,
val filterOptions: List<FilterOption>
val filters: List<FilterOption> = emptyList()
) {
open fun toMap(): Map<String, String> {
val queryParams = mutableMapOf<String, String>()
offset?.let { queryParams["offset"] = it.toString() }
limit?.let { queryParams["limit"] = it.toString() }

filterOptions.forEach { queryParams["filter"] = "${it.field}('${it.value}')" }
val parts = mutableListOf<String>()

for (expr in filters) {
parts += expr.format()
}

if (parts.isNotEmpty()) {
queryParams["filter"] = parts.joinToString(",")
}

return queryParams
}
Expand All @@ -30,10 +33,11 @@ class RequestParameters(
open class RequestParametersWithIncludes<TIncludes>(
offset: Int? = null,
limit: Int? = null,
filterOptions: List<FilterOption> = emptyList(),
filters: List<FilterOption> = emptyList(),
val includes: List<TIncludes> = emptyList()
) : AbstractRequestParameters(offset, limit, filterOptions) where TIncludes : JsonApiIncludes {
) : AbstractRequestParameters(offset, limit, filters) where TIncludes : JsonApiIncludes {

@Suppress("unused")
fun withIncludes(vararg includes: TIncludes): RequestParametersWithIncludes<TIncludes> {
return copy(includes = this.includes + includes)
}
Expand All @@ -53,7 +57,7 @@ open class RequestParametersWithIncludes<TIncludes>(
}

private fun copy(
filterOptions: List<FilterOption> = this.filterOptions,
includes: List<TIncludes> = this.includes
) = RequestParametersWithIncludes(offset, limit, filterOptions, includes)
includes: List<TIncludes> = this.includes,
filters: List<FilterOption> = this.filters
) = RequestParametersWithIncludes(offset, limit, filters, includes)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.ctrlhub.core.router.request

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

class RequestParametersFiltersTest {

@Test
fun `and of two field expressions formats correctly`() {
val expr = AndExpression(
listOf(
FieldFilterExpression("status", listOf("open")),
FieldFilterExpression("category", listOf("news"))
)
)

val params = RequestParameters(filterOptions = listOf(expr))
val map = params.toMap()

assertEquals("and(status('open'),category('news'))", map["filter"])
}

@Test
fun `and of functions formats correctly`() {
val expr = AndExpression(
listOf(
ValueFilterExpression("is_latest()"),
ValueFilterExpression("no_start()"),
)
)

val params = RequestParameters(filterOptions = listOf(expr))
val map = params.toMap()

assertEquals("and(is_latest(),no_start())", map["filter"])
}

@Test
fun `mixed and expression with field and function`() {
val expr = AndExpression(
listOf(
FieldFilterExpression("status", listOf("active")),
ValueFilterExpression("is_latest()")
)
)

val params = RequestParameters(filterOptions = listOf(expr))
val map = params.toMap()

assertEquals("and(status('active'),is_latest())", map["filter"])
}
}