agent-messenger 2.27.0 → 2.27.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 (37) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/dist/package.json +1 -1
  3. package/dist/src/platforms/discord/listener.d.ts +9 -1
  4. package/dist/src/platforms/discord/listener.d.ts.map +1 -1
  5. package/dist/src/platforms/discord/listener.js +79 -3
  6. package/dist/src/platforms/discord/listener.js.map +1 -1
  7. package/dist/src/platforms/discordbot/listener.d.ts +6 -0
  8. package/dist/src/platforms/discordbot/listener.d.ts.map +1 -1
  9. package/dist/src/platforms/discordbot/listener.js +78 -2
  10. package/dist/src/platforms/discordbot/listener.js.map +1 -1
  11. package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
  12. package/dist/src/platforms/kakaotalk/client.js +4 -4
  13. package/dist/src/platforms/kakaotalk/client.js.map +1 -1
  14. package/package.json +1 -1
  15. package/skills/agent-channeltalk/SKILL.md +1 -1
  16. package/skills/agent-channeltalkbot/SKILL.md +1 -1
  17. package/skills/agent-discord/SKILL.md +1 -1
  18. package/skills/agent-discordbot/SKILL.md +1 -1
  19. package/skills/agent-instagram/SKILL.md +1 -1
  20. package/skills/agent-kakaotalk/SKILL.md +1 -1
  21. package/skills/agent-line/SKILL.md +1 -1
  22. package/skills/agent-slack/SKILL.md +1 -1
  23. package/skills/agent-slackbot/SKILL.md +1 -1
  24. package/skills/agent-teams/SKILL.md +1 -1
  25. package/skills/agent-telegram/SKILL.md +1 -1
  26. package/skills/agent-telegrambot/SKILL.md +1 -1
  27. package/skills/agent-webex/SKILL.md +1 -1
  28. package/skills/agent-webexbot/SKILL.md +1 -1
  29. package/skills/agent-wechatbot/SKILL.md +1 -1
  30. package/skills/agent-whatsapp/SKILL.md +1 -1
  31. package/skills/agent-whatsappbot/SKILL.md +1 -1
  32. package/src/platforms/discord/listener.test.ts +175 -143
  33. package/src/platforms/discord/listener.ts +87 -3
  34. package/src/platforms/discordbot/listener.test.ts +186 -184
  35. package/src/platforms/discordbot/listener.ts +83 -2
  36. package/src/platforms/kakaotalk/client.test.ts +40 -0
  37. package/src/platforms/kakaotalk/client.ts +6 -4
@@ -107,11 +107,40 @@ function createMockClient(overrides: Record<string, any> = {}) {
107
107
  } as any
108
108
  }
109
109
 
