Completed
Push — master ( 03ffe6...2c1c5a )
by Will
11s
created

testEnqueueWithDelaySecondsMetadata()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 27
nc 1
nop 0
1
<?php
2
3
/**
4
 * This file is part of graze/queue.
5
 *
6
 * Copyright (c) 2015 Nature Delivered Ltd. <https://www.graze.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * @license https://github.com/graze/queue/blob/master/LICENSE MIT
12
 *
13
 * @link    https://github.com/graze/queue
14
 */
15
16
namespace Graze\Queue\Adapter;
17
18
use Aws\ResultInterface;
19
use Aws\Sqs\SqsClient;
20
use Graze\DataStructure\Container\ContainerInterface;
21
use Graze\Queue\Message\MessageFactoryInterface;
22
use Graze\Queue\Message\MessageInterface;
23
use Mockery as m;
24
use Mockery\MockInterface;
25
use PHPUnit_Framework_TestCase as TestCase;
26
27
class SqsAdapterTest extends TestCase
28
{
29
    /** @var MessageInterface|MockInterface */
30
    private $messageA;
31
    /** @var MessageInterface|MockInterface */
32
    private $messageB;
33
    /** @var MessageInterface|MockInterface */
34
    private $messageC;
35
    /** @var MessageInterface[]|MockInterface[] */
36
    private $messages;
37
    /** @var ResultInterface|MockInterface */
38
    private $model;
39
    /** @var MessageFactoryInterface|MockInterface */
40
    private $factory;
41
    /** @var SqsClient */
42
    private $client;
43
44
    public function setUp()
45
    {
46
        $this->client = m::mock(SqsClient::class);
47
        $this->model = m::mock(ResultInterface::class);
48
        $this->factory = m::mock(MessageFactoryInterface::class);
49
50
        $this->messageA = $a = m::mock(MessageInterface::class);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $a. Configured minimum length is 2.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
51
        $this->messageB = $b = m::mock(MessageInterface::class);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $b. Configured minimum length is 2.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
52
        $this->messageC = $c = m::mock(MessageInterface::class);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $c. Configured minimum length is 2.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
53
        $this->messages = [$a, $b, $c];
54
    }
55
56
    /**
57
     * @param string $body
58
     * @param int    $id
59
     * @param string $handle
60
     */
61
    protected function stubCreateDequeueMessage($body, $id, $handle)
62
    {
63
        $this->factory->shouldReceive('createMessage')->once()->with($body, m::on(function ($opts) use ($id, $handle) {
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Graze\Queue\Message\MessageFactoryInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
64
            $meta = ['Attributes' => [], 'MessageAttributes' => [], 'MessageId' => $id, 'ReceiptHandle' => $handle];
65
            $validator = isset($opts['validator']) && is_callable($opts['validator']);
66
67
            return isset($opts['metadata']) && $opts['metadata'] === $meta && $validator;
68
        }))->andReturn($this->messageA);
69
    }
70
71
    /**
72
     * @param string $name
73
     * @param array  $options
74
     *
75
     * @return string
76
     */
77 View Code Duplication
    protected function stubCreateQueue($name, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
78
    {
79
        $url = 'foo://bar';
80
        $model = m::mock(ResultInterface::class);
81
        $model->shouldReceive('get')->once()->with('QueueUrl')->andReturn($url);
82
83
        $this->client->shouldReceive('createQueue')->once()->with([
84
            'QueueName'  => $name,
85
            'Attributes' => $options,
86
        ])->andReturn($model);
87
88
        return $url;
89
    }
90
91
    /**
92
     * @param string $url
93
     *
94
     * @return int
95
     */
96 View Code Duplication
    protected function stubQueueVisibilityTimeout($url)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
    {
98
        $timeout = 120;
99
        $model = m::mock(ResultInterface::class);
100
        $model->shouldReceive('get')->once()->with('Attributes')->andReturn(['VisibilityTimeout' => $timeout]);
101
102
        $this->client->shouldReceive('getQueueAttributes')->once()->with([
103
            'QueueUrl'       => $url,
104
            'AttributeNames' => ['VisibilityTimeout'],
105
        ])->andReturn($model);
106
107
        return $timeout;
108
    }
109
110
    public function testInterface()
111
    {
112
        assertThat(new SqsAdapter($this->client, 'foo'), is(anInstanceOf('Graze\Queue\Adapter\AdapterInterface')));
113
    }
114
115
    public function testAcknowledge()
116
    {
117
        $adapter = new SqsAdapter($this->client, 'foo');
118
        $url = $this->stubCreateQueue('foo');
119
120
        $this->messageA->shouldReceive('getMetadata->get')->once()->with('ReceiptHandle')->andReturn('foo');
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Graze\Queue\Message\MessageInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
121
        $this->messageB->shouldReceive('getMetadata->get')->once()->with('ReceiptHandle')->andReturn('bar');
122
        $this->messageC->shouldReceive('getMetadata->get')->once()->with('ReceiptHandle')->andReturn('baz');
123
124
        $this->model->shouldReceive('get')->once()->with('Failed')->andReturn([]);
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Aws\ResultInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
125
126
        $this->client->shouldReceive('deleteMessageBatch')->once()->with([
127
            'QueueUrl' => $url,
128
            'Entries'  => [
129
                ['Id' => 0, 'ReceiptHandle' => 'foo'],
130
                ['Id' => 1, 'ReceiptHandle' => 'bar'],
131
                ['Id' => 2, 'ReceiptHandle' => 'baz'],
132
            ],
133
        ])->andReturn($this->model);
134
135
        $adapter->acknowledge($this->messages);
0 ignored issues
show
Documentation introduced by
$this->messages is of type array<integer,object<Mockery\MockInterface>>, but the function expects a array<integer,object<Gra...sage\MessageInterface>>.

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...
136
    }
137
138
    public function testDequeue()
139
    {
140
        $adapter = new SqsAdapter($this->client, 'foo');
141
        $url = $this->stubCreateQueue('foo');
142
        $timeout = $this->stubQueueVisibilityTimeout($url);
143
144
        $this->stubCreateDequeueMessage('foo', 0, 'a');
145
        $this->stubCreateDequeueMessage('bar', 1, 'b');
146
        $this->stubCreateDequeueMessage('baz', 2, 'c');
147
148
        $this->model->shouldReceive('get')->once()->with('Messages')->andReturn([
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Aws\ResultInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
149
            ['Body' => 'foo', 'Attributes' => [], 'MessageAttributes' => [], 'MessageId' => 0, 'ReceiptHandle' => 'a'],
150
            ['Body' => 'bar', 'Attributes' => [], 'MessageAttributes' => [], 'MessageId' => 1, 'ReceiptHandle' => 'b'],
151
            ['Body' => 'baz', 'Attributes' => [], 'MessageAttributes' => [], 'MessageId' => 2, 'ReceiptHandle' => 'c'],
152
        ]);
153
154
        $this->client->shouldReceive('receiveMessage')->once()->with([
155
            'QueueUrl'            => $url,
156
            'AttributeNames'      => ['All'],
157
            'MaxNumberOfMessages' => 3,
158
            'VisibilityTimeout'   => $timeout,
159
        ])->andReturn($this->model);
160
161
        $iterator = $adapter->dequeue($this->factory, 3);
162
163
        assertThat($iterator, is(anInstanceOf('Generator')));
164
        assertThat(iterator_to_array($iterator), is(equalTo($this->messages)));
165
    }
166
167
    public function testDequeueInBatches()
168
    {
169
        $adapter = new SqsAdapter($this->client, 'foo');
170
        $url = $this->stubCreateQueue('foo');
171
        $timeout = $this->stubQueueVisibilityTimeout($url);
172
173
        $limit = SqsAdapter::BATCHSIZE_RECEIVE;
174
175
        $return = [];
176
        $messages = [];
177
178
        for ($i = 0; $i < $limit; $i++) {
179
            $this->stubCreateDequeueMessage('tmp' . $i, $i, 'h' . $i);
180
            $return[] = [
181
                'Body'              => 'tmp' . $i,
182
                'Attributes'        => [],
183
                'MessageAttributes' => [],
184
                'MessageId'         => $i,
185
                'ReceiptHandle'     => 'h' . $i,
186
            ];
187
            $messages[] = $this->messageA;
188
        }
189
190
        $this->model->shouldReceive('get')->once()->with('Messages')->andReturn($return);
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Aws\ResultInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
191
192
        $this->client->shouldReceive('receiveMessage')->once()->with([
193
            'QueueUrl'            => $url,
194
            'AttributeNames'      => ['All'],
195
            'MaxNumberOfMessages' => $limit,
196
            'VisibilityTimeout'   => $timeout,
197
        ])->andReturn($this->model);
198
199
        $iterator = $adapter->dequeue($this->factory, $limit);
200
201
        assertThat($iterator, is(anInstanceOf('Generator')));
202
        assertThat(iterator_to_array($iterator), is(equalTo($messages)));
203
    }
204
205
    public function testEnqueue()
206
    {
207
        $adapter = new SqsAdapter($this->client, 'foo');
208
        $url = $this->stubCreateQueue('foo');
209
210
        $metadata = m::mock(ContainerInterface::class);
211
        $metadata->shouldReceive('get')
212
                 ->with('MessageAttributes')
213
                 ->times(3)
214
                 ->andReturn(null);
215
        $metadata->shouldReceive('get')
216
                 ->with('DelaySeconds')
217
                 ->andReturn(null);
218
219
        $this->messageA->shouldReceive('getBody')->once()->withNoArgs()->andReturn('foo');
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Graze\Queue\Message\MessageInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
220
        $this->messageB->shouldReceive('getBody')->once()->withNoArgs()->andReturn('bar');
221
        $this->messageC->shouldReceive('getBody')->once()->withNoArgs()->andReturn('baz');
222
        $this->messageA->shouldReceive('getMetadata')->andReturn($metadata);
223
        $this->messageB->shouldReceive('getMetadata')->andReturn($metadata);
224
        $this->messageC->shouldReceive('getMetadata')->andReturn($metadata);
225
226
        $this->model->shouldReceive('get')->once()->with('Failed')->andReturn([]);
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Aws\ResultInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
227
228
        $this->client->shouldReceive('sendMessageBatch')->once()->with([
229
            'QueueUrl' => $url,
230
            'Entries'  => [
231
                ['Id' => 0, 'MessageBody' => 'foo', 'MessageAttributes' => []],
232
                ['Id' => 1, 'MessageBody' => 'bar', 'MessageAttributes' => []],
233
                ['Id' => 2, 'MessageBody' => 'baz', 'MessageAttributes' => []],
234
            ],
235
        ])->andReturn($this->model);
236
237
        $adapter->enqueue($this->messages);
0 ignored issues
show
Documentation introduced by
$this->messages is of type array<integer,object<Mockery\MockInterface>>, but the function expects a array<integer,object<Gra...sage\MessageInterface>>.

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...
238
    }
239
240
    public function testEnqueueWithDelaySecondsMetadata()
241
    {
242
        $adapter = new SqsAdapter($this->client, 'foo');
243
        $url = $this->stubCreateQueue('foo');
244
245
        $metadataA = m::mock(ContainerInterface::class);
246
        $metadataA->shouldReceive('get')->with('MessageAttributes')->once()->andReturn(null);
247
        $metadataA->shouldReceive('get')->with('DelaySeconds')->andReturn(1);
248
        $metadataB = m::mock(ContainerInterface::class);
249
        $metadataB->shouldReceive('get')->with('MessageAttributes')->once()->andReturn(null);
250
        $metadataB->shouldReceive('get')->with('DelaySeconds')->andReturn(2);
251
        $metadataC = m::mock(ContainerInterface::class);
252
        $metadataC->shouldReceive('get')->with('MessageAttributes')->once()->andReturn(null);
253
        $metadataC->shouldReceive('get')->with('DelaySeconds')->andReturn(3);
254
255
        $this->messageA->shouldReceive('getBody')->once()->withNoArgs()->andReturn('foo');
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Graze\Queue\Message\MessageInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
256
        $this->messageB->shouldReceive('getBody')->once()->withNoArgs()->andReturn('bar');
257
        $this->messageC->shouldReceive('getBody')->once()->withNoArgs()->andReturn('baz');
258
        $this->messageA->shouldReceive('getMetadata')->andReturn($metadataA);
259
        $this->messageB->shouldReceive('getMetadata')->andReturn($metadataB);
260
        $this->messageC->shouldReceive('getMetadata')->andReturn($metadataC);
261
262
        $this->model->shouldReceive('get')->once()->with('Failed')->andReturn([]);
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Aws\ResultInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
263
264
        $this->client->shouldReceive('sendMessageBatch')->once()->with([
265
            'QueueUrl' => $url,
266
            'Entries'  => [
267
                ['Id' => 0, 'MessageBody' => 'foo', 'MessageAttributes' => [], 'DelaySeconds' => 1],
268
                ['Id' => 1, 'MessageBody' => 'bar', 'MessageAttributes' => [], 'DelaySeconds' => 2],
269
                ['Id' => 2, 'MessageBody' => 'baz', 'MessageAttributes' => [], 'DelaySeconds' => 3],
270
            ],
271
        ])->andReturn($this->model);
272
273
        $adapter->enqueue($this->messages);
0 ignored issues
show
Documentation introduced by
$this->messages is of type array<integer,object<Mockery\MockInterface>>, but the function expects a array<integer,object<Gra...sage\MessageInterface>>.

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...
274
    }
275
276
    public function testEnqueueWithDelaySecondsQueueConfiguration()
277
    {
278
        $options = ['DelaySeconds' => 10];
279
280
        $adapter = new SqsAdapter($this->client, 'foo', $options);
281
        $url = $this->stubCreateQueue('foo', $options);
282
283
        $metadataA = m::mock(ContainerInterface::class);
284
        $metadataA->shouldReceive('get')->with('MessageAttributes')->once()->andReturn(null);
285
        $metadataA->shouldReceive('get')->with('DelaySeconds')->andReturn(null);
286
        $metadataB = m::mock(ContainerInterface::class);
287
        $metadataB->shouldReceive('get')->with('MessageAttributes')->once()->andReturn(null);
288
        $metadataB->shouldReceive('get')->with('DelaySeconds')->andReturn(0);
289
        $metadataC = m::mock(ContainerInterface::class);
290
        $metadataC->shouldReceive('get')->with('MessageAttributes')->once()->andReturn(null);
291
        $metadataC->shouldReceive('get')->with('DelaySeconds')->andReturn(2);
292
293
        $this->messageA->shouldReceive('getBody')->once()->withNoArgs()->andReturn('foo');
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Graze\Queue\Message\MessageInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
294
        $this->messageB->shouldReceive('getBody')->once()->withNoArgs()->andReturn('bar');
295
        $this->messageC->shouldReceive('getBody')->once()->withNoArgs()->andReturn('baz');
296
        $this->messageA->shouldReceive('getMetadata')->andReturn($metadataA);
297
        $this->messageB->shouldReceive('getMetadata')->andReturn($metadataB);
298
        $this->messageC->shouldReceive('getMetadata')->andReturn($metadataC);
299
300
        $this->model->shouldReceive('get')->once()->with('Failed')->andReturn([]);
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Aws\ResultInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
301
302
        $this->client->shouldReceive('sendMessageBatch')->once()->with([
303
            'QueueUrl' => $url,
304
            'Entries'  => [
305
                ['Id' => 0, 'MessageBody' => 'foo', 'MessageAttributes' => []],
306
                ['Id' => 1, 'MessageBody' => 'bar', 'MessageAttributes' => [], 'DelaySeconds' => 0],
307
                ['Id' => 2, 'MessageBody' => 'baz', 'MessageAttributes' => [], 'DelaySeconds' => 2],
308
            ],
309
        ])->andReturn($this->model);
310
311
        $adapter->enqueue($this->messages);
0 ignored issues
show
Documentation introduced by
$this->messages is of type array<integer,object<Mockery\MockInterface>>, but the function expects a array<integer,object<Gra...sage\MessageInterface>>.

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...
312
    }
313
314
    public function testReceiveMessageWaitTimeSecondsOption()
315
    {
316
        $options = ['ReceiveMessageWaitTimeSeconds' => 20];
317
318
        $adapter = new SqsAdapter($this->client, 'foo', $options);
319
        $url = $this->stubCreateQueue('foo', $options);
320
        $timeout = $this->stubQueueVisibilityTimeout($url);
321
322
        $this->stubCreateDequeueMessage('foo', 0, 'a');
323
        $this->stubCreateDequeueMessage('bar', 1, 'b');
324
        $this->stubCreateDequeueMessage('baz', 2, 'c');
325
326
        $this->model->shouldReceive('get')->once()->with('Messages')->andReturn([
0 ignored issues
show
Bug introduced by
The method shouldReceive does only exist in Mockery\MockInterface, but not in Aws\ResultInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
327
            ['Body' => 'foo', 'Attributes' => [], 'MessageAttributes' => [], 'MessageId' => 0, 'ReceiptHandle' => 'a'],
328
            ['Body' => 'bar', 'Attributes' => [], 'MessageAttributes' => [], 'MessageId' => 1, 'ReceiptHandle' => 'b'],
329
            ['Body' => 'baz', 'Attributes' => [], 'MessageAttributes' => [], 'MessageId' => 2, 'ReceiptHandle' => 'c'],
330
        ]);
331
332
        $this->client->shouldReceive('receiveMessage')->once()->with([
333
            'QueueUrl'            => $url,
334
            'AttributeNames'      => ['All'],
335
            'MaxNumberOfMessages' => 3,
336
            'VisibilityTimeout'   => $timeout,
337
            'WaitTimeSeconds'     => 20,
338
        ])->andReturn($this->model);
339
340
        $iterator = $adapter->dequeue($this->factory, 3);
341
342
        assertThat($iterator, is(anInstanceOf('Generator')));
343
        assertThat(iterator_to_array($iterator), is(equalTo($this->messages)));
344
    }
345
346 View Code Duplication
    public function testPurge()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
347
    {
348
        $adapter = new SqsAdapter($this->client, 'foo');
349
        $url = $this->stubCreateQueue('foo');
350
351
        $this->client->shouldReceive('purgeQueue')->once()->with([
352
            'QueueUrl' => $url,
353
        ])->andReturn($this->model);
354
355
        assertThat($adapter->purge(), is(nullValue()));
356
    }
357
358 View Code Duplication
    public function testDelete()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
359
    {
360
        $adapter = new SqsAdapter($this->client, 'foo');
361
        $url = $this->stubCreateQueue('foo');
362
363
        $this->client->shouldReceive('deleteQueue')->once()->with([
364
            'QueueUrl' => $url,
365
        ])->andReturn($this->model);
366
367
        assertThat($adapter->delete(), is(nullValue()));
368
    }
369
}
370