Completed
Pull Request — master (#276)
by Maksim
01:50
created

testInitializeWithDeadLetterExchangeAndDeadLetterRoutingKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 47
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 47
rs 9.0303
c 2
b 0
f 0
cc 1
eloc 29
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\NotificationBundle\Tests\Backend;
13
14
use Enqueue\AmqpLib\AmqpConnectionFactory;
15
use Interop\Amqp\AmqpBind;
16
use Interop\Amqp\AmqpConsumer;
17
use Interop\Amqp\AmqpContext;
18
use Interop\Amqp\AmqpQueue;
19
use Interop\Amqp\AmqpTopic;
20
use Interop\Amqp\Impl\AmqpBind as ImplAmqpBind;
21
use Interop\Amqp\Impl\AmqpQueue as ImplAmqpQueue;
22
use Interop\Amqp\Impl\AmqpTopic as ImplAmqpTopic;
23
use PhpAmqpLib\Channel\AMQPChannel;
24
use PHPUnit\Framework\TestCase;
25
use Sonata\NotificationBundle\Backend\AMQPBackend;
26
use Sonata\NotificationBundle\Backend\AMQPBackendDispatcher;
27
use Sonata\NotificationBundle\Iterator\AMQPMessageIterator;
28
29
class AMQPBackendTest extends TestCase
30
{
31
    const EXCHANGE = 'exchange';
32
    const QUEUE = 'foo';
33
    const KEY = 'message.type.foo';
34
    const DEAD_LETTER_EXCHANGE = 'dlx';
35
    const DEAD_LETTER_ROUTING_KEY = 'message.type.dl';
36
    const TTL = 60000;
37
    const PREFETCH_COUNT = 1;
38
39
    protected function setUp()
40
    {
41
        if (!class_exists(AmqpConnectionFactory::class)) {
42
            $this->markTestSkipped('enqueue/amqp-lib library is not installed');
43
        }
44
    }
45
46
    public function testInitializeWithNoDeadLetterExchangeAndNoDeadLetterRoutingKey()
47
    {
48
        /**
49
         * @var AMQPBackend $backend
50
         * @var AmqpContext|\PHPUnit_Framework_MockObject_MockObject $contextMock
51
         */
52
        list($backend, $contextMock) = $this->getBackendAndContextMock();
53
54
        $queue = new ImplAmqpQueue(self::QUEUE);
55
        $topic = new ImplAmqpTopic(self::EXCHANGE);
56
57
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
58
            ->method('createQueue')
59
            ->with($this->identicalTo(self::QUEUE))
60
            ->willReturn($queue);
61
62
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
63
            ->method('declareQueue')
64
            ->with($this->identicalTo($queue))
65
            ->willReturnCallback(function(AmqpQueue $queue) {
66
                $this->assertTrue((bool) ($queue->getFlags() & AmqpQueue::FLAG_DURABLE));
67
                $this->assertSame([], $queue->getArguments());
68
69
            });
70
71
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
72
            ->method('createTopic')
73
            ->with($this->identicalTo(self::EXCHANGE))
74
            ->willReturn($topic);
75
76
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
77
            ->method('declareTopic')
78
            ->with($this->identicalTo($topic))
79
            ->willReturnCallback(function(AmqpTopic $topic) {
80
                $this->assertTrue((bool) ($topic->getFlags() & AmqpTopic::FLAG_DURABLE));
81
                $this->assertSame(AmqpTopic::TYPE_DIRECT, $topic->getType());
82
                $this->assertSame([], $topic->getArguments());
83
84
            });
85
86
87
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
88
            ->method('bind')
89
            ->with($this->isInstanceOf(AmqpBind::class))
90
            ->willReturnCallback(function(ImplAmqpBind $bind) use ($queue, $topic) {
91
                $this->assertSame($queue, $bind->getTarget());
92
                $this->assertSame($topic, $bind->getSource());
93
                $this->assertSame(self::KEY, $bind->getRoutingKey());
94
            });
95
96
        $backend->initialize();
97
    }
98
99
    public function testInitializeWithDeadLetterExchangeAndNoDeadLetterRoutingKey()
100
    {
101
        /**
102
         * @var AMQPBackend $backend
103
         * @var AmqpContext|\PHPUnit_Framework_MockObject_MockObject $contextMock
104
         */
105
        list($backend, $contextMock) = $this->getBackendAndContextMock(false, self::DEAD_LETTER_EXCHANGE);
106
107
        $queue = new ImplAmqpQueue(self::QUEUE);
108
        $topic = new ImplAmqpTopic(self::EXCHANGE);
109
        $deadLetterTopic = new ImplAmqpTopic(self::DEAD_LETTER_EXCHANGE);
110
111
        $contextMock->expects($this->at(0))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
112
            ->method('createQueue')
113
            ->with($this->identicalTo(self::QUEUE))
114
            ->willReturn($queue);
115
116
        $contextMock->expects($this->at(1))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
117
            ->method('declareQueue')
118
            ->with($this->identicalTo($queue))
119
            ->willReturnCallback(function(AmqpQueue $queue) {
120
                $this->assertTrue((bool) ($queue->getFlags() & AmqpQueue::FLAG_DURABLE));
121
                $this->assertSame(['x-dead-letter-exchange' => self::DEAD_LETTER_EXCHANGE], $queue->getArguments());
122
123
            });
124
125
        $contextMock->expects($this->at(2))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
126
            ->method('createTopic')
127
            ->with($this->identicalTo(self::EXCHANGE))
128
            ->willReturn($topic);
129
130
        $contextMock->expects($this->at(3))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
131
            ->method('declareTopic')
132
            ->with($this->identicalTo($topic));
133
134
        $contextMock->expects($this->at(4))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
135
            ->method('bind')
136
            ->with($this->isInstanceOf(AmqpBind::class));
137
138
        $contextMock->expects($this->at(5))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
139
            ->method('createTopic')
140
            ->with($this->identicalTo(self::DEAD_LETTER_EXCHANGE))
141
            ->willReturn($deadLetterTopic);
142
143
        $contextMock->expects($this->at(6))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
144
            ->method('declareTopic')
145
            ->with($this->identicalTo($deadLetterTopic))
146
            ->willReturnCallback(function(AmqpTopic $topic) {
147
                $this->assertTrue((bool) ($topic->getFlags() & AmqpTopic::FLAG_DURABLE));
148
                $this->assertSame(AmqpTopic::TYPE_DIRECT, $topic->getType());
149
                $this->assertSame([], $topic->getArguments());
150
151
            });
152
153
        $backend->initialize();
154
    }
155
//
156
    public function testInitializeWithDeadLetterExchangeAndDeadLetterRoutingKey()
157
    {
158
        /**
159
         * @var AMQPBackend $backend
160
         * @var AmqpContext|\PHPUnit_Framework_MockObject_MockObject $contextMock
161
         */
162
        list($backend, $contextMock) = $this->getBackendAndContextMock(false, self::DEAD_LETTER_EXCHANGE, self::DEAD_LETTER_ROUTING_KEY);
163
164
        $queue = new ImplAmqpQueue(self::QUEUE);
165
        $topic = new ImplAmqpTopic(self::EXCHANGE);
166
        $deadLetterTopic = new ImplAmqpTopic(self::DEAD_LETTER_EXCHANGE);
0 ignored issues
show
Unused Code introduced by
$deadLetterTopic is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
167
168
        $contextMock->expects($this->at(0))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
169
            ->method('createQueue')
170
            ->with($this->identicalTo(self::QUEUE))
171
            ->willReturn($queue);
172
173
        $contextMock->expects($this->at(1))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
174
            ->method('declareQueue')
175
            ->with($this->identicalTo($queue))
176
            ->willReturnCallback(function(AmqpQueue $queue) {
177
                $this->assertTrue((bool) ($queue->getFlags() & AmqpQueue::FLAG_DURABLE));
178
                $this->assertSame(
179
                    [
180
                        'x-dead-letter-exchange' => self::DEAD_LETTER_EXCHANGE,
181
                        'x-dead-letter-routing-key' => self::DEAD_LETTER_ROUTING_KEY,
182
                    ],
183
                    $queue->getArguments()
184
                );
185
186
            });
187
188
        $contextMock->expects($this->at(2))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
189
            ->method('createTopic')
190
            ->with($this->identicalTo(self::EXCHANGE))
191
            ->willReturn($topic);
192
193
        $contextMock->expects($this->at(3))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
194
            ->method('declareTopic')
195
            ->with($this->identicalTo($topic));
196
197
        $contextMock->expects($this->at(4))
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
198
            ->method('bind')
199
            ->with($this->isInstanceOf(AmqpBind::class));
200
201
        $backend->initialize();
202
    }
203
204
    public function testInitializeWithTTL()
205
    {
206
        /**
207
         * @var AMQPBackend $backend
208
         * @var AmqpContext|\PHPUnit_Framework_MockObject_MockObject $contextMock
209
         */
210
        list($backend, $contextMock) = $this->getBackendAndContextMock(false, null, null, self::TTL);
211
212
        $queue = new ImplAmqpQueue(self::QUEUE);
213
        $topic = new ImplAmqpTopic(self::EXCHANGE);
214
215
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
216
            ->method('createQueue')
217
            ->with($this->identicalTo(self::QUEUE))
218
            ->willReturn($queue);
219
220
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
221
            ->method('declareQueue')
222
            ->with($this->identicalTo($queue))
223
            ->willReturnCallback(function(AmqpQueue $queue) {
224
                $this->assertTrue((bool) ($queue->getFlags() & AmqpQueue::FLAG_DURABLE));
225
                $this->assertSame(['x-message-ttl' => self::TTL], $queue->getArguments());
226
227
            });
228
229
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
230
            ->method('createTopic')
231
            ->with($this->identicalTo(self::EXCHANGE))
232
            ->willReturn($topic);
233
234
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
235
            ->method('declareTopic')
236
            ->with($this->identicalTo($topic));
237
238
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
239
            ->method('bind')
240
            ->with($this->isInstanceOf(AmqpBind::class));
241
242
        $backend->initialize();
243
    }
244
245
    public function testGetIteratorWithNoPrefetchCount()
246
    {
247
        /**
248
         * @var AMQPBackend $backend
249
         * @var AmqpContext|\PHPUnit_Framework_MockObject_MockObject $contextMock
250
         */
251
        list($backend, $contextMock) = $this->getBackendAndContextMock();
252
253
        $queue = new ImplAmqpQueue('aQueue');
254
        $consumerMock = $this->createMock(AmqpConsumer::class);
255
        $consumerMock->expects($this->once())
256
            ->method('getQueue')
257
            ->willReturn($queue);
258
259
        $contextMock->expects($this->never())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
260
            ->method('setQos');
261
262
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
263
            ->method('createQueue')
264
            ->willReturn($queue);
265
266
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
267
            ->method('createConsumer')
268
            ->with($this->identicalTo($queue))
269
            ->willReturn($consumerMock);
270
271
        $iterator = $backend->getIterator();
272
273
        $this->assertInstanceOf(AMQPMessageIterator::class, $iterator);
274
    }
275
276
    public function testGetIteratorWithPrefetchCount()
277
    {
278
        /**
279
         * @var AMQPBackend $backend
280
         * @var AmqpContext|\PHPUnit_Framework_MockObject_MockObject $contextMock
281
         */
282
        list($backend, $contextMock) = $this->getBackendAndContextMock(false, null, null, null, self::PREFETCH_COUNT);
283
284
        $queue = new ImplAmqpQueue('aQueue');
285
        $consumerMock = $this->createMock(AmqpConsumer::class);
286
        $consumerMock->expects($this->once())
287
            ->method('getQueue')
288
            ->willReturn($queue);
289
290
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
291
            ->method('setQos')
292
            ->with($this->isNull(), $this->identicalTo(self::PREFETCH_COUNT), $this->isFalse());
293
294
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
295
            ->method('createQueue')
296
            ->willReturn($queue);
297
298
        $contextMock->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Interop\Amqp\AmqpContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
299
            ->method('createConsumer')
300
            ->with($this->identicalTo($queue))
301
            ->willReturn($consumerMock);
302
303
        $iterator = $backend->getIterator();
304
305
        $this->assertInstanceOf(AMQPMessageIterator::class, $iterator);
306
    }
307
308
    protected function getBackendAndContextMock($recover = false, $deadLetterExchange = null, $deadLetterRoutingKey = null, $ttl = null, $prefetchCount = null)
309
    {
310
        $backend = new AMQPBackend(
311
            self::EXCHANGE,
312
            self::QUEUE,
313
            $recover,
0 ignored issues
show
Documentation introduced by
$recover is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
314
            self::KEY,
315
            $deadLetterExchange,
316
            $deadLetterRoutingKey,
317
            $ttl,
318
            $prefetchCount
319
        );
320
321
        $settings = [
322
            'host' => 'foo',
323
            'port' => 'port',
324
            'user' => 'user',
325
            'pass' => 'pass',
326
            'vhost' => '/',
327
        ];
328
329
        $queues = [
330
            ['queue' => self::QUEUE, 'routing_key' => self::KEY],
331
        ];
332
333
        $contextMock = $this->getMockBuilder(AmqpContext::class)
334
            ->disableOriginalConstructor()
335
            ->getMock();
336
337
        $dispatcherMock = $this->getMockBuilder(AMQPBackendDispatcher::class)
338
            ->setConstructorArgs([$settings, $queues, 'default', [['type' => self::KEY, 'backend' => $backend]]])
339
            ->setMethods(['getContext', 'getChannel'])
340
            ->getMock();
341
342
        $dispatcherMock
343
            ->expects($this->any())
344
            ->method('getChannel')
345
            ->willReturn($this->createMock(AMQPChannel::class))
346
        ;
347
348
        $dispatcherMock->method('getContext')
349
            ->willReturn($contextMock);
350
351
        $backend->setDispatcher($dispatcherMock);
352
353
        return [$backend, $contextMock];
354
    }
355
}
356