Test Failed
Pull Request — master (#60)
by Chad
02:04
created

tests/QueueTest.php (6 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace TraderInteractive\Mongo;
4
5
use MongoDB\BSON\UTCDateTime;
6
use PHPUnit\Framework\TestCase;
7
8
/**
9
 * @coversDefaultClass \TraderInteractive\Mongo\Queue
10
 * @covers ::<private>
11
 */
12
final class QueueTest extends TestCase
13
{
14
    private $collection;
15
    private $mongoUrl;
16
    private $queue;
17
18
    public function setUp()
19
    {
20
        $this->mongoUrl = getenv('TESTING_MONGO_URL') ?: 'mongodb://localhost:27017';
21
        $mongo = new \MongoDB\Client(
22
            $this->mongoUrl,
23
            [],
24
            ['typeMap' => ['root' => 'array', 'document' => 'array', 'array' => 'array']]
25
        );
26
        $this->collection = $mongo->selectDatabase('testing')->selectCollection('messages');
27
        $this->collection->drop();
28
29
        $this->queue = new Queue($this->mongoUrl, 'testing', 'messages');
30
    }
31
32
    /**
33
     * @test
34
     * @covers ::__construct
35
     * @expectedException \InvalidArgumentException
36
     */
37
    public function constructWithNonStringUrl()
38
    {
39
        new Queue(1, 'testing', 'messages');
40
    }
41
42
    /**
43
     * @test
44
     * @covers ::ensureGetIndex
45
     */
46
    public function ensureGetIndex()
47
    {
48
        $this->queue->ensureGetIndex(['type' => 1], ['boo' => -1]);
49
        $this->queue->ensureGetIndex(['another.sub' => 1]);
50
51
        $indexes = iterator_to_array($this->collection->listIndexes());
52
        $this->assertSame(3, count($indexes));
53
54
        $expectedOne = [
55
            'earliestGet' => 1,
56
            'payload.type' => 1,
57
            'priority' => 1,
58
            'created' => 1,
59
            'payload.boo' => -1,
60
        ];
61
        $this->assertSame($expectedOne, $indexes[1]['key']);
62
63
        $expectedTwo = [
64
            'earliestGet' => 1,
65
            'payload.another.sub' => 1,
66
            'priority' => 1,
67
            'created' => 1,
68
        ];
69
        $this->assertSame($expectedTwo, $indexes[2]['key']);
70
    }
71
72
    /**
73
     * @test
74
     * @covers ::ensureGetIndex
75
     * @expectedException \Exception
76
     */
77
    public function ensureGetIndexWithTooLongCollectionName()
78
    {
79
        $collectionName = 'messages012345678901234567890123456789012345678901234567890123456789';
80
        $collectionName .= '012345678901234567890123456789012345678901234567890123456789';//128 chars
81
82
        $queue = new Queue($this->mongoUrl, 'testing', $collectionName);
83
        $queue->ensureGetIndex([]);
84
    }
85
86
    /**
87
     * @test
88
     * @covers ::ensureGetIndex
89
     * @expectedException \InvalidArgumentException
90
     */
91
    public function ensureGetIndexWithNonStringBeforeSortKey()
92
    {
93
        $this->queue->ensureGetIndex([0 => 1]);
94
    }
95
96
    /**
97
     * @test
98
     * @covers ::ensureGetIndex
99
     * @expectedException \InvalidArgumentException
100
     */
101
    public function ensureGetIndexWithNonStringAfterSortKey()
102
    {
103
        $this->queue->ensureGetIndex(['field' => 1], [0 => 1]);
104
    }
105
106
    /**
107
     * @test
108
     * @covers ::ensureGetIndex
109
     * @expectedException \InvalidArgumentException
110
     */
111
    public function ensureGetIndexWithBadBeforeSortValue()
112
    {
113
        $this->queue->ensureGetIndex(['field' => 'NotAnInt']);
114
    }
115
116
    /**
117
     * @test
118
     * @covers ::ensureGetIndex
119
     * @expectedException \InvalidArgumentException
120
     */
121
    public function ensureGetIndexWithBadAfterSortValue()
122
    {
123
        $this->queue->ensureGetIndex([], ['field' => 'NotAnInt']);
124
    }
125
126
    /**
127
     * Verifies the behaviour of the Queue when it cannot create an index after 5 attempts.
128
     *
129
     * @test
130
     * @covers ::ensureGetIndex
131
     * @expectedException \Exception
132
     * @expectedExceptionMessage couldnt create index after 5 attempts
133
     */
134
    public function ensureIndexCannotBeCreatedAfterFiveAttempts()
135
    {
136
        $mockCollection = $this->getMockBuilder('\MongoDB\Collection')->disableOriginalConstructor()->getMock();
137
138
        $mockCollection->method('listIndexes')->willReturn([]);
139
140
        $queue = new Queue($mockCollection);
141
        $queue->ensureCountIndex(['type' => 1], false);
142
    }
143
144
    /**
145
     * @test
146
     * @covers ::ensureCountIndex
147
     */
148
    public function ensureCountIndex()
149
    {
150
        $this->queue->ensureCountIndex(['type' => 1, 'boo' => -1], false);
151
        $this->queue->ensureCountIndex(['another.sub' => 1], true);
152
153
        $indexes = iterator_to_array($this->collection->listIndexes());
154
        $this->assertSame(3, count($indexes));
155
156
        $expectedOne = ['payload.type' => 1, 'payload.boo' => -1];
157
        $this->assertSame($expectedOne, $indexes[1]['key']);
158
159
        $expectedTwo = ['earliestGet' => 1, 'payload.another.sub' => 1];
160
        $this->assertSame($expectedTwo, $indexes[2]['key']);
161
    }
162
163
    /**
164
     * @test
165
     * @covers ::ensureCountIndex
166
     */
167
    public function ensureCountIndexWithPrefixOfPrevious()
168
    {
169
        $this->queue->ensureCountIndex(['type' => 1, 'boo' => -1], false);
170
        $this->queue->ensureCountIndex(['type' => 1], false);
171
172
        $indexes = iterator_to_array($this->collection->listIndexes());
173
        $this->assertSame(2, count($indexes));
174
175
        $expected = ['payload.type' => 1, 'payload.boo' => -1];
176
        $this->assertSame($expected, $indexes[1]['key']);
177
    }
178
179
    /**
180
     * @test
181
     * @covers ::ensureCountIndex
182
     * @expectedException \InvalidArgumentException
183
     */
184
    public function ensureCountIndexWithNonStringKey()
185
    {
186
        $this->queue->ensureCountIndex([0 => 1], false);
187
    }
188
189
    /**
190
     * @test
191
     * @covers ::ensureCountIndex
192
     * @expectedException \InvalidArgumentException
193
     */
194
    public function ensureCountIndexWithBadValue()
195
    {
196
        $this->queue->ensureCountIndex(['field' => 'NotAnInt'], false);
197
    }
198
199
    /**
200
     * @test
201
     * @covers ::get
202
     */
203
    public function getByBadQuery()
204
    {
205
        $this->queue->send(['key1' => 0, 'key2' => true]);
206
207
        $result = $this->queue->get(['key3' => 0], PHP_INT_MAX, 0);
208
        $this->assertNull($result);
209
210
        $this->assertSame(1, $this->collection->count());
211
    }
212
213
    /**
214
     * @test
215
     * @covers ::get
216
     */
217
    public function getWithNegativePollDuration()
218
    {
219
        $this->queue->send(['key1' => 0]);
220
        $this->assertNotNull($this->queue->get([], 0, 0, -1));
221
    }
222
223
    /**
224
     * @test
225
     * @covers ::get
226
     * @expectedException \InvalidArgumentException
227
     */
228
    public function getWithNonStringKey()
229
    {
230
        $this->queue->get([0 => 'a value'], 0);
231
    }
232
233
    /**
234
     * @test
235
     * @covers ::get
236
     */
237
    public function getByFullQuery()
238
    {
239
        $messageOne = ['id' => 'SHOULD BE REMOVED', 'key1' => 0, 'key2' => true];
240
241
        $this->queue->send($messageOne);
242
        $this->queue->send(['key' => 'value']);
243
244
        $result = $this->queue->get($messageOne, PHP_INT_MAX, 0);
245
246
        $this->assertNotSame($messageOne['id'], $result['id']);
247
248
        $messageOne['id'] = $result['id'];
249
        $this->assertSame($messageOne, $result);
250
    }
251
252
    /**
253
     * @test
254
     * @covers ::get
255
     */
256
    public function getBySubDocQuery()
257
    {
258
        $messageTwo = [
259
            'one' => [
260
                'two' => [
261
                    'three' => 5,
262
                    'notused' => 'notused',
263
                ],
264
                'notused' => 'notused',
265
            ],
266
            'notused' => 'notused',
267
        ];
268
269
        $this->queue->send(['key1' => 0, 'key2' => true]);
270
        $this->queue->send($messageTwo);
271
272
        $result = $this->queue->get(['one.two.three' => ['$gt' => 4]], PHP_INT_MAX, 0);
273
        $this->assertSame(['id' => $result['id']] + $messageTwo, $result);
274
    }
275
276
    /**
277
     * @test
278
     * @covers ::get
279
     */
280
    public function getBeforeAck()
281
    {
282
        $messageOne = ['key1' => 0, 'key2' => true];
283
284
        $this->queue->send($messageOne);
285
        $this->queue->send(['key' => 'value']);
286
287
        $this->queue->get($messageOne, PHP_INT_MAX, 0);
288
289
        //try get message we already have before ack
290
        $result = $this->queue->get($messageOne, PHP_INT_MAX, 0);
291
        $this->assertNull($result);
292
    }
293
294
    /**
295
     * @test
296
     * @covers ::get
297
     */
298
    public function getWithCustomPriority()
299
    {
300
        $messageOne = ['key' => 0];
301
        $messageTwo = ['key' => 1];
302
        $messageThree = ['key' => 2];
303
304
        $this->queue->send($messageOne, 0, 0.5);
305
        $this->queue->send($messageTwo, 0, 0.4);
306
        $this->queue->send($messageThree, 0, 0.3);
307
308
        $resultOne = $this->queue->get([], PHP_INT_MAX, 0);
309
        $resultTwo = $this->queue->get([], PHP_INT_MAX, 0);
310
        $resultThree = $this->queue->get([], PHP_INT_MAX, 0);
311
312
        $this->assertSame(['id' => $resultOne['id']] + $messageThree, $resultOne);
313
        $this->assertSame(['id' => $resultTwo['id']] + $messageTwo, $resultTwo);
314
        $this->assertSame(['id' => $resultThree['id']] + $messageOne, $resultThree);
315
    }
316
317
    /**
318
     * @test
319
     * @covers ::get
320
     */
321
    public function getWithTimeBasedPriority()
322
    {
323
        $messageOne = ['key' => 0];
324
        $messageTwo = ['key' => 1];
325
        $messageThree = ['key' => 2];
326
327
        $this->queue->send($messageOne);
328
        $this->queue->send($messageTwo);
329
        $this->queue->send($messageThree);
330
331
        $resultOne = $this->queue->get([], PHP_INT_MAX, 0);
332
        $resultTwo = $this->queue->get([], PHP_INT_MAX, 0);
333
        $resultThree = $this->queue->get([], PHP_INT_MAX, 0);
334
335
        $this->assertSame(['id' => $resultOne['id']] + $messageOne, $resultOne);
336
        $this->assertSame(['id' => $resultTwo['id']] + $messageTwo, $resultTwo);
337
        $this->assertSame(['id' => $resultThree['id']] + $messageThree, $resultThree);
338
    }
339
340
    /**
341
     * @test
342
     * @covers ::get
343
     */
344
    public function getWithTimeBasedPriorityWithOldTimestamp()
345
    {
346
        $messageOne = ['key' => 0];
347
        $messageTwo = ['key' => 1];
348
        $messageThree = ['key' => 2];
349
350
        $this->queue->send($messageOne);
351
        $this->queue->send($messageTwo);
352
        $this->queue->send($messageThree);
353
354
        $resultTwo = $this->queue->get([], PHP_INT_MAX, 0);
355
        //ensuring using old timestamp shouldn't affect normal time order of send()s
356
        $this->queue->requeue($resultTwo, 0, 0.0, false);
0 ignored issues
show
It seems like $resultTwo defined by $this->queue->get(array(), PHP_INT_MAX, 0) on line 354 can also be of type null; however, TraderInteractive\Mongo\AbstractQueue::requeue() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
357
358
        $resultOne = $this->queue->get([], PHP_INT_MAX, 0);
359
        $resultTwo = $this->queue->get([], PHP_INT_MAX, 0);
360
        $resultThree = $this->queue->get([], PHP_INT_MAX, 0);
361
362
        $this->assertSame(['id' => $resultOne['id']] + $messageOne, $resultOne);
363
        $this->assertSame(['id' => $resultTwo['id']] + $messageTwo, $resultTwo);
364
        $this->assertSame(['id' => $resultThree['id']] + $messageThree, $resultThree);
365
    }
366
367
    /**
368
     * @test
369
     * @covers ::get
370
     */
371
    public function getWait()
372
    {
373
        $start = microtime(true);
374
375
        $this->queue->get([], PHP_INT_MAX, 200);
376
377
        $end = microtime(true);
378
379
        $this->assertTrue($end - $start >= 0.200);
380
        $this->assertTrue($end - $start < 0.300);
381
    }
382
383
    /**
384
     * @test
385
     * @covers ::get
386
     */
387
    public function earliestGet()
388
    {
389
         $messageOne = ['key1' => 0, 'key2' => true];
390
391
         $this->queue->send($messageOne, time() + 1);
392
393
         $this->assertNull($this->queue->get($messageOne, PHP_INT_MAX, 0));
394
395
         sleep(1);
396
397
         $this->assertNotNull($this->queue->get($messageOne, PHP_INT_MAX, 0));
398
    }
399
400
    /**
401
     * @test
402
     * @covers ::get
403
     */
404
    public function resetStuck()
405
    {
406
        $messageOne = ['key' => 0];
407
        $messageTwo = ['key' => 1];
408
409
        $this->queue->send($messageOne);
410
        $this->queue->send($messageTwo);
411
412
        //sets to running
413
        $this->collection->updateOne(
414
            ['payload.key' => 0],
415
            ['$set' => ['earliestGet' => new \MongoDB\BSON\UTCDateTime(time() * 1000)]]
416
        );
417
        $this->collection->updateOne(
418
            ['payload.key' => 1],
419
            ['$set' => ['earliestGet' => new \MongoDB\BSON\UTCDateTime(time() * 1000)]]
420
        );
421
422
        $this->assertSame(
423
            2,
424
            $this->collection->count(
425
                ['earliestGet' => ['$lte' => new \MongoDB\BSON\UTCDateTime((int)(microtime(true) * 1000))]]
426
            )
427
        );
428
429
        //resets and gets messageOne
430
        $this->assertNotNull($this->queue->get($messageOne, PHP_INT_MAX, 0));
431
432
        $this->assertSame(
433
            1,
434
            $this->collection->count(
435
                ['earliestGet' => ['$lte' => new \MongoDB\BSON\UTCDateTime((int)(microtime(true) * 1000))]]
436
            )
437
        );
438
    }
439
440
    /**
441
     * @test
442
     * @covers ::count
443
     * @expectedException \InvalidArgumentException
444
     */
445
    public function countWithNonStringKey()
446
    {
447
        $this->queue->count([0 => 'a value']);
448
    }
449
450
    /**
451
     * @test
452
     * @covers ::count
453
     */
454
    public function testCount()
455
    {
456
        $message = ['boo' => 'scary'];
457
458
        $this->assertSame(0, $this->queue->count($message, true));
459
        $this->assertSame(0, $this->queue->count($message, false));
460
        $this->assertSame(0, $this->queue->count($message));
461
462
        $this->queue->send($message);
463
        $this->assertSame(1, $this->queue->count($message, false));
464
        $this->assertSame(0, $this->queue->count($message, true));
465
        $this->assertSame(1, $this->queue->count($message));
466
467
        $this->queue->get($message, PHP_INT_MAX, 0);
468
        $this->assertSame(0, $this->queue->count($message, false));
469
        $this->assertSame(1, $this->queue->count($message, true));
470
        $this->assertSame(1, $this->queue->count($message));
471
    }
472
473
    /**
474
     * @test
475
     * @covers ::ack
476
     */
477
    public function ack()
478
    {
479
        $messageOne = ['key1' => 0, 'key2' => true];
480
481
        $this->queue->send($messageOne);
482
        $this->queue->send(['key' => 'value']);
483
484
        $result = $this->queue->get($messageOne, PHP_INT_MAX, 0);
485
        $this->assertSame(2, $this->collection->count());
486
487
        $this->queue->ack($result);
0 ignored issues
show
It seems like $result defined by $this->queue->get($messageOne, PHP_INT_MAX, 0) on line 484 can also be of type null; however, TraderInteractive\Mongo\AbstractQueue::ack() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
488
        $this->assertSame(1, $this->collection->count());
489
    }
490
491
    /**
492
     * @test
493
     * @covers ::ack
494
     * @expectedException \InvalidArgumentException
495
     */
496
    public function ackBadArg()
497
    {
498
        $this->queue->ack(['id' => new \stdClass()]);
499
    }
500
501
    /**
502
     * @test
503
     * @covers ::ackSend
504
     */
505
    public function ackSend()
506
    {
507
        $messageOne = ['key1' => 0, 'key2' => true];
508
        $messageThree = ['hi' => 'there', 'rawr' => 2];
509
510
        $this->queue->send($messageOne);
511
        $this->queue->send(['key' => 'value']);
512
513
        $resultOne = $this->queue->get($messageOne, PHP_INT_MAX, 0);
514
        $this->assertSame(2, $this->collection->count());
515
516
        $this->queue->ackSend($resultOne, $messageThree);
0 ignored issues
show
It seems like $resultOne defined by $this->queue->get($messageOne, PHP_INT_MAX, 0) on line 513 can also be of type null; however, TraderInteractive\Mongo\AbstractQueue::ackSend() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
517
        $this->assertSame(2, $this->collection->count());
518
519
        $actual = $this->queue->get(['hi' => 'there'], PHP_INT_MAX, 0);
520
        $expected = ['id' => $resultOne['id']] + $messageThree;
521
522
        $actual['id'] = $actual['id']->__toString();
523
        $expected['id'] = $expected['id']->__toString();
524
        $this->assertSame($expected, $actual);
525
    }
526
527
    /**
528
     * Verify earliestGet with ackSend.
529
     *
530
     * @test
531
     * @covers ::ackSend
532
     *
533
     * @return void
534
     */
535
    public function ackSendWithEarliestGet()
536
    {
537
        $message = ['key1' => 0, 'key2' => true];
538
        $this->queue->send($message);
539
        $result = $this->queue->get([], PHP_INT_MAX, 0);
540
        $this->assertSame($message['key1'], $result['key1']);
541
        $this->assertSame($message['key2'], $result['key2']);
542
        $this->queue->ackSend($result, ['key1' => 1, 'key2' => 2], strtotime('+ 1 day'));
543
        $actual = $this->queue->get([], PHP_INT_MAX, 0);
544
        $this->assertNull($actual);
545
    }
546
547
    /**
548
     * @test
549
     * @covers ::ackSend
550
     * @expectedException \InvalidArgumentException
551
     */
552
    public function ackSendWithWrongIdType()
553
    {
554
        $this->queue->ackSend(['id' => 5], []);
555
    }
556
557
    /**
558
     * @test
559
     * @covers ::ackSend
560
     * @expectedException \InvalidArgumentException
561
     */
562
    public function ackSendWithNanPriority()
563
    {
564
        $this->queue->ackSend(['id' => new \MongoDB\BSON\ObjectID()], [], 0, NAN);
565
    }
566
567
    /**
568
     * @test
569
     * @covers ::ackSend
570
     */
571
    public function ackSendWithHighEarliestGet()
572
    {
573
        $this->queue->send([]);
574
        $messageToAck = $this->queue->get([], PHP_INT_MAX, 0);
575
576
        $this->queue->ackSend($messageToAck, [], PHP_INT_MAX);
0 ignored issues
show
It seems like $messageToAck defined by $this->queue->get(array(), PHP_INT_MAX, 0) on line 574 can also be of type null; however, TraderInteractive\Mongo\AbstractQueue::ackSend() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
577
578
        $expected = [
579
            'payload' => [],
580
            'earliestGet' => Queue::MONGO_INT32_MAX,
581
            'priority' => 0.0,
582
        ];
583
584
        $message = $this->collection->findOne();
585
586
        $this->assertLessThanOrEqual(time(), $message['created']->toDateTime()->getTimestamp());
587
        $this->assertGreaterThan(time() - 10, $message['created']->toDateTime()->getTimestamp());
588
589
        unset($message['_id'], $message['created']);
590
        $message['earliestGet'] = (int)$message['earliestGet']->__toString();
591
592
        $this->assertSame($expected, $message);
593
    }
594
595
    /**
596
     * @covers ::ackSend
597
     */
598
    public function ackSendWithLowEarliestGet()
599
    {
600
        $this->queue->send([]);
601
        $messageToAck = $this->queue->get([], PHP_INT_MAX, 0);
602
603
        $this->queue->ackSend($messageToAck, [], -1);
0 ignored issues
show
It seems like $messageToAck defined by $this->queue->get(array(), PHP_INT_MAX, 0) on line 601 can also be of type null; however, TraderInteractive\Mongo\AbstractQueue::ackSend() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
604
605
        $expected = [
606
            'payload' => [],
607
            'running' => false,
608
            'resetTimestamp' => Queue::MONGO_INT32_MAX,
609
            'earliestGet' => 0,
610
            'priority' => 0.0,
611
        ];
612
613
        $message = $this->collection->findOne();
614
615
        $this->assertLessThanOrEqual(time(), $message['created']->toDateTime()->getTimestamp());
616
        $this->assertGreaterThan(time() - 10, $message['created']->toDateTime()->getTimestamp());
617
618
        unset($message['_id'], $message['created']);
619
        $message['resetTimestamp'] = (int)$message['resetTimestamp']->__toString();
620
        $message['earliestGet'] = (int)$message['earliestGet']->__toString();
621
622
        $this->assertSame($expected, $message);
623
    }
624
625
    /**
626
     * @test
627
     * @covers ::requeue
628
     */
629
    public function requeue()
630
    {
631
        $messageOne = ['key1' => 0, 'key2' => true];
632
633
        $this->queue->send($messageOne);
634
        $this->queue->send(['key' => 'value']);
635
636
        $resultBeforeRequeue = $this->queue->get($messageOne, PHP_INT_MAX, 0);
637
638
        $this->queue->requeue($resultBeforeRequeue);
0 ignored issues
show
It seems like $resultBeforeRequeue defined by $this->queue->get($messageOne, PHP_INT_MAX, 0) on line 636 can also be of type null; however, TraderInteractive\Mongo\AbstractQueue::requeue() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
639
        $this->assertSame(2, $this->collection->count());
640
641
        $resultAfterRequeue = $this->queue->get($messageOne, 0);
642
        $this->assertSame(['id' => $resultAfterRequeue['id']] + $messageOne, $resultAfterRequeue);
643
    }
644
645
    /**
646
     * @test
647
     * @covers ::requeue
648
     * @expectedException \InvalidArgumentException
649
     */
650
    public function requeueBadArg()
651
    {
652
        $this->queue->requeue(['id' => new \stdClass()]);
653
    }
654
655
    /**
656
     * @test
657
     * @covers ::send
658
     */
659
    public function send()
660
    {
661
        $payload = ['key1' => 0, 'key2' => true];
662
        $this->queue->send($payload, 34, 0.8);
663
664
        $expected = [
665
            'payload' => $payload,
666
            'earliestGet' => 34,
667
            'priority' => 0.8,
668
        ];
669
670
        $message = $this->collection->findOne();
671
672
        $this->assertLessThanOrEqual(time(), $message['created']->toDateTime()->getTimestamp());
673
        $this->assertGreaterThan(time() - 10, $message['created']->toDateTime()->getTimestamp());
674
675
        unset($message['_id'], $message['created']);
676
        $message['earliestGet'] = $message['earliestGet']->toDateTime()->getTimestamp();
677
678
        $this->assertSame($expected, $message);
679
    }
680
681
    /**
682
     * @test
683
     * @covers ::send
684
     * @expectedException \InvalidArgumentException
685
     */
686
    public function sendWithNanPriority()
687
    {
688
        $this->queue->send([], 0, NAN);
689
    }
690
691
    /**
692
     * @test
693
     * @covers ::send
694
     */
695
    public function sendWithHighEarliestGet()
696
    {
697
        $this->queue->send([], PHP_INT_MAX);
698
699
        $expected = [
700
            'payload' => [],
701
            'earliestGet' => (new UTCDateTime(Queue::MONGO_INT32_MAX))->toDateTime()->getTimestamp(),
702
            'priority' => 0.0,
703
        ];
704
705
        $message = $this->collection->findOne();
706
707
        $this->assertLessThanOrEqual(time(), $message['created']->toDateTime()->getTimestamp());
708
        $this->assertGreaterThan(time() - 10, $message['created']->toDateTime()->getTimestamp());
709
710
        unset($message['_id'], $message['created']);
711
        $message['earliestGet'] = $message['earliestGet']->toDateTime()->getTimestamp();
712
713
        $this->assertSame($expected, $message);
714
    }
715
716
    /**
717
     * @test
718
     * @covers ::send
719
     */
720
    public function sendWithLowEarliestGet()
721
    {
722
        $this->queue->send([], -1);
723
724
        $expected = [
725
            'payload' => [],
726
            'earliestGet' => 0,
727
            'priority' => 0.0,
728
        ];
729
730
        $message = $this->collection->findOne();
731
732
        $this->assertLessThanOrEqual(time(), $message['created']->toDateTime()->getTimestamp());
733
        $this->assertGreaterThan(time() - 10, $message['created']->toDateTime()->getTimestamp());
734
735
        unset($message['_id'], $message['created']);
736
        $message['earliestGet'] = $message['earliestGet']->toDateTime()->getTimestamp();
737
738
        $this->assertSame($expected, $message);
739
    }
740
741
    /**
742
     * Verify Queue can be constructed with \MongoDB\Collection
743
     *
744
     * @test
745
     * @covers ::__construct
746
     *
747
     * @return void
748
     */
749
    public function constructWithCollection()
750
    {
751
        $mongo = new \MongoDB\Client(
752
            $this->mongoUrl,
753
            [],
754
            ['typeMap' => ['root' => 'array', 'document' => 'array', 'array' => 'array']]
755
        );
756
        $collection = $mongo->selectDatabase('testing')->selectCollection('custom_collection');
757
        $collection->drop();
758
        $queue = new Queue($collection);
759
760
        $payload = ['key1' => 0, 'key2' => true];
761
        $queue->send($payload, 34, 0.8);
762
763
        $expected = [
764
            'payload' => $payload,
765
            'earliestGet' => 34,
766
            'priority' => 0.8,
767
        ];
768
769
        $this->assertSame(1, $collection->count());
770
771
        $message = $collection->findOne();
772
773
        $this->assertLessThanOrEqual(time(), $message['created']->toDateTime()->getTimestamp());
774
        $this->assertGreaterThan(time() - 10, $message['created']->toDateTime()->getTimestamp());
775
776
        unset($message['_id'], $message['created']);
777
        $message['earliestGet'] = $message['earliestGet']->toDateTime()->getTimestamp();
778
779
        $this->assertSame($expected, $message);
780
    }
781
}
782