Completed
Push — feature/CVE-2016-4423-symfony-... ( 29fbe6...7c6f71 )
by Lucas
22:10 queued 12:30
created

ShowcaseControllerTest::testExtraFieldPost()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 25
rs 8.8571
cc 1
eloc 18
nc 1
nop 0
1
<?php
2
/**
3
 * functional test for /hans/showcase
4
 */
5
6
namespace Graviton\CoreBundle\Tests\Controller;
7
8
use Graviton\TestBundle\Test\RestTestCase;
9
use Symfony\Component\HttpFoundation\Response;
10
11
/**
12
 * Functional test for /hans/showcase
13
 *
14
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
15
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
16
 * @link     http://swisscom.ch
17
 */
18
class ShowcaseControllerTest extends RestTestCase
19
{
20
    /**
21
     * @const complete content type string expected on a resouce
22
     */
23
    const CONTENT_TYPE = 'application/json; charset=UTF-8; profile=http://localhost/schema/hans/showcase/item';
24
25
    /**
26
     * @const corresponding vendorized schema mime type
27
     */
28
    const COLLECTION_TYPE = 'application/json; charset=UTF-8; profile=http://localhost/schema/hans/showcase/collection';
29
30
    /**
31
     * suppress setup client and load fixtures of parent class
32
     *
33
     * @return void
34
     */
35
    public function setUp()
36
    {
37
    }
38
39
    /**
40
     * checks empty objects
41
     *
42
     * @return void
43
     */
44
    public function testGetEmptyObject()
45
    {
46
        $showCase = (object) [
47
            'anotherInt'            => 100,
48
            'aBoolean'              => true,
49
            'testField'             => ['en' => 'test'],
50
            'someOtherField'        => ['en' => 'other'],
51
            'contactCode'           => [
52
                'someDate'          => '2015-06-07T06:30:00+0000',
53
                'text'              => ['en' => 'text'],
54
            ],
55
            'contact'               => [
56
                'type'      => 'type',
57
                'value'     => 'value',
58
                'protocol'  => 'protocol',
59
                'uri'       => 'protocol:value',
60
            ],
61
62
            'nestedApps'            => [],
63
            'unstructuredObject'    => (object) [],
64
            'choices'               => "<>"
65
        ];
66
67
        $client = static::createRestClient();
68
        $client->post('/hans/showcase/', $showCase);
69
        $this->assertEquals(Response::HTTP_CREATED, $client->getResponse()->getStatusCode());
70
        $this->assertNull($client->getResults());
71
72
        $url = $client->getResponse()->headers->get('Location');
73
        $this->assertNotNull($url);
74
75
        $client = static::createRestClient();
76
        $client->request('GET', $url);
77
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
78
79
        $created = $client->getResults();
80
        $this->assertEquals($showCase->nestedApps, $created->nestedApps);
81
        $this->assertEquals($showCase->unstructuredObject, $created->unstructuredObject);
82
    }
83
84
    /**
85
     * see how our missing fields are explained to us
86
     *
87
     * @return void
88
     */
89
    public function testMissingFields()
90
    {
91
        $document = json_decode(
92
            file_get_contents(dirname(__FILE__).'/../resources/showcase-incomplete.json'),
93
            true
94
        );
95
96
        $client = static::createRestClient();
97
        $client->post('/hans/showcase', $document);
98
99
        $expectedErrors = [];
100
        $notNullError = new \stdClass();
101
        $notNullError->propertyPath = 'data.aBoolean';
102
        $notNullError->message = 'The value "" is not a valid boolean.';
103
        $expectedErrors[] = $notNullError;
104
        // test choices field (string should not be blank)
105
        $notNullErrorChoices = new \stdClass();
106
        $notNullErrorChoices->propertyPath = 'data.choices';
107
        $notNullErrorChoices->message = 'This value should not be blank.';
108
        $expectedErrors[] = $notNullErrorChoices;
109
110
        $this->assertJsonStringEqualsJsonString(
111
            json_encode($expectedErrors),
112
            json_encode($client->getResults())
113
        );
114
    }
115
116
    /**
117
     * see how our empty fields are explained to us
118
     *
119
     * @return void
120
     */
121
    public function testEmptyAllFields()
122
    {
123
        $document = [
124
            'anotherInt'  => 6555488894525,
125
            'testField'   => ['en' => 'a test string'],
126
            'aBoolean'    => '',
127
            'contactCode' => [
128
                'text'     => ['en' => 'Some Text'],
129
                'someDate' => '1984-05-01T00:00:00+0000',
130
            ],
131
            'contact'     => [
132
                'type'      => '',
133
                'value'     => '',
134
                'protocol'  => '',
135
            ],
136
        ];
137
138
        $client = static::createRestClient();
139
        $client->post('/hans/showcase', $document);
140
141
        $this->assertEquals(
142
            Response::HTTP_BAD_REQUEST,
143
            $client->getResponse()->getStatusCode()
144
        );
145
146
        $this->assertEquals(
147
            [
148
                (object) [
149
                    'propertyPath'  => 'data.aBoolean',
150
                    'message'       => 'The value "" is not a valid boolean.',
151
                ],
152
                (object) [
153
                    'propertyPath'  => 'data.choices',
154
                    'message'       => 'This value should not be blank.',
155
                ],
156
                (object) [
157
                    'propertyPath'  => 'data.contact.type',
158
                    'message'       => 'This value should not be blank.',
159
                ],
160
                (object) [
161
                    'propertyPath'  => 'data.contact.protocol',
162
                    'message'       => 'This value should not be blank.',
163
                ],
164
                (object) [
165
                    'propertyPath'  => 'data.contact.value',
166
                    'message'       => 'This value should not be blank.',
167
                ],
168
            ],
169
            $client->getResults()
170
        );
171
    }
172
173
    /**
174
     * see how our empty fields are explained to us
175
     *
176
     * @return void
177
     */
178
    public function testEmptyFields()
179
    {
180
        $document = [
181
            'anotherInt'  => 6555488894525,
182
            'testField'   => ['en' => 'a test string'],
183
            'aBoolean'    => true,
184
            'contactCode' => [
185
                'text'     => ['en' => 'Some Text'],
186
                'someDate' => '1984-05-01T00:00:00+0000',
187
            ],
188
            'contact'     => [
189
                'type'      => 'abc',
190
                'value'     => '',
191
                'protocol'  => '',
192
            ],
193
        ];
194
195
        $client = static::createRestClient();
196
        $client->post('/hans/showcase', $document);
197
198
        $this->assertEquals(
199
            Response::HTTP_BAD_REQUEST,
200
            $client->getResponse()->getStatusCode()
201
        );
202
203
        $this->assertEquals(
204
            [
205
                (object) [
206
                    'propertyPath'  => 'data.choices',
207
                    'message'       => 'This value should not be blank.',
208
                ],
209
                (object) [
210
                    'propertyPath'  => 'data.contact.protocol',
211
                    'message'       => 'This value should not be blank.',
212
                ],
213
                (object) [
214
                    'propertyPath'  => 'data.contact.value',
215
                    'message'       => 'This value should not be blank.',
216
                ],
217
            ],
218
            $client->getResults()
219
        );
220
    }
221
222
    /**
223
     * insert various formats to see if all works as expected
224
     *
225
     * @dataProvider postCreationDataProvider
226
     *
227
     * @param string $filename filename
228
     *
229
     * @return void
230
     */
231
    public function testPost($filename)
232
    {
233
        // showcase contains some datetime fields that we need rendered as UTC in the case of this test
234
        ini_set('date.timezone', 'UTC');
235
        $document = json_decode(
236
            file_get_contents($filename),
237
            false
238
        );
239
240
        $client = static::createRestClient();
241
        $client->post('/hans/showcase/', $document);
242
        $response = $client->getResponse();
243
244
        $this->assertEquals(Response::HTTP_CREATED, $response->getStatusCode());
245
246
        $client = static::createRestClient();
247
        $client->request('GET', $response->headers->get('Location'));
248
249
        $result = $client->getResults();
250
251
        // unset id as we cannot compare and don't care
252
        $this->assertNotNull($result->id);
253
        unset($result->id);
254
255
        $this->assertJsonStringEqualsJsonString(
256
            json_encode($document),
257
            json_encode($result)
258
        );
259
    }
260
261
    /**
262
     * Provides test sets for the testPost() test.
263
     *
264
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string[]>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
265
     */
266
    public function postCreationDataProvider()
267
    {
268
        $basePath = dirname(__FILE__).'/../resources/';
269
270
        return array(
271
            'minimal' => array($basePath.'showcase-minimal.json'),
272
            'complete' => array($basePath.'showcase-complete.json')
273
        );
274
    }
275
276
    /**
277
     * test if we can save & retrieve extrefs inside 'free form objects'
278
     *
279
     * @return void
280
     */
281
    public function testFreeFormExtRefs()
282
    {
283
        $minimalExample = $this->postCreationDataProvider()['minimal'][0];
284
285
        $document = json_decode(
286
            file_get_contents($minimalExample),
287
            false
288
        );
289
290
        $document->id = 'dynextreftest';
291
292
        // insert some refs!
293
        $document->unstructuredObject = new \stdClass();
294
        $document->unstructuredObject->testRef = new \stdClass();
295
        $document->unstructuredObject->testRef->{'$ref'} = 'http://localhost/hans/showcase/500';
296
297
        // let's go more deep..
298
        $document->unstructuredObject->go = new \stdClass();
299
        $document->unstructuredObject->go->more = new \stdClass();
300
        $document->unstructuredObject->go->more->deep = new \stdClass();
301
        $document->unstructuredObject->go->more->deep->{'$ref'} = 'http://localhost/hans/showcase/500';
302
303
        // array?
304
        $document->unstructuredObject->refArray = [];
305
        $document->unstructuredObject->refArray[0] = new \stdClass();
306
        $document->unstructuredObject->refArray[0]->{'$ref'} = 'http://localhost/core/app/dude';
307
        $document->unstructuredObject->refArray[1] = new \stdClass();
308
        $document->unstructuredObject->refArray[1]->{'$ref'} = 'http://localhost/core/app/dude2';
309
310
        $client = static::createRestClient();
311
        $client->put('/hans/showcase/'.$document->id, $document);
312
313
        $this->assertEquals(204, $client->getResponse()->getStatusCode());
314
315
        $client = static::createRestClient();
316
        $client->request('GET', '/hans/showcase/'.$document->id);
317
318
        // all still the same?
319
        $this->assertEquals($document, $client->getResults());
320
    }
321
322
    /**
323
     * are extra fields denied?
324
     *
325
     * @return void
326
     */
327
    public function testExtraFieldPost()
328
    {
329
        ini_set('date.timezone', 'UTC');
330
        $document = json_decode(
331
            file_get_contents(dirname(__FILE__).'/../resources/showcase-minimal.json'),
332
            false
333
        );
334
        $document->extraFields = "nice field";
335
        $document->anotherExtraField = "one more";
336
337
        $client = static::createRestClient();
338
        $client->post('/hans/showcase', $document);
339
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
340
341
        $expectedErrors = [];
342
        $expectedErrors[0] = new \stdClass();
343
        $expectedErrors[0]->propertyPath = "";
344
        $expectedErrors[0]->message = 'This form should not contain extra fields like '.
345
            '"extraFields", "anotherExtraField".';
346
347
        $this->assertJsonStringEqualsJsonString(
348
            json_encode($expectedErrors),
349
            json_encode($client->getResults())
350
        );
351
    }
352
353
    /**
354
     * Test RQL select statement
355
     *
356
     * @return void
357
     */
358
    public function testRqlSelect()
359
    {
360
        $this->loadFixtures(
361
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
362
            null,
363
            'doctrine_mongodb'
364
        );
365
366
        $filtred = json_decode(
367
            file_get_contents(dirname(__FILE__).'/../resources/showcase-rql-select-filtred.json'),
368
            false
369
        );
370
371
        $fields = [
372
            'someFloatyDouble',
373
            'contact.uri',
374
            'contactCode.text.en',
375
            'unstructuredObject.booleanField',
376
            'unstructuredObject.hashField.someField',
377
            'unstructuredObject.nestedArrayField.anotherField',
378
            'nestedCustomers.$ref',
379
            'choices'
380
        ];
381
        $rqlSelect = 'select('.implode(',', array_map([$this, 'encodeRqlString'], $fields)).')';
382
383
        $client = static::createRestClient();
384
        $client->request('GET', '/hans/showcase/?'.$rqlSelect);
385
386
        $this->assertEquals($filtred, $client->getResults());
387
388
389
        foreach ([
390
                     '500' => $filtred[0],
391
                     '600' => $filtred[1],
392
                 ] as $id => $item) {
393
            $client = static::createRestClient();
394
            $client->request('GET', '/hans/showcase/'.$id.'?'.$rqlSelect);
395
            $this->assertEquals($item, $client->getResults());
396
        }
397
    }
398
399
    /**
400
     * Test to see if we can do like() searches on identifier fields
401
     *
402
     * @return void
403
     */
404
    public function testLikeSearchOnIdentifierField()
405
    {
406
        // Load fixtures
407
        $this->loadFixtures(
408
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
409
            null,
410
            'doctrine_mongodb'
411
        );
412
413
        $client = static::createRestClient();
414
        $client->request('GET', '/hans/showcase/?like(id,5*)');
415
416
        // we should only get 1 ;-)
417
        $this->assertEquals(1, count($client->getResults()));
418
419
        $client = static::createRestClient();
420
        $client->request('GET', '/hans/showcase/?like(id,*0)');
421
422
        // this should get both
423
        $this->assertEquals(2, count($client->getResults()));
424
    }
425
426
    /**
427
     * Test PATCH for deep nested attribute
428
     *
429
     * @return void
430
     */
431 View Code Duplication
    public function testPatchDeepNestedProperty()
432
    {
433
        // Load fixtures
434
        $this->loadFixtures(
435
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
436
            null,
437
            'doctrine_mongodb'
438
        );
439
440
        // Apply PATCH request
441
        $client = static::createRestClient();
442
        $patchJson = json_encode(
443
            [
444
                [
445
                    'op' => 'replace',
446
                    'path' => '/unstructuredObject/hashField/anotherField',
447
                    'value' => 'changed nested hash field with patch'
448
                ]
449
            ]
450
        );
451
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
452
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
453
454
        // Get changed showcase
455
        $client = static::createRestClient();
456
        $client->request('GET', '/hans/showcase/500');
457
458
        $result = $client->getResults();
459
        $this->assertEquals(
460
            'changed nested hash field with patch',
461
            $result->unstructuredObject->hashField->anotherField
462
        );
463
    }
464
465
    /**
466
     * Test success PATCH method - response headers contains link to resource
467
     *
468
     * @return void
469
     */
470
    public function testPatchSuccessResponseHeaderContainsResourceLink()
471
    {
472
        // Load fixtures
473
        $this->loadFixtures(
474
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
475
            null,
476
            'doctrine_mongodb'
477
        );
478
479
        // Apply PATCH request
480
        $client = static::createRestClient();
481
        $patchJson = json_encode(
482
            [
483
                [
484
                    'op' => 'replace',
485
                    'path' => '/testField/en',
486
                    'value' => 'changed value'
487
                ]
488
            ]
489
        );
490
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
491
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
492
493
        $this->assertEquals(
494
            '/hans/showcase/500',
495
            $client->getResponse()->headers->get('Content-Location')
496
        );
497
    }
498
499
    /**
500
     * Test PATCH method - remove/change ID not allowed
501
     *
502
     * @return void
503
     */
504
    public function testPatchRemoveAndChangeIdNotAllowed()
505
    {
506
        // Load fixtures
507
        $this->loadFixtures(
508
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
509
            null,
510
            'doctrine_mongodb'
511
        );
512
513
        // Apply PATCH request
514
        $client = static::createRestClient();
515
        $patchJson = json_encode(
516
            [
517
                [
518
                    'op' => 'remove',
519
                    'path' => '/id'
520
                ]
521
            ]
522
        );
523
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
524
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
525
    }
526
527
    /**
528
     * Test PATCH: add property to free object structure
529
     *
530
     * @return void
531
     */
532 View Code Duplication
    public function testPatchAddPropertyToFreeObject()
533
    {
534
        // Load fixtures
535
        $this->loadFixtures(
536
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
537
            null,
538
            'doctrine_mongodb'
539
        );
540
541
        // Apply PATCH request
542
        $client = static::createRestClient();
543
        $patchJson = json_encode(
544
            [
545
                [
546
                    'op' => 'add',
547
                    'path' => '/unstructuredObject/hashField/newAddedField',
548
                    'value' => 'new field value'
549
                ]
550
            ]
551
        );
552
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
553
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
554
555
        // Get changed showcase
556
        $client = static::createRestClient();
557
        $client->request('GET', '/hans/showcase/500');
558
559
        $result = $client->getResults();
560
        $this->assertEquals(
561
            'new field value',
562
            $result->unstructuredObject->hashField->newAddedField
563
        );
564
    }
565
566
    /**
567
     * Test PATCH for $ref attribute
568
     *
569
     * @return void
570
     * @incomplete
571
     */
572 View Code Duplication
    public function testApplyPatchForRefAttribute()
573
    {
574
        // Load fixtures
575
        $this->loadFixtures(
576
            [
577
                'GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'
578
            ],
579
            null,
580
            'doctrine_mongodb'
581
        );
582
583
        // Apply PATCH request
584
        $client = static::createRestClient();
585
        $patchJson = json_encode(
586
            [
587
                [
588
                    'op' => 'replace',
589
                    'path' => '/nestedApps/0/$ref',
590
                    'value' => 'http://localhost/core/app/admin'
591
                ]
592
            ]
593
        );
594
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
595
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
596
597
        // Check patched result
598
        $client = static::createRestClient();
599
        $client->request('GET', '/hans/showcase/500');
600
601
        $result = $client->getResults();
602
        $this->assertEquals(
603
            'http://localhost/core/app/admin',
604
            $result->nestedApps[0]->{'$ref'}
605
        );
606
    }
607
608
    /**
609
     * Test PATCH: apply patch which results to invalid Showcase schema
610
     *
611
     * @return void
612
     */
613
    public function testPatchToInvalidShowcase()
614
    {
615
        // Load fixtures
616
        $this->loadFixtures(
617
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
618
            null,
619
            'doctrine_mongodb'
620
        );
621
622
        // Apply PATCH request, remove required field
623
        $client = static::createRestClient();
624
        $patchJson = json_encode(
625
            [
626
                [
627
                    'op' => 'remove',
628
                    'path' => '/anotherInt'
629
                ]
630
            ]
631
        );
632
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
633
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
634
635
        // Check that Showcase has not been changed
636
        $client = static::createRestClient();
637
        $client->request('GET', '/hans/showcase/500');
638
639
        $result = $client->getResults();
640
        $this->assertObjectHasAttribute('anotherInt', $result);
641
    }
642
643
    /**
644
     * Test PATCH: remove element from array
645
     *
646
     * @return void
647
     */
648 View Code Duplication
    public function testRemoveFromArrayPatch()
649
    {
650
        // Load fixtures
651
        $this->loadFixtures(
652
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
653
            null,
654
            'doctrine_mongodb'
655
        );
656
657
        // Apply PATCH request, remove nested app, initially there are 2 apps
658
        $client = static::createRestClient();
659
        $patchJson = json_encode(
660
            [
661
                [
662
                    'op' => 'remove',
663
                    'path' => '/nestedApps/0'
664
                ]
665
            ]
666
        );
667
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
668
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
669
670
        // Check patched result
671
        $client = static::createRestClient();
672
        $client->request('GET', '/hans/showcase/500');
673
674
        $result = $client->getResults();
675
        $this->assertEquals(1, count($result->nestedApps));
676
        $this->assertEquals('http://localhost/core/app/admin', $result->nestedApps[0]->{'$ref'});
677
    }
678
679
    /**
680
     * Test PATCH: add new element to array
681
     *
682
     * @return void
683
     */
684
    public function testAddElementToSpecificIndexInArrayPatch()
685
    {
686
        // Load fixtures
687
        $this->loadFixtures(
688
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
689
            null,
690
            'doctrine_mongodb'
691
        );
692
693
        // Apply PATCH request, add new element
694
        $client = static::createRestClient();
695
        $newElement = ['name' => 'element three'];
696
        $patchJson = json_encode(
697
            [
698
                [
699
                    'op' => 'add',
700
                    'path' => '/nestedArray/1',
701
                    'value' => $newElement
702
                ]
703
            ]
704
        );
705
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
706
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
707
708
        // Check patched result
709
        $client = static::createRestClient();
710
        $client->request('GET', '/hans/showcase/500');
711
712
        $result = $client->getResults();
713
        $this->assertEquals(3, count($result->nestedArray));
714
        $this->assertJsonStringEqualsJsonString(
715
            json_encode($newElement),
716
            json_encode($result->nestedArray[1])
717
        );
718
    }
719
720
    /**
721
     * Test PATCH: add complex object App to array
722
     *
723
     * @group ref
724
     * @return void
725
     */
726 View Code Duplication
    public function testPatchAddComplexObjectToSpecificIndexInArray()
727
    {
728
        // Load fixtures
729
        $this->loadFixtures(
730
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
731
            null,
732
            'doctrine_mongodb'
733
        );
734
735
        // Apply PATCH request, add new element
736
        $client = static::createRestClient();
737
        $newApp = ['ref' => 'http://localhost/core/app/admin'];
738
        $patchJson = json_encode(
739
            [
740
                [
741
                    'op' => 'add',
742
                    'path' => '/nestedApps/0',
743
                    'value' => $newApp
744
                ]
745
            ]
746
        );
747
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
748
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
749
750
        // Check patched result
751
        $client = static::createRestClient();
752
        $client->request('GET', '/hans/showcase/500');
753
754
        $result = $client->getResults();
755
        $this->assertEquals(3, count($result->nestedApps));
756
        $this->assertEquals(
757
            'http://localhost/core/app/admin',
758
            $result->nestedApps[0]->{'$ref'}
759
        );
760
    }
761
762
    /**
763
     * Test PATCH: add complex object App to array
764
     *
765
     * @group ref
766
     * @return void
767
     */
768 View Code Duplication
    public function testPatchAddComplexObjectToTheEndOfArray()
769
    {
770
        // Load fixtures
771
        $this->loadFixtures(
772
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
773
            null,
774
            'doctrine_mongodb'
775
        );
776
777
        // Apply PATCH request, add new element
778
        $client = static::createRestClient();
779
        $newApp = ['ref' => 'http://localhost/core/app/test'];
780
        $patchJson = json_encode(
781
            [
782
                [
783
                    'op' => 'add',
784
                    'path' => '/nestedApps/-',
785
                    'value' => $newApp
786
                ]
787
            ]
788
        );
789
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
790
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
791
792
        // Check patched result
793
        $client = static::createRestClient();
794
        $client->request('GET', '/hans/showcase/500');
795
796
        $result = $client->getResults();
797
        $this->assertEquals(3, count($result->nestedApps));
798
        $this->assertEquals(
799
            'http://localhost/core/app/test',
800
            $result->nestedApps[2]->{'$ref'}
801
        );
802
    }
803
804
    /**
805
     * Test PATCH: test operation to undefined index
806
     *
807
     * @group ref
808
     * @return void
809
     */
810
    public function testPatchTestOperationToUndefinedIndexThrowsException()
811
    {
812
        // Load fixtures
813
        $this->loadFixtures(
814
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
815
            null,
816
            'doctrine_mongodb'
817
        );
818
819
        // Apply PATCH request, add new element
820
        $client = static::createRestClient();
821
        $newApp = ['ref' => 'http://localhost/core/app/test'];
822
        $patchJson = json_encode(
823
            [
824
                [
825
                    'op' => 'test',
826
                    'path' => '/nestedApps/9',
827
                    'value' => $newApp
828
                ]
829
            ]
830
        );
831
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
832
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
833
    }
834
835
    /**
836
     * Test PATCH: add complex object App to array
837
     *
838
     * @group ref
839
     * @return void
840
     */
841
    public function testPatchAddElementToUndefinedIndexResponseAsBadRequest()
842
    {
843
        // Load fixtures
844
        $this->loadFixtures(
845
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
846
            null,
847
            'doctrine_mongodb'
848
        );
849
850
        // Apply PATCH request, add new element
851
        $client = static::createRestClient();
852
        $newApp = ['ref' => 'http://localhost/core/app/admin'];
853
        $patchJson = json_encode(
854
            [
855
                [
856
                    'op' => 'add',
857
                    'path' => '/nestedApps/9',
858
                    'value' => $newApp
859
                ]
860
            ]
861
        );
862
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
863
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
864
865
        // Check that patched document not changed
866
        $client = static::createRestClient();
867
        $client->request('GET', '/hans/showcase/500');
868
869
        $result = $client->getResults();
870
        $this->assertEquals(2, count($result->nestedApps));
871
    }
872
873
    /**
874
     * Encode string value in RQL
875
     *
876
     * @param string $value String value
877
     * @return string
878
     */
879 View Code Duplication
    private function encodeRqlString($value)
880
    {
881
        return strtr(
882
            rawurlencode($value),
883
            [
884
                '-' => '%2D',
885
                '_' => '%5F',
886
                '.' => '%2E',
887
                '~' => '%7E',
888
            ]
889
        );
890
    }
891
892
    /**
893
     * Trigger a 301 Status code
894
     *
895
     * @param string $url         requested url
896
     * @param string $redirectUrl redirected url
897
     * @dataProvider rqlDataProvider
898
     * @return void
899
     */
900
    public function testTrigger301($url, $redirectUrl)
901
    {
902
        $client = static::createRestClient();
903
        $client->request('GET', $url);
904
        $this->assertEquals(301, $client->getResponse()->getStatusCode());
905
        $this->assertEquals($redirectUrl, $client->getResponse()->headers->get('Location'));
906
    }
907
908
    /**
909
     * Provides urls for the testTrigger301() test.
910
     *
911
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array<string,string>>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
912
     */
913
    public function rqlDataProvider()
914
    {
915
        return [
916
            'rql' => ['url' => '/hans/showcase?id=blah' , 'redirect_url' => 'http://localhost/hans/showcase/?id=blah'],
917
            'noRql' => ['url' => '/hans/showcase' , 'redirect_url' => 'http://localhost/hans/showcase/']
918
        ];
919
    }
920
921
    /**
922
     * test finding of showcases by ref
923
     *
924
     * @dataProvider findByExtrefProvider
925
     *
926
     * @param string  $field which reference to search in
927
     * @param mixed   $url   ref to search for
928
     * @param integer $count number of results to expect
929
     *
930
     * @return void
931
     */
932
    public function testFindByExtref($field, $url, $count)
933
    {
934
        $this->loadFixtures(
935
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
936
            null,
937
            'doctrine_mongodb'
938
        );
939
940
        $url = sprintf(
941
            '/hans/showcase/?%s=%s',
942
            $this->encodeRqlString($field),
943
            $this->encodeRqlString($url)
944
        );
945
946
        $client = static::createRestClient();
947
        $client->request('GET', $url);
948
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
949
        $this->assertCount($count, $client->getResults());
950
    }
951
952
    /**
953
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array<string|integer>>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
954
     */
955 View Code Duplication
    public function findByExtrefProvider()
956
    {
957
        return [
958
            'find a linked record when searching for "tablet" ref by array field' => [
959
                'nestedApps.0.$ref',
960
                'http://localhost/core/app/tablet',
961
                1
962
            ],
963
            'find a linked record when searching for "admin" ref by array field' => [
964
                'nestedApps.0.$ref',
965
                'http://localhost/core/app/admin',
966
                1
967
            ],
968
            'find nothing when searching for inextistant (and unlinked) ref by array field' => [
969
                'nestedApps.0.$ref',
970
                'http://localhost/core/app/inexistant',
971
                0
972
            ],
973
            'return nothing when searching with incomplete ref by array field' => [
974
                'nestedApps.0.$ref',
975
                'http://localhost/core/app',
976
                0
977
            ],
978
        ];
979
    }
980
}
981