Completed
Push — 1.x ( 560e55...2deed9 )
by Kevin
14s queued 12s
created

envelope_collection_assertions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 14
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 24
rs 9.7998
1
<?php
2
3
namespace Zenstruck\Messenger\Test\Tests;
4
5
use PHPUnit\Framework\AssertionFailedError;
6
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
7
use Symfony\Component\DependencyInjection\ContainerInterface;
8
use Symfony\Component\HttpKernel\KernelInterface;
9
use Symfony\Component\Messenger\Envelope;
10
use Symfony\Component\Messenger\MessageBusInterface;
11
use Symfony\Component\Messenger\Stamp\DelayStamp;
12
use Symfony\Component\Messenger\Stamp\SerializerStamp;
13
use Zenstruck\Assert;
14
use Zenstruck\Messenger\Test\InteractsWithMessenger;
15
use Zenstruck\Messenger\Test\TestEnvelope;
16
use Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageA;
17
use Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageAHandler;
18
use Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageB;
19
use Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageBHandler;
20
use Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageC;
21
use Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageD;
22
use Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageE;
23
use Zenstruck\Messenger\Test\Tests\Fixture\Messenger\MessageF;
24
use Zenstruck\Messenger\Test\Tests\Fixture\NoBundleKernel;
25
26
/**
27
 * @author Kevin Bond <[email protected]>
28
 */
29
final class InteractsWithMessengerTest extends WebTestCase
30
{
31
    use InteractsWithMessenger;
32
33
    /**
34
     * @test
35
     */
36
    public function can_interact_with_queue(): void
37
    {
38
        self::bootKernel();
39
40
        $this->messenger()->queue()->assertEmpty();
41
        $this->assertEmpty(self::getContainer()->get(MessageAHandler::class)->messages);
42
        $this->assertEmpty(self::getContainer()->get(MessageBHandler::class)->messages);
43
44
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
45
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageB());
46
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
47
48
        $this->messenger()->queue()->assertCount(3);
49
        $this->messenger()->queue()->assertContains(MessageA::class);
50
        $this->messenger()->queue()->assertContains(MessageA::class, 2);
51
        $this->messenger()->queue()->assertContains(MessageB::class);
52
        $this->messenger()->queue()->assertContains(MessageB::class, 1);
53
        $this->messenger()->queue()->assertNotContains(MessageC::class);
54
        $this->assertEmpty(self::getContainer()->get(MessageAHandler::class)->messages);
55
        $this->assertEmpty(self::getContainer()->get(MessageBHandler::class)->messages);
56
57
        $this->messenger()->process(2);
58
59
        $this->messenger()->queue()->assertCount(1);
60
        $this->messenger()->queue()->assertContains(MessageA::class, 1);
61
        $this->messenger()->queue()->assertNotContains(MessageB::class);
62
        $this->assertCount(1, self::getContainer()->get(MessageAHandler::class)->messages);
63
        $this->assertCount(1, self::getContainer()->get(MessageBHandler::class)->messages);
64
65
        $this->messenger()->process();
66
67
        $this->messenger()->queue()->assertEmpty();
68
        $this->messenger()->queue()->assertNotContains(MessageA::class);
69
        $this->messenger()->queue()->assertNotContains(MessageB::class);
70
        $this->assertCount(2, self::getContainer()->get(MessageAHandler::class)->messages);
71
        $this->assertCount(1, self::getContainer()->get(MessageBHandler::class)->messages);
72
    }
73
74
    /**
75
     * @test
76
     */
77
    public function can_disable_intercept(): void
78
    {
79
        self::bootKernel();
80
81
        $this->messenger()->unblock();
82
83
        $this->messenger()->queue()->assertEmpty();
84
        $this->messenger()->acknowledged()->assertEmpty();
85
        $this->messenger()->dispatched()->assertEmpty();
86
87
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
88
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageB());
89
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
90
91
        $this->messenger()->queue()->assertEmpty();
92
        $this->messenger()->queue()->assertNotContains(MessageA::class);
93
        $this->messenger()->dispatched()->assertCount(3);
94
        $this->messenger()->dispatched()->assertContains(MessageA::class, 2);
95
        $this->messenger()->dispatched()->assertContains(MessageB::class, 1);
96
        $this->messenger()->acknowledged()->assertCount(3);
97
        $this->messenger()->acknowledged()->assertContains(MessageA::class, 2);
