1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
/** |
3
|
|
|
* This file is part of the daikon-cqrs/message-bus project. |
4
|
|
|
* |
5
|
|
|
* For the full copyright and license information, please view the LICENSE |
6
|
|
|
* file that was distributed with this source code. |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace Daikon\Tests\MessageBus\Channel; |
10
|
|
|
|
11
|
|
|
use Daikon\MessageBus\Channel\Channel; |
12
|
|
|
use Daikon\MessageBus\Channel\ChannelInterface; |
13
|
|
|
use Daikon\MessageBus\Channel\Subscription\SubscriptionInterface; |
14
|
|
|
use Daikon\MessageBus\Channel\Subscription\SubscriptionMap; |
15
|
|
|
use Daikon\MessageBus\Envelope; |
16
|
|
|
use Daikon\MessageBus\EnvelopeInterface; |
17
|
|
|
use Daikon\MessageBus\Exception\EnvelopeNotAcceptable; |
18
|
|
|
use Daikon\MessageBus\Exception\SubscriptionUnknown; |
19
|
|
|
use Daikon\MessageBus\MessageBusInterface; |
20
|
|
|
use Daikon\MessageBus\MessageInterface; |
21
|
|
|
use Daikon\Metadata\Metadata; |
22
|
|
|
use PHPUnit\Framework\TestCase; |
23
|
|
|
|
24
|
|
|
final class ChannelTest extends TestCase |
25
|
|
|
{ |
26
|
|
|
const CHANNEL_NAME = 'test_channel'; |
27
|
|
|
|
28
|
|
|
const SUB_NAME = 'test_subscription'; |
29
|
|
|
|
30
|
1 |
|
public function testGetKey(): void |
31
|
|
|
{ |
32
|
1 |
|
$channel = new Channel(self::CHANNEL_NAME, new SubscriptionMap); |
33
|
1 |
|
$this->assertEquals($channel->getKey(), self::CHANNEL_NAME); |
34
|
1 |
|
} |
35
|
|
|
|
36
|
1 |
|
public function testPublish(): void |
37
|
|
|
{ |
38
|
|
|
/** @var MessageInterface $messageMock */ |
39
|
1 |
|
$messageMock = $this->createMock(MessageInterface::class); |
40
|
1 |
|
$envelope = Envelope::wrap($messageMock); |
41
|
1 |
|
$envelopeExpectation = $this->callback(function (EnvelopeInterface $envelope) { |
42
|
1 |
|
return self::CHANNEL_NAME === $envelope->getMetadata()->get(ChannelInterface::METADATA_KEY); |
43
|
1 |
|
}); |
44
|
|
|
/** @var MessageBusInterface $messageBusMock */ |
45
|
1 |
|
$messageBusMock = $this->createMock(MessageBusInterface::class); |
46
|
1 |
|
$subscriptionMock = $this->createMock(SubscriptionInterface::class); |
47
|
1 |
|
$subscriptionMock->expects($this->once()) |
48
|
1 |
|
->method('publish') |
49
|
1 |
|
->with($envelopeExpectation, $this->equalTo($messageBusMock)); |
50
|
1 |
|
$channel = new Channel(self::CHANNEL_NAME, new SubscriptionMap(['mock' => $subscriptionMock])); |
51
|
1 |
|
$this->assertNull($channel->publish($envelope, $messageBusMock)); |
|
|
|
|
52
|
1 |
|
} |
53
|
|
|
|
54
|
1 |
|
public function testPublishPreventedByGuard(): void |
55
|
|
|
{ |
56
|
|
|
/** @var MessageInterface $messageMock */ |
57
|
1 |
|
$messageMock = $this->createMock(MessageInterface::class); |
58
|
1 |
|
$envelope = Envelope::wrap($messageMock); |
59
|
|
|
/** @var MessageBusInterface $messageBusMock */ |
60
|
1 |
|
$messageBusMock = $this->createMock(MessageBusInterface::class); |
61
|
1 |
|
$subscriptionMock = $this->createMock(SubscriptionInterface::class); |
62
|
1 |
|
$subscriptionMock->expects($this->never())->method('publish'); |
63
|
1 |
|
$guard = function (EnvelopeInterface $e): bool { |
64
|
1 |
|
return $e->getUuid()->toString() === 'this envelope is acceptable'; |
65
|
1 |
|
}; |
66
|
1 |
|
$channel = new Channel('foo', new SubscriptionMap(['mock' => $subscriptionMock]), $guard); |
67
|
1 |
|
$this->assertNull($channel->publish($envelope, $messageBusMock)); |
|
|
|
|
68
|
1 |
|
} |
69
|
|
|
|
70
|
1 |
|
public function testPublishAcceptedByGuard(): void |
71
|
|
|
{ |
72
|
|
|
/** @var MessageInterface $messageMock */ |
73
|
1 |
|
$messageMock = $this->createMock(MessageInterface::class); |
74
|
1 |
|
$envelope = Envelope::wrap($messageMock); |
75
|
|
|
/** @var MessageBusInterface $messageBusMock */ |
76
|
1 |
|
$messageBusMock = $this->createMock(MessageBusInterface::class); |
77
|
1 |
|
$subscriptionMock = $this->createMock(SubscriptionInterface::class); |
78
|
1 |
|
$subscriptionMock->expects($this->once())->method('publish'); |
79
|
1 |
|
$guard = function (EnvelopeInterface $e): bool { |
80
|
1 |
|
return $e->getUuid()->toString() !== 'this envelope is inacceptable'; |
81
|
1 |
|
}; |
82
|
1 |
|
$channel = new Channel('foo', new SubscriptionMap(['mock' => $subscriptionMock]), $guard); |
83
|
1 |
|
$this->assertNull($channel->publish($envelope, $messageBusMock)); |
|
|
|
|
84
|
1 |
|
} |
85
|
|
|
|
86
|
1 |
|
public function testReceive(): void |
87
|
|
|
{ |
88
|
|
|
/** @var MessageInterface $messageMock */ |
89
|
1 |
|
$messageMock = $this->createMock(MessageInterface::class); |
90
|
1 |
|
$envelopeExpectation = Envelope::wrap($messageMock, Metadata::fromNative([ |
91
|
1 |
|
ChannelInterface::METADATA_KEY => self::CHANNEL_NAME, |
92
|
1 |
|
SubscriptionInterface::METADATA_KEY => self::SUB_NAME |
93
|
|
|
])); |
94
|
1 |
|
$subscriptionMock = $this->createMock(SubscriptionInterface::class); |
95
|
1 |
|
$subscriptionMock->expects($this->once())->method('receive')->with($envelopeExpectation); |
96
|
1 |
|
$channel = new Channel(self::CHANNEL_NAME, new SubscriptionMap([self::SUB_NAME => $subscriptionMock])); |
97
|
1 |
|
$this->assertNull($channel->receive($envelopeExpectation)); |
|
|
|
|
98
|
1 |
|
} |
99
|
|
|
|
100
|
1 |
|
public function testReceiveWithExistingSubscription(): void |
101
|
|
|
{ |
102
|
|
|
/** @var MessageInterface $messageMock */ |
103
|
1 |
|
$messageMock = $this->createMock(MessageInterface::class); |
104
|
1 |
|
$envelope = Envelope::wrap($messageMock, Metadata::fromNative([ |
105
|
1 |
|
ChannelInterface::METADATA_KEY => self::CHANNEL_NAME, |
106
|
1 |
|
SubscriptionInterface::METADATA_KEY => 'foobar' |
107
|
|
|
])); |
108
|
1 |
|
$subscriptionMock = $this->createMock(SubscriptionInterface::class); |
109
|
1 |
|
$channel = new Channel(self::CHANNEL_NAME, new SubscriptionMap(['mock' => $subscriptionMock])); |
110
|
|
|
|
111
|
1 |
|
$this->expectException(SubscriptionUnknown::class); |
112
|
1 |
|
$this->expectExceptionMessage( |
113
|
1 |
|
"Channel '".self::CHANNEL_NAME."' has no subscription 'foobar' and thus ". |
114
|
1 |
|
"Envelope '{$envelope->getUuid()->toString()}' cannot be handled." |
115
|
|
|
); |
116
|
1 |
|
$this->expectExceptionCode(0); |
117
|
|
|
|
118
|
1 |
|
$channel->receive($envelope); |
119
|
|
|
} |
120
|
|
|
|
121
|
1 |
|
public function testReceiveWithMissingChannel(): void |
122
|
|
|
{ |
123
|
|
|
/** @var MessageInterface $messageMock */ |
124
|
1 |
|
$messageMock = $this->createMock(MessageInterface::class); |
125
|
1 |
|
$subscriptionMock = $this->createMock(SubscriptionInterface::class); |
126
|
1 |
|
$envelope = Envelope::wrap($messageMock); |
127
|
1 |
|
$channel = new Channel(self::CHANNEL_NAME, new SubscriptionMap(['mock' => $subscriptionMock])); |
128
|
|
|
|
129
|
1 |
|
$this->expectException(EnvelopeNotAcceptable::class); |
130
|
1 |
|
$this->expectExceptionMessage( |
131
|
1 |
|
"Channel key '".ChannelInterface::METADATA_KEY."' missing in metadata of Envelope '". |
132
|
1 |
|
"{$envelope->getUuid()->toString()}' received on channel '".self::CHANNEL_NAME."'." |
133
|
|
|
); |
134
|
1 |
|
$this->expectExceptionCode(EnvelopeNotAcceptable::CHANNEL_KEY_MISSING); |
135
|
|
|
|
136
|
1 |
|
$channel->receive($envelope); |
137
|
|
|
} |
138
|
|
|
|
139
|
1 |
|
public function testReceiveWithWrongChannel(): void |
140
|
|
|
{ |
141
|
|
|
/** @var MessageInterface $messageMock */ |
142
|
1 |
|
$messageMock = $this->createMock(MessageInterface::class); |
143
|
1 |
|
$subscriptionMock = $this->createMock(SubscriptionInterface::class); |
144
|
1 |
|
$envelope = Envelope::wrap($messageMock, Metadata::fromNative([ |
145
|
1 |
|
ChannelInterface::METADATA_KEY => 'foobar' |
146
|
|
|
])); |
147
|
1 |
|
$channel = new Channel(self::CHANNEL_NAME, new SubscriptionMap(['mock' => $subscriptionMock])); |
148
|
|
|
|
149
|
1 |
|
$this->expectException(EnvelopeNotAcceptable::class); |
150
|
1 |
|
$this->expectExceptionMessage( |
151
|
1 |
|
"Channel '".self::CHANNEL_NAME."' inadvertently received ". |
152
|
1 |
|
"Envelope '{$envelope->getUuid()->toString()}' for channel 'foobar'." |
153
|
|
|
); |
154
|
1 |
|
$this->expectExceptionCode(EnvelopeNotAcceptable::CHANNEL_KEY_UNEXPECTED); |
155
|
|
|
|
156
|
1 |
|
$channel->receive($envelope); |
157
|
|
|
} |
158
|
|
|
|
159
|
1 |
|
public function testReceiveWithMissingSubscription(): void |
160
|
|
|
{ |
161
|
|
|
/** @var MessageInterface $messageMock */ |
162
|
1 |
|
$messageMock = $this->createMock(MessageInterface::class); |
163
|
1 |
|
$subscriptionMock = $this->createMock(SubscriptionInterface::class); |
164
|
1 |
|
$envelope = Envelope::wrap($messageMock, Metadata::fromNative([ |
165
|
1 |
|
ChannelInterface::METADATA_KEY => self::CHANNEL_NAME |
166
|
|
|
])); |
167
|
1 |
|
$channel = new Channel(self::CHANNEL_NAME, new SubscriptionMap(['mock' => $subscriptionMock])); |
168
|
|
|
|
169
|
1 |
|
$this->expectException(EnvelopeNotAcceptable::class); |
170
|
1 |
|
$this->expectExceptionMessage( |
171
|
1 |
|
"Subscription key '".SubscriptionInterface::METADATA_KEY."' missing in metadata of ". |
172
|
1 |
|
"Envelope '{$envelope->getUuid()->toString()}' received on channel '".self::CHANNEL_NAME."'." |
173
|
|
|
); |
174
|
1 |
|
$this->expectExceptionCode(EnvelopeNotAcceptable::SUBSCRIPTION_KEY_MISSING); |
175
|
|
|
|
176
|
1 |
|
$channel->receive($envelope); |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.