Completed
Push — master ( 746a07...6b648b )
by
unknown
7s
created

ScopeTest::testNullResourceDataAndJustMeta()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 12
loc 12
rs 9.4285
cc 1
eloc 7
nc 1
nop 0
1
<?php namespace League\Fractal\Test;
2
3
use League\Fractal\Manager;
4
use League\Fractal\Pagination\Cursor;
5
use League\Fractal\Resource\Collection;
6
use League\Fractal\Resource\Item;
7
use League\Fractal\Resource\NullResource;
8
use League\Fractal\Scope;
9
use League\Fractal\Serializer\ArraySerializer;
10
use League\Fractal\Test\Stub\ArraySerializerWithNull;
11
use League\Fractal\Test\Stub\Transformer\DefaultIncludeBookTransformer;
12
use League\Fractal\Test\Stub\Transformer\NullIncludeBookTransformer;
13
use Mockery;
14
15
class ScopeTest extends \PHPUnit_Framework_TestCase
16
{
17
    protected $simpleItem = ['foo' => 'bar'];
18
    protected $simpleCollection = [['foo' => 'bar']];
19
20
    public function testEmbedChildScope()
21
    {
22
        $manager = new Manager();
23
24
        $resource = new Item(['foo' => 'bar'], function () {
25
        });
26
27
        $scope = new Scope($manager, $resource, 'book');
28
        $this->assertSame($scope->getScopeIdentifier(), 'book');
29
        $childScope = $scope->embedChildScope('author', $resource);
30
31
        $this->assertInstanceOf('League\Fractal\Scope', $childScope);
32
    }
33
34 View Code Duplication
    public function testGetManager()
35
    {
36
        $resource = new Item(['foo' => 'bar'], function () {
37
        });
38
39
        $scope = new Scope(new Manager(), $resource, 'book');
40
41
        $this->assertInstanceOf('League\Fractal\Manager', $scope->getManager());
42
    }
43
44 View Code Duplication
    public function testGetResource()
45
    {
46
        $resource = new Item(['foo' => 'bar'], function () {
47
        });
48
49
        $scope = new Scope(new Manager(), $resource, 'book');
50
51
        $this->assertInstanceOf('League\Fractal\Resource\ResourceAbstract', $scope->getResource());
52
        $this->assertInstanceOf('League\Fractal\Resource\Item', $scope->getResource());
53
    }
54
55
    /**
56
     * @covers \League\Fractal\Scope::toArray
57
     */
58 View Code Duplication
    public function testToArray()
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...
59
    {
60
        $manager = new Manager();
61
62
        $resource = new Item(['foo' => 'bar'], function ($data) {
63
            return $data;
64
        });
65
66
        $scope = new Scope($manager, $resource);
67
68
69
        $this->assertSame(['data' => ['foo' => 'bar']], $scope->toArray());
70
    }
71
72
    public function testToJson()
73
    {
74
        $data = [
75
            'foo' => 'bar',
76
        ];
77
78
        $manager = new Manager();
79
80
        $resource = new Item($data, function ($data) {
81
            return $data;
82
        });
83
84
        $scope = new Scope($manager, $resource);
85
86
        $expected = json_encode([
87
            'data' => $data,
88
        ]);
89
90
        $this->assertSame($expected, $scope->toJson());
91
    }
92
93 View Code Duplication
    public function testGetCurrentScope()
94
    {
95
        $manager = new Manager();
96
97
        $resource = new Item(['name' => 'Larry Ullman'], function () {
98
        });
99
100
        $scope = new Scope($manager, $resource, 'book');
101
        $this->assertSame('book', $scope->getScopeIdentifier());
102
103
        $childScope = $scope->embedChildScope('author', $resource);
104
        $this->assertSame('author', $childScope->getScopeIdentifier());
105
106
        $grandChildScope = $childScope->embedChildScope('profile', $resource);
107
        $this->assertSame('profile', $grandChildScope->getScopeIdentifier());
108
    }
109
110 View Code Duplication
    public function testGetIdentifier()
111
    {
112
        $manager = new Manager();
113
114
        $resource = new Item(['name' => 'Larry Ullman'], function () {
115
        });
116
117
        $scope = new Scope($manager, $resource, 'book');
118
        $this->assertSame('book', $scope->getIdentifier());
119
120
        $childScope = $scope->embedChildScope('author', $resource);
121
        $this->assertSame('book.author', $childScope->getIdentifier());
122
123
        $grandChildScope = $childScope->embedChildScope('profile', $resource);
124
        $this->assertSame('book.author.profile', $grandChildScope->getIdentifier());
125
    }
126
127
    public function testGetParentScopes()
128
    {
129
        $manager = new Manager();
130
131
        $resource = new Item(['name' => 'Larry Ullman'], function () {
132
        });
133
134
        $scope = new Scope($manager, $resource, 'book');
135
136
        $childScope = $scope->embedChildScope('author', $resource);
137
138
        $this->assertSame(['book'], $childScope->getParentScopes());
139
140
        $grandChildScope = $childScope->embedChildScope('profile', $resource);
141
        $this->assertSame(['book', 'author'], $grandChildScope->getParentScopes());
142
    }
143
144
    public function testIsRequested()
145
    {
146
        $manager = new Manager();
147
        $manager->parseIncludes(['foo', 'bar', 'baz.bart']);
148
149
        $scope = new Scope($manager, Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
150
151
        $this->assertTrue($scope->isRequested('foo'));
152
        $this->assertTrue($scope->isRequested('bar'));
153
        $this->assertTrue($scope->isRequested('baz'));
154
        $this->assertTrue($scope->isRequested('baz.bart'));
155
        $this->assertFalse($scope->isRequested('nope'));
156
157
        $childScope = $scope->embedChildScope('baz', Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
158
        $this->assertTrue($childScope->isRequested('bart'));
159
        $this->assertFalse($childScope->isRequested('foo'));
160
        $this->assertFalse($childScope->isRequested('bar'));
161
        $this->assertFalse($childScope->isRequested('baz'));
162
    }
163
164
    public function testIsExcluded()
165
    {
166
        $manager = new Manager();
167
        $manager->parseIncludes(['foo', 'bar', 'baz.bart']);
168
169
        $scope = new Scope($manager, Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
170
        $childScope = $scope->embedChildScope('baz', Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
0 ignored issues
show
Unused Code introduced by
$childScope 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...
171
172
        $manager->parseExcludes('bar');
173
174
        $this->assertFalse($scope->isExcluded('foo'));
175
        $this->assertTrue($scope->isExcluded('bar'));
176
        $this->assertFalse($scope->isExcluded('baz.bart'));
177
178
        $manager->parseExcludes('baz.bart');
179
180
        $this->assertFalse($scope->isExcluded('baz'));
181
        $this->assertTrue($scope->isExcluded('baz.bart'));
182
    }
183
184
    /**
185
     * @expectedException InvalidArgumentException
186
     */
187
    public function testScopeRequiresConcreteImplementation()
188
    {
189
        $manager = new Manager();
190
        $manager->parseIncludes('book');
191
192
        $resource = Mockery::mock('League\Fractal\Resource\ResourceAbstract', [
193
            ['bar' => 'baz'],
194
            function () {},
195
        ])->makePartial();
196
197
        $scope = new Scope($manager, $resource);
0 ignored issues
show
Documentation introduced by
$resource is of type object<Mockery\Mock>, but the function expects a object<League\Fractal\Resource\ResourceInterface>.

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...
198
        $scope->toArray();
199
    }
200
201
    public function testToArrayWithIncludes()
202
    {
203
        $manager = new Manager();
204
        $manager->parseIncludes('book');
205
206
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
207
        $transformer->shouldReceive('getAvailableIncludes')->twice()->andReturn(['book']);
208
        $transformer->shouldReceive('transform')->once()->andReturnUsing(function (array $data) {
209
            return $data;
210
        });
211
        $transformer->shouldReceive('processIncludedResources')->once()->andReturn(['book' => ['yin' => 'yang']]);
212
213
        $resource = new Item(['bar' => 'baz'], $transformer);
214
215
        $scope = new Scope($manager, $resource);
216
217
        $this->assertSame(['data' => ['bar' => 'baz', 'book' => ['yin' => 'yang']]], $scope->toArray());
218
    }
219
220
    public function testToArrayWithSideloadedIncludes()
221
    {
222
        $serializer = Mockery::mock('League\Fractal\Serializer\ArraySerializer')->makePartial();
223
        $serializer->shouldReceive('sideloadIncludes')->andReturn(true);
224
        $serializer->shouldReceive('item')->andReturnUsing(function ($key, $data) {
225
            return ['data' => $data];
226
        });
227
        $serializer->shouldReceive('includedData')->andReturnUsing(function ($key, $data) {
228
            return ['sideloaded' => array_pop($data)];
229
        });
230
231
        $manager = new Manager();
232
        $manager->parseIncludes('book');
233
        $manager->setSerializer($serializer);
0 ignored issues
show
Documentation introduced by
$serializer is of type object<Mockery\Mock>, but the function expects a object<League\Fractal\Se...zer\SerializerAbstract>.

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...
234
235
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
236
        $transformer->shouldReceive('getAvailableIncludes')->twice()->andReturn(['book']);
237
        $transformer->shouldReceive('transform')->once()->andReturnUsing(function (array $data) {
238
            return $data;
239
        });
240
        $transformer->shouldReceive('processIncludedResources')->once()->andReturn(['book' => ['yin' => 'yang']]);
241
242
        $resource = new Item(['bar' => 'baz'], $transformer);
243
244
        $scope = new Scope($manager, $resource);
245
246
        $expected = [
247
            'data' => ['bar' => 'baz'],
248
            'sideloaded' => ['book' => ['yin' => 'yang']],
249
        ];
250
251
        $this->assertSame($expected, $scope->toArray());
252
    }
253
254
    public function testPushParentScope()
255
    {
256
        $manager = new Manager();
257
258
        $resource = new Item(['name' => 'Larry Ullman'], function () {
259
        });
260
261
        $scope = new Scope($manager, $resource);
262
263
        $this->assertSame(1, $scope->pushParentScope('book'));
264
        $this->assertSame(2, $scope->pushParentScope('author'));
265
        $this->assertSame(3, $scope->pushParentScope('profile'));
266
267
268
        $this->assertSame(['book', 'author', 'profile'], $scope->getParentScopes());
269
    }
270
271
    public function testRunAppropriateTransformerWithItem()
272
    {
273
        $manager = new Manager();
274
275
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract');
276
        $transformer->shouldReceive('transform')->once()->andReturn($this->simpleItem);
277
        $transformer->shouldReceive('getAvailableIncludes')->once()->andReturn([]);
278
        $transformer->shouldReceive('getDefaultIncludes')->once()->andReturn([]);
279
        $transformer->shouldReceive('setCurrentScope')->once()->andReturn([]);
280
281
        $resource = new Item($this->simpleItem, $transformer);
282
        $scope = $manager->createData($resource);
283
284
        $this->assertSame(['data' => $this->simpleItem], $scope->toArray());
285
    }
286
287
    public function testRunAppropriateTransformerWithCollection()
288
    {
289
        $manager = new Manager();
290
291
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract');
292
        $transformer->shouldReceive('transform')->once()->andReturn(['foo' => 'bar']);
293
        $transformer->shouldReceive('getAvailableIncludes')->once()->andReturn([]);
294
        $transformer->shouldReceive('getDefaultIncludes')->once()->andReturn([]);
295
        $transformer->shouldReceive('setCurrentScope')->once()->andReturn([]);
296
297
        $resource = new Collection([['foo' => 'bar']], $transformer);
298
        $scope = $manager->createData($resource);
299
300
        $this->assertSame(['data' => [['foo' => 'bar']]], $scope->toArray());
301
302
    }
303
304
    /**
305
     * @covers \League\Fractal\Scope::executeResourceTransformers
306
     * @expectedException InvalidArgumentException
307
     * @expectedExceptionMessage Argument $resource should be an instance of League\Fractal\Resource\Item or League\Fractal\Resource\Collection
308
     */
309
    public function testCreateDataWithClassFuckKnows()
310
    {
311
        $manager = new Manager();
312
313
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
314
315
        $resource = Mockery::mock('League\Fractal\Resource\ResourceAbstract', [$this->simpleItem, $transformer])->makePartial();
316
        $scope = $manager->createData($resource);
317
        $scope->toArray();
318
    }
319
320
    public function testPaginatorOutput()
321
    {
322
        $manager = new Manager();
323
324
        $collection = new Collection([['foo' => 'bar', 'baz' => 'ban']], function (array $data) {
325
            return $data;
326
        });
327
328
        $paginator = Mockery::mock('League\Fractal\Pagination\IlluminatePaginatorAdapter')->makePartial();
329
330
        $total = 100;
331
        $perPage = $count = 5;
332
        $currentPage = 2;
333
        $lastPage = 20;
334
335
        $paginator->shouldReceive('getTotal')->once()->andReturn($total);
336
        $paginator->shouldReceive('getCount')->once()->andReturn($count);
337
        $paginator->shouldReceive('getPerPage')->once()->andReturn($perPage);
338
        $paginator->shouldReceive('getCurrentPage')->once()->andReturn($currentPage);
339
        $paginator->shouldReceive('getLastPage')->once()->andReturn($lastPage);
340
        $paginator->shouldReceive('getUrl')->times(2)->andReturnUsing(function ($page) {
341
            return 'http://example.com/foo?page='.$page;
342
        });
343
344
        $collection->setPaginator($paginator);
345
346
        $rootScope = $manager->createData($collection);
347
348
349
        $expectedOutput = [
350
            'data' => [
351
                [
352
                    'foo' => 'bar',
353
                    'baz' => 'ban',
354
                ],
355
            ],
356
            'meta' => [
357
                'pagination' => [
358
                    'total' => $total,
359
                    'count' => $count,
360
                    'per_page' => $perPage,
361
                    'current_page' => $currentPage,
362
                    'total_pages' => $lastPage,
363
                    'links' => [
364
                        'previous' => 'http://example.com/foo?page=1',
365
                        'next' => 'http://example.com/foo?page=3',
366
367
                    ],
368
                ],
369
            ],
370
        ];
371
372
        $this->assertSame($expectedOutput, $rootScope->toArray());
373
    }
374
375
    public function testCursorOutput()
376
    {
377
        $manager = new Manager();
378
379
        $inputData = [
380
            [
381
                'foo' => 'bar',
382
                'baz' => 'ban',
383
            ],
384
        ];
385
386
        $collection = new Collection($inputData, function (array $data) {
387
            return $data;
388
        });
389
390
        $cursor = new Cursor(0, 'ban', 'ban', 2);
391
392
        $collection->setCursor($cursor);
393
394
        $rootScope = $manager->createData($collection);
395
396
397
        $expectedOutput = [
398
            'data' => $inputData,
399
            'meta' => [
400
                'cursor' => [
401
                    'current' => 0,
402
                    'prev' => 'ban',
403
                    'next' => 'ban',
404
                    'count' => 2,
405
406
                ],
407
            ],
408
        ];
409
410
        $this->assertSame($expectedOutput, $rootScope->toArray());
411
    }
412
413 View Code Duplication
    public function testDefaultIncludeSuccess()
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...
414
    {
415
        $manager = new Manager();
416
        $manager->setSerializer(new ArraySerializer());
417
418
        // Send this stub junk, it has a specific format anyhow
419
        $resource = new Item([], new DefaultIncludeBookTransformer());
420
421
        // Try without metadata
422
        $scope = new Scope($manager, $resource);
423
424
        $expected = [
425
            'a' => 'b',
426
            'author' => [
427
                'c' => 'd',
428
            ],
429
        ];
430
431
        $this->assertSame($expected, $scope->toArray());
432
    }
433
434
    public function testNullResourceIncludeSuccess()
435
    {
436
        $manager = new Manager();
437
        $manager->setSerializer(new ArraySerializerWithNull);
438
439
        // Send this stub junk, it has a specific format anyhow
440
        $resource = new Item([], new NullIncludeBookTransformer);
441
442
        // Try without metadata
443
        $scope = new Scope($manager, $resource);
444
        $expected = [
445
            'a' => 'b',
446
            'author' => null,
447
        ];
448
449
        $this->assertSame($expected, $scope->toArray());
450
    }
451
452
    /**
453
     * @covers \League\Fractal\Scope::toArray
454
     */
455 View Code Duplication
    public function testNullResourceDataAndJustMeta()
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...
456
    {
457
        $manager = new Manager();
458
        $manager->setSerializer(new ArraySerializerWithNull);
459
460
        $resource = new NullResource();
461
        $resource->setMeta(['foo' => 'bar']);
462
463
        $scope = new Scope($manager, $resource);
464
465
        $this->assertSame(['meta' => ['foo' => 'bar']], $scope->toArray());
466
    }
467
468
    public function tearDown()
469
    {
470
        Mockery::close();
471
    }
472
}
473