@streamr/trackerless-network 102.0.0-beta.0 → 102.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/dist/generated/google/protobuf/any.js.map +1 -0
  2. package/dist/generated/google/protobuf/empty.js.map +1 -0
  3. package/dist/generated/google/protobuf/timestamp.js.map +1 -0
  4. package/dist/{src/proto → generated}/packages/dht/protos/DhtRpc.client.d.ts +9 -0
  5. package/dist/{src/proto → generated}/packages/dht/protos/DhtRpc.client.js +7 -0
  6. package/dist/generated/packages/dht/protos/DhtRpc.client.js.map +1 -0
  7. package/dist/{src/proto → generated}/packages/dht/protos/DhtRpc.d.ts +32 -8
  8. package/dist/{src/proto → generated}/packages/dht/protos/DhtRpc.js +23 -7
  9. package/dist/generated/packages/dht/protos/DhtRpc.js.map +1 -0
  10. package/dist/{src/proto → generated}/packages/dht/protos/DhtRpc.server.d.ts +5 -0
  11. package/dist/generated/packages/dht/protos/DhtRpc.server.js.map +1 -0
  12. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js.map +1 -0
  13. package/dist/generated/packages/trackerless-network/protos/NetworkRpc.client.js.map +1 -0
  14. package/dist/{src/proto → generated}/packages/trackerless-network/protos/NetworkRpc.d.ts +3 -3
  15. package/dist/{src/proto → generated}/packages/trackerless-network/protos/NetworkRpc.js +1 -1
  16. package/dist/generated/packages/trackerless-network/protos/NetworkRpc.js.map +1 -0
  17. package/dist/generated/packages/trackerless-network/protos/NetworkRpc.server.js.map +1 -0
  18. package/dist/package.json +9 -10
  19. package/dist/src/NetworkNode.d.ts +4 -3
  20. package/dist/src/NetworkNode.js.map +1 -1
  21. package/dist/src/NetworkStack.d.ts +2 -2
  22. package/dist/src/NetworkStack.js +4 -4
  23. package/dist/src/NetworkStack.js.map +1 -1
  24. package/dist/src/exports.d.ts +3 -2
  25. package/dist/src/exports.js +3 -2
  26. package/dist/src/exports.js.map +1 -1
  27. package/dist/src/logic/ContentDeliveryLayerNode.d.ts +2 -1
  28. package/dist/src/logic/ContentDeliveryLayerNode.js +5 -5
  29. package/dist/src/logic/ContentDeliveryLayerNode.js.map +1 -1
  30. package/dist/src/logic/ContentDeliveryManager.d.ts +2 -1
  31. package/dist/src/logic/ContentDeliveryManager.js +2 -1
  32. package/dist/src/logic/ContentDeliveryManager.js.map +1 -1
  33. package/dist/src/logic/ContentDeliveryRpcLocal.d.ts +3 -3
  34. package/dist/src/logic/ContentDeliveryRpcLocal.js +1 -1
  35. package/dist/src/logic/ContentDeliveryRpcLocal.js.map +1 -1
  36. package/dist/src/logic/ContentDeliveryRpcRemote.d.ts +2 -2
  37. package/dist/src/logic/ControlLayerNode.d.ts +1 -1
  38. package/dist/src/logic/DiscoveryLayerNode.d.ts +3 -3
  39. package/dist/src/logic/DuplicateMessageDetector.js +1 -1
  40. package/dist/src/logic/DuplicateMessageDetector.js.map +1 -1
  41. package/dist/src/logic/PeerDescriptorStoreManager.d.ts +1 -1
  42. package/dist/src/logic/PeerDescriptorStoreManager.js +1 -1
  43. package/dist/src/logic/PeerDescriptorStoreManager.js.map +1 -1
  44. package/dist/src/logic/inspect/InspectSession.d.ts +2 -2
  45. package/dist/src/logic/inspect/InspectSession.js +2 -2
  46. package/dist/src/logic/inspect/InspectSession.js.map +1 -1
  47. package/dist/src/logic/inspect/Inspector.d.ts +1 -1
  48. package/dist/src/logic/inspect/Inspector.js +1 -1
  49. package/dist/src/logic/inspect/Inspector.js.map +1 -1
  50. package/dist/src/logic/neighbor-discovery/HandshakeRpcLocal.d.ts +2 -2
  51. package/dist/src/logic/neighbor-discovery/HandshakeRpcRemote.d.ts +2 -2
  52. package/dist/src/logic/neighbor-discovery/Handshaker.js +2 -2
  53. package/dist/src/logic/neighbor-discovery/Handshaker.js.map +1 -1
  54. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js +2 -2
  55. package/dist/src/logic/neighbor-discovery/NeighborUpdateManager.js.map +1 -1
  56. package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.d.ts +2 -2
  57. package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js +1 -1
  58. package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.js.map +1 -1
  59. package/dist/src/logic/neighbor-discovery/NeighborUpdateRpcRemote.d.ts +1 -1
  60. package/dist/src/logic/node-info/NodeInfoClient.d.ts +1 -1
  61. package/dist/src/logic/node-info/NodeInfoClient.js +1 -1
  62. package/dist/src/logic/node-info/NodeInfoClient.js.map +1 -1
  63. package/dist/src/logic/node-info/NodeInfoRpcLocal.d.ts +2 -2
  64. package/dist/src/logic/node-info/NodeInfoRpcLocal.js +1 -1
  65. package/dist/src/logic/node-info/NodeInfoRpcLocal.js.map +1 -1
  66. package/dist/src/logic/node-info/NodeInfoRpcRemote.d.ts +2 -2
  67. package/dist/src/logic/propagation/Propagation.d.ts +1 -1
  68. package/dist/src/logic/propagation/PropagationTaskStore.d.ts +1 -1
  69. package/dist/src/logic/proxy/ProxyClient.d.ts +1 -2
  70. package/dist/src/logic/proxy/ProxyClient.js +2 -3
  71. package/dist/src/logic/proxy/ProxyClient.js.map +1 -1
  72. package/dist/src/logic/proxy/ProxyConnectionRpcLocal.d.ts +2 -2
  73. package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js +4 -4
  74. package/dist/src/logic/proxy/ProxyConnectionRpcLocal.js.map +1 -1
  75. package/dist/src/logic/proxy/ProxyConnectionRpcRemote.d.ts +2 -2
  76. package/dist/src/logic/proxy/ProxyConnectionRpcRemote.js +1 -1
  77. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.d.ts +4 -4
  78. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js +1 -1
  79. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcLocal.js.map +1 -1
  80. package/dist/src/logic/temporary-connection/TemporaryConnectionRpcRemote.d.ts +1 -1
  81. package/dist/src/logic/utils.d.ts +1 -1
  82. package/dist/src/logic/utils.js +2 -2
  83. package/dist/src/logic/utils.js.map +1 -1
  84. package/dist/src/types.d.ts +6 -0
  85. package/dist/src/types.js +3 -0
  86. package/dist/src/types.js.map +1 -0
  87. package/dist/test/benchmark/first-message.js +2 -2
  88. package/dist/test/benchmark/first-message.js.map +1 -1
  89. package/dist/test/utils/utils.d.ts +2 -2
  90. package/dist/test/utils/utils.js +5 -4
  91. package/dist/test/utils/utils.js.map +1 -1
  92. package/jest.config.ts +13 -0
  93. package/package.json +9 -10
  94. package/proto.sh +2 -2
  95. package/protos/NetworkRpc.proto +2 -3
  96. package/.eslintignore +0 -7
  97. package/.eslintrc +0 -3
  98. package/dist/src/proto/google/protobuf/any.js.map +0 -1
  99. package/dist/src/proto/google/protobuf/empty.js.map +0 -1
  100. package/dist/src/proto/google/protobuf/timestamp.js.map +0 -1
  101. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +0 -1
  102. package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +0 -1
  103. package/dist/src/proto/packages/dht/protos/DhtRpc.server.js.map +0 -1
  104. package/dist/src/proto/packages/proto-rpc/protos/ProtoRpc.js.map +0 -1
  105. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.client.js.map +0 -1
  106. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.js.map +0 -1
  107. package/dist/src/proto/packages/trackerless-network/protos/NetworkRpc.server.js.map +0 -1
  108. package/jest.config.js +0 -8
  109. package/src/NetworkNode.ts +0 -141
  110. package/src/NetworkStack.ts +0 -198
  111. package/src/exports.ts +0 -16
  112. package/src/logic/ContentDeliveryLayerNode.ts +0 -424
  113. package/src/logic/ContentDeliveryManager.ts +0 -399
  114. package/src/logic/ContentDeliveryRpcLocal.ts +0 -48
  115. package/src/logic/ContentDeliveryRpcRemote.ts +0 -44
  116. package/src/logic/ControlLayerNode.ts +0 -17
  117. package/src/logic/DiscoveryLayerNode.ts +0 -30
  118. package/src/logic/DuplicateMessageDetector.ts +0 -167
  119. package/src/logic/ExternalNetworkRpc.ts +0 -42
  120. package/src/logic/NodeList.ts +0 -114
  121. package/src/logic/PeerDescriptorStoreManager.ts +0 -96
  122. package/src/logic/StreamPartNetworkSplitAvoidance.ts +0 -90
  123. package/src/logic/StreamPartReconnect.ts +0 -38
  124. package/src/logic/createContentDeliveryLayerNode.ts +0 -130
  125. package/src/logic/formStreamPartDeliveryServiceId.ts +0 -7
  126. package/src/logic/inspect/InspectSession.ts +0 -54
  127. package/src/logic/inspect/Inspector.ts +0 -100
  128. package/src/logic/neighbor-discovery/HandshakeRpcLocal.ts +0 -138
  129. package/src/logic/neighbor-discovery/HandshakeRpcRemote.ts +0 -66
  130. package/src/logic/neighbor-discovery/Handshaker.ts +0 -215
  131. package/src/logic/neighbor-discovery/NeighborFinder.ts +0 -77
  132. package/src/logic/neighbor-discovery/NeighborUpdateManager.ts +0 -69
  133. package/src/logic/neighbor-discovery/NeighborUpdateRpcLocal.ts +0 -75
  134. package/src/logic/neighbor-discovery/NeighborUpdateRpcRemote.ts +0 -35
  135. package/src/logic/node-info/NodeInfoClient.ts +0 -23
  136. package/src/logic/node-info/NodeInfoRpcLocal.ts +0 -28
  137. package/src/logic/node-info/NodeInfoRpcRemote.ts +0 -11
  138. package/src/logic/propagation/FifoMapWithTTL.ts +0 -116
  139. package/src/logic/propagation/Propagation.ts +0 -84
  140. package/src/logic/propagation/PropagationTaskStore.ts +0 -41
  141. package/src/logic/proxy/ProxyClient.ts +0 -287
  142. package/src/logic/proxy/ProxyConnectionRpcLocal.ts +0 -106
  143. package/src/logic/proxy/ProxyConnectionRpcRemote.ts +0 -26
  144. package/src/logic/temporary-connection/TemporaryConnectionRpcLocal.ts +0 -73
  145. package/src/logic/temporary-connection/TemporaryConnectionRpcRemote.ts +0 -29
  146. package/src/logic/utils.ts +0 -18
  147. package/src/proto/google/protobuf/any.ts +0 -326
  148. package/src/proto/google/protobuf/empty.ts +0 -81
  149. package/src/proto/google/protobuf/timestamp.ts +0 -287
  150. package/src/proto/packages/dht/protos/DhtRpc.client.ts +0 -407
  151. package/src/proto/packages/dht/protos/DhtRpc.server.ts +0 -160
  152. package/src/proto/packages/dht/protos/DhtRpc.ts +0 -1244
  153. package/src/proto/packages/proto-rpc/protos/ProtoRpc.ts +0 -108
  154. package/src/proto/packages/trackerless-network/protos/NetworkRpc.client.ts +0 -218
  155. package/src/proto/packages/trackerless-network/protos/NetworkRpc.server.ts +0 -85
  156. package/src/proto/packages/trackerless-network/protos/NetworkRpc.ts +0 -783
  157. package/test/benchmark/StreamPartIdDataKeyDistribution.test.ts +0 -60
  158. package/test/benchmark/first-message.ts +0 -169
  159. package/test/end-to-end/content-delivery-layer-node-with-real-connections.test.ts +0 -160
  160. package/test/end-to-end/external-network-rpc.test.ts +0 -67
  161. package/test/end-to-end/inspect.test.ts +0 -124
  162. package/test/end-to-end/proxy-and-full-node.test.ts +0 -143
  163. package/test/end-to-end/proxy-connections.test.ts +0 -228
  164. package/test/end-to-end/proxy-key-exchange.test.ts +0 -126
  165. package/test/end-to-end/webrtc-full-node-network.test.ts +0 -85
  166. package/test/end-to-end/websocket-full-node-network.test.ts +0 -84
  167. package/test/integration/ContentDeliveryLayerNode-Layer1Node-Latencies.test.ts +0 -139
  168. package/test/integration/ContentDeliveryLayerNode-Layer1Node.test.ts +0 -162
  169. package/test/integration/ContentDeliveryManager.test.ts +0 -157
  170. package/test/integration/ContentDeliveryRpcRemote.test.ts +0 -100
  171. package/test/integration/HandshakeRpcRemote.test.ts +0 -79
  172. package/test/integration/Handshakes.test.ts +0 -176
  173. package/test/integration/Inspect.test.ts +0 -89
  174. package/test/integration/NeighborUpdateRpcRemote.test.ts +0 -82
  175. package/test/integration/NetworkNode.test.ts +0 -115
  176. package/test/integration/NetworkRpc.test.ts +0 -52
  177. package/test/integration/NetworkStack.test.ts +0 -72
  178. package/test/integration/NodeInfoRpc.test.ts +0 -109
  179. package/test/integration/Propagation.test.ts +0 -76
  180. package/test/integration/joining-streams-on-offline-peers.test.ts +0 -82
  181. package/test/integration/stream-without-default-entrypoints.test.ts +0 -128
  182. package/test/integration/streamEntryPointReplacing.test.ts +0 -97
  183. package/test/types/global.d.ts +0 -2
  184. package/test/unit/ContentDeliveryLayerNode.test.ts +0 -112
  185. package/test/unit/ContentDeliveryManager.test.ts +0 -95
  186. package/test/unit/ContentDeliveryRpcLocal.test.ts +0 -60
  187. package/test/unit/DuplicateMessageDetector.test.ts +0 -192
  188. package/test/unit/ExternalNetworkRpc.test.ts +0 -48
  189. package/test/unit/FifoMapWithTtl.test.ts +0 -253
  190. package/test/unit/HandshakeRpcLocal.test.ts +0 -168
  191. package/test/unit/Handshaker.test.ts +0 -69
  192. package/test/unit/InspectSession.test.ts +0 -80
  193. package/test/unit/Inspector.test.ts +0 -51
  194. package/test/unit/NeighborFinder.test.ts +0 -51
  195. package/test/unit/NeighborUpdateRpcLocal.test.ts +0 -139
  196. package/test/unit/NetworkNode.test.ts +0 -42
  197. package/test/unit/NodeList.test.ts +0 -164
  198. package/test/unit/NumberPair.test.ts +0 -22
  199. package/test/unit/PeerDescriptorStoreManager.test.ts +0 -103
  200. package/test/unit/Propagation.test.ts +0 -151
  201. package/test/unit/ProxyConnectionRpcRemote.test.ts +0 -39
  202. package/test/unit/StreamPartIDDataKey.test.ts +0 -12
  203. package/test/unit/StreamPartNetworkSplitAvoidance.test.ts +0 -31
  204. package/test/unit/StreamPartReconnect.test.ts +0 -30
  205. package/test/unit/TemporaryConnectionRpcLocal.test.ts +0 -38
  206. package/test/utils/fake/FakePeerDescriptorStoreManager.ts +0 -29
  207. package/test/utils/mock/MockConnectionsView.ts +0 -18
  208. package/test/utils/mock/MockControlLayerNode.ts +0 -78
  209. package/test/utils/mock/MockDiscoveryLayerNode.ts +0 -60
  210. package/test/utils/mock/MockHandshaker.ts +0 -17
  211. package/test/utils/mock/MockNeighborFinder.ts +0 -20
  212. package/test/utils/mock/MockNeighborUpdateManager.ts +0 -21
  213. package/test/utils/mock/MockTransport.ts +0 -30
  214. package/test/utils/utils.ts +0 -143
  215. package/tsconfig.browser.json +0 -12
  216. package/tsconfig.jest.json +0 -16
  217. package/tsconfig.json +0 -3
  218. package/tsconfig.node.json +0 -16
  219. /package/dist/{src/proto → generated}/google/protobuf/any.d.ts +0 -0
  220. /package/dist/{src/proto → generated}/google/protobuf/any.js +0 -0
  221. /package/dist/{src/proto → generated}/google/protobuf/empty.d.ts +0 -0
  222. /package/dist/{src/proto → generated}/google/protobuf/empty.js +0 -0
  223. /package/dist/{src/proto → generated}/google/protobuf/timestamp.d.ts +0 -0
  224. /package/dist/{src/proto → generated}/google/protobuf/timestamp.js +0 -0
  225. /package/dist/{src/proto → generated}/packages/dht/protos/DhtRpc.server.js +0 -0
  226. /package/dist/{src/proto → generated}/packages/proto-rpc/protos/ProtoRpc.d.ts +0 -0
  227. /package/dist/{src/proto → generated}/packages/proto-rpc/protos/ProtoRpc.js +0 -0
  228. /package/dist/{src/proto → generated}/packages/trackerless-network/protos/NetworkRpc.client.d.ts +0 -0
  229. /package/dist/{src/proto → generated}/packages/trackerless-network/protos/NetworkRpc.client.js +0 -0
  230. /package/dist/{src/proto → generated}/packages/trackerless-network/protos/NetworkRpc.server.d.ts +0 -0
  231. /package/dist/{src/proto → generated}/packages/trackerless-network/protos/NetworkRpc.server.js +0 -0
