Completed
Pull Request — 3.x (#276)
by Maksim
05:10 queued 30s
created

testGetIteratorWithNoPrefetchCount()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 30
rs 8.8571
cc 1
eloc 18
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
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
        $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...
71
            ->method('createTopic')
72
            ->with($this->identicalTo(self::EXCHANGE))
73
            ->willReturn($topic);
74
75
        $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...
76
            ->method('declareTopic')
77
            ->with($this->identicalTo($topic))
78
            ->willReturnCallback(function (AmqpTopic $topic) {
79
                $this->assertTrue((bool) ($topic->getFlags() & AmqpTopic::FLAG_DURABLE));
80
                $this->assertSame(AmqpTopic::TYPE_DIRECT, $topic->getType());
81
                $this->assertSame([], $topic->getArguments());
82
            });
83
84
        $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...
85
            ->method('bind')
86
            ->with($this->isInstanceOf(AmqpBind::class))
87
            ->willReturnCallback(function (ImplAmqpBind $bind) use ($queue, $topic) {
88
                $this->assertSame($queue, $bind->getTarget());
89
                $this->assertSame($topic, $bind->getSource());
90
                $this->assertSame(self::KEY, $bind->getRoutingKey());
91
            });
92
93
        $backend->initialize();
94
    }
95
96
    public function testInitializeWithDeadLetterExchangeAndNoDeadLetterRoutingKey()
97
    {
98
        /**
99
         * @var AMQPBackend
100
         * @var AmqpContext|\PHPUnit_Framework_MockObject_MockObject $contextMock
101
         */
102
        list($backend, $contextMock) = $this->getBackendAndContextMock(false, self::DEAD_LETTER_EXCHANGE);
103
104
        $queue = new ImplAmqpQueue(self::QUEUE);
105
        $topic = new ImplAmqpTopic(self::EXCHANGE);
106
        $deadLetterTopic = new ImplAmqpTopic(self::DEAD_LETTER_EXCHANGE);
107
108
        $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...
109
            ->method('createQueue')
110
            ->with($this->identicalTo(self::QUEUE))
111
            ->willReturn($queue);
112
113
        $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...
114
            ->method('declareQueue')
115
            ->with($this->identicalTo($queue))
116
            ->willReturnCallback(function (AmqpQueue $queue) {
117
                $this->assertTrue((bool) ($queue->getFlags() & AmqpQueue::FLAG_DURABLE));
118
                $this->assertSame(['x-dead-letter-exchange' => self::DEAD_LETTER_EXCHANGE], $queue->getArguments());
119
            });
120
121
        $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...
122
            ->method('createTopic')
123
            ->with($this->identicalTo(self::EXCHANGE))
124
            ->willReturn($topic);
125
126
        $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...
127
            ->method('declareTopic')
128
            ->with($this->identicalTo($topic));
129
130
        $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...
131
            ->method('bind')
132
            ->with($this->isInstanceOf(AmqpBind::class));
133
134
        $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...
135
            ->method('createTopic')
136
            ->with($this->identicalTo(self::DEAD_LETTER_EXCHANGE))
137
            ->willReturn($deadLetterTopic);
138
139
        $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...
140
            ->method('declareTopic')
141
            ->with($this->identicalTo($deadLetterTopic))
142
            ->willReturnCallback(function (AmqpTopic $topic) {
143
                $this->assertTrue((bool) ($topic->getFlags() & AmqpTopic::FLAG_DURABLE));
144
                $this->assertSame(AmqpTopic::TYPE_DIRECT, $topic->getType());
145
                $this->assertSame([], $topic->getArguments());
146
            });
147
148
        $backend->initialize();
149
    }
150
151
//
152
    public function testInitializeWithDeadLetterExchangeAndDeadLetterRoutingKey()
153
    {
154
        /**
155
         * @var AMQPBackend
156
         * @var AmqpContext|\PHPUnit_Framework_MockObject_MockObject $contextMock
157
         */
158
        list($backend, $contextMock) = $this->getBackendAndContextMock(false, self::DEAD_LETTER_EXCHANGE, self::DEAD_LETTER_ROUTING_KEY);
159
160
        $queue = new ImplAmqpQueue(self::QUEUE);
161
        $topic = new ImplAmqpTopic(self::EXCHANGE);
162
        $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...
163
164
        $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...
165
            ->method('createQueue')
166
            ->with($this->identicalTo(self::QUEUE))
167
            ->willReturn($queue);
168
169
        $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...
170
            ->method('declareQueue')
171
            ->with($this->identicalTo($queue))
172
            ->willReturnCallback(function (AmqpQueue $queue) {
173
                $this->assertTrue((bool) ($queue->getFlags() & AmqpQueue::FLAG_DURABLE));
174
                $this->assertSame(
175
                    [
176
                        'x-dead-letter-exchange' => self::DEAD_LETTER_EXCHANGE,
177
                        'x-dead-letter-routing-key' => self::DEAD_LETTER_ROUTING_KEY,
178
                    ],
179
                    $queue->getArguments()
180
                );
181
            });
182
183
        $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...
184
            ->method('createTopic')
185
            ->with($this->identicalTo(self::EXCHANGE))
186
            ->willReturn($topic);
187
188
        $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...
189
            ->method('declareTopic')
190
            ->with($this->identicalTo($topic));
191
192
        $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...
193
            ->method('bind')
194
            ->with($this->isInstanceOf(AmqpBind::class));
195
196
        $backend->initialize();
197
    }
