@@ -3,82 +3,85 @@ package com.lightspark.sdk.webhooks
3
3
import com.lightspark.sdk.core.LightsparkException
4
4
import com.lightspark.sdk.model.WebhookEventType
5
5
import kotlin.test.Test
6
+ import kotlin.test.assertContains
6
7
import kotlin.test.assertEquals
7
- import kotlin.test.assertNotNull
8
+ import kotlin.test.assertFailsWith
8
9
import kotlin.test.assertNull
9
- import kotlin.test.assertTrue
10
- import kotlin.test.fail
11
10
import kotlinx.coroutines.ExperimentalCoroutinesApi
12
11
import kotlinx.coroutines.test.runTest
13
12
import kotlinx.datetime.Instant
13
+ import kotlinx.serialization.ExperimentalSerializationApi
14
+ import kotlinx.serialization.MissingFieldException
14
15
import kotlinx.serialization.json.jsonPrimitive
15
16
16
17
@OptIn(ExperimentalCoroutinesApi ::class )
17
18
class WebhookTests {
18
19
@Test
19
20
fun `test valid verifyAndParse` () = runTest {
20
21
val eventType = WebhookEventType .NODE_STATUS
21
- val eventId = " 1615c8be5aa44e429eba700db2ed8ca5"
22
- val entityId = " lightning_node:01882c25-157a-f96b-0000-362d42b64397"
23
- val timestamp = Instant .parse(" 2023-05-17T23:56:47.874449+00:00" )
24
22
val data = """ {"event_type": "NODE_STATUS", "event_id": "1615c8be5aa44e429eba700db2ed8ca5", "timestamp": "2023-05-17T23:56:47.874449+00:00", "entity_id": "lightning_node:01882c25-157a-f96b-0000-362d42b64397"}"""
25
- val hexdigest = " 62a8829aeb48b4142533520b1f7f86cdb1ee7d718bf3ea15bc1c662d4c453b74"
23
+ val hexDigest = " 62a8829aeb48b4142533520b1f7f86cdb1ee7d718bf3ea15bc1c662d4c453b74"
26
24
val webhookSecret = " 3gZ5oQQUASYmqQNuEk0KambNMVkOADDItIJjzUlAWjX"
27
25
28
- val event = verifyAndParseWebhook(data.encodeToByteArray(), hexdigest , webhookSecret)
26
+ val event = verifyAndParseWebhook(data.encodeToByteArray(), hexDigest , webhookSecret)
29
27
assertEquals(eventType, event.eventType)
30
- assertEquals(eventId , event.eventId)
31
- assertEquals(entityId , event.entityId)
32
- assertEquals(timestamp , event.timestamp)
28
+ assertEquals(" 1615c8be5aa44e429eba700db2ed8ca5 " , event.eventId)
29
+ assertEquals(" lightning_node:01882c25-157a-f96b-0000-362d42b64397 " , event.entityId)
30
+ assertEquals(Instant .parse( " 2023-05-17T23:56:47.874449+00:00 " ) , event.timestamp)
33
31
assertNull(event.walletId)
34
32
assertNull(event.data)
35
33
}
36
34
37
35
@Test
38
36
fun `test invalid signature` () = runTest {
39
37
val data = """ {"event_type": "NODE_STATUS", "event_id": "1615c8be5aa44e429eba700db2ed8ca5", "timestamp": "2023-05-17T23:56:47.874449+00:00", "entity_id": "lightning_node:01882c25-157a-f96b-0000-362d42b64397"}"""
40
- val hexdigest = " deadbeef"
38
+ val hexDigest = " deadbeef"
41
39
val webhookSecret = " 3gZ5oQQUASYmqQNuEk0KambNMVkOADDItIJjzUlAWjX"
42
40
43
- try {
44
- verifyAndParseWebhook(data.encodeToByteArray(), hexdigest, webhookSecret)
45
- fail(" Expected LightsparkException" )
46
- } catch (e: LightsparkException ) {
47
- assertEquals(" webhook_signature_verification_failed" , e.errorCode)
48
- }
41
+ val err = assertFailsWith<LightsparkException > {
42
+ verifyAndParseWebhook(data.encodeToByteArray(), hexDigest, webhookSecret)
43
+ }
44
+ assertEquals(" webhook_signature_verification_failed" , err.errorCode)
45
+ }
46
+
47
+ @Test
48
+ fun `test invalid digest bytes` () = runTest {
49
+ val data = """ {"event_type": "NODE_STATUS", "event_id": "1615c8be5aa44e429eba700db2ed8ca5", "timestamp": "2023-05-17T23:56:47.874449+00:00", "entity_id": "lightning_node:01882c25-157a-f96b-0000-362d42b64397"}"""
50
+ val webhookSecret = " 3gZ5oQQUASYmqQNuEk0KambNMVkOADDItIJjzUlAWjX"
51
+ val hexDigest = " NotAHexDigest"
52
+
53
+ val err = assertFailsWith<LightsparkException > {
54
+ verifyAndParseWebhook(data.encodeToByteArray(), hexDigest, webhookSecret)
55
+ }
56
+ assertEquals(" webhook_signature_verification_failed" , err.errorCode)
49
57
}
50
58
51
59
@Test
60
+ @OptIn(ExperimentalSerializationApi ::class )
52
61
fun `test invalid json structure` () = runTest {
53
62
val data = """ {"event_typeeee": "NODE_STATUS", "event_id": "1615c8be5aa44e429eba700db2ed8ca5", "timestamp": "2023-05-17T23:56:47.874449+00:00", "entity_id": "lightning_node:01882c25-157a-f96b-0000-362d42b64397"}"""
54
- val hexdigest = " 4c4232ea3cccf8d40f56f873ef3a353ad8c80f2e6ea3404197d08c4d46274bf4"
63
+ val hexDigest = " 4c4232ea3cccf8d40f56f873ef3a353ad8c80f2e6ea3404197d08c4d46274bf4"
55
64
val webhookSecret = " 3gZ5oQQUASYmqQNuEk0KambNMVkOADDItIJjzUlAWjX"
56
65
57
- try {
58
- verifyAndParseWebhook(data.encodeToByteArray(), hexdigest, webhookSecret)
59
- fail(" Expected Exception" )
60
- } catch (e: Exception ) {
61
- assertTrue(e.message!! .contains(" event_type" ))
66
+ val err = assertFailsWith<MissingFieldException > {
67
+ verifyAndParseWebhook(data.encodeToByteArray(), hexDigest, webhookSecret)
62
68
}
69
+ assertContains(err.message!! , " event_type" )
63
70
}
64
71
65
72
@Test
66
73
fun `test valid verifyAndParse with wallet` () = runTest {
67
74
val eventType = WebhookEventType .WALLET_INCOMING_PAYMENT_FINISHED
68
- val eventId = " 1615c8be5aa44e429eba700db2ed8ca5"
69
- val entityId = " lightning_node:01882c25-157a-f96b-0000-362d42b64397"
70
- val walletId = " wallet:01882c25-157a-f96b-0000-362d42b64397"
71
- val timestamp = Instant .parse(" 2023-05-17T23:56:47.874449+00:00" )
72
75
val data = """ {"event_type": "WALLET_INCOMING_PAYMENT_FINISHED", "event_id": "1615c8be5aa44e429eba700db2ed8ca5", "timestamp": "2023-05-17T23:56:47.874449+00:00", "entity_id": "lightning_node:01882c25-157a-f96b-0000-362d42b64397", "wallet_id": "wallet:01882c25-157a-f96b-0000-362d42b64397" }"""
73
- val hexdigest = " b4eeb95f18956b3c33b99e9effc61636effc4634f83604cb41de13470c42669a"
76
+ val hexDigest = " b4eeb95f18956b3c33b99e9effc61636effc4634f83604cb41de13470c42669a"
74
77
val webhookSecret = " 3gZ5oQQUASYmqQNuEk0KambNMVkOADDItIJjzUlAWjX"
75
78
76
- val event = verifyAndParseWebhook(data.encodeToByteArray(), hexdigest , webhookSecret)
79
+ val event = verifyAndParseWebhook(data.encodeToByteArray(), hexDigest , webhookSecret)
77
80
assertEquals(eventType, event.eventType)
78
- assertEquals(eventId , event.eventId)
79
- assertEquals(entityId , event.entityId)
80
- assertEquals(walletId , event.walletId)
81
- assertEquals(timestamp , event.timestamp)
81
+ assertEquals(" 1615c8be5aa44e429eba700db2ed8ca5 " , event.eventId)
82
+ assertEquals(" lightning_node:01882c25-157a-f96b-0000-362d42b64397 " , event.entityId)
83
+ assertEquals(" wallet:01882c25-157a-f96b-0000-362d42b64397 " , event.walletId)
84
+ assertEquals(Instant .parse( " 2023-05-17T23:56:47.874449+00:00 " ) , event.timestamp)
82
85
assertNull(event.data)
83
86
}
84
87
@@ -87,7 +90,6 @@ class WebhookTests {
87
90
val data = """ {"event_type": "REMOTE_SIGNING", "event_id": "8be9c360a68e420b9126b43ff6007a32", "timestamp": "2023-08-10T02:14:27.559234+00:00", "entity_id": "node_with_server_signing:0189d6bc-558d-88df-0000-502f04e71816", "data": {"sub_event_type": "GET_PER_COMMITMENT_POINT", "bitcoin_network": "TESTNET", "derivation_path": "m/3/2104864975", "per_commitment_point_idx": 281474976710654}}"""
88
91
val event = parseWebhook(data.encodeToByteArray())
89
92
assertEquals(WebhookEventType .REMOTE_SIGNING , event.eventType)
90
- assertNotNull(event.data)
91
93
assertEquals(" GET_PER_COMMITMENT_POINT" , event.data!! [" sub_event_type" ]?.jsonPrimitive?.content)
92
94
}
93
95
}
0 commit comments