98
        $this->messenger()->acknowledged()->assertContains(MessageB::class, 1);
99
        $this->assertCount(2, self::getContainer()->get(MessageAHandler::class)->messages);
100
        $this->assertCount(1, self::getContainer()->get(MessageBHandler::class)->messages);
101
    }
102
103
    /**
104
     * @test
105
     */
106
    public function disabling_intercept_with_items_on_queue_processes_all(): void
107
    {
108
        self::bootKernel();
109
110
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
111
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageB());
112
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
113
114
        $this->messenger()->queue()->assertCount(3);
115
116
        $this->messenger()->process();
117
118
        $this->messenger()->queue()->assertEmpty();
119
        $this->assertCount(2, self::getContainer()->get(MessageAHandler::class)->messages);
120
        $this->assertCount(1, self::getContainer()->get(MessageBHandler::class)->messages);
121
    }
122
123
    /**
124
     * @test
125
     */
126
    public function unblocking_processes_existing_messages_on_queue(): void
127
    {
128
        self::bootKernel();
129
130
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
131
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageB());
132
133
        $this->messenger()->queue()->assertCount(2);
134
        $this->messenger()->acknowledged()->assertEmpty();
135
136
        $this->messenger()->unblock();
137
138
        $this->messenger()->queue()->assertEmpty();
139
        $this->messenger()->acknowledged()->assertCount(2);
140
    }
141
142
    /**
143
     * @test
144
     */
145
    public function can_access_envelope_collection_items_via_first(): void
146
    {
147
        self::bootKernel();
148
149
        self::getContainer()->get(MessageBusInterface::class)->dispatch($m1 = new MessageA());
150
        self::getContainer()->get(MessageBusInterface::class)->dispatch($m2 = new MessageB());
151
        self::getContainer()->get(MessageBusInterface::class)->dispatch($m3 = new MessageA(true));
152
153
        $this->messenger()->queue()->assertCount(3);
154
155
        $this->assertSame($m1, $this->messenger()->queue()->first()->getMessage());
0 ignored issues
show
Bug introduced by
The method getMessage() does not exist on Zenstruck\Messenger\Test\TestEnvelope. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

155
        $this->assertSame($m1, $this->messenger()->queue()->first()->/** @scrutinizer ignore-call */ getMessage());
Loading history...
156
        $this->assertSame($m2, $this->messenger()->queue()->first(MessageB::class)->getMessage());
157
        $this->assertSame($m3, $this->messenger()->queue()->first(fn(Envelope $e) => $e->getMessage()->fail)->getMessage());
158
        $this->assertSame($m3, $this->messenger()->queue()->first(fn($e) => $e->getMessage()->fail)->getMessage());
159
        $this->assertSame($m3, $this->messenger()->queue()->first(fn(MessageA $m) => $m->fail)->getMessage());
160
    }
161
162
    /**
163
     * @test
164
     */
165
    public function envelope_collection_first_throws_exception_if_no_match(): void
166
    {
167
        self::bootKernel();
168
169
        $this->expectException(\RuntimeException::class);
170
171
        $this->messenger()->queue()->first();
172
    }
173
174
    /**
175
     * @test
176
     */
177
    public function can_make_stamp_assertions_on_test_envelope(): void
178
    {
179
        self::bootKernel();
180
181
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA(), [new DelayStamp(1000)]);
182
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageB());
183
184
        $this->messenger()->queue()->first()->assertHasStamp(DelayStamp::class);
185
        $this->messenger()->queue()->first(MessageB::class)->assertNotHasStamp(DelayStamp::class);
186
187
        Assert::that(fn() => $this->messenger()->queue()->first()->assertHasStamp(SerializerStamp::class))
188
            ->throws(AssertionFailedError::class, \sprintf('Expected to find stamp "%s" but did not.', SerializerStamp::class))
189
        ;
190
    }
191
192
    /**
193
     * @test
194
     */
195
    public function cannot_access_queue_if_none_registered(): void
196
    {
197
        self::bootKernel(['environment' => 'test']);
198
199
        $this->expectException(\LogicException::class);
200
        $this->expectExceptionMessage('No transports registered');
201
202
        $this->messenger();
203
    }
204
205
    /**
206
     * @test
207
     */
208
    public function accessing_transport_boots_kernel_if_not_yet_booted(): void
209
    {
210
        $this->messenger()->queue()->assertEmpty();
211
    }
212
213
    /**
214
     * @test
215
     */