198
199
    public function testInitializeWithTTL()
200
    {
201
        /**
202
         * @var AMQPBackend
203
         * @var AmqpContext|\PHPUnit_Framework_MockObject_MockObject $contextMock
204
         */
205
        list($backend, $contextMock) = $this->getBackendAndContextMock(false, null, null, self::TTL);
206
207
        $queue = new ImplAmqpQueue(self::QUEUE);
208
        $topic = new ImplAmqpTopic(self::EXCHANGE);
209
210
        $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...
211
            ->method('createQueue')
212
            ->with($this->identicalTo(self::QUEUE))
213
            ->willReturn($queue);
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('declareQueue')
217
            ->with($this->identicalTo($queue))
218
            ->willReturnCallback(function (AmqpQueue $queue) {
219
                $this->assertTrue((bool) ($queue->getFlags() & AmqpQueue::FLAG_DURABLE));
220
                $this->assertSame(['x-message-ttl' => self::TTL], $queue->getArguments());
221
            });
222
223
        $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...
224
            ->method('createTopic')
225
            ->with($this->identicalTo(self::EXCHANGE))
226
            ->willReturn($topic);
227
228
        $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...
229
            ->method('declareTopic')
230
            ->with($this->identicalTo($topic));
231
232
        $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...
233
            ->method('bind')
234
            ->with($this->isInstanceOf(AmqpBind::class));
235
236
        $backend->initialize();
237
    }
238
239
    public function testGetIteratorWithNoPrefetchCount()
240
    {
241
        /**
242
         * @var AMQPBackend
243
         * @var AmqpContext|\PHPUnit_Framework_MockObject_MockObject $contextMock
244
         */
245
        list($backend, $contextMock) = $this->getBackendAndContextMock();
246
247
        $queue = new ImplAmqpQueue('aQueue');
248
        $consumerMock = $this->createMock(AmqpConsumer::class);
249
        $consumerMock->expects($this->once())
250
            ->method('getQueue')
251
            ->willReturn($queue);
252
253
        $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...
254
            ->method('setQos');
255
256
        $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...
257
            ->method('createQueue')
258
            ->willReturn($queue);
259
260
        $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...
261
            ->method('createConsumer')
262
            ->with($this->identicalTo($queue))
263
            ->willReturn($consumerMock);
264
265
        $iterator = $backend->getIterator();
266
267
        $this->assertInstanceOf(AMQPMessageIterator::class, $iterator);
268
    }
269
270
    public function testGetIteratorWithPrefetchCount()
271
    {
272
        /**
273
         * @var AMQPBackend
274
         * @var AmqpContext|\PHPUnit_Framework_MockObject_MockObject $contextMock
275
         */
276
        list($backend, $contextMock) = $this->getBackendAndContextMock(false, null, null, null, self::PREFETCH_COUNT);
277
278
        $queue = new ImplAmqpQueue('aQueue');
279
        $consumerMock = $this->createMock(AmqpConsumer::class);
280
        $consumerMock->expects($this->once())
281
            ->method('getQueue')
282
            ->willReturn($queue);
283
284
        $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...
285
            ->method('setQos')
286
            ->with($this->isNull(), $this->identicalTo(self::PREFETCH_COUNT), $this->isFalse());
287
288
        $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...
289
            ->method('createQueue')
290
            ->willReturn($queue);
291
292
        $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...
293
            ->method('createConsumer')
294
            ->with($this->identicalTo($queue))
295
            ->willReturn($consumerMock);
296
297
        $iterator = $backend->getIterator();
298
299
        $this->assertInstanceOf(AMQPMessageIterator::class, $iterator);
300
    }
301
302
    protected function getBackendAndContextMock($recover = false, $deadLetterExchange = null, $deadLetterRoutingKey = null, $ttl = null, $prefetchCount = null)
303
    {
304
        $backend = new AMQPBackend(
305
            self::EXCHANGE,
306
            self::QUEUE,
307
            $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...
308
            self::KEY,
309
            $deadLetterExchange,
310
            $deadLetterRoutingKey,
311
            $ttl,
312
            $prefetchCount
313
        );
314
315
        $settings = [
316
            'host' => 'foo',
317
            'port' => 'port',
318
            'user' => 'user',
319
            'pass' => 'pass',
320
            'vhost' => '/',
321
        ];
322
323
        $queues = [
324
            ['queue' => self::QUEUE, 'routing_key' => self::KEY],
325
        ];
326
327
        $contextMock = $this->getMockBuilder(AmqpContext::class)
328
            ->disableOriginalConstructor()
329
            ->getMock();
330
331
        $dispatcherMock = $this->getMockBuilder(AMQPBackendDispatcher::class)
332
            ->setConstructorArgs([$settings, $queues, 'default', [['type' => self::KEY, 'backend' => $backend]]])
333
            ->setMethods(['getContext', 'getChannel'])
334
            ->getMock();
335
336
        $dispatcherMock
337
            ->expects($this->any())
338
            ->method('getChannel')
339
            ->willReturn($this->createMock(AMQPChannel::class))
340
        ;
341
342
        $dispatcherMock->method('getContext')
343
            ->willReturn($contextMock);
344
345
        $backend->setDispatcher($dispatcherMock);
346
347
        return [$backend, $contextMock];
348
    }
349
}
350