Completed
Pull Request — master (#281)
by Grégoire
01:45
created

AMQPBackendDispatcherTest::testQueue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
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\AmqpContext;
16
use MyProject\Proxies\__CG__\stdClass;
17
use PHPUnit\Framework\TestCase;
18
use Sonata\NotificationBundle\Backend\AMQPBackendDispatcher;
19
use Sonata\NotificationBundle\Exception\BackendNotFoundException;
20
use Sonata\NotificationBundle\Tests\Mock\AmqpConnectionFactoryStub;
21
22
class AMQPBackendDispatcherTest extends TestCase
23
{
24
    protected function setUp()
25
    {
26
        if (!class_exists(AmqpConnectionFactory::class)) {
27
            $this->markTestSkipped('enqueue/amqp-lib library is not installed');
28
        }
29
30
        AmqpConnectionFactoryStub::$config = null;
31
        AmqpConnectionFactoryStub::$context = null;
32
    }
33
34
    public function testThrowIfSettingsMissFactoryClassOptionOnGetContext()
35
    {
36
        $dispatcher = new AMQPBackendDispatcher([], [], 'default', []);
37
38
        $this->expectException(\LogicException::class);
39
        $this->expectExceptionMessage('The factory_class option is missing though it is required.');
40
        $dispatcher->getContext();
41
    }
42
43
    public function testThrowIfFactoryClassIsNotRealClass()
44
    {
45
        $dispatcher = new AMQPBackendDispatcher(['factory_class' => 'anInvalidClass'], [], 'default', []);
46
47
        $this->expectException(\LogicException::class);
48
        $this->expectExceptionMessage('The factory_class option "anInvalidClass" has to be valid class that implements "Interop\Amqp\AmqpConnectionFactory"');
49
        $dispatcher->getContext();
50
    }
51
52
    public function testThrowIfFactoryClassIsNotInstanceOfAmqpConnectionFactoryInterface()
53
    {
54
        $dispatcher = new AMQPBackendDispatcher(['factory_class' => \stdClass::class], [], 'default', []);
55
56
        $this->expectException(\LogicException::class);
57
        $this->expectExceptionMessage('The factory_class option "stdClass" has to be valid class that implements "Interop\Amqp\AmqpConnectionFactory"');
58
        $dispatcher->getContext();
59
    }
60
61
    public function testShouldPassExpectedOptionsToAmqpConnectionFactoryConstructor()
62
    {
63
        $dispatcher = new AMQPBackendDispatcher(
64
            [
65
                'host' => 'theHost',
66
                'port' => 'thePort',
67
                'user' => 'theUser',
68
                'pass' => 'thePass',
69
                'vhost' => 'theVhost',
70
                'factory_class' => AmqpConnectionFactoryStub::class,
71
            ],
72
            [],
73
            'default',
74
            []
75
        );
76
77
        $dispatcher->getContext();
78
79
        $this->assertSame([
80
            'host' => 'theHost',
81
            'port' => 'thePort',
82
            'user' => 'theUser',
83
            'pass' => 'thePass',
84
            'vhost' => 'theVhost',
85
        ], AmqpConnectionFactoryStub::$config);
86
    }
87
88
    public function testShouldReturnExpectedAmqpContext()
89
    {
90
        $expectedContext = $this->createMock(AmqpContext::class);
91
92
        $dispatcher = new AMQPBackendDispatcher(
93
            [
94
                'host' => 'aHost',
95
                'port' => 'aPort',
96
                'user' => 'aUser',
97
                'pass' => 'aPass',
98
                'vhost' => 'aVhost',
99
                'factory_class' => AmqpConnectionFactoryStub::class,
100
            ],
101
            [],
102
            'default',
103
            []
104
        );
105
106
        AmqpConnectionFactoryStub::$context = $expectedContext;
107
108
        $actualContext = $dispatcher->getContext();
109
110
        $this->assertSame($expectedContext, $actualContext);
111
    }
112
113
    public function testQueue()
114
    {
115
        $mock = $this->getMockQueue('foo', 'message.type.foo', $this->once());
116
        $mock2 = $this->getMockQueue('bar', 'message.type.foo', $this->never());
117
        $fooBackend = ['type' => 'message.type.foo', 'backend' => $mock];
118
        $barBackend = ['type' => 'message.type.bar', 'backend' => $mock2];
119
        $backends = [$fooBackend, $barBackend];
120
        $dispatcher = $this->getDispatcher($backends);
121
        $dispatcher->createAndPublish('message.type.foo', []);
122
    }
123
124
    public function testDefaultQueue()
125
    {
126
        $mock = $this->getMockQueue('foo', 'message.type.foo', $this->once());
127
        $fooBackend = ['type' => 'default', 'backend' => $mock];
128
        $dispatcher = $this->getDispatcher([$fooBackend]);
129
        $dispatcher->createAndPublish('some.other.type', []);
130
    }
131
132
    public function testDefaultQueueNotFound()
133
    {
134
        $mock = $this->getMockQueue('foo', 'message.type.foo', $this->never());
135
        $fooBackend = ['type' => 'message.type.foo', 'backend' => $mock];
136
        $dispatcher = $this->getDispatcher([$fooBackend]);
137
138
        $this->expectException(BackendNotFoundException::class);
139
        $dispatcher->createAndPublish('some.other.type', []);
140
    }
141
142
    public function testInvalidQueue()
143
    {
144
        $mock = $this->getMockQueue('foo', 'message.type.bar');
145
        $dispatcher = $this->getDispatcher(
146
            [['type' => 'bar', 'backend' => $mock]],
147
            [['queue' => 'foo', 'routing_key' => 'message.type.bar']]
148
        );
149
150
        $this->expectException(BackendNotFoundException::class);
151
        $dispatcher->createAndPublish('message.type.bar', []);
152
    }
153
154
    public function testAllQueueInitializeOnce()
155
    {
156
        $queues = [
157
            ['queue' => 'foo', 'routing_key' => 'message.type.foo'],
158
            ['queue' => 'bar', 'routing_key' => 'message.type.bar'],
159
            ['queue' => 'baz', 'routing_key' => 'message.type.baz'],
160
        ];
161
162
        $backends = [];
163
164
        foreach ($queues as $queue) {
165
            $mock = $this->getMockQueue($queue['queue'], $queue['routing_key']);
166
            $mock->expects($this->once())
167
                ->method('initialize');
168
            $backends[] = ['type' => $queue['routing_key'], 'backend' => $mock];
169
        }
170
171
        $dispatcher = $this->getDispatcher($backends, $queues);
172
173
        $dispatcher->createAndPublish('message.type.foo', []);
174
        $dispatcher->createAndPublish('message.type.foo', []);
175
    }
176
177
    protected function getMockQueue($queue, $type, $called = null)
178
    {
179
        $methods = ['createAndPublish', 'initialize'];
180
        $args = ['', 'foo', false, 'message.type.foo'];
181
        $mock = $this->getMockBuilder('Sonata\NotificationBundle\Backend\AMQPBackend')
182
                     ->setConstructorArgs($args)
183
                     ->setMethods($methods)
184
                     ->getMock();
185
186
        if (null !== $called) {
187
            $mock->expects($called)
188
                ->method('createAndPublish')
189
            ;
190
        }
191
192
        return $mock;
193
    }
194
195
    protected function getDispatcher(array $backends, array $queues = [['queue' => 'foo', 'routing_key' => 'message.type.foo']])
196
    {
197
        $settings = [
198
                'host' => 'foo',
199
                'port' => 'port',
200
                'user' => 'user',
201
                'pass' => 'pass',
202
                'vhost' => '/',
203
        ];
204
205
        return new AMQPBackendDispatcher($settings, $queues, 'default', $backends);
206
    }
207
}
208