216
    public function can_interact_with_multiple_queues(): void
217
    {
218
        self::bootKernel(['environment' => 'multi_transport']);
219
220
        $this->messenger('async1')->queue()->assertEmpty();
221
        $this->messenger('async2')->queue()->assertEmpty();
222
        $this->assertEmpty(self::getContainer()->get(MessageAHandler::class)->messages);
223
        $this->assertEmpty(self::getContainer()->get(MessageBHandler::class)->messages);
224
225
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
226
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageB());
227
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
228
229
        $this->messenger('async1')->queue()->assertCount(2);
230
        $this->messenger('async2')->queue()->assertEmpty();
231
        $this->messenger('async1')->queue()->assertContains(MessageA::class);
232
        $this->messenger('async1')->queue()->assertContains(MessageA::class, 2);
233
        $this->messenger('async2')->queue()->assertNotContains(MessageB::class);
234
        $this->assertEmpty(self::getContainer()->get(MessageAHandler::class)->messages);
235
        $this->assertCount(1, self::getContainer()->get(MessageBHandler::class)->messages);
236
237
        $this->messenger('async1')->process(1);
238
239
        $this->messenger('async1')->queue()->assertCount(1);
240
        $this->messenger('async1')->queue()->assertContains(MessageA::class, 1);
241
        $this->messenger('async2')->queue()->assertNotContains(MessageB::class);
242
        $this->assertCount(1, self::getContainer()->get(MessageAHandler::class)->messages);
243
        $this->assertCount(1, self::getContainer()->get(MessageBHandler::class)->messages);
244
245
        $this->messenger('async1')->process();
246
247
        $this->messenger('async1')->queue()->assertEmpty();
248
        $this->messenger('async2')->queue()->assertEmpty();
249
        $this->messenger('async2')->acknowledged()->assertCount(1);
250
        $this->messenger('async2')->acknowledged()->assertContains(MessageB::class, 1);
251
        $this->assertCount(2, self::getContainer()->get(MessageAHandler::class)->messages);
252
        $this->assertCount(1, self::getContainer()->get(MessageBHandler::class)->messages);
253
    }
254
255
    /**
256
     * @test
257
     */
258
    public function can_enable_intercept(): void
259
    {
260
        self::bootKernel(['environment' => 'multi_transport']);
261
262
        $this->messenger('async2')->intercept();
263
264
        $this->messenger('async2')->queue()->assertEmpty();
265
        $this->assertEmpty(self::getContainer()->get(MessageBHandler::class)->messages);
266
267
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageB());
268
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageB());
269
270
        $this->messenger('async2')->queue()->assertCount(2);
271
    }
272
273
    /**
274
     * @test
275
     */
276
    public function cannot_access_queue_that_does_not_exist(): void
277
    {
278
        self::bootKernel(['environment' => 'multi_transport']);
279
280
        $this->expectException(\InvalidArgumentException::class);
281
        $this->expectExceptionMessage('"invalid" not registered');
282
283
        $this->messenger('invalid');
284
    }
285
286
    /**
287
     * @test
288
     */
289
    public function cannot_access_queue_that_is_not_test_transport(): void
290
    {
291
        self::bootKernel(['environment' => 'multi_transport']);
292
293
        $this->expectException(\LogicException::class);
294
        $this->expectExceptionMessage('Transport "async3" needs to be set to "test://" in your test config to use this feature.');
295
296
        $this->messenger('async3');
297
    }
298
299
    /**
300
     * @test
301
     */
302
    public function queue_name_is_required_if_using_multiple_transports(): void
303
    {
304
        self::bootKernel(['environment' => 'multi_transport']);
305
306
        $this->expectException(\LogicException::class);
307
        $this->expectExceptionMessage('Multiple transports are registered (async1, async2, async3), you must specify a name.');
308
309
        $this->messenger();
310
    }
311
312
    /**
313
     * @test
314
     */
315
    public function can_access_message_objects_on_queue(): void
316
    {
317
        self::bootKernel();
318
319
        self::getContainer()->get(MessageBusInterface::class)->dispatch($m1 = new MessageA());
320
        self::getContainer()->get(MessageBusInterface::class)->dispatch($m2 = new MessageB());
321
        self::getContainer()->get(MessageBusInterface::class)->dispatch($m3 = new MessageA());
322
323
        $this->assertSame([$m1, $m2, $m3], $this->messenger()->queue()->messages());
324
        $this->assertSame([$m1, $m3], $this->messenger()->queue()->messages(MessageA::class));
325
        $this->assertSame([$m2], $this->messenger()->queue()->messages(MessageB::class));
326
    }
