Completed
Pull Request — master (#13)
by Antonio
07:54
created

BeanstalkdQueueStoreAdapterTest   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 241
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 13
c 1
b 0
f 1
lcom 1
cbo 11
dl 0
loc 241
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 12 1
B testEnqueueDequeueAndAcknowledge() 0 81 5
A testEnqueDequeueWithDelay() 0 54 3
A testBadMethodCallExceptionOnAck() 0 7 1
A testNonCompletedAck() 0 73 3
1
<?php
2
namespace Da\Mailer\Test\Queue\Backend\Redis;
3
4
use Da\Mailer\Model\MailMessage;
5
use Da\Mailer\Queue\Backend\Beanstalk\BeanstalkdQueueStoreAdapter;
6
use Da\Mailer\Queue\Backend\Beanstalk\BeanstalkdQueueStoreConnection;
7
use Da\Mailer\Test\Fixture\FixtureHelper;
8
use Mockery;
9
use Pheanstalk\Job;
10
use Pheanstalk\Response\ArrayResponse;
11
use PHPUnit_Framework_TestCase;
12
13
class BeanstalkdQueueStoreAdapterTest extends PHPUnit_Framework_TestCase
14
{
15
    private $mailJob;
16
    private $payload;
17
18
    protected function setUp()
19
    {
20
        parent::setUp();
21
        $this->mailJob = FixtureHelper::getBeanstalkdMailJob();
22
        $this->payload = json_encode(
23
            [
24
                'id' => '123456789',
25
                'attempt' => $this->mailJob->getAttempt(),
26
                'message' => $this->mailJob->getMessage()
27
            ]
28
        );
29
    }
30
31
    public function testEnqueueDequeueAndAcknowledge()
32
    {
33
34
        $payload = json_decode($this->payload, true);
35
        $payload['job'] = new Job(1, 'demo');
36
        $btJob2 = Mockery::mock('\Pheanstalk\Job')
37
            ->shouldReceive('getData')
38
            ->andReturn(json_encode($payload))
39
            ->getMock();
40
        $btClient = Mockery::mock('\Pheanstalk\Pheanstalk')
41
            ->shouldReceive('useTube')
42
            ->with('mail_queue')
43
            ->andReturnSelf()
44
            ->shouldReceive('put')
45
            ->andReturn(1)
46
            ->shouldReceive('watchOnly')
47
            ->andReturnSelf()
48
            ->shouldReceive('statsTube')
49
            ->twice()
50
            ->andReturnUsing(
51
                function () {
52
                    static $f;
53
                    if ($f === null) {
54
                        $f = true;
55
                    }
56
                    $f = !$f;
57
58
                    return $f
59
                        ? new ArrayResponse(
60
                            'test', [
61
                                'current-jobs-delayed' => 0,
62
                                'current-jobs-urgent' => 0,
63
                                'current-jobs-ready' => 0
64
                            ]
65
                        )
66
                        : new ArrayResponse('test', ['current-jobs-delayed' => 1,]);
67
                }
68
            )
69
            ->shouldReceive('reserve')
70
            ->with(0)
71
            ->andReturnUsing(function() use ($btJob2) {
72
                static $f;
73
                if($f === null) {
74
                    $f = false;
75
                }
76
                $f = !$f;
77
                return $f ? $btJob2 : null;
78
            })
79
            ->shouldReceive('delete')
80
            ->andReturn(1)
81
            ->getMock();
82
83
        $btStoreConnection = Mockery::mock('\Da\Mailer\Queue\Backend\Beanstalk\BeanstalkdQueueStoreConnection')
84
            ->shouldReceive('connect')
85
            ->andReturnSelf()
86
            ->shouldReceive('getInstance')
87
            ->andReturn($btClient)
88
            ->getMock();
89
90
        $btQueueStore = new BeanstalkdQueueStoreAdapter($btStoreConnection);
91
92
        $this->assertSame($btQueueStore, $btQueueStore->init());
93
        $this->assertTrue($btQueueStore->enqueue($this->mailJob) > 0);
94
95
        $this->assertTrue($btQueueStore->isEmpty() === false);
96
97
        $mailJob = $btQueueStore->dequeue();
98
99
        $this->assertTrue($btQueueStore->isEmpty() === true);
100
101
        $this->assertTrue(!empty($mailJob->getMessage()));
102
103
        $dequeuedMailMessage = MailMessage::fromArray(json_decode($mailJob->getMessage(), true));
104
105
        $this->assertEquals(FixtureHelper::getMailMessage(), $dequeuedMailMessage);
106
107
        $mailJob->markAsCompleted();
108
        $btQueueStore->ack($mailJob);
0 ignored issues
show
Bug introduced by
It seems like $mailJob defined by $btQueueStore->dequeue() on line 97 can be null; however, Da\Mailer\Queue\Backend\...ueueStoreAdapter::ack() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
109
110
        $this->assertTrue($btQueueStore->dequeue() === null);
111
    }
112
113
    public function testEnqueDequeueWithDelay()
114
    {
115
        $time = time() + 2;
116
        $payload = json_decode($this->payload, true);
117
        $payload['job'] = new Job(1, 'demo');
118
        $btJob2 = Mockery::mock('\Pheanstalk\Job')
119
            ->shouldReceive('getData')
120
            ->andReturn(json_encode($payload))
121
            ->getMock();
122
        $btClient = Mockery::mock('\Pheanstalk\Pheanstalk')
0 ignored issues
show
Bug introduced by
The method shouldReceive() does not seem to exist on object<Mockery\Expectation>.

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...
123
            ->shouldReceive('useTube')
124
            ->with(Mockery::mustBe('mail_queue'))
125
            ->andReturnSelf()
126
            ->shouldReceive('put')
127
            ->withAnyArgs()
128
            ->andReturn(1)
129
            ->shouldReceive('watchOnly')
130
            ->with(Mockery::mustBe('mail_queue'))
131
            ->andReturnSelf()
132
            ->shouldReceive('reserve')
133
            ->with(0)
134
            ->andReturnUsing(function() use ($btJob2) {
135
                static $f;
136
                if($f === null) {
137
                    $f = true;
138
                }
139
                $f = !$f;
140
                return $f ? $btJob2 : null;
141
            })
142
            ->shouldReceive('delete')
143
            ->andReturn(1)
144
            ->getMock();
145
146
        $btConnection = Mockery::mock('\Da\Mailer\Queue\Backend\Beanstalk\BeanstalkdQueueStoreConnection')
0 ignored issues
show
Bug introduced by
The method shouldReceive() does not seem to exist on object<Mockery\Expectation>.

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...
147
            ->shouldReceive('connect')
148
            ->andReturnSelf()
149
            ->shouldReceive('getInstance')
150
            ->andReturn($btClient)
151
            ->getMock();
152
153
        $btQueueStore = new BeanstalkdQueueStoreAdapter($btConnection);
154
155
        $mailJob = $this->mailJob;
156
        $mailJob->setTimeToSend($time);
157
        $this->assertTrue($btQueueStore->enqueue($mailJob) > 0);
158
        $this->assertTrue($btQueueStore->dequeue() === null);
159
        sleep(3); // sleep three seconds to expire in delayed
160
        $mailJob = $btQueueStore->dequeue(); // now it should have migrated
161
162
        $this->assertTrue(!empty($mailJob->getMessage()));
163
164
        $mailJob->markAsCompleted();
165
        $btQueueStore->ack($mailJob);
0 ignored issues
show
Bug introduced by
It seems like $mailJob defined by $btQueueStore->dequeue() on line 160 can be null; however, Da\Mailer\Queue\Backend\...ueueStoreAdapter::ack() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
166
    }
167
168
169
    /**
170
     * @expectedException \Da\Mailer\Exception\InvalidCallException
171
     */
172
    public function testBadMethodCallExceptionOnAck()
173
    {
174
        $mailJob = FixtureHelper::getBeanstalkdMailJob();
175
        $connection = new BeanstalkdQueueStoreConnection([]);
176
        $btQueueStore = new BeanstalkdQueueStoreAdapter($connection);
177
        $btQueueStore->ack($mailJob);
178
    }
179
180
    public function testNonCompletedAck()
181
    {
182
        $payload = json_decode($this->payload, true);
183
        $payload['job'] = new Job(1, 'demo');
184
        $btJob2 = Mockery::mock('\Pheanstalk\Job')
185
            ->shouldReceive('getData')
186
            ->andReturn(json_encode($payload))
187
            ->getMock();
188
        $btClient = Mockery::mock('\Pheanstalk\Pheanstalk')
0 ignored issues
show
Bug introduced by
The method shouldReceive() does not seem to exist on object<Mockery\Expectation>.

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
            ->shouldReceive('useTube')
190
            ->with(Mockery::mustBe('mail_queue'))
191
            ->andReturnSelf()
192
            ->shouldReceive('put')
193
            ->withAnyArgs()
194
            ->andReturn(3)
195
            ->shouldReceive('statsTube')
196
            ->twice()
197
            ->andReturnUsing(
198
                function () {
199
                    static $f;
200
                    if($f === null){
201
                        $f = true;
202
                    }
203
                    $f = !$f;
204
                    return $f
205
                        ? new ArrayResponse(
206
                            'test', [
207
                                'current-jobs-delayed' => 0,
208
                                'current-jobs-urgent' => 0,
209
                                'current-jobs-ready' => 0
210
                            ]
211
                        )
212
                        : new ArrayResponse('test', ['current-jobs-delayed' => 1,]);
213
                }
214
            )
215
            ->shouldReceive('watchOnly')
216
            ->with(Mockery::mustBe('mail_queue'))
217
            ->andReturnSelf()
218
            ->shouldReceive('reserve')
219
            ->with(0)
220
            ->andReturn($btJob2)
221
            ->shouldReceive('release')
222
            ->andReturn(1)
223
            ->shouldReceive('delete')
224
            ->andReturn(1)
225
            ->getMock();
226
227
        $btConnection = Mockery::mock('\Da\Mailer\Queue\Backend\Beanstalk\BeanstalkdQueueStoreConnection')
0 ignored issues
show
Bug introduced by
The method shouldReceive() does not seem to exist on object<Mockery\Expectation>.

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...
228
            ->shouldReceive('connect')
229
            ->andReturnSelf()
230
            ->shouldReceive('getInstance')
231
            ->andReturn($btClient)
232
            ->getMock();
233
234
        $btQueueStore = new BeanstalkdQueueStoreAdapter($btConnection);
235
236
237
        $this->assertSame($btQueueStore, $btQueueStore->init());
238
        $this->assertTrue($btQueueStore->enqueue($this->mailJob) > 1);
239
240
        $this->assertTrue($btQueueStore->isEmpty() === false);
241
242
        $mailJob = $btQueueStore->dequeue();
243
244
        $this->assertTrue($btQueueStore->isEmpty() === true);
245
246
        $this->assertTrue(!empty($mailJob->getMessage()));
247
248
        $dequeuedMailMessage = MailMessage::fromArray(json_decode($mailJob->getMessage(), true));
249
250
        $this->assertEquals(FixtureHelper::getMailMessage(), $dequeuedMailMessage);
251
        $btQueueStore->ack($mailJob);
0 ignored issues
show
Bug introduced by
It seems like $mailJob defined by $btQueueStore->dequeue() on line 242 can be null; however, Da\Mailer\Queue\Backend\...ueueStoreAdapter::ack() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
252
    }
253
}
254