Skip to content

Commit 64d3ce8

Browse files
committed
feat: support data capture forms endpoint
1 parent c9ef202 commit 64d3ce8

File tree

4 files changed

+140
-0
lines changed

4 files changed

+140
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.ctrlhub.core.datacapture
2+
3+
import com.ctrlhub.core.Api
4+
import com.ctrlhub.core.datacapture.response.Form
5+
import com.ctrlhub.core.router.Router
6+
import io.ktor.client.HttpClient
7+
8+
class FormsRouter(httpClient: HttpClient) : Router(httpClient) {
9+
suspend fun all(organisationId: String): List<Form> {
10+
return fetchJsonApiResources("/v3/orgs/${organisationId}/data-capture/forms", emptyMap(), Form::class.java)
11+
}
12+
13+
suspend fun one(organisationId: String, formId: String): Form {
14+
return fetchJsonApiResource("/v3/orgs/${organisationId}/data-capture-forms/${formId}")
15+
}
16+
}
17+
18+
val Api.forms: FormsRouter
19+
get() = FormsRouter(httpClient)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.ctrlhub.core.datacapture.response
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator
4+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
5+
import com.fasterxml.jackson.annotation.JsonProperty
6+
import com.github.jasminb.jsonapi.StringIdHandler
7+
import com.github.jasminb.jsonapi.annotations.Id
8+
import com.github.jasminb.jsonapi.annotations.Meta
9+
import com.github.jasminb.jsonapi.annotations.Type
10+
import java.time.LocalDateTime
11+
12+
@Type("forms")
13+
@JsonIgnoreProperties(ignoreUnknown = true)
14+
class Form @JsonCreator constructor(
15+
@Id(StringIdHandler::class) var id: String = "",
16+
@JsonProperty("name") var name: String = "",
17+
@JsonProperty("status") var status: String = "",
18+
@Meta
19+
var meta: FormMeta? = null
20+
) {
21+
constructor(): this(
22+
id = "",
23+
name = "",
24+
status = ""
25+
)
26+
}
27+
28+
@JsonIgnoreProperties(ignoreUnknown = true)
29+
class FormMeta @JsonCreator constructor(
30+
@JsonProperty("created_at") var createdAt: LocalDateTime,
31+
@JsonProperty("updated_at") var updatedAt: LocalDateTime
32+
)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.ctrlhub.core.datacapture
2+
3+
import com.ctrlhub.core.configureForTest
4+
import io.ktor.client.HttpClient
5+
import io.ktor.client.engine.mock.MockEngine
6+
import io.ktor.client.engine.mock.respond
7+
import io.ktor.http.HttpHeaders
8+
import io.ktor.http.HttpStatusCode
9+
import io.ktor.http.headersOf
10+
import io.ktor.utils.io.ByteReadChannel
11+
import kotlinx.coroutines.runBlocking
12+
import java.nio.file.Files
13+
import java.nio.file.Paths
14+
import kotlin.test.Test
15+
import kotlin.test.assertEquals
16+
17+
class FormsRouterTest {
18+
19+
@Test
20+
fun `test can get all forms successfully`() {
21+
// Load mocked JSON response
22+
val jsonFilePath = Paths.get("src/test/resources/datacapture/all-forms-response.json")
23+
val jsonContent = Files.readString(jsonFilePath)
24+
25+
// Create a mock engine to intercept HTTP calls
26+
val mockEngine = MockEngine { request ->
27+
respond(
28+
content = ByteReadChannel(jsonContent),
29+
status = HttpStatusCode.OK,
30+
headers = headersOf(HttpHeaders.ContentType, "application/json")
31+
)
32+
}
33+
34+
val formsRouter = FormsRouter(httpClient = HttpClient(mockEngine).configureForTest())
35+
36+
runBlocking {
37+
val organisationId = "test-org-id"
38+
val response = formsRouter.all(organisationId)
39+
40+
// Assuming the mock response includes 1 form as in your earlier example
41+
assertEquals(1, response.size)
42+
assertEquals("Form 3", response[0].name)
43+
assertEquals("active", response[0].status)
44+
}
45+
}
46+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"data": [
3+
{
4+
"id": "2fa82b8b-6fc3-4c0b-8e47-196b3b67f3b9",
5+
"type": "forms",
6+
"attributes": {
7+
"description": "...",
8+
"name": "Form 3",
9+
"status": "active"
10+
},
11+
"relationships": {
12+
"categories": {
13+
"data": [
14+
{
15+
"id": "0f99ec15-9172-4994-bb5a-ff22e0185a47",
16+
"type": "form-categories"
17+
}
18+
]
19+
},
20+
"organisation": {
21+
"data": {
22+
"id": "705adf65-e1cf-4b45-97b0-f3d055245b56",
23+
"type": "organisations"
24+
}
25+
},
26+
"schemas": {
27+
"data": []
28+
}
29+
},
30+
"meta": {
31+
"created_at": "2025-05-07T07:31:52.473Z",
32+
"updated_at": "2025-05-12T11:49:20.536Z",
33+
"counts": {
34+
"schemas": 0,
35+
"categories": 1
36+
}
37+
}
38+
}
39+
],
40+
"jsonapi": {
41+
"version": "1.0"
42+
}
43+
}

0 commit comments

Comments
 (0)