Completed
Pull Request — master (#296)
by Josh
03:05
created

ScopeTest::testEmbedChildScope()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 13
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\Transformer\DefaultIncludeBookTransformer;
11
use Mockery;
12
13
class ScopeTest extends \PHPUnit_Framework_TestCase
14
{
15
    protected $simpleItem = ['foo' => 'bar'];
16
    protected $simpleCollection = [['foo' => 'bar']];
17
18
    public function testEmbedChildScope()
19
    {
20
        $manager = new Manager();
21
22
        $resource = new Item(['foo' => 'bar'], function () {
23
        });
24
25
        $scope = new Scope($manager, $resource, 'book');
26
        $this->assertSame($scope->getScopeIdentifier(), 'book');
27
        $childScope = $scope->embedChildScope('author', $resource);
28
29
        $this->assertInstanceOf('League\Fractal\Scope', $childScope);
30
    }
31
32 View Code Duplication
    public function testGetManager()
33
    {
34
        $resource = new Item(['foo' => 'bar'], function () {
35
        });
36
37
        $scope = new Scope(new Manager(), $resource, 'book');
38
39
        $this->assertInstanceOf('League\Fractal\Manager', $scope->getManager());
40
    }
41
42 View Code Duplication
    public function testGetResource()
43
    {
44
        $resource = new Item(['foo' => 'bar'], function () {
45
        });
46
47
        $scope = new Scope(new Manager(), $resource, 'book');
48
49
        $this->assertInstanceOf('League\Fractal\Resource\ResourceAbstract', $scope->getResource());
50
        $this->assertInstanceOf('League\Fractal\Resource\Item', $scope->getResource());
51
    }
52
53
    /**
54
     * @covers League\Fractal\Scope::toArray
55
     */
56
    public function testToArray()
57
    {
58
        $manager = new Manager();
59
60
        $resource = new Item(['foo' => 'bar'], function ($data) {
61
            return $data;
62
        });
63
64
        $scope = new Scope($manager, $resource);
65
66
67
        $this->assertSame(['data' => ['foo' => 'bar']], $scope->toArray());
68
    }
69
70
    public function testToJson()
71
    {
72
        $data = [
73
            'foo' => 'bar',
74
        ];
75
76
        $manager = new Manager();
77
78
        $resource = new Item($data, function ($data) {
79
            return $data;
80
        });
81
82
        $scope = new Scope($manager, $resource);
83
84
        $expected = json_encode([
85
            'data' => $data,
86
        ]);
87
88
        $this->assertSame($expected, $scope->toJson());
89
    }
90
91 View Code Duplication
    public function testGetCurrentScope()
92
    {
93
        $manager = new Manager();
94
95
        $resource = new Item(['name' => 'Larry Ullman'], function () {
96
        });
97
98
        $scope = new Scope($manager, $resource, 'book');
99
        $this->assertSame('book', $scope->getScopeIdentifier());
100
101
        $childScope = $scope->embedChildScope('author', $resource);
102
        $this->assertSame('author', $childScope->getScopeIdentifier());
103
104
        $grandChildScope = $childScope->embedChildScope('profile', $resource);
105
        $this->assertSame('profile', $grandChildScope->getScopeIdentifier());
106
    }
107
108 View Code Duplication
    public function testGetIdentifier()
109
    {
110
        $manager = new Manager();
111
112
        $resource = new Item(['name' => 'Larry Ullman'], function () {
113
        });
114
115
        $scope = new Scope($manager, $resource, 'book');
116
        $this->assertSame('book', $scope->getIdentifier());
117
118
        $childScope = $scope->embedChildScope('author', $resource);
119
        $this->assertSame('book.author', $childScope->getIdentifier());
120
121
        $grandChildScope = $childScope->embedChildScope('profile', $resource);
122
        $this->assertSame('book.author.profile', $grandChildScope->getIdentifier());
123
    }
124
125
    public function testGetParentScopes()
126
    {
127
        $manager = new Manager();
128
129
        $resource = new Item(['name' => 'Larry Ullman'], function () {
130
        });
131
132
        $scope = new Scope($manager, $resource, 'book');
133
134
        $childScope = $scope->embedChildScope('author', $resource);
135
136
        $this->assertSame(['book'], $childScope->getParentScopes());
137
138
        $grandChildScope = $childScope->embedChildScope('profile', $resource);
139
        $this->assertSame(['book', 'author'], $grandChildScope->getParentScopes());
140
    }
141
142
    public function testIsRequested()
143
    {
144
        $manager = new Manager();
145
        $manager->parseIncludes(['foo', 'bar', 'baz.bart']);
146
147
        $scope = new Scope($manager, Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
148
149
        $this->assertTrue($scope->isRequested('foo'));
150
        $this->assertTrue($scope->isRequested('bar'));
151
        $this->assertTrue($scope->isRequested('baz'));
152
        $this->assertTrue($scope->isRequested('baz.bart'));
153
        $this->assertFalse($scope->isRequested('nope'));
154
155
        $childScope = $scope->embedChildScope('baz', Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
156
        $this->assertTrue($childScope->isRequested('bart'));
157
        $this->assertFalse($childScope->isRequested('foo'));
158
        $this->assertFalse($childScope->isRequested('bar'));
159
        $this->assertFalse($childScope->isRequested('baz'));
160
    }
161
162
    public function testIsExcluded()
163
    {
164
        $manager = new Manager();
165
        $manager->parseIncludes(['foo', 'bar', 'baz.bart']);
166
167
        $scope = new Scope($manager, Mockery::mock('League\Fractal\Resource\ResourceAbstract'));
168
        $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...
169
170
        $manager->parseExcludes('bar');
171
172
        $this->assertFalse($scope->isExcluded('foo'));
173
        $this->assertTrue($scope->isExcluded('bar'));
174
        $this->assertFalse($scope->isExcluded('baz.bart'));
175
176
        $manager->parseExcludes('baz.bart');
177
178
        $this->assertFalse($scope->isExcluded('baz'));
179
        $this->assertTrue($scope->isExcluded('baz.bart'));
180
    }
181
182
    /**
183
     * @expectedException InvalidArgumentException
184
     */
185
    public function testScopeRequiresConcreteImplementation()
186
    {
187
        $manager = new Manager();
188
        $manager->parseIncludes('book');
189
190
        $resource = Mockery::mock('League\Fractal\Resource\ResourceAbstract', [
191
            ['bar' => 'baz'],
192
            function () {},
193
        ])->makePartial();
194
195
        $scope = new Scope($manager, $resource);
196
        $scope->toArray();
197
    }
198
199
    public function testToArrayWithIncludes()
200
    {
201
        $manager = new Manager();
202
        $manager->parseIncludes('book');
203
204
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
205
        $transformer->shouldReceive('getAvailableIncludes')->twice()->andReturn(['book']);
206
        $transformer->shouldReceive('transform')->once()->andReturnUsing(function (array $data) {
207
            return $data;
208
        });
209
        $transformer->shouldReceive('processIncludedResources')->once()->andReturn(['book' => ['yin' => 'yang']]);
210
211
        $resource = new Item(['bar' => 'baz'], $transformer);
212
213
        $scope = new Scope($manager, $resource);
214
215
        $this->assertSame(['data' => ['bar' => 'baz', 'book' => ['yin' => 'yang']]], $scope->toArray());
216
    }
217
218
    public function testToArrayWithSideloadedIncludes()
219
    {
220
        $serializer = Mockery::mock('League\Fractal\Serializer\ArraySerializer')->makePartial();
221
        $serializer->shouldReceive('sideloadIncludes')->andReturn(true);
222
        $serializer->shouldReceive('item')->andReturnUsing(function ($key, $data) {
223
            return ['data' => $data];
224
        });
225
        $serializer->shouldReceive('includedData')->andReturnUsing(function ($key, $data) {
226
            return ['sideloaded' => array_pop($data)];
227
        });
228
229
        $manager = new Manager();
230
        $manager->parseIncludes('book');
231
        $manager->setSerializer($serializer);
232
233
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
234
        $transformer->shouldReceive('getAvailableIncludes')->twice()->andReturn(['book']);
235
        $transformer->shouldReceive('transform')->once()->andReturnUsing(function (array $data) {
236
            return $data;
237
        });
238
        $transformer->shouldReceive('processIncludedResources')->once()->andReturn(['book' => ['yin' => 'yang']]);
239
240
        $resource = new Item(['bar' => 'baz'], $transformer);
241
242
        $scope = new Scope($manager, $resource);
243
244
        $expected = [
245
            'data' => ['bar' => 'baz'],
246
            'sideloaded' => ['book' => ['yin' => 'yang']],
247
        ];
248
249
        $this->assertSame($expected, $scope->toArray());
250
    }
251
252
    public function testItCanReturnAnObject()
253
    {
254
        $serializer = Mockery::mock('League\Fractal\Serializer\ArraySerializer')->makePartial();
255
        $serializer->shouldReceive('null')->andReturn((object) []);
256
257
        $manager = new Manager();
258
        $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...
259
260
        $resource = new NullResource;
261
262
        $scope = new Scope($manager, $resource);
263
264
        $this->assertEquals((object) [], $scope->toArray());
265
    }
266
267
    public function testPushParentScope()
268
    {
269
        $manager = new Manager();
270
271
        $resource = new Item(['name' => 'Larry Ullman'], function () {
272
        });
273
274
        $scope = new Scope($manager, $resource);
275
276
        $this->assertSame(1, $scope->pushParentScope('book'));
277
        $this->assertSame(2, $scope->pushParentScope('author'));
278
        $this->assertSame(3, $scope->pushParentScope('profile'));
279
280
281
        $this->assertSame(['book', 'author', 'profile'], $scope->getParentScopes());
282
    }
283
284
    public function testRunAppropriateTransformerWithItem()
285
    {
286
        $manager = new Manager();
287
288
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract');
289
        $transformer->shouldReceive('transform')->once()->andReturn($this->simpleItem);
290
        $transformer->shouldReceive('getAvailableIncludes')->once()->andReturn([]);
291
        $transformer->shouldReceive('getDefaultIncludes')->once()->andReturn([]);
292
        $transformer->shouldReceive('setCurrentScope')->once()->andReturn([]);
293
294
        $resource = new Item($this->simpleItem, $transformer);
295
        $scope = $manager->createData($resource);
296
297
        $this->assertSame(['data' => $this->simpleItem], $scope->toArray());
298
    }
299
300
    public function testRunAppropriateTransformerWithCollection()
301
    {
302
        $manager = new Manager();
303
304
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract');
305
        $transformer->shouldReceive('transform')->once()->andReturn(['foo' => 'bar']);
306
        $transformer->shouldReceive('getAvailableIncludes')->once()->andReturn([]);
307
        $transformer->shouldReceive('getDefaultIncludes')->once()->andReturn([]);
308
        $transformer->shouldReceive('setCurrentScope')->once()->andReturn([]);
309
310
        $resource = new Collection([['foo' => 'bar']], $transformer);
311
        $scope = $manager->createData($resource);
312
313
        $this->assertSame(['data' => [['foo' => 'bar']]], $scope->toArray());
314
315
    }
316
317
    /**
318
     * @covers League\Fractal\Scope::executeResourceTransformers
319
     * @expectedException InvalidArgumentException
320
     * @expectedExceptionMessage Argument $resource should be an instance of League\Fractal\Resource\Item or League\Fractal\Resource\Collection
321
     */
322
    public function testCreateDataWithClassFuckKnows()
323
    {
324
        $manager = new Manager();
325
326
        $transformer = Mockery::mock('League\Fractal\TransformerAbstract')->makePartial();
327
328
        $resource = Mockery::mock('League\Fractal\Resource\ResourceAbstract', [$this->simpleItem, $transformer])->makePartial();
329
        $scope = $manager->createData($resource);
330
        $scope->toArray();
331
    }
332
333
    public function testPaginatorOutput()
334
    {
335
        $manager = new Manager();
336
337
        $collection = new Collection([['foo' => 'bar', 'baz' => 'ban']], function (array $data) {
338
            return $data;
339
        });
340
341
        $paginator = Mockery::mock('League\Fractal\Pagination\IlluminatePaginatorAdapter')->makePartial();
342
343
        $total = 100;
344
        $perPage = $count = 5;
345
        $currentPage = 2;
346
        $lastPage = 20;
347
348
        $paginator->shouldReceive('getTotal')->once()->andReturn($total);
349
        $paginator->shouldReceive('getCount')->once()->andReturn($count);
350
        $paginator->shouldReceive('getPerPage')->once()->andReturn($perPage);
351
        $paginator->shouldReceive('getCurrentPage')->once()->andReturn($currentPage);
352
        $paginator->shouldReceive('getLastPage')->once()->andReturn($lastPage);
353
        $paginator->shouldReceive('getUrl')->times(2)->andReturnUsing(function ($page) {
354
            return 'http://example.com/foo?page='.$page;
355
        });
356
357
        $collection->setPaginator($paginator);
358
359
        $rootScope = $manager->createData($collection);
360
361
362
        $expectedOutput = [
363
            'data' => [
364
                [
365
                    'foo' => 'bar',
366
                    'baz' => 'ban',
367
                ],
368
            ],
369
            'meta' => [
370
                'pagination' => [
371
                    'total' => $total,
372
                    'count' => $count,
373
                    'per_page' => $perPage,
374
                    'current_page' => $currentPage,
375
                    'total_pages' => $lastPage,
376
                    'links' => [
377
                        'previous' => 'http://example.com/foo?page=1',
378
                        'next' => 'http://example.com/foo?page=3',
379
380
                    ],
381
                ],
382
            ],
383
        ];
384
385
        $this->assertSame($expectedOutput, $rootScope->toArray());
386
    }
387
388
    public function testCursorOutput()
389
    {
390
        $manager = new Manager();
391
392
        $inputData = [
393
            [
394
                'foo' => 'bar',
395
                'baz' => 'ban',
396
            ],
397
        ];
398
399
        $collection = new Collection($inputData, function (array $data) {
400
            return $data;
401
        });
402
403
        $cursor = new Cursor(0, 'ban', 'ban', 2);
404
405
        $collection->setCursor($cursor);
406
407
        $rootScope = $manager->createData($collection);
408
409
410
        $expectedOutput = [
411
            'data' => $inputData,
412
            'meta' => [
413
                'cursor' => [
414
                    'current' => 0,
415
                    'prev' => 'ban',
416
                    'next' => 'ban',
417
                    'count' => 2,
418
419
                ],
420
            ],
421
        ];
422
423
        $this->assertSame($expectedOutput, $rootScope->toArray());
424
    }
425
426
    public function testDefaultIncludeSuccess()
427
    {
428
        $manager = new Manager();
429
        $manager->setSerializer(new ArraySerializer());
430
431
        // Send this stub junk, it has a specific format anyhow
432
        $resource = new Item([], new DefaultIncludeBookTransformer());
433
434
        // Try without metadata
435
        $scope = new Scope($manager, $resource);
436
437
        $expected = [
438
            'a' => 'b',
439
            'author' => [
440
                'c' => 'd',
441
            ],
442
        ];
443
444
        $this->assertSame($expected, $scope->toArray());
445
    }
446
447
    public function tearDown()
448
    {
449
        Mockery::close();
450
    }
451
}
452