Skip to content

Commit a9677be

Browse files
author
paulwinter
committed
feat: add ChangeMediumMetadataValue command and test (#162)
1 parent 425ae19 commit a9677be

5 files changed

Lines changed: 162 additions & 0 deletions

File tree

xesar-connect/src/main/kotlin/com/open200/xesar/connect/Topics.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,9 @@ class Topics(vararg val topics: String) {
480480

481481
/** MQTT topic string for the "ChangePersonMetadataValueMapi" command. */
482482
val CHANGE_PERSON_METADATA_VALUE = "xs3/1/cmd/ChangePersonMetadataValueMapi"
483+
484+
/** MQTT topic string for the "ChangeMediumMetadataValueMapi" command. */
485+
val CHANGE_MEDIUM_METADATA_VALUE = "xs3/1/cmd/ChangeMediumMetadataValueMapi"
483486
}
484487
}
485488

xesar-connect/src/main/kotlin/com/open200/xesar/connect/extension/XesarConnectIdentificationMediumExt.kt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,35 @@ suspend fun XesarConnect.requestToAddMediumToInstallationAsync(
482482
)
483483
}
484484

485+
/**
486+
* Changes the value of custom data field of a medium asynchronously.
487+
*
488+
* @param id The ID of the medium.
489+
* @param metadataId The metadataID of the data field.
490+
* @param value The new value of the field.
491+
* @param requestConfig The request configuration (optional).
492+
*/
493+
suspend fun XesarConnect.changeMediumMetadataValueAsync(
494+
id: UUID,
495+
metadataId: UUID,
496+
value: String,
497+
requestConfig: XesarConnect.RequestConfig = buildRequestConfig(),
498+
): SingleEventResult<MediumChanged> {
499+
return sendCommandAsync<ChangeMediumMetadataValueMapi, MediumChanged>(
500+
Topics.Command.CHANGE_MEDIUM_METADATA_VALUE,
501+
Topics.Event.MEDIUM_CHANGED,
502+
true,
503+
ChangeMediumMetadataValueMapi(
504+
config.uuidGenerator.generateId(),
505+
id,
506+
metadataId,
507+
value,
508+
token,
509+
),
510+
requestConfig,
511+
)
512+
}
513+
485514
/**
486515
* Retrieves a cold stream of [IdentificationMedium] objects, fetching them incrementally in
487516
* smaller,more manageable chunks rather than retrieving the entire dataset at once. Use
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.open200.xesar.connect.messages.command
2+
3+
import com.open200.xesar.connect.utils.UUIDSerializer
4+
import java.util.*
5+
import kotlinx.serialization.Serializable
6+
7+
/**
8+
* Represents a command POJO to change a custom data field value for a medium.
9+
*
10+
* @param commandId The id of the command.
11+
* @param id The id of the medium.
12+
* @param metadataId The id of the custom data field.
13+
* @param value The new value of the custom data field.
14+
* @param token The token of the command.
15+
*/
16+
@Serializable
17+
data class ChangeMediumMetadataValueMapi(
18+
override val commandId: @Serializable(with = UUIDSerializer::class) UUID,
19+
val id: @Serializable(with = UUIDSerializer::class) UUID? = null,
20+
val metadataId: @Serializable(with = UUIDSerializer::class) UUID,
21+
val value: String,
22+
val token: String,
23+
) : Command

xesar-connect/src/main/kotlin/com/open200/xesar/connect/messages/event/MediumChanged.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.open200.xesar.connect.messages.event
22