327
328
    /**
329
     * @test
330
     */
331
    public function can_access_envelopes_on_envelope_collection(): void
332
    {
333
        self::bootKernel();
334
335
        self::getContainer()->get(MessageBusInterface::class)->dispatch($m1 = new MessageA());
336
        self::getContainer()->get(MessageBusInterface::class)->dispatch($m2 = new MessageB());
337
        self::getContainer()->get(MessageBusInterface::class)->dispatch($m3 = new MessageA());
338
339
        $messages = \array_map(fn(TestEnvelope $envelope) => $envelope->getMessage(), $this->messenger()->queue()->all());
340
        $messagesFromIterator = \array_map(fn(TestEnvelope $envelope) => $envelope->getMessage(), \iterator_to_array($this->messenger()->queue()));
341
342
        $this->assertSame([$m1, $m2, $m3], $messages);
343
        $this->assertSame([$m1, $m2, $m3], $messagesFromIterator);
344
    }
345
346
    /**
347
     * @test
348
     */
349
    public function can_access_sent_acknowledged_and_rejected(): void
350
    {
351
        self::bootKernel();
352
353
        self::getContainer()->get(MessageBusInterface::class)->dispatch($m1 = new MessageA(true));
354
        self::getContainer()->get(MessageBusInterface::class)->dispatch($m2 = new MessageB());
355
356
        $this->assertCount(2, $this->messenger()->queue());
357
        $this->assertCount(2, $this->messenger()->dispatched());
358
        $this->assertCount(0, $this->messenger()->acknowledged());
359
        $this->assertCount(0, $this->messenger()->rejected());
360
361
        $this->messenger()->process();
362
363
        $this->assertCount(0, $this->messenger()->queue());
364
        $this->assertCount(2, $this->messenger()->dispatched());
365
        $this->assertCount(1, $this->messenger()->acknowledged());
366
        $this->assertCount(1, $this->messenger()->rejected());
367
    }
368
369
    /**
370
     * @test
371
     */
372
    public function cannot_access_queue_if_bundle_not_enabled(): void
373
    {
374
        self::$class = NoBundleKernel::class;
375
        self::bootKernel(['environment' => 'no_bundle']);
376
        self::$class = null;
377
378
        $this->expectException(\LogicException::class);
379
        $this->expectExceptionMessage('Cannot access transport - is ZenstruckMessengerTestBundle enabled in your test environment?');
380
381
        $this->messenger();
382
    }
383
384
    /**
385
     * @test
386
     */
387
    public function can_configure_throwing_exceptions(): void
388
    {
389
        self::bootKernel();
390
391
        $this->messenger()->throwExceptions();
392
393
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA(true));
394
395
        $this->expectException(\RuntimeException::class);
396
        $this->expectExceptionMessage('handling failed...');
397
398
        $this->messenger()->process();
399
    }
400
401
    /**
402
     * @test
403
     */
404
    public function can_configure_throwing_exceptions_with_intercept_disabled(): void
405
    {
406
        self::bootKernel();
407
408
        $this->messenger()->throwExceptions()->unblock();
409
410
        $this->expectException(\RuntimeException::class);
411
        $this->expectExceptionMessage('handling failed...');
412
413
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA(true));
414
    }
415
416
    /**
417
     * @test
418
     */
419
    public function can_disable_exception_catching_in_transport_config(): void
420
    {
421
        self::bootKernel(['environment' => 'multi_transport']);
422
423
        $this->expectException(\RuntimeException::class);
424
        $this->expectExceptionMessage('handling failed...');
425
426
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageB(true));
427
    }
428
429
    /**
430
     * @test
431
     */
432
    public function can_re_enable_exception_catching_if_disabled_in_transport_config(): void
433
    {
434
        self::bootKernel(['environment' => 'multi_transport']);
435
436
        $this->messenger('async2')->catchExceptions();
437
438
        $this->messenger('async2')->rejected()->assertEmpty();
439
440
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageB(true));
441
442
        $this->messenger('async2')->rejected()->assertCount(1);
443
    }
444
445
    /**
446
     * @test
447
     */
448
    public function transport_data_is_persisted_between_requests_and_kernel_shutdown(): void
