Skip to content

Commit 60d3e49

Browse files
authored
feat: Allow receiving all messages with a non-null 'status' (#100)
In addition to the status "ok", "error" and "timeout", there may be custom status such as "approved". It would be more convenient if all messages with a non-null "status" could be received in the same callback.
1 parent f635586 commit 60d3e49

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

src/main/kotlin/org/phoenixframework/Push.kt

+26
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ class Push(
4747
/** Hooks into a Push. Where .receive("ok", callback(Payload)) are stored */
4848
var receiveHooks: MutableMap<String, List<((message: Message) -> Unit)>> = HashMap()
4949

50+
/** Hooks into a Push. Where .receiveAll(callback(status, message)) are stored */
51+
private var receiveAllHooks: MutableList<(status: String, message: Message) -> Unit> = mutableListOf()
52+
5053
/** True if the Push has been sent */
5154
var sent: Boolean = false
5255

@@ -117,6 +120,28 @@ class Push(
117120
return this
118121
}
119122

123+
/**
124+
* Receives any event that was a response to an outbound message.
125+
*
126+
* Example:
127+
* channel
128+
* .send("event", mPayload)
129+
* .receive { status, message ->
130+
* print(status) // "ok"
131+
* }
132+
*/
133+
fun receive(callback: (status: String, message: Message) -> Unit): Push {
134+
// If the message has already been received, pass it to the callback.
135+
receivedMessage?.let {
136+
val status = it.status
137+
if (status != null) {
138+
callback(status, it)
139+
}
140+
}
141+
receiveAllHooks.add(callback)
142+
return this
143+
}
144+
120145
//------------------------------------------------------------------------------
121146
// Internal
122147
//------------------------------------------------------------------------------
@@ -182,6 +207,7 @@ class Push(
182207
*/
183208
private fun matchReceive(status: String, message: Message) {
184209
receiveHooks[status]?.forEach { it(message) }
210+
receiveAllHooks.forEach { it(status, message) }
185211
}
186212

187213
/** Removes receive hook from Channel regarding this Push */

src/test/kotlin/org/phoenixframework/ChannelTest.kt

+52
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ChannelTest {
2828

2929
@Mock lateinit var socket: Socket
3030
@Mock lateinit var mockCallback: ((Message) -> Unit)
31+
@Mock lateinit var mockStatusCallback: ((String, Message) -> Unit)
3132

3233
private val kDefaultRef = "1"
3334
private val kDefaultTimeout = 10_000L
@@ -410,6 +411,11 @@ class ChannelTest {
410411
joinPush.trigger("error", mapOf("a" to "b"))
411412
}
412413

414+
private fun receivesApproved() {
415+
fakeClock.tick(joinPush.timeout / 2)
416+
joinPush.trigger("approved", mapOf("a" to "b"))
417+
}
418+
413419
@Nested
414420
@DisplayName("receives 'ok'")
415421
inner class ReceivesOk {
@@ -652,6 +658,52 @@ class ChannelTest {
652658
/* End ReceivesError */
653659
}
654660

661+
662+
@Nested
663+
@DisplayName("receives 'all status'")
664+
inner class ReceivesAllStatus {
665+
@Test
666+
internal fun `triggers receive('error') callback after error response`() {
667+
assertThat(channel.state).isEqualTo(Channel.State.JOINING)
668+
joinPush.receive(mockStatusCallback)
669+
670+
receivesError()
671+
joinPush.trigger("error", kEmptyPayload)
672+
verify(mockStatusCallback, times(1)).invoke(any(), any())
673+
}
674+
675+
@Test
676+
internal fun `triggers receive('error') callback if error response already received`() {
677+
receivesError()
678+
679+
joinPush.receive(mockStatusCallback)
680+
681+
verify(mockStatusCallback).invoke(any(), any())
682+
}
683+
684+
@Test
685+
internal fun `triggers receive('approved') callback after approved response`() {
686+
assertThat(channel.state).isEqualTo(Channel.State.JOINING)
687+
joinPush.receive(mockStatusCallback)
688+
689+
receivesApproved()
690+
joinPush.trigger("approved", kEmptyPayload)
691+
verify(mockStatusCallback, times(1)).invoke(any(), any())
692+
693+
}
694+
695+
@Test
696+
internal fun `triggers receive('approved') callback if approved response already received`() {
697+
receivesApproved()
698+
699+
joinPush.receive(mockStatusCallback)
700+
701+
verify(mockStatusCallback).invoke(any(), any())
702+
}
703+
704+
/* End ReceivesAllStatus */
705+
}
706+
655707
/* End JoinPush */
656708
}
657709

0 commit comments

Comments
 (0)