33
import com.open200.xesar.connect.messages.DisengagePeriod
4+
import com.open200.xesar.connect.messages.EntityMetadata
45
import com.open200.xesar.connect.utils.LocalDateTimeSerializer
56
import com.open200.xesar.connect.utils.UUIDSerializer
67
import java.time.LocalDateTime
@@ -22,6 +23,7 @@ import kotlinx.serialization.Serializable
2223
* @param accessEndAt The access end date of the medium.
2324
* @param phoneNumber The phone number of the medium (smartphone).
2425
* @param messageLanguage The message language of the medium (smartphone).
26+
* @param entityMetadata Contains the information for all defined custom data fields for the medium.
2527
*/
2628
@Serializable
2729
data class MediumChanged(
@@ -37,4 +39,5 @@ data class MediumChanged(
3739
val accessEndAt: @Serializable(with = LocalDateTimeSerializer::class) LocalDateTime? = null,
3840
val phoneNumber: String? = null,
3941
val messageLanguage: String? = null,
42+
val entityMetadata: List<EntityMetadata>? = null,
4043
) : Event
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.open200.xesar.connect.it.command
2+
3+
import com.open200.xesar.connect.Topics
4+
import com.open200.xesar.connect.XesarConnect
5+
import com.open200.xesar.connect.XesarMqttClient
6+
import com.open200.xesar.connect.extension.changeMediumMetadataValueAsync
7+
import com.open200.xesar.connect.it.MosquittoContainer
8+
import com.open200.xesar.connect.messages.EntityMetadata
9+
import com.open200.xesar.connect.messages.event.ApiEvent
10+
import com.open200.xesar.connect.messages.event.MediumChanged
11+
import com.open200.xesar.connect.messages.event.encodeEvent
12+
import io.kotest.common.runBlocking
13+
import io.kotest.core.spec.style.FunSpec
14+
import io.kotest.extensions.testcontainers.perProject
15+
import io.kotest.matchers.equals.shouldBeEqual
16+
import io.mockk.coEvery
17+
import java.time.LocalDateTime
18+
import java.util.UUID
19+
import kotlinx.coroutines.CompletableDeferred
20+
import kotlinx.coroutines.launch
21+
22+
class ChangeMediumMetadataValueTest :
23+
FunSpec({
24+
val container = MosquittoContainer.container()
25+
val config = MosquittoContainer.config(container)
26+
listener(container.perProject())
27+
28+
test("change medium metadata value") {
29+
coEvery { config.uuidGenerator.generateId() }
30+
.returns(UUID.fromString("00000000-1281-40ae-89d7-5c541d77a757"))
31+
32+
val mediumId = UUID.fromString("11111111-2222-3333-4444-555555555555")
33+
val metadataId = UUID.fromString("aaaaaaaa-0000-0000-0000-000000000001")
34+
35+
runBlocking {
36+
val simulatedBackendReady = CompletableDeferred<Unit>()
37+
val commandReceived = CompletableDeferred<String>()
38+
39+
launch {
40+
XesarMqttClient.connectAsync(config).await().use { client ->
41+
client.subscribeAsync(arrayOf(Topics.ALL_TOPICS)).await()
42+
43+
client.onMessage = { topic, payload ->
44+
when (topic) {
45+
Topics.Command.CHANGE_MEDIUM_METADATA_VALUE -> {
46+
commandReceived.complete(payload.decodeToString())
47+
}
48+
}
49+
}
50+
51+
simulatedBackendReady.complete(Unit)
52+
53+
val commandContent = commandReceived.await()
54+
55+
commandContent.shouldBeEqual(
56+
"{\"commandId\":\"00000000-1281-40ae-89d7-5c541d77a757\",\"id\":\"11111111-2222-3333-4444-555555555555\",\"metadataId\":\"aaaaaaaa-0000-0000-0000-000000000001\",\"value\":\"Vogons\",\"token\":\"JDJhJDEwJDFSNEljZ2FaRUNXUXBTQ25XN05KbE9qRzFHQ1VjMzkvWTBVcFpZb1M4Vmt0dnJYZ0tJVFBx\"}"
57+
)
58+
59+
val apiEvent =
60+
ApiEvent(
61+
UUID.fromString("00000000-1281-40ae-89d7-5c541d77a757"),
62+
MediumChanged(
63+
id = mediumId,
64+
changedAt = LocalDateTime.parse("2023-08-23T16:25:52.225991"),
65+
entityMetadata =
66+
listOf(
67+
EntityMetadata(
68+
id = metadataId,
69+
name = "Group",
70+
value = "Vogons",
71+
)
72+
),
73+
),
74+
)
75+
76+
client
77+
.publishAsync(Topics.Event.MEDIUM_CHANGED, encodeEvent(apiEvent))
78+
.await()
79+
}
80+
}
81+
82+
launch {
83+
simulatedBackendReady.await()
84+
85+
val api = XesarConnect.connectAndLoginAsync(config).await()
86+
api.subscribeAsync(Topics(Topics.Event.MEDIUM_CHANGED)).await()
87+
88+
val result =
89+
api.changeMediumMetadataValueAsync(
90+
id = mediumId,
91+
metadataId = metadataId,
92+
value = "Vogons",
93+
)
94+
.await()
95+
96+
result.id.shouldBeEqual(mediumId)
97+
result.entityMetadata!!
98+
.single { it.id == metadataId }
99+
.value
100+
?.shouldBeEqual("Vogons")
101+
}
102+
}
103+
}
104+
})

0 commit comments

Comments
 (0)