110
+ // start() now resolves only once the gateway emits READY, so the handshake must be
111
+ // driven concurrently while start() is pending. This waits for connect() to create the
112
+ // socket (after the awaited gatewayConnect microtask) before the caller drives it.
113
+ async function waitForSocket(): Promise<MockWs> {
114
+ for (let i = 0; i < 50 && !mockWsInstance; i++) {
115
+ await Promise.resolve()
116
+ }
117
+ return mockWsInstance
118
+ }
119
+
120
+ async function startAndReady(listener: DiscordListener): Promise<void> {
121
+ const started = listener.start()
122
+ const ws = await waitForSocket()
123
+ ws.simulateOpen()
124
+ ws.simulateHello()
125
+ ws.simulateReady()
126
+ await started
127
+ }
128
+
129
+ // For tests that exercise pre-READY behavior (Identify/heartbeat/close paths): start() stays
130
+ // pending here. The start promise's rejection is swallowed; afterEach stop() clears its timer.
131
+ async function startConnecting(listener: DiscordListener): Promise<MockWs> {
132
+ listener.start().catch(() => {})
133
+ const ws = await waitForSocket()
134
+ ws.simulateOpen()
135
+ return ws
136
+ }
137
+
110
138
  describe('DiscordListener', () => {
111
139
  let listener: DiscordListener
112
140
 
113
141
  afterEach(() => {
114
142
  listener?.stop()
143
+ mockWsInstance = undefined as unknown as MockWs
115
144
  })
116
145
 
117
146
  describe('start', () => {
@@ -119,21 +148,75 @@ describe('DiscordListener', () => {
119
148
  const client = createMockClient()
120
149
  listener = new DiscordListener(client)
121
150
 
122
- await listener.start()
123
- mockWsInstance.simulateOpen()
151
+ await startAndReady(listener)
124
152
 
125
153
  expect(client.gatewayConnect).toHaveBeenCalledTimes(1)
126
154
  })
127
155
 
156
+ it('does not resolve until a READY dispatch is delivered', async () => {
157
+ const client = createMockClient()
158
+ listener = new DiscordListener(client)
159
+
160
+ let resolved = false
161
+ const started = listener.start().then(() => {
162
+ resolved = true
163
+ })
164
+
165
+ const ws = await waitForSocket()
166
+ ws.simulateOpen()
167
+ ws.simulateHello()
168
+
169
+ // given: socket open + Hello (Identify sent) but no READY yet
170
+ await Promise.resolve()
171
+ expect(resolved).toBe(false)
172
+
173
+ // when: READY arrives
174
+ ws.simulateReady()
175
+ await started
176
+
177
+ expect(resolved).toBe(true)
178
+ })
179
+
128
180
  it('is idempotent', async () => {
129
181
  const client = createMockClient()
130
182
  listener = new DiscordListener(client)
131
183
 
132
- await listener.start()
184
+ await startAndReady(listener)
133
185
  await listener.start()
134
186
 
135
187
  expect(client.gatewayConnect).toHaveBeenCalledTimes(1)
136
188
  })
189
+
190
+ it('shares one readiness promise across concurrent start() calls', async () => {
191
+ const client = createMockClient()
192
+ listener = new DiscordListener(client)
193
+
194
+ const first = listener.start()
195
+ const second = listener.start()
196
+
197
+ const ws = await waitForSocket()
198
+ ws.simulateOpen()
199
+ ws.simulateHello()
200
+ ws.simulateReady()
201
+
202
+ await Promise.all([first, second])
203
+ expect(client.gatewayConnect).toHaveBeenCalledTimes(1)
204
+ })
205
+
206
+ it('rejects an in-flight start() when stop() is called before READY', async () => {
207
+ const client = createMockClient()
208
+ listener = new DiscordListener(client)
209
+
210
+ const started = listener.start()
211
+ const ws = await waitForSocket()
212
+ ws.simulateOpen()
213
+ ws.simulateHello()
214
+
215
+ // given: start() is still awaiting READY when the consumer stops the listener
216
+ listener.stop()
217
+
218
+ await expect(started).rejects.toThrow(/stopped before becoming ready/)
219
+ })
137
220
  })
138
221
 
139
222
  describe('connected event', () => {
@@ -144,10 +227,7 @@ describe('DiscordListener', () => {
144
227
  const connected: any[] = []
145
228
  listener.on('connected', (info) => connected.push(info))
146
229
 
147
- await listener.start()
148
- mockWsInstance.simulateOpen()
149
- mockWsInstance.simulateHello()
150
- mockWsInstance.simulateReady()
230
+ await startAndReady(listener)
151
231
 
152
232
  expect(connected.length).toBe(1)
153
233
  expect(connected[0].user.id).toBe('U_SELF')
@@ -160,9 +240,8 @@ describe('DiscordListener', () => {
160
240
  const client = createMockClient()
161
241
  listener = new DiscordListener(client)
162
242
 
163
- await listener.start()
164
- mockWsInstance.simulateOpen()
165
- mockWsInstance.simulateHello()
243
+ const ws = await startConnecting(listener)
244
+ ws.simulateHello()
166
245
 
167
246
  const sentMessages = mockWsInstance.sent.map((s) => JSON.parse(s))
168
247
  const identifyMsg = sentMessages.find((m) => m.op === 2)
@@ -175,9 +254,8 @@ describe('DiscordListener', () => {
175
254
  const client = createMockClient()
176
255
  listener = new DiscordListener(client)
177
256
 
178
- await listener.start()
179
- mockWsInstance.simulateOpen()
180
- mockWsInstance.simulateHello()
257
+ const ws = await startConnecting(listener)
258
+ ws.simulateHello()
181
259
 
182
260
  const sentMessages = mockWsInstance.sent.map((s) => JSON.parse(s))
183
261
  const identifyMsg = sentMessages.find((m) => m.op === 2)
@@ -204,10 +282,7 @@ describe('DiscordListener', () => {
204
282
  const messages: DiscordGatewayMessageCreateEvent[] = []
205
283
  listener.on('message_create', (event) => messages.push(event))
206
284
 
207
- await listener.start()
208
- mockWsInstance.simulateOpen()
209
- mockWsInstance.simulateHello()
210
- mockWsInstance.simulateReady()
285
+ await startAndReady(listener)
211
286
  mockWsInstance.simulateDispatch(
212
287
  'MESSAGE_CREATE',
213
288
  {
@@ -232,10 +307,7 @@ describe('DiscordListener', () => {
232
307
  const updates: DiscordGatewayMessageUpdateEvent[] = []
233
308
  listener.on('message_update', (event) => updates.push(event))
234
309
 
235
- await listener.start()
236
- mockWsInstance.simulateOpen()
237
- mockWsInstance.simulateHello()
238
- mockWsInstance.simulateReady()
310
+ await startAndReady(listener)
239
311
  mockWsInstance.simulateDispatch(
240
312
  'MESSAGE_UPDATE',
241
313
  { id: 'msg_1', channel_id: 'C123', content: 'edited', edited_timestamp: '2024-01-01T00:01:00Z' },
@@ -254,10 +326,7 @@ describe('DiscordListener', () => {
254
326
  const deletes: DiscordGatewayMessageDeleteEvent[] = []
255
327
  listener.on('message_delete', (event) => deletes.push(event))
256
328
 
257
- await listener.start()
258
- mockWsInstance.simulateOpen()
259
- mockWsInstance.simulateHello()
260
- mockWsInstance.simulateReady()
329
+ await startAndReady(listener)
261
330
  mockWsInstance.simulateDispatch('MESSAGE_DELETE', { id: 'msg_1', channel_id: 'C123' }, 2)
262
331
 
263
332
  expect(deletes.length).toBe(1)
@@ -273,10 +342,7 @@ describe('DiscordListener', () => {
273
342
  const reactions: DiscordGatewayReactionEvent[] = []
274
343
  listener.on('message_reaction_add', (event) => reactions.push(event))
275
344
 
276
- await listener.start()
277
- mockWsInstance.simulateOpen()
278
- mockWsInstance.simulateHello()
279
- mockWsInstance.simulateReady()
345
+ await startAndReady(listener)
280
346
  mockWsInstance.simulateDispatch(
281
347
  'MESSAGE_REACTION_ADD',
282
348
  {
@@ -302,10 +368,7 @@ describe('DiscordListener', () => {
302
368
  const events: DiscordGatewayGenericEvent[] = []
303
369
  listener.on('discord_event', (event) => events.push(event))
304
370
 
305
- await listener.start()
306
- mockWsInstance.simulateOpen()
307
- mockWsInstance.simulateHello()
308
- mockWsInstance.simulateReady()
371
+ await startAndReady(listener)
309
372
  mockWsInstance.simulateDispatch(
310
373
  'MESSAGE_CREATE',
311
374
  { id: 'm1', channel_id: 'C1', content: 'hi', timestamp: 't', author: { id: 'U1', username: 'u' } },
@@ -328,9 +391,8 @@ describe('DiscordListener', () => {
328
391
  const client = createMockClient()
329
392
  listener = new DiscordListener(client)
330
393
 
331
- await listener.start()
332
- mockWsInstance.simulateOpen()
333
- mockWsInstance.simulateHello(50)
394
+ const ws = await startConnecting(listener)
395
+ ws.simulateHello(50)
334
396
 
335
397
  await new Promise((r) => setTimeout(r, 150))
336
398
 
@@ -350,10 +412,7 @@ describe('DiscordListener', () => {
350
412
  const events: DiscordGatewayGenericEvent[] = []
351
413
  listener.on('discord_event', (event) => events.push(event))
352
414
 
353
- await listener.start()
354
- mockWsInstance.simulateOpen()
355
- mockWsInstance.simulateHello()
356
- mockWsInstance.simulateReady()
415
+ await startAndReady(listener)
357
416
  mockWsInstance.simulateHeartbeatACK()
358
417
 
359
418
  expect(events.length).toBe(0)
@@ -370,9 +429,8 @@ describe('DiscordListener', () => {
370
429
  const disconnected: boolean[] = []
371
430
  listener.on('disconnected', () => disconnected.push(true))
372
431
 
373
- await listener.start()
374
- mockWsInstance.simulateOpen()
375
- mockWsInstance.simulateHello(50)
432
+ const ws = await startConnecting(listener)
433
+ ws.simulateHello(50)
376
434
 
377
435
  await new Promise((r) => setTimeout(r, 300))
378
436
 
@@ -388,8 +446,7 @@ describe('DiscordListener', () => {
388
446
  const client = createMockClient()
389
447
  listener = new DiscordListener(client)
390
448
 
391
- await listener.start()
392
- mockWsInstance.simulateOpen()
449
+ await startConnecting(listener)
393
450
 
394
451
  listener.stop()
395
452
 
@@ -406,9 +463,8 @@ describe('DiscordListener', () => {
406
463
  const disconnected: boolean[] = []
407
464
  listener.on('disconnected', () => disconnected.push(true))
408
465
 
409
- await listener.start()
410
- mockWsInstance.simulateOpen()
411
- mockWsInstance.simulateClose()
466
+ const ws = await startConnecting(listener)
467
+ ws.simulateClose()
412
468
 
413
469
  expect(disconnected.length).toBe(1)
414
470
 
@@ -416,28 +472,20 @@ describe('DiscordListener', () => {
416
472
  expect(client.gatewayConnect.mock.calls.length).toBeGreaterThanOrEqual(2)
417
473
  })
418
474
 
419
- it('emits error and reconnects on gatewayConnect failure', async () => {
420
- let callCount = 0
475
+ it('rejects start() and stops on gatewayConnect failure during initial connect', async () => {
421
476
  const client = createMockClient({
422
- gatewayConnect: mock(() => {
423
- callCount++
424
- if (callCount === 1) return Promise.reject(new Error('network_error'))
425
- return Promise.resolve({ token: 'fake-token' })
426
- }),
477
+ gatewayConnect: mock(() => Promise.reject(new Error('network_error'))),
427
478
  })
428
479
 
429
480
  listener = new DiscordListener(client)
481
+ listener.on('error', () => {})
430
482
 
431
- const errors: Error[] = []
432
- listener.on('error', (err) => errors.push(err))
433
-
434
- await listener.start()
483
+ await expect(listener.start()).rejects.toThrow('network_error')
435
484
 
485
+ // given: a pre-READY connect error tears down the listener (no resurrected reconnect loop)
436
486
  await new Promise((r) => setTimeout(r, 1500))
437
-
438
- expect(errors.length).toBe(1)
439
- expect(errors[0].message).toBe('network_error')
440
- expect(client.gatewayConnect.mock.calls.length).toBeGreaterThanOrEqual(2)
487
+ expect((listener as any).running).toBe(false)
488
+ expect(client.gatewayConnect).toHaveBeenCalledTimes(1)
441
489
  })
442
490
  })
443
491
 
@@ -450,10 +498,7 @@ describe('DiscordListener', () => {
450
498
  const handler = (event: DiscordGatewayMessageCreateEvent) => messages.push(event)
451
499
  listener.on('message_create', handler)
452
500
 
453
- await listener.start()
454
- mockWsInstance.simulateOpen()
455
- mockWsInstance.simulateHello()
456
- mockWsInstance.simulateReady()
501
+ await startAndReady(listener)
457
502
  mockWsInstance.simulateDispatch(
458
503
  'MESSAGE_CREATE',
459
504
  { id: 'm1', channel_id: 'C1', content: 'a', timestamp: 't', author: { id: 'U1', username: 'u' } },
@@ -478,10 +523,7 @@ describe('DiscordListener', () => {
478
523
  const messages: DiscordGatewayMessageCreateEvent[] = []
479
524
  listener.once('message_create', (event) => messages.push(event))
480
525
 
481
- await listener.start()
482
- mockWsInstance.simulateOpen()
483
- mockWsInstance.simulateHello()
484
- mockWsInstance.simulateReady()
526
+ await startAndReady(listener)
485
527
  mockWsInstance.simulateDispatch(
486
528
  'MESSAGE_CREATE',
487
529
  { id: 'm1', channel_id: 'C1', content: 'first', timestamp: 't', author: { id: 'U1', username: 'u' } },
@@ -503,10 +545,7 @@ describe('DiscordListener', () => {
503
545
  const client = createMockClient()
504
546
  listener = new DiscordListener(client)
505
547
 
506
- await listener.start()
507
- mockWsInstance.simulateOpen()
508
- mockWsInstance.simulateHello()
509
- mockWsInstance.simulateReady()
548
+ await startAndReady(listener)
510
549
 
511
550
  ;(listener as any).reconnectAttempts = 5
512
551
  mockWsInstance.simulateReconnect()
@@ -520,10 +559,7 @@ describe('DiscordListener', () => {
520
559
  const client = createMockClient()
521
560
  listener = new DiscordListener(client)
522
561
 
523
- await listener.start()
524
- mockWsInstance.simulateOpen()
525
- mockWsInstance.simulateHello()
526
- mockWsInstance.simulateReady()
562
+ await startAndReady(listener)
527
563
 
528
564
  expect((listener as any).sessionId).toBe('session_123')
529
565
 
@@ -538,10 +574,7 @@ describe('DiscordListener', () => {
538
574
  const client = createMockClient()
539
575
  listener = new DiscordListener(client)
540
576
 
541
- await listener.start()
542
- mockWsInstance.simulateOpen()
543
- mockWsInstance.simulateHello()
544
- mockWsInstance.simulateReady()
577
+ await startAndReady(listener)
545
578
 
546
579
  const sessionIdBefore = (listener as any).sessionId
547
580
 
@@ -556,10 +589,7 @@ describe('DiscordListener', () => {
556
589
  const client = createMockClient()
557
590
  listener = new DiscordListener(client)
558
591
 
559
- await listener.start()
560
- mockWsInstance.simulateOpen()
561
- mockWsInstance.simulateHello()
562
- mockWsInstance.simulateReady()
592
+ await startAndReady(listener)
563
593
 
564
594
  mockWsInstance.simulateClose()
565
595
 
@@ -577,22 +607,38 @@ describe('DiscordListener', () => {
577
607
  })
578
608
 
579
609
  describe('non-recoverable close codes', () => {
580
- it('emits error and stops on code 4004', async () => {
581
- const client = createMockClient()
582
- listener = new DiscordListener(client)
610
+ for (const code of [4004, 4013, 4014]) {
611
+ it(`rejects start() and stops on non-recoverable close ${code}`, async () => {
612
+ const client = createMockClient()
613
+ listener = new DiscordListener(client)
614
+ listener.on('error', () => {})
583
615
 
584
- const errors: Error[] = []
585
- listener.on('error', (err) => errors.push(err))
616
+ const started = listener.start()
617
+ const ws = await waitForSocket()
618
+ ws.simulateOpen()
619
+ ws.simulateClose(code)
586
620
 
587
- await listener.start()
588
- mockWsInstance.simulateOpen()
589
- mockWsInstance.simulateClose(4004)
621
+ await expect(started).rejects.toThrow(String(code))
622
+ expect((listener as any).running).toBe(false)
623
+ expect(client.gatewayConnect).toHaveBeenCalledTimes(1)
624
+ })
625
+ }
626
+ })
590
627
 
591
- await new Promise((r) => setTimeout(r, 50))
628
+ describe('connect timeout', () => {
629
+ it('rejects start() and tears down when READY never arrives', async () => {
630
+ const client = createMockClient()
631
+ listener = new DiscordListener(client, { connectTimeoutMs: 100 })
632
+ listener.on('error', () => {})
592
633
 
593
- expect(errors.length).toBe(1)
594
- expect(errors[0].message).toContain('4004')
595
- expect(client.gatewayConnect).toHaveBeenCalledTimes(1)
634
+ const started = listener.start()
635
+ const ws = await waitForSocket()
636
+ ws.simulateOpen()
637
+ ws.simulateHello()
638
+ // given: Identify sent but the gateway never delivers READY
639
+
640
+ await expect(started).rejects.toThrow(/did not become ready/)
641
+ expect((listener as any).running).toBe(false)
596
642
  })
597
643
  })
598
644
 
@@ -601,10 +647,7 @@ describe('DiscordListener', () => {
601
647
  const client = createMockClient()
602
648
  listener = new DiscordListener(client)
603
649
 
604
- await listener.start()
605
- mockWsInstance.simulateOpen()
606
- mockWsInstance.simulateHello()
607
- mockWsInstance.simulateReady()
650
+ await startAndReady(listener)
608
651
 
609
652
  expect((listener as any).sessionId).toBe('session_123')
610
653
 
@@ -631,10 +674,7 @@ describe('DiscordListener', () => {
631
674
  const client = createMockClient()
632
675
  listener = new DiscordListener(client)
633
676
 
634
- await listener.start()
635
- mockWsInstance.simulateOpen()
636
- mockWsInstance.simulateHello()
637
- mockWsInstance.simulateReady()
677
+ await startAndReady(listener)
638
678
 
639
679
  mockWsInstance.simulateClose(4009)
640
680
 
@@ -651,10 +691,12 @@ describe('DiscordListener', () => {
651
691
  const client = createMockClient()
652
692
  listener = new DiscordListener(client)
653
693
 
654
- await listener.start()
655
- mockWsInstance.simulateOpen()
656
- mockWsInstance.simulateHello(50)
657
- mockWsInstance.simulateReady()
694
+ const started = listener.start()
695
+ const ws = await waitForSocket()
696
+ ws.simulateOpen()
697
+ ws.simulateHello(50)
698
+ ws.simulateReady()
699
+ await started
658
700
 
659
701
  mockWsInstance.simulateHello(50)
660
702
 
@@ -679,10 +721,7 @@ describe('DiscordListener', () => {
679
721
  const client = createMockClient()
680
722
  listener = new DiscordListener(client)
681
723
 
682
- await listener.start()
683
- mockWsInstance.simulateOpen()
684
- mockWsInstance.simulateHello()
685
- mockWsInstance.simulateReady()
724
+ await startAndReady(listener)
686
725
 
687
726
  mockWsInstance.simulateInvalidSession(true)
688
727
 
@@ -698,10 +737,7 @@ describe('DiscordListener', () => {
698
737
  const client = createMockClient()
699
738
  listener = new DiscordListener(client)
700
739
 
701
- await listener.start()
702
- mockWsInstance.simulateOpen()
703
- mockWsInstance.simulateHello()
704
- mockWsInstance.simulateReady()
740
+ await startAndReady(listener)
705
741
 
706
742
  mockWsInstance.simulateInvalidSession(false)
707
743
 
@@ -724,10 +760,7 @@ describe('DiscordListener', () => {
724
760
  const client = createMockClient()
725
761
  listener = new DiscordListener(client)
726
762
 
727
- await listener.start()
728
- mockWsInstance.simulateOpen()
729
- mockWsInstance.simulateHello()
730
- mockWsInstance.simulateReady()
763
+ await startAndReady(listener)
731
764
 
732
765
  const sentBefore = mockWsInstance.sent.length
733
766
  mockWsInstance.simulateMessage({ op: 1 })
@@ -744,10 +777,7 @@ describe('DiscordListener', () => {
744
777
  const client = createMockClient()
745
778
  listener = new DiscordListener(client)
746
779
 
747
- await listener.start()
748
- mockWsInstance.simulateOpen()
749
- mockWsInstance.simulateHello()
750
- mockWsInstance.simulateReady()
780
+ await startAndReady(listener)
751
781
 
752
782
  mockWsInstance.simulateDispatch(
753
783
  'MESSAGE_CREATE',
@@ -762,10 +792,7 @@ describe('DiscordListener', () => {
762
792
  const client = createMockClient()
763
793
  listener = new DiscordListener(client)
764
794
 
765
- await listener.start()
766
- mockWsInstance.simulateOpen()
767
- mockWsInstance.simulateHello()
768
- mockWsInstance.simulateReady()
795
+ await startAndReady(listener)
769
796
 
770
797
  mockWsInstance.simulateDispatch(
771
798
  'MESSAGE_CREATE',
@@ -789,11 +816,11 @@ describe('DiscordListener', () => {
789
816
  const client = createMockClient()
790
817
  listener = new DiscordListener(client)
791
818
 
792
- await listener.start()
819
+ await startConnecting(listener)
793
820
  ;(listener as any).reconnectAttempts = 5
794
821
  listener.stop()
795
822
 
796
- await listener.start()
823
+ await startConnecting(listener)
797
824
  expect((listener as any).reconnectAttempts).toBe(0)
798
825
  })
799
826
  })
@@ -803,10 +830,11 @@ describe('DiscordListener', () => {
803
830
  const client = createMockClient()
804
831
  listener = new DiscordListener(client)
805
832
 
806
- await listener.start()
807
- mockWsInstance.simulateOpen()
808
- mockWsInstance.simulateHello()
809
- mockWsInstance.simulateMessage({
833
+ const started = listener.start()
834
+ const ws = await waitForSocket()
835
+ ws.simulateOpen()
836
+ ws.simulateHello()
837
+ ws.simulateMessage({
810
838
  op: 0,
811
839
  t: 'READY',
812
840
  s: 1,
@@ -816,6 +844,7 @@ describe('DiscordListener', () => {
816
844
  user: { id: 'U_SELF', username: 'user' },
817
845
  },
818
846
  })
847
+ await started
819
848
 
820
849
  mockWsInstance.simulateClose()
821
850
  await new Promise((r) => setTimeout(r, 1500))
@@ -829,10 +858,11 @@ describe('DiscordListener', () => {
829
858
  const client = createMockClient()
830
859
  listener = new DiscordListener(client)
831
860
 
832
- await listener.start()
861
+ listener.start().catch(() => {})
862
+ const ws = await waitForSocket()
833
863
  ;(listener as any).reconnectAttempts = 5
834
864
 
835
- mockWsInstance.simulateOpen()
865
+ ws.simulateOpen()
836
866
 
837
867
  expect((listener as any).reconnectAttempts).toBe(5)
838
868
  })
@@ -841,12 +871,14 @@ describe('DiscordListener', () => {
841
871
  const client = createMockClient()
842
872
  listener = new DiscordListener(client)
843
873
 
844
- await listener.start()
874
+ const started = listener.start()
875
+ const ws = await waitForSocket()
845
876
  ;(listener as any).reconnectAttempts = 5
846
877
 
847
- mockWsInstance.simulateOpen()
848
- mockWsInstance.simulateHello()
849
- mockWsInstance.simulateReady()
878
+ ws.simulateOpen()
879
+ ws.simulateHello()
880
+ ws.simulateReady()
881
+ await started
850
882
 
851
883
  expect((listener as any).reconnectAttempts).toBe(0)
852
884
  })