@@ -1,95 +0,0 @@
1
- import { areEqualPeerDescriptors } from '@streamr/dht'
2
- import { StreamPartIDUtils, waitForCondition } from '@streamr/utils'
3
- import { ContentDeliveryManager } from '../../src/logic/ContentDeliveryManager'
4
- import { ProxyDirection } from '../../src/proto/packages/trackerless-network/protos/NetworkRpc'
5
- import { MockControlLayerNode } from '../utils/mock/MockControlLayerNode'
6
- import { MockTransport } from '../utils/mock/MockTransport'
7
- import { createMockPeerDescriptor, createStreamMessage, mockConnectionLocker } from '../utils/utils'
8
- import { randomUserId } from '@streamr/test-utils'
9
-
10
- describe('ContentDeliveryManager', () => {
11
-
12
- let manager: ContentDeliveryManager
13
- const peerDescriptor = createMockPeerDescriptor()
14
-
15
- beforeEach(async () => {
16
- manager = new ContentDeliveryManager({})
17
- const mockLayer0 = new MockControlLayerNode(peerDescriptor)
18
- await manager.start(mockLayer0, new MockTransport(), mockConnectionLocker)
19
- })
20
-
21
- afterEach(async () => {
22
- await manager.destroy()
23
- })
24
-
25
- it('PeerDescriptor is correct', () => {
26
- expect(areEqualPeerDescriptors(peerDescriptor, manager.getPeerDescriptor()))
27
- })
28
-
29
- describe('join and leave', () => {
30
-
31
- const streamPartId = StreamPartIDUtils.parse('stream#0')
32
- const message = createStreamMessage(
33
- JSON.stringify({ hello: 'WORLD' }),
34
- streamPartId,
35
- randomUserId()
36
- )
37
-
38
- beforeEach(async () => {
39
- manager.setStreamPartEntryPoints(streamPartId, [manager.getPeerDescriptor()])
40
- })
41
-
42
- it('can join stream part', async () => {
43
- manager.joinStreamPart(streamPartId)
44
- expect(manager.hasStreamPart(streamPartId)).toEqual(true)
45
- })
46
-
47
- it('can leave stream part', async () => {
48
- manager.joinStreamPart(streamPartId)
49
- expect(manager.hasStreamPart(streamPartId)).toEqual(true)
50
- await manager.leaveStreamPart(streamPartId)
51
- expect(manager.hasStreamPart(streamPartId)).toEqual(false)
52
- })
53
-
54
- it('broadcast joins stream', async () => {
55
- manager.broadcast(message)
56
- await waitForCondition(() => manager.hasStreamPart(streamPartId))
57
- })
58
- })
59
-
60
- describe('proxied stream', () => {
61
- it('happy path', async () => {
62
- const streamPartId = StreamPartIDUtils.parse('stream#0')
63
- const proxy = createMockPeerDescriptor()
64
- const userId = randomUserId()
65
- await manager.setProxies(streamPartId, [proxy], ProxyDirection.PUBLISH, userId)
66
- expect(manager.isProxiedStreamPart(streamPartId)).toBe(true)
67
- await manager.setProxies(streamPartId, [], ProxyDirection.PUBLISH, userId)
68
- expect(manager.isProxiedStreamPart(streamPartId)).toBe(false)
69
- })
70
-
71
- it('empty node list', async () => {
72
- const streamPartId = StreamPartIDUtils.parse('stream#0')
73
- const proxy = createMockPeerDescriptor()
74
- const userId = randomUserId()
75
- await manager.setProxies(streamPartId, [], ProxyDirection.PUBLISH, userId)
76
- expect(manager.isProxiedStreamPart(streamPartId)).toBe(false)
77
- await manager.setProxies(streamPartId, [proxy], ProxyDirection.PUBLISH, userId)
78
- expect(manager.isProxiedStreamPart(streamPartId)).toBe(true)
79
- await manager.setProxies(streamPartId, [], ProxyDirection.PUBLISH, userId)
80
- expect(manager.isProxiedStreamPart(streamPartId)).toBe(false)
81
- })
82
-
83
- it('connection count to 0', async () => {
84
- const streamPartId = StreamPartIDUtils.parse('stream#0')
85
- const proxy = createMockPeerDescriptor()
86
- const userId = randomUserId()
87
- await manager.setProxies(streamPartId, [proxy], ProxyDirection.PUBLISH, userId, 0)
88
- expect(manager.isProxiedStreamPart(streamPartId)).toBe(false)
89
- await manager.setProxies(streamPartId, [proxy], ProxyDirection.PUBLISH, userId)
90
- expect(manager.isProxiedStreamPart(streamPartId)).toBe(true)
91
- await manager.setProxies(streamPartId, [proxy], ProxyDirection.PUBLISH, userId, 0)
92
- expect(manager.isProxiedStreamPart(streamPartId)).toBe(false)
93
- })
94
- })
95
- })
@@ -1,60 +0,0 @@
1
- import { ListeningRpcCommunicator } from '@streamr/dht'
2
- import { StreamPartIDUtils } from '@streamr/utils'
3
- import { ContentDeliveryRpcLocal } from '../../src/logic/ContentDeliveryRpcLocal'
4
- import { LeaveStreamPartNotice } from '../../src/proto/packages/trackerless-network/protos/NetworkRpc'
5
- import { MockTransport } from '../utils/mock/MockTransport'
6
- import { createMockPeerDescriptor, createStreamMessage } from '../utils/utils'
7
- import { randomUserId } from '@streamr/test-utils'
8
-
9
- describe('ContentDeliveryRpcLocal', () => {
10
-
11
- let rpcLocal: ContentDeliveryRpcLocal
12
- const peerDescriptor = createMockPeerDescriptor()
13
-
14
- const mockSender = createMockPeerDescriptor()
15
-
16
- const message = createStreamMessage(
17
- JSON.stringify({ hello: 'WORLD' }),
18
- StreamPartIDUtils.parse('random-graph#0'),
19
- randomUserId()
20
- )
21
-
22
- let mockBroadcast: jest.Mock
23
- let mockDuplicateCheck: jest.Mock
24
- let mockOnLeaveNotice: jest.Mock
25
- let mockMarkForInspection: jest.Mock
26
-
27
- beforeEach(async () => {
28
- mockDuplicateCheck = jest.fn((_c, _p) => true)
29
- mockBroadcast = jest.fn((_m, _p) => {})
30
- mockOnLeaveNotice = jest.fn((_m) => {})
31
- mockMarkForInspection = jest.fn((_m) => {})
32
-
33
- rpcLocal = new ContentDeliveryRpcLocal({
34
- markAndCheckDuplicate: mockDuplicateCheck,
35
- broadcast: mockBroadcast,
36
- onLeaveNotice: mockOnLeaveNotice,
37
- markForInspection: mockMarkForInspection,
38
- localPeerDescriptor: peerDescriptor,
39
- streamPartId: StreamPartIDUtils.parse('stream#0'),
40
- rpcCommunicator: new ListeningRpcCommunicator('random-graph-node', new MockTransport())
41
- })
42
- })
43
-
44
- it('Server sendStreamMessage()', async () => {
45
- await rpcLocal.sendStreamMessage(message, { incomingSourceDescriptor: mockSender } as any)
46
- expect(mockDuplicateCheck).toHaveBeenCalledTimes(1)
47
- expect(mockBroadcast).toHaveBeenCalledTimes(1)
48
- expect(mockMarkForInspection).toHaveBeenCalledTimes(1)
49
- })
50
-
51
- it('Server leaveStreamPartNotice()', async () => {
52
- const leaveNotice: LeaveStreamPartNotice = {
53
- streamPartId: StreamPartIDUtils.parse('stream#0'),
54
- isEntryPoint: false
55
- }
56
- await rpcLocal.leaveStreamPartNotice(leaveNotice, { incomingSourceDescriptor: mockSender } as any)
57
- expect(mockOnLeaveNotice).toHaveBeenCalledTimes(1)
58
- })
59
-
60
- })
@@ -1,192 +0,0 @@
1
- import { DuplicateMessageDetector, NumberPair, GapMisMatchError, InvalidNumberingError } from '../../src/logic/DuplicateMessageDetector'
2
-
3
- test('starts empty', () => {
4
- const detector = new DuplicateMessageDetector()
5
- expect(detector.toString()).toEqual('')
6
- })
7
-
8
- test('first check initializes default gap', () => {
9
- const detector = new DuplicateMessageDetector()
10
- const result = detector.markAndCheck(new NumberPair(1, 5), new NumberPair(10, 10))
11
- const state = detector.toString()
12
- expect(result).toEqual(true)
13
- expect(state).toEqual('(10|10, Infinity|Infinity]')
14
- })
15
-
16
- test('checking numbers in order introduces no new gaps', () => {
17
- const detector = new DuplicateMessageDetector()
18
- detector.markAndCheck(null, new NumberPair(10, 0))
19
- expect(detector.markAndCheck(new NumberPair(10, 0), new NumberPair(20, 0))).toEqual(true)
20
- expect(detector.markAndCheck(new NumberPair(20, 0), new NumberPair(30, 0))).toEqual(true)
21
- expect(detector.markAndCheck(null, new NumberPair(30, 1))).toEqual(true)
22
- expect(detector.markAndCheck(new NumberPair(30, 1), new NumberPair(30, 5))).toEqual(true)
23
- const state = detector.toString()
24
- expect(state).toEqual('(30|5, Infinity|Infinity]')
25
- })
26
-
27
- test('skipping next expected messages creates gaps', () => {
28
- const detector = new DuplicateMessageDetector()
29
- detector.markAndCheck(null, new NumberPair(10, 0))
30
-
31
- expect(detector.markAndCheck(new NumberPair(15, 0), new NumberPair(20, 0))).toEqual(true)
32
- expect(detector.toString()).toEqual('(10|0, 15|0], (20|0, Infinity|Infinity]')
33
-
34
- expect(detector.markAndCheck(new NumberPair(30, 0), new NumberPair(40, 0))).toEqual(true)
35
- expect(detector.toString()).toEqual('(10|0, 15|0], (20|0, 30|0], (40|0, Infinity|Infinity]')
36
-
37
- expect(detector.markAndCheck(new NumberPair(40, 10), new NumberPair(80, 20))).toEqual(true)
38
- expect(detector.toString()).toEqual('(10|0, 15|0], (20|0, 30|0], (40|0, 40|10], (80|20, Infinity|Infinity]')
39
- })
40
-
41
- test('only last gap is checked if no previous number given', () => {
42
- const detector = new DuplicateMessageDetector()
43
- detector.markAndCheck(null, new NumberPair(10, 0))
44
- detector.markAndCheck(new NumberPair(10, 0), new NumberPair(20, 0))
45
-
46
- expect(detector.markAndCheck(null, new NumberPair(15, 0))).toEqual(false)
47
- expect(detector.markAndCheck(null, new NumberPair(30, 5))).toEqual(true)
48
- const state = detector.toString()
49
- expect(state).toEqual('(30|5, Infinity|Infinity]')
50
- })
51
-
52
- describe('gap handling', () => {
53
- let detector: DuplicateMessageDetector
54
- beforeEach(() => {
55
- detector = new DuplicateMessageDetector()
56
- detector.markAndCheck(null, new NumberPair(10, 0))
57
- detector.markAndCheck(new NumberPair(20, 0), new NumberPair(40, 0))
58
- detector.markAndCheck(new NumberPair(80, 10), new NumberPair(100, 0))
59
- expect(detector.toString()).toEqual('(10|0, 20|0], (40|0, 80|10], (100|0, Infinity|Infinity]')
60
- })
61
-
62
- test('gap division', () => {
63
- expect(detector.markAndCheck(new NumberPair(15, 0), new NumberPair(18, 0)))
64
- expect(detector.toString()).toEqual('(10|0, 15|0], (18|0, 20|0], (40|0, 80|10], (100|0, Infinity|Infinity]')
65
-
66
- expect(detector.markAndCheck(new NumberPair(60, 0), new NumberPair(79, 5)))
67
- expect(detector.toString()).toEqual('(10|0, 15|0], (18|0, 20|0], (40|0, 60|0], (79|5, 80|10], (100|0, Infinity|Infinity]')
68
- })
69
-
70
- test('left-side gap contraction', () => {
71
- expect(detector.markAndCheck(new NumberPair(10, 0), new NumberPair(15, 0))).toEqual(true)
72
- expect(detector.toString()).toEqual('(15|0, 20|0], (40|0, 80|10], (100|0, Infinity|Infinity]')
73
-
74
- expect(detector.markAndCheck(new NumberPair(40, 0), new NumberPair(80, 9))).toEqual(true)
75
- expect(detector.toString()).toEqual('(15|0, 20|0], (80|9, 80|10], (100|0, Infinity|Infinity]')
76
- })
77
-
78
- test('right-side gap contraction', () => {
79
- expect(detector.markAndCheck(new NumberPair(15, 0), new NumberPair(20, 0))).toEqual(true)
80
- expect(detector.toString()).toEqual('(10|0, 15|0], (40|0, 80|10], (100|0, Infinity|Infinity]')
81
-
82
- expect(detector.markAndCheck(new NumberPair(40, 1), new NumberPair(80, 10))).toEqual(true)
83
- expect(detector.toString()).toEqual('(10|0, 15|0], (40|0, 40|1], (100|0, Infinity|Infinity]')
84
- })
85
-
86
- test('full contraction', () => {
87
- expect(detector.markAndCheck(new NumberPair(40, 0), new NumberPair(80, 10)))
88
- expect(detector.toString()).toEqual('(10|0, 20|0], (100|0, Infinity|Infinity]')
89
-
90
- expect(detector.markAndCheck(new NumberPair(10, 0), new NumberPair(20, 0)))
91
- expect(detector.toString()).toEqual('(100|0, Infinity|Infinity]')
92
- })
93
- })
94
-
95
- describe('duplicates return false and do not change state', () => {
96
- let detector: DuplicateMessageDetector
97
- let expectedState: string
98
- beforeEach(() => {
99
- detector = new DuplicateMessageDetector()
100
- detector.markAndCheck(new NumberPair(1, 0), new NumberPair(10, 0))
101
- detector.markAndCheck(new NumberPair(20, 0), new NumberPair(40, 0))
102
- detector.markAndCheck(new NumberPair(80, 10), new NumberPair(100, 0))
103
- expectedState = detector.toString()
104
- expect(expectedState).toEqual('(10|0, 20|0], (40|0, 80|10], (100|0, Infinity|Infinity]')
105
- })
106
-
107
- it('way below 1st gap', () => {
108
- expect(detector.markAndCheck(new NumberPair(5, 0), new NumberPair(7, 0))).toEqual(false)
109
- expect(detector.toString()).toEqual(expectedState)
110
- })
111
-
112
- it('number touches lower bound of 1st gap', () => {
113
- expect(detector.markAndCheck(new NumberPair(8, 0), new NumberPair(10, 0))).toEqual(false)
114
- expect(detector.toString()).toEqual(expectedState)
115
- })
116
-
117
- it('in-between gaps', () => {
118
- expect(detector.markAndCheck(new NumberPair(25, 5), new NumberPair(30, 0))).toEqual(false)
119
- expect(detector.toString()).toEqual(expectedState)
120
- })
121
-
122
- it('number touches lower bound of 2nd gap', () => {
123
- expect(detector.markAndCheck(new NumberPair(25, 0), new NumberPair(40, 0))).toEqual(false)
124
- expect(detector.toString()).toEqual(expectedState)
125
- })
126
-
127
- it('previous number touches upper bound of 2nd gap', () => {
128
- expect(detector.markAndCheck(new NumberPair(80, 10), new NumberPair(90, 0))).toEqual(false)
129
- expect(detector.toString()).toEqual(expectedState)
130
- })
131
-
132
- it('previous number not provided, number is below last gap', () => {
133
- expect(detector.markAndCheck(null, new NumberPair(80, 10))).toEqual(false)
134
- expect(detector.toString()).toEqual(expectedState)
135
- })
136
-
137
- it('previous number not provided, number touches lower bound of last gap', () => {
138
- expect(detector.markAndCheck(null, new NumberPair(100, 0))).toEqual(false)
139
- expect(detector.toString()).toEqual(expectedState)
140
- })
141
- })
142
-
143
- describe('erroneous messages that overlap gaps', () => {
144
- let detector: DuplicateMessageDetector
145
- let expectedState
146
- beforeEach(() => {
147
- detector = new DuplicateMessageDetector()
148
- detector.markAndCheck(new NumberPair(1, 0), new NumberPair(10, 0))
149
- detector.markAndCheck(new NumberPair(20, 0), new NumberPair(40, 0))
150
- detector.markAndCheck(new NumberPair(80, 10), new NumberPair(100, 0))
151
- expectedState = detector.toString()
152
- expect(expectedState).toEqual('(10|0, 20|0], (40|0, 80|10], (100|0, Infinity|Infinity]')
153
- })
154
-
155
- it('completely around gap', () => {
156
- expect(() => detector.markAndCheck(new NumberPair(5, 0), new NumberPair(30, 0))).toThrowError(GapMisMatchError)
157
- })
158
-
159
- it('previousNumber below gap while number in gap', () => {
160
- expect(() => detector.markAndCheck(new NumberPair(5, 0), new NumberPair(15, 0))).toThrowError(GapMisMatchError)
161
- })
162
-
163
- it('previousNumber in gap while number over gap', () => {
164
- expect(() => detector.markAndCheck(new NumberPair(15, 0), new NumberPair(20, 5))).toThrowError(GapMisMatchError)
165
- })
166
-
167
- it('completely around multiple gaps', () => {
168
- expect(() => detector.markAndCheck(new NumberPair(10, 0), new NumberPair(200, 0))).toThrowError(GapMisMatchError)
169
- })
170
- })
171
-
172
- test('checks that number > previousNumber', () => {
173
- const detector = new DuplicateMessageDetector()
174
- expect(() => detector.markAndCheck(new NumberPair(5, 0), new NumberPair(1, 0)))
175
- .toThrowError(InvalidNumberingError)
176
- expect(() => detector.markAndCheck(new NumberPair(5, 5), new NumberPair(5, 5)))
177
- .toThrowError(InvalidNumberingError)
178
- })
179
-
180
- test('lowest gaps get dropped when reaching maximum number of gaps', () => {
181
- const detector = new DuplicateMessageDetector(3)
182
- detector.markAndCheck(new NumberPair(1, 0), new NumberPair(10, 0))
183
- detector.markAndCheck(new NumberPair(20, 0), new NumberPair(40, 0))
184
- detector.markAndCheck(new NumberPair(80, 10), new NumberPair(100, 0))
185
- expect(detector.toString()).toEqual('(10|0, 20|0], (40|0, 80|10], (100|0, Infinity|Infinity]')
186
-
187
- detector.markAndCheck(new NumberPair(150, 0), new NumberPair(200, 0))
188
- expect(detector.toString()).toEqual('(40|0, 80|10], (100|0, 150|0], (200|0, Infinity|Infinity]')
189
-
190
- detector.markAndCheck(new NumberPair(50, 0), new NumberPair(70, 0))
191
- expect(detector.toString()).toEqual('(70|0, 80|10], (100|0, 150|0], (200|0, Infinity|Infinity]')
192
- })
@@ -1,48 +0,0 @@
1
- import { Message } from '@streamr/dht'
2
- import { ExternalNetworkRpc, SERVICE_ID } from '../../src/logic/ExternalNetworkRpc'
3
- import { HandshakeRequest, HandshakeResponse } from '../../src/proto/packages/dht/protos/DhtRpc'
4
- import { MockTransport } from '../utils/mock/MockTransport'
5
- import { RpcMessage } from '@streamr/proto-rpc'
6
- import { Any } from '../../src/proto/google/protobuf/any'
7
- import { HandshakeRpcClient } from '../../src/proto/packages/trackerless-network/protos/NetworkRpc.client'
8
-
9
- describe('ExternalNetworkRpc', () => {
10
-
11
- let rpc: ExternalNetworkRpc
12
- let fn: jest.Mock
13
- let transport: MockTransport
14
-
15
- beforeEach(() => {
16
- transport = new MockTransport
17
- rpc = new ExternalNetworkRpc(transport)
18
- fn = jest.fn()
19
- })
20
-
21
- afterEach(() => {
22
- rpc.destroy()
23
- })
24
-
25
- it('registers method', async () => {
26
- rpc.registerRpcMethod(HandshakeRequest, HandshakeResponse, 'handshake', () => fn())
27
- transport.emit('message', Message.create({
28
- serviceId: SERVICE_ID,
29
- body: {
30
- oneofKind: 'rpcMessage',
31
- rpcMessage: RpcMessage.create({
32
- header: {
33
- request: 'request',
34
- method: 'handshake'
35
- },
36
- body: Any.pack(HandshakeRequest.create(), HandshakeRequest)
37
- })
38
- }
39
- }))
40
- expect(fn).toHaveBeenCalledTimes(1)
41
- })
42
-
43
- it('creates clients', async () => {
44
- const client = rpc.createRpcClient(HandshakeRpcClient)
45
- expect(client.methods.length).toEqual(2)
46
- })
47
-
48
- })
@@ -1,253 +0,0 @@
1
- import { FifoMapWithTTL } from '../../src/logic/propagation/FifoMapWithTTL'
2
-
3
- describe('FifoMapWithTtl', () => {
4
- describe('invalid constructor arguments', () => {
5
- it('cannot instantiate with negative ttl', () => {
6
- expect(() => new FifoMapWithTTL({ ttlInMs: -5, maxSize: 10 }))
7
- .toThrow('ttlInMs (-5) cannot be < 0')
8
- })
9
-
10
- it('cannot instantiate with negative maxSize', () => {
11
- expect(() => new FifoMapWithTTL({ ttlInMs: 100, maxSize: -6 }))
12
- .toThrow('maxSize (-6) cannot be < 0')
13
- })
14
- })
15
-
16
- it('of maxSize=0 always remains empty', () => {
17
- const fifoMap = new FifoMapWithTTL<string, string>({
18
- ttlInMs: 100,
19
- maxSize: 0
20
- })
21
- fifoMap.set('hello', 'world')
22
- fifoMap.set('are', 'you empty?')
23
- expect(fifoMap.get('hello')).toBeUndefined()
24
- expect(fifoMap.get('are')).toBeUndefined()
25
- })
26
-
27
- describe('of maxSize=5', () => {
28
- let fifoMap: FifoMapWithTTL<string, string>
29
-
30
- beforeEach(() => {
31
- fifoMap = new FifoMapWithTTL<string, string>({
32
- ttlInMs: 100,
33
- maxSize: 5
34
- })
35
- })
36
-
37
- function setFirstFiveMessages() {
38
- fifoMap.set('1st', 'foo')
39
- fifoMap.set('2nd', 'bar')
40
- fifoMap.set('3rd', 'hello')
41
- fifoMap.set('4th', 'world')
42
- fifoMap.set('5th', '!')
43
- }
44
-
45
- function set6thAnd7thMessages() {
46
- fifoMap.set('6th', 'new')
47
- fifoMap.set('7th', 'messages')
48
- }
49
-
50
- it('can insert 5 items and retrieve all of them', () => {
51
- setFirstFiveMessages()
52
- expect(fifoMap.get('1st')).toEqual('foo')
53
- expect(fifoMap.get('2nd')).toEqual('bar')
54
- expect(fifoMap.get('3rd')).toEqual('hello')
55
- expect(fifoMap.get('4th')).toEqual('world')
56
- expect(fifoMap.get('5th')).toEqual('!')
57
- })
58
-
59
- it('inserting items when full causes oldest items to get dropped', () => {
60
- setFirstFiveMessages()
61
- set6thAnd7thMessages()
62
- expect(fifoMap.get('1st')).toBeUndefined()
63
- expect(fifoMap.get('2nd')).toBeUndefined()
64
- expect(fifoMap.get('3rd')).toEqual('hello')
65
- expect(fifoMap.get('4th')).toEqual('world')
66
- expect(fifoMap.get('5th')).toEqual('!')
67
- expect(fifoMap.get('6th')).toEqual('new')
68
- expect(fifoMap.get('7th')).toEqual('messages')
69
- })
70
-
71
- describe('(re-)setting an item', () => {
72
- beforeEach(() => {
73
- setFirstFiveMessages()
74
- fifoMap.set('4th', 'modified-once')
75
- fifoMap.set('4th', 'modified-twice')
76
- })
77
-
78
- it('does not cause oldest items to drop', () => {
79
- expect(fifoMap.get('1st')).toEqual('foo')
80
- expect(fifoMap.get('2nd')).toEqual('bar')
81
- expect(fifoMap.get('3rd')).toEqual('hello')
82
- expect(fifoMap.get('5th')).toEqual('!')
83
- })
84
-
85
- it('newest value stays in place', () => {
86
- expect(fifoMap.get('4th')).toEqual('modified-twice')
87
- })
88
- })
89
-
90
- describe('#delete', () => {
91
- it('can delete an item', () => {
92
- setFirstFiveMessages()
93
- fifoMap.delete('4th')
94
- expect(fifoMap.get('1st')).toEqual('foo')
95
- expect(fifoMap.get('2nd')).toEqual('bar')
96
- expect(fifoMap.get('3rd')).toEqual('hello')
97
- expect(fifoMap.get('4th')).toBeUndefined()
98
- expect(fifoMap.get('5th')).toEqual('!')
99
- })
100
-
101
- it('deleting items makes room for new ones', () => {
102
- setFirstFiveMessages()
103
- fifoMap.delete('2nd')
104
- fifoMap.delete('4th')
105
- set6thAnd7thMessages()
106
- expect(fifoMap.get('1st')).toEqual('foo')
107
- expect(fifoMap.get('2nd')).toBeUndefined()
108
- expect(fifoMap.get('3rd')).toEqual('hello')
109
- expect(fifoMap.get('4th')).toBeUndefined()
110
- expect(fifoMap.get('5th')).toEqual('!')
111
- expect(fifoMap.get('6th')).toEqual('new')
112
- expect(fifoMap.get('7th')).toEqual('messages')
113
- })
114
-
115
- it('deleting a non-existing item does not throw', () => {
116
- setFirstFiveMessages()
117
- expect(() =>fifoMap.delete('non-existing-key')).not.toThrow()
118
- })
119
-
120
- it('deleting a non-existing item keeps existing items intact', () => {
121
- setFirstFiveMessages()
122
- fifoMap.delete('non-existing-key')
123
- expect(fifoMap.get('1st')).toEqual('foo')
124
- expect(fifoMap.get('2nd')).toEqual('bar')
125
- expect(fifoMap.get('3rd')).toEqual('hello')
126
- expect(fifoMap.get('4th')).toEqual('world')
127
- expect(fifoMap.get('5th')).toEqual('!')
128
- })
129
- })
130
-
131
- describe('TTL', () => {
132
- let time: number
133
-
134
- beforeEach(() => {
135
- time = 0
136
- fifoMap = new FifoMapWithTTL<string, string>({
137
- ttlInMs: 100,
138
- maxSize: 5,
139
- timeProvider: () => time
140
- })
141
- })
142
-
143
- it('#get returns undefined after TTL', () => {
144
- time = 0
145
- fifoMap.set('hello', 'world')
146
- time = 50
147
- fifoMap.set('foo', 'bar')
148
-
149
- time = 100
150
- expect(fifoMap.get('hello')).toBeUndefined()
151
- expect(fifoMap.get('foo')).toEqual('bar')
152
-
153
- time = 160
154
- expect(fifoMap.get('hello')).toBeUndefined()
155
- expect(fifoMap.get('foo')).toBeUndefined()
156
- })
157
-
158
- it('re-setting an item resets TTL', () => {
159
- time = 0
160
- fifoMap.set('hello', 'world')
161
-
162
- time = 90
163
- fifoMap.set('hello', 'world')
164
-
165
- time = 100
166
- expect(fifoMap.get('hello')).toEqual('world')
167
- })
168
-
169
- it('re-setting expired resets TTL', () => {
170
- time = 0
171
- fifoMap.set('hello', 'world')
172
-
173
- time = 110
174
- expect(fifoMap.get('hello')).toBeUndefined() // sanity check
175
- fifoMap.set('hello', 'world')
176
-
177
- time = 150
178
- expect(fifoMap.get('hello')).toEqual('world')
179
- })
180
-
181
- it('#values returns non-expired items', () => {
182
- time = 0
183
- fifoMap.set('hello', 'world')
184
- time = 50
185
- fifoMap.set('foo', 'bar')
186
- time = 100
187
- fifoMap.set('lorem', 'ipsum')
188
- time = 120
189
- fifoMap.set('dolor', 'sit')
190
-
191
- expect(fifoMap.values()).toEqual(['bar', 'ipsum', 'sit'])
192
-
193
- time = 130
194
- fifoMap.set('amet', 'consectetur')
195
-
196
- expect(fifoMap.values()).toEqual(['bar', 'ipsum', 'sit', 'consectetur'])
197
-
198
- time = 200
199
- expect(fifoMap.values()).toEqual(['sit', 'consectetur'])
200
-
201
- time = 300
202
- expect(fifoMap.values()).toEqual([])
203
- })
204
- })
205
-
206
- describe('onItemDropped callback', () => {
207
- let time: number
208
- let onItemDropped: jest.Mock<undefined, [string]>
209
-
210
- beforeEach(() => {
211
- time = 0
212
- onItemDropped = jest.fn<undefined, [string]>()
213
- fifoMap = new FifoMapWithTTL<string, string>({
214
- ttlInMs: 100,
215
- maxSize: 5,
216
- onItemDropped,
217
- timeProvider: () => time
218
- })
219
- })
220
-
221
- it('invoked when deleting an item', () => {
222
- setFirstFiveMessages()
223
- fifoMap.delete('3rd')
224
- expect(onItemDropped).toHaveBeenCalledTimes(1)
225
- expect(onItemDropped).toHaveBeenCalledWith('3rd')
226
- })
227
-
228
- it('invoked when items are dropped due to being full', () => {
229
- setFirstFiveMessages()
230
- set6thAnd7thMessages()
231
- expect(onItemDropped).toHaveBeenCalledTimes(2)
232
- expect(onItemDropped).toHaveBeenNthCalledWith(1, '1st')
233
- expect(onItemDropped).toHaveBeenNthCalledWith(2, '2nd')
234
- })
235
-
236
- it('invoked when re-setting an item', () => {
237
- setFirstFiveMessages()
238
- fifoMap.set('4th', '!!!')
239
- expect(onItemDropped).toHaveBeenCalledTimes(1)
240
- expect(onItemDropped).toHaveBeenNthCalledWith(1, '4th')
241
- })
242
-
243
- it('invoked when getting a stale item', () => {
244
- time = 0
245
- setFirstFiveMessages()
246
- time = 500
247
- expect(fifoMap.get('1st')).toBeUndefined()
248
- expect(onItemDropped).toHaveBeenCalledTimes(1)
249
- expect(onItemDropped).toHaveBeenNthCalledWith(1, '1st')
250
- })
251
- })
252
- })
253
- })