449
    {
450
        self::bootKernel();
451
452
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
453
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA(true));
454
455
        $this->messenger()->queue()->assertCount(2);
456
457
        self::ensureKernelShutdown();
458
        self::bootKernel();
459
460
        $this->messenger()->queue()->assertCount(2);
461
462
        $this->messenger()->process();
463
464
        self::ensureKernelShutdown();
465
        self::bootKernel();
466
467
        $this->messenger()->queue()->assertEmpty();
468
        $this->messenger()->dispatched()->assertCount(2);
469
        $this->messenger()->acknowledged()->assertCount(1);
470
        $this->messenger()->rejected()->assertCount(1);
471
472
        self::ensureKernelShutdown();
473
474
        $client = self::createClient();
475
476
        $client->request('GET', '/dispatch');
477
478
        $this->messenger()->queue()->assertCount(1);
479
        $this->messenger()->dispatched()->assertCount(3);
480
        $this->messenger()->acknowledged()->assertCount(1);
481
        $this->messenger()->rejected()->assertCount(1);
482
483
        $client->request('GET', '/dispatch');
484
485
        $this->messenger()->queue()->assertCount(2);
486
        $this->messenger()->dispatched()->assertCount(4);
487
        $this->messenger()->acknowledged()->assertCount(1);
488
        $this->messenger()->rejected()->assertCount(1);
489
    }
490
491
    /**
492
     * @test
493
     */
494
    public function can_reset_transport_data(): void
495
    {
496
        self::bootKernel();
497
498
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
499
500
        $this->messenger()->queue()->assertNotEmpty();
501
502
        $this->messenger()->reset();
503
504
        $this->messenger()->queue()->assertEmpty();
505
    }
506
507
    /**
508
     * @test
509
     */
510
    public function disabling_intercept_is_remembered_between_kernel_reboots(): void
511
    {
512
        self::bootKernel();
513
514
        $this->messenger()->unblock();
515
516
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
517
518
        $this->messenger()->queue()->assertEmpty();
519
        $this->messenger()->dispatched()->assertCount(1);
520
521
        self::ensureKernelShutdown();
522
        self::bootKernel();
523
524
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
525
526
        $this->messenger()->queue()->assertEmpty();
527
        $this->messenger()->dispatched()->assertCount(2);
528
    }
529
530
    /**
531
     * @test
532
     */
533
    public function throwing_exceptions_is_remembered_between_kernel_reboots(): void
534
    {
535
        self::bootKernel();
536
537
        $this->messenger()->throwExceptions();
538
539
        self::ensureKernelShutdown();
540
        self::bootKernel();
541
542
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA(true));
543
544
        $this->expectException(\RuntimeException::class);
545
        $this->expectErrorMessage('handling failed...');
546
547
        $this->messenger()->process();
548
    }
549
550
    /**
551
     * @test
552
     */
553
    public function can_manually_send_message_to_transport_and_process(): void
554
    {
555
        self::bootKernel();
556
557
        $this->messenger()->queue()->assertEmpty();
558
        $this->assertEmpty(self::getContainer()->get(MessageAHandler::class)->messages);
559
560
        $this->messenger()->send(Envelope::wrap(new MessageA()));
561
562
        $this->messenger()->queue()->assertCount(1);
563
        $this->assertEmpty(self::getContainer()->get(MessageAHandler::class)->messages);
564
565
        $this->messenger()->process();
566
567
        $this->messenger()->queue()->assertEmpty();
568
        $this->assertCount(1, self::getContainer()->get(MessageAHandler::class)->messages);
569
    }
570
571
    /**
572
     * @test
573
     */
574
    public function process_all_is_recursive(): void
575
    {
576
        self::bootKernel();
577
578
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageD());
579
580
        $this->messenger()->queue()->assertCount(1);
581
        $this->messenger()->queue()->assertContains(MessageD::class, 1);
582
583
        $this->messenger()->process();
584
585
        $this->messenger()->queue()->assertEmpty();
586
        $this->messenger()->dispatched()->assertCount(3);
587
        $this->messenger()->acknowledged()->assertCount(3);
588
        $this->messenger()->acknowledged()->assertContains(MessageD::class, 1);
589
        $this->messenger()->acknowledged()->assertContains(MessageE::class, 1);
590
        $this->messenger()->acknowledged()->assertContains(MessageF::class, 1);
591
    }
592
593
    /**
594
     * @test
595
     */
596
    public function process_x_messages_is_recursive(): void
597
    {
598
        self::bootKernel();
599
600
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageD());
601
602
        $this->messenger()->queue()->assertCount(1);
603
        $this->messenger()->queue()->assertContains(MessageD::class, 1);
604
605
        $this->messenger()->process(1);
606
607
        $this->messenger()->queue()->assertCount(1);
608
        $this->messenger()->queue()->assertContains(MessageE::class, 1);
609
        $this->messenger()->acknowledged()->assertCount(1);
610
        $this->messenger()->acknowledged()->assertContains(MessageD::class, 1);
611
612
        $this->messenger()->process(2);
613
614
        $this->messenger()->queue()->assertEmpty();
615
        $this->messenger()->acknowledged()->assertCount(3);
616
        $this->messenger()->acknowledged()->assertContains(MessageE::class, 1);
617
        $this->messenger()->acknowledged()->assertContains(MessageF::class, 1);
618
    }
619
620
    /**
621
     * @test
622
     */
623
    public function fails_if_trying_to_process_more_messages_than_can_be_processed(): void
624
    {
625
        self::bootKernel();
626
627
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
628
629
        Assert::that(fn() => $this->messenger()->process(2))->throws(function(AssertionFailedError $e) {
630
            $this->assertStringContainsString('Expected to process 2 messages but only processed 1.', $e->getMessage());
631
            $this->messenger()->queue()->assertEmpty();
632
            $this->messenger()->acknowledged()->assertContains(MessageA::class, 1);
633
        });
634
    }
635
636
    /**
637
     * @test
638
     */
639
    public function process_or_fail_processes_messages(): void
640
    {
641
        self::bootKernel();
642
643
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
644
645
        $this->messenger()->queue()->assertCount(1);
646
        $this->messenger()->queue()->assertContains(MessageA::class, 1);
647
648
        $this->messenger()->processOrFail();
649
650
        $this->messenger()->queue()->assertEmpty();
651
        $this->messenger()->acknowledged()->assertCount(1);
652
        $this->messenger()->acknowledged()->assertContains(MessageA::class, 1);
653
    }
654
655
    /**
656
     * @test
657
     */
658
    public function process_or_fail_fails_if_no_messages_on_queue(): void
659
    {
660
        self::bootKernel();
661
662
        Assert::that(fn() => $this->messenger()->processOrFail())
663
            ->throws(AssertionFailedError::class, 'No messages to process.')
664
        ;
665
    }
666
667
    /**
668
     * @test
669
     */
670
    public function envelope_collection_assertions(): void
671
    {
672
        self::bootKernel();
673
674
        Assert::that(fn() => $this->messenger()->dispatched()->assertCount(2))
675
            ->throws(AssertionFailedError::class, 'Expected 2 messages but 0 messages found.')
676
        ;
677
        Assert::that(fn() => $this->messenger()->dispatched()->assertContains(MessageA::class))
678
            ->throws(AssertionFailedError::class, \sprintf('Message "%s" not found.', MessageA::class))
679
        ;
680
        Assert::that(fn() => $this->messenger()->dispatched()->assertNotEmpty())
681
            ->throws(AssertionFailedError::class, 'Expected some messages but found none.')
682
        ;
683
684
        self::getContainer()->get(MessageBusInterface::class)->dispatch(new MessageA());
685
686
        Assert::that(fn() => $this->messenger()->dispatched()->assertEmpty())
687
            ->throws(AssertionFailedError::class, 'Expected 0 messages but 1 messages found.')
688
        ;
689
        Assert::that(fn() => $this->messenger()->dispatched()->assertContains(MessageA::class, 2))
690
            ->throws(AssertionFailedError::class, \sprintf('Expected to find "%s" 2 times but found 1 times.', MessageA::class))
691
        ;
692
        Assert::that(fn() => $this->messenger()->dispatched()->assertNotContains(MessageA::class))
693
            ->throws(AssertionFailedError::class, \sprintf('Found message "%s" but should not.', MessageA::class))
694
        ;
695
    }
696
697
    protected static function bootKernel(array $options = []): KernelInterface
698
    {
699
        return parent::bootKernel(\array_merge(['environment' => 'single_transport'], $options));
700
    }
701
702
    protected static function getContainer(): ContainerInterface
703
    {
704
        if (\method_exists(parent::class, 'getContainer')) {
705
            return parent::getContainer();
706
        }
707
708
        return self::$container;
709
    }
710
}
711