Skip to content

Commit e242316

Browse files
committed
Add reset message queues before scenario with zentruck/messenger-test
1 parent a747b43 commit e242316

File tree

4 files changed

+182
-1
lines changed

4 files changed

+182
-1
lines changed

README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Behat Messenger Context Bundle
2-
[![Latest Stable Version](http://poser.pugx.org/macpaw/behat-messenger-context/v)](https://packagist.org/packages/macpaw/behat-messenger-context) [![Total Downloads](http://poser.pugx.org/macpaw/behat-messenger-context/downloads)](https://packagist.org/packages/macpaw/behat-messenger-context) [![Latest Unstable Version](http://poser.pugx.org/macpaw/behat-messenger-context/v/unstable)](https://packagist.org/packages/macpaw/behat-messenger-context) [![License](http://poser.pugx.org/macpaw/behat-messenger-context/license)](https://packagist.org/packages/macpaw/behat-messenger-context) [![PHP Version Require](http://poser.pugx.org/macpaw/behat-messenger-context/require/php)](https://packagist.org/packages/macpaw/behat-messenger-context)
2+
[![Latest Stable Version](http://poser.pugx.org/macpaw/behat-messenger-context/v)](https://packagist.org/packages/macpaw/behat-messenger-context)
3+
[![Total Downloads](http://poser.pugx.org/macpaw/behat-messenger-context/downloads)](https://packagist.org/packages/macpaw/behat-messenger-context)
4+
[![Latest Unstable Version](http://poser.pugx.org/macpaw/behat-messenger-context/v/unstable)](https://packagist.org/packages/macpaw/behat-messenger-context)
5+
[![License](http://poser.pugx.org/macpaw/behat-messenger-context/license)](https://packagist.org/packages/macpaw/behat-messenger-context)
6+
[![PHP Version Require](http://poser.pugx.org/macpaw/behat-messenger-context/require/php)](https://packagist.org/packages/macpaw/behat-messenger-context)
37

48
| Version | Build Status | Coverage |
59
|------------|------------------------------------------------------------|--------------------------------------------------------------------------|
@@ -28,6 +32,10 @@ You can use regular expressions to validate messages that contain dynamic or var
2832
* Documentation for specific message: [Check Transport Message with Regexp](docs/MessengerContext/check_transport_message_regexp.md)
2933
* Documentation for all messages: [Check All Transport Messages with Regexp](docs/MessengerContext/check_all_transport_message_regexp.md)
3034

35+
### Check Every Messages with Mask Regular Expressions
36+
You can use regular expression to validate all messages messages that contain dynamic or variable data.
37+
* Documentation for all specific message: [Check Transport Messages with Regexp](docs/MessengerContext/check_transport_messages_regexp_mask.md)
38+
3139
### Verify Message Count in a Transport
3240
Ensure that a specific number of messages exist in a given transport.
3341

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
# Behat Custom Step: Transport JSON Message Assertion with Regexp Fields
3+
4+
This documentation outlines the purpose and usage of the custom Behat step definition for verifying if a Symfony Messenger transport contains a message with a specific JSON mask for every message, using regular expressions to handle dynamic fields.
5+
6+
## Purpose
7+
8+
This function is designed to check if a given transport (such as an asynchronous queue) contains a message that matches a message with a specific JSON mask for every message, while allowing certain fields to be validated using regular expressions. It is particularly useful when testing messages with dynamic data, such as timestamps, unique identifiers, or payloads, where the exact value cannot be guaranteed.
9+
## Function Overview
10+
11+
### Signature:
12+
```php
13+
/**
14+
* @Then all transport :transportName messages have JSON by :fields with mask :mask:
15+
*/
16+
public function allTransportMessagesHaveJsonByFieldsWithMask(
17+
string $transportName,
18+
string $variableFields,
19+
PyStringNode $expectedMessageList,
20+
): void {
21+
```
22+
23+
### Parameters:
24+
- `transportName` (string): The name of the transport (e.g., 'webhook') where the message is expected to be found.
25+
- `variableFields` (string): A comma-separated list of field names where values should be matched using regular expressions.
26+
- `expectedMessage` (PyStringNode): The expected message content in JSON format, where fields marked with `~` in their values will be treated as regular expressions.
27+
28+
```gherkin
29+
And all transport "webhook" messages should contain message with JSON and variable fields "time, payload" by mask:
30+
"""
31+
{
32+
"event": "customer_agreement_status_updated",
33+
"time": "~^\\d{13}$",
34+
"payload": "~^\\{.*\\}$"
35+
}
36+
"""
37+
```

src/Context/MessengerContext.php

+31
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,37 @@ public function allTransportMessagesShouldBeJson(string $transportName, PyString
135135
}
136136
}
137137

138+
/**
139+
* // phpcs:disable
140+
* @And all transport :transportName messages should contain message with JSON and variable fields :fields by mask :mask:
141+
* // phpcs:enable
142+
*/
143+
public function allTransportMessagesHaveJsonByFieldsWithMask(
144+
string $transportName,
145+
string $variableFields,
146+
PyStringNode $expectedMessageList,
147+
): void {
148+
$expectedMessageList = $this->decodeExpectedJson($expectedMessageList);
149+
$variableFields = explode(', ', $variableFields);
150+
151+
$transport = $this->getMessengerTransportByName($transportName);
152+
$actualMessageList = [];
153+
$expectedMessages = [];
154+
foreach ($transport->get() as $envelope) {
155+
$actualMessageList[] = $this->convertToArray($envelope->getMessage());
156+
$expectedMessages[] = $expectedMessageList;
157+
}
158+
159+
if (!$this->isArraysSimilar($expectedMessages, $actualMessageList, $variableFields)) {
160+
throw new Exception(
161+
sprintf(
162+
'The expected transport messages doesn\'t match actual: %s',
163+
$this->getPrettyJson($actualMessageList),
164+
),
165+
);
166+
}
167+
}
168+
138169
/**
139170
* @Then all transport :transportName messages should be JSON with variable fields :variableFields:
140171
*/

tests/Unit/MessengerContextTest.php

+105
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,111 @@ public function testFailAllTransportMessagesShouldBeJsonWithVariableFields(): vo
449449
);
450450
}
451451

452+
public function testAllTransportMessagesHaveJsonByFieldsWithMask(): void
453+
{
454+
$message1 = new \stdClass();
455+
$message1->id = 1;
456+
$message1->name = 'Test';
457+
458+
$message2 = new \stdClass();
459+
$message2->id = 2;
460+
$message2->name = 'Test';
461+
462+
$message3 = new \stdClass();
463+
$message3->id = 1000;
464+
$message3->name = 'Test5';
465+
466+
$envelope1 = new Envelope($message1);
467+
$envelope2 = new Envelope($message2);
468+
$envelope3 = new Envelope($message3);
469+
470+
$transport = $this->createMock(InMemoryTransport::class);
471+
$transport->method('get')->willReturn([$envelope1, $envelope2, $envelope3]);
472+
473+
$this->container
474+
->expects(self::once())
475+
->method('has')
476+
->with('messenger.transport.test')
477+
->willReturn(true);
478+
$this->container
479+
->expects(self::once())
480+
->method('get')
481+
->with('messenger.transport.test')
482+
->willReturn($transport);
483+
484+
$this->normalizer
485+
->expects($this->exactly(3))
486+
->method('normalize')
487+
->willReturnOnConsecutiveCalls(
488+
['id' => 1, 'name' => 'Test'],
489+
['id' => 2, 'name' => 'Test'],
490+
['id' => 1000, 'name' => 'Test5'],
491+
);
492+
493+
$expectedJson = new PyStringNode([
494+
'{"id": "~[0-9]+", "name": "~[a-zA-Z]+"}'
495+
], 1);
496+
497+
$this->messengerContext->allTransportMessagesHaveJsonByFieldsWithMask(
498+
'test',
499+
'id, name',
500+
$expectedJson
501+
);
502+
}
503+
504+
public function testFailAllTransportMessagesHaveJsonByFieldsWithMask(): void
505+
{
506+
$message1 = new \stdClass();
507+
$message1->id = 1;
508+
$message1->name = 'Test';
509+
510+
$message2 = new \stdClass();
511+
$message2->id = 2;
512+
$message2->name = 'Test';
513+
514+
$message3 = new \stdClass();
515+
$message3->id = 1000;
516+
$message3->name = 'Test5';
517+
518+
$envelope1 = new Envelope($message1);
519+
$envelope2 = new Envelope($message2);
520+
$envelope3 = new Envelope($message3);
521+
522+
$transport = $this->createMock(InMemoryTransport::class);
523+
$transport->method('get')->willReturn([$envelope1, $envelope2, $envelope3]);
524+
525+
$this->container
526+
->expects(self::once())
527+
->method('has')
528+
->with('messenger.transport.test')
529+
->willReturn(true);
530+
$this->container
531+
->expects(self::once())
532+
->method('get')
533+
->with('messenger.transport.test')
534+
->willReturn($transport);
535+
536+
$this->normalizer
537+
->expects($this->exactly(3))
538+
->method('normalize')
539+
->willReturnOnConsecutiveCalls(
540+
['id' => 1, 'name' => 'Test'],
541+
['id' => 2, 'name' => 'Test'],
542+
['id' => 1000, 'name' => 'Test5'],
543+
);
544+
545+
$expectedJson = new PyStringNode([
546+
'{"id": "~[a-zA-Z]+", "name": "~[a-zA-Z]+"}'
547+
], 1);
548+
549+
$this->expectException(Exception::class);
550+
$this->messengerContext->allTransportMessagesHaveJsonByFieldsWithMask(
551+
'test',
552+
'id, name',
553+
$expectedJson
554+
);
555+
}
556+
452557
public function testTransportWasReset(): void
453558
{
454559
$serviceProvider = $this->createMock(ServiceProviderInterface::class);

0 commit comments

Comments
 (0)