Skip to content

Commit 9356f1c

Browse files
committed
feat: support creating a form submission
1 parent 91029eb commit 9356f1c

File tree

7 files changed

+125
-2
lines changed

7 files changed

+125
-2
lines changed

src/main/kotlin/com/ctrlhub/core/assets/equipment/exposures/EquipmentExposuresRouter.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.ctrlhub.core.router.request.FilterOption
99
import com.ctrlhub.core.router.request.JsonApiIncludes
1010
import com.ctrlhub.core.router.request.RequestParametersWithIncludes
1111
import io.ktor.client.HttpClient
12+
import io.ktor.http.ContentType
1213

1314
enum class EquipmentExposureIncludes(val value: String) : JsonApiIncludes {
1415
Equipment("equipment"),
@@ -92,6 +93,7 @@ class EquipmentExposuresRouter(httpClient: HttpClient) : Router(httpClient) {
9293
val request = EquipmentExposureRequestParameters()
9394
return postJsonApiResource(
9495
"/v3/orgs/$organisationId/assets/equipment/$equipmentId/exposures", resource, request.toMap(),
96+
contentType = ContentType.Application.Json,
9597
EquipmentItem::class.java
9698
)
9799
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.ctrlhub.core.datacapture
2+
3+
import com.ctrlhub.core.Api
4+
import com.ctrlhub.core.datacapture.resource.FormSubmissionVersion
5+
import com.ctrlhub.core.datacapture.response.FormSchema
6+
import com.ctrlhub.core.router.Router
7+
import io.ktor.client.HttpClient
8+
import io.ktor.http.ContentType
9+
10+
class FormSubmissionsRouter(httpClient: HttpClient) : Router(httpClient) {
11+
suspend fun create(organisationId: String, formId: String, schemaId: String, payload: Map<String, Any>): FormSubmissionVersion {
12+
return postJsonApiResource("/v3/orgs/$organisationId/data-capture/forms/$formId/submissions", requestBody = FormSubmissionVersion(
13+
payload = payload,
14+
id = "",
15+
schema = FormSchema(
16+
id = schemaId,
17+
rawSchema = null,
18+
)
19+
), queryParameters = emptyMap(), contentType = ContentType.parse("application/vnd.api+json"), FormSubmissionVersion::class.java,
20+
FormSchema::class.java)
21+
}
22+
}
23+
24+
val Api.formSubmissions
25+
get() = FormSubmissionsRouter(httpClient = httpClient)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.ctrlhub.core.datacapture.resource
2+
3+
import com.ctrlhub.core.datacapture.response.FormSchema
4+
import com.fasterxml.jackson.annotation.JsonCreator
5+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
6+
import com.fasterxml.jackson.annotation.JsonProperty
7+
import com.github.jasminb.jsonapi.StringIdHandler
8+
import com.github.jasminb.jsonapi.annotations.Id
9+
import com.github.jasminb.jsonapi.annotations.Relationship
10+
import com.github.jasminb.jsonapi.annotations.Type
11+
12+
@JsonIgnoreProperties(ignoreUnknown = true)
13+
@Type("form-submission-versions")
14+
data class FormSubmissionVersion @JsonCreator constructor(
15+
@Id(StringIdHandler::class)
16+
var id: String = "",
17+
18+
@JsonProperty("payload")
19+
var payload: Map<String, Any>? = null,
20+
21+
@JsonProperty("iteration")
22+
var iteration: Int = 0,
23+
24+
@Relationship("schema")
25+
var schema: FormSchema? = null,
26+
)

src/main/kotlin/com/ctrlhub/core/datacapture/response/FormSchema.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ import com.fasterxml.jackson.annotation.JsonCreator
44
import com.fasterxml.jackson.annotation.JsonIgnore
55
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
66
import com.fasterxml.jackson.annotation.JsonProperty
7+
import com.github.jasminb.jsonapi.StringIdHandler
8+
import com.github.jasminb.jsonapi.annotations.Id
79
import com.github.jasminb.jsonapi.annotations.Meta
810
import com.github.jasminb.jsonapi.annotations.Type
911
import java.time.LocalDateTime
1012

1113
@Type("form-schemas")
1214
data class FormSchema(
15+
@Id(StringIdHandler::class)
1316
val id: String? = null,
1417
@JsonIgnore val rawSchema: String? = null,
1518
@Meta

src/main/kotlin/com/ctrlhub/core/router/Router.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,11 @@ abstract class Router(val httpClient: HttpClient) {
3838
protected suspend inline fun <reified T> performPost(
3939
endpoint: String,
4040
body: T,
41-
queryParameters: Map<String, String> = emptyMap()
41+
queryParameters: Map<String, String> = emptyMap(),
42+
contentType: ContentType = ContentType.Application.Json
4243
): HttpResponse {
4344
return httpClient.post(endpoint) {
44-
contentType(ContentType.Application.Json)
45+
contentType(contentType)
4546
url {
4647
queryParameters.forEach { key, value -> parameters.append(key, value) }
4748
}
@@ -188,6 +189,7 @@ abstract class Router(val httpClient: HttpClient) {
188189
endpoint: String,
189190
requestBody: T,
190191
queryParameters: Map<String, String> = emptyMap(),
192+
contentType: ContentType = ContentType.Application.Json,
191193
vararg includedClasses: Class<*>
192194
): T {
193195
return try {
@@ -201,6 +203,7 @@ abstract class Router(val httpClient: HttpClient) {
201203
val response: HttpResponse = performPost(
202204
endpoint = endpoint,
203205
body = jsonApiRequest,
206+
contentType = contentType,
204207
queryParameters = queryParameters
205208
)
206209

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.ctrlhub.core.datacapture
2+
3+
import com.ctrlhub.core.configureForTest
4+
import com.ctrlhub.core.datacapture.resource.FormSubmissionVersion
5+
import io.ktor.client.*
6+
import io.ktor.client.engine.mock.*
7+
import io.ktor.http.*
8+
import kotlinx.coroutines.runBlocking
9+
import org.junit.jupiter.api.Test
10+
import java.nio.file.Files
11+
import java.nio.file.Paths
12+
import kotlin.test.assertEquals
13+
import kotlin.test.assertNotNull
14+
import kotlin.test.assertIs
15+
16+
class FormSubmissionsRouterTest {
17+
18+
@Test
19+
fun `can create form submission`() {
20+
val jsonFilePath = Paths.get("src/test/resources/datacapture/form-submission-response.json")
21+
val jsonContent = Files.readString(jsonFilePath)
22+
23+
val mockEngine = MockEngine { request ->
24+
respond(
25+
content = jsonContent,
26+
status = HttpStatusCode.Created,
27+
headers = headersOf(HttpHeaders.ContentType, "application/vnd.api+json")
28+
)
29+
}
30+
31+
val formSubmissionsRouter = FormSubmissionsRouter(httpClient = HttpClient(mockEngine).configureForTest())
32+
33+
runBlocking {
34+
val result = formSubmissionsRouter.create(
35+
organisationId = "org-123",
36+
formId = "form-456",
37+
schemaId = "schema-789",
38+
payload = mapOf("Test" to "value")
39+
)
40+
41+
assertIs<FormSubmissionVersion>(result)
42+
assertNotNull(result.id)
43+
}
44+
}
45+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"data": {
3+
"type": "form-submission-versions",
4+
"id": "submission-123",
5+
"attributes": {
6+
"payload": {
7+
"Test": "value"
8+
}
9+
},
10+
"relationships": {
11+
"schema": {
12+
"data": {
13+
"type": "form-schema",
14+
"id": "schema-789"
15+
}
16+
}
17+
}
18+
}
19+
}

0 commit comments

Comments
 (0)