Completed
Push — feature/other-validation ( 7c1fa1...b6df1c )
by Narcotic
62:33
created

ShowcaseControllerTest::testEmptyFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 47
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 47
rs 9.0303
cc 1
eloc 31
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\I18nBundle\DataFixtures\MongoDB\LoadLanguageData;
9
use Graviton\TestBundle\Test\RestTestCase;
10
use Symfony\Component\HttpFoundation\Response;
11
12
/**
13
 * Functional test for /hans/showcase
14
 *
15
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
16
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
17
 * @link     http://swisscom.ch
18
 */
19
class ShowcaseControllerTest extends RestTestCase
20
{
21
    /**
22
     * @const complete content type string expected on a resouce
23
     */
24
    const CONTENT_TYPE = 'application/json; charset=UTF-8; profile=http://localhost/schema/hans/showcase/item';
25
26
    /**
27
     * @const corresponding vendorized schema mime type
28
     */
29
    const COLLECTION_TYPE = 'application/json; charset=UTF-8; profile=http://localhost/schema/hans/showcase/collection';
30
31
    /**
32
     * suppress setup client and load fixtures of parent class
33
     *
34
     * @return void
35
     */
36
    public function setUp()
37
    {
38
        $this->loadFixtures(
39
            [
40
                LoadLanguageData::class
41
            ],
42
            null,
43
            'doctrine_mongodb'
44
        );
45
    }
46
47
    /**
48
     * checks empty objects
49
     *
50
     * @return void
51
     */
52
    public function testGetEmptyObject()
53
    {
54
        $showCase = (object) [
55
            'anotherInt'            => 100,
56
            'aBoolean'              => true,
57
            'testField'             => ['en' => 'test'],
58
            'someOtherField'        => ['en' => 'other'],
59
            'contactCode'           => [
60
                'someDate'          => '2015-06-07T06:30:00+0000',
61
                'text'              => ['en' => 'text'],
62
            ],
63
            'contact'               => [
64
                'type'      => 'type',
65
                'value'     => 'value',
66
                'protocol'  => 'protocol',
67
                'uri'       => 'protocol:value',
68
            ],
69
70
            'nestedApps'            => [],
71
            'unstructuredObject'    => (object) [],
72
            'choices'               => "<>"
73
        ];
74
75
        $client = static::createRestClient();
76
        $client->post('/hans/showcase/', $showCase);
77
        $this->assertEquals(Response::HTTP_CREATED, $client->getResponse()->getStatusCode());
78
        $this->assertNull($client->getResults());
79
80
        $url = $client->getResponse()->headers->get('Location');
81
        $this->assertNotNull($url);
82
83
        $client = static::createRestClient();
84
        $client->request('GET', $url);
85
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
86
87
        $created = $client->getResults();
88
        $this->assertEquals($showCase->nestedApps, $created->nestedApps);
89
        $this->assertEquals($showCase->unstructuredObject, $created->unstructuredObject);
90
    }
91
92
    /**
93
     * see how our missing fields are explained to us
94
     *
95
     * @return void
96
     */
97
    public function testMissingFields()
98
    {
99
        $document = json_decode(
100
            file_get_contents(dirname(__FILE__).'/../resources/showcase-incomplete.json'),
101
            true
102
        );
103
104
        $client = static::createRestClient();
105
        $client->post('/hans/showcase', $document);
106
107
        $expectedErrors = [];
108
        $notNullError = new \stdClass();
109
        $notNullError->propertyPath = 'aBoolean';
110
        $notNullError->message = 'The property aBoolean is required';
111
        $expectedErrors[] = $notNullError;
112
        // test choices field (string should not be blank)
113
        $notNullErrorChoices = new \stdClass();
114
        $notNullErrorChoices->propertyPath = 'choices';
115
        $notNullErrorChoices->message = 'The property choices is required';
116
        $expectedErrors[] = $notNullErrorChoices;
117
118
        $this->assertJsonStringEqualsJsonString(
119
            json_encode($expectedErrors),
120
            json_encode($client->getResults())
121
        );
122
    }
123
124
    /**
125
     * see how our empty fields are explained to us
126
     *
127
     * @return void
128
     */
129
    public function testEmptyAllFields()
130
    {
131
        $document = [
132
            'anotherInt'  => 6555488894525,
133
            'testField'   => ['en' => 'a test string'],
134
            'aBoolean'    => '',
135
            'contactCode' => [
136
                'text'     => ['en' => 'Some Text'],
137
                'someDate' => '1984-05-01T00:00:00+0000',
138
            ],
139
            'contact'     => [
140
                'type'      => '',
141
                'value'     => '',
142
                'protocol'  => '',
143
            ],
144
        ];
145
146
        $client = static::createRestClient();
147
        $client->post('/hans/showcase', $document);
148
149
        $this->assertEquals(
150
            Response::HTTP_BAD_REQUEST,
151
            $client->getResponse()->getStatusCode()
152
        );
153
154
        $this->assertEquals(
155
            [
156
                (object) [
157
                    'propertyPath'  => 'choices',
158
                    'message'       => 'The property choices is required',
159
                ],
160
                (object) [
161
                    'propertyPath'  => 'aBoolean',
162
                    'message'       => 'String value found, but a boolean is required',
163
                ],
164
                (object) [
165
                    'propertyPath'  => 'contact.uri',
166
                    'message'       => 'The property uri is required',
167
                ],
168
                (object) [
169
                    'propertyPath'  => 'contact.type',
170
                    'message'       => 'Must be at least 1 characters long',
171
                ],
172
                (object) [
173
                    'propertyPath'  => 'contact.protocol',
174
                    'message'       => 'Must be at least 1 characters long',
175
                ],
176
                (object) [
177
                    'propertyPath'  => 'contact.value',
178
                    'message'       => 'Must be at least 1 characters long',
179
                ]
180
            ],
181
            $client->getResults()
182
        );
183
    }
184
185
    /**
186
     * see how our empty fields are explained to us
187
     *
188
     * @return void
189
     */
190
    public function testEmptyFields()
191
    {
192
        $document = [
193
            'anotherInt'  => 6555488894525,
194
            'testField'   => ['en' => 'a test string'],
195
            'aBoolean'    => true,
196
            'contactCode' => [
197
                'text'     => ['en' => 'Some Text'],
198
                'someDate' => '1984-05-01T00:00:00+0000',
199
            ],
200
            'contact'     => [
201
                'type'      => 'abc',
202
                'value'     => '',
203
                'protocol'  => '',
204
            ],
205
        ];
206
207
        $client = static::createRestClient();
208
        $client->post('/hans/showcase', $document);
209
210
        $this->assertEquals(
211
            Response::HTTP_BAD_REQUEST,
212
            $client->getResponse()->getStatusCode()
213
        );
214
215
        $this->assertEquals(
216
            [
217
                (object) [
218
                    'propertyPath'  => 'choices',
219
                    'message'       => 'The property choices is required',
220
                ],
221
                (object) [
222
                    'propertyPath'  => 'contact.uri',
223
                    'message'       => 'The property uri is required',
224
                ],
225
                (object) [
226
                    'propertyPath'  => 'contact.protocol',
227
                    'message'       => 'Must be at least 1 characters long',
228
                ],
229
                (object) [
230
                    'propertyPath'  => 'contact.value',
231
                    'message'       => 'Must be at least 1 characters long',
232
                ],
233
            ],
234
            $client->getResults()
235
        );
236
    }
237
238
    /**
239
     * insert various formats to see if all works as expected
240
     *
241
     * @dataProvider postCreationDataProvider
242
     *
243
     * @param string $filename filename
244
     *
245
     * @return void
246
     */
247
    public function testPost($filename)
248
    {
249
        // showcase contains some datetime fields that we need rendered as UTC in the case of this test
250
        ini_set('date.timezone', 'UTC');
251
        $document = json_decode(
252
            file_get_contents($filename),
253
            false
254
        );
255
256
        $client = static::createRestClient();
257
        $client->post('/hans/showcase/', $document);
258
        $response = $client->getResponse();
259
260
        $this->assertEquals(Response::HTTP_CREATED, $response->getStatusCode());
261
262
        $client = static::createRestClient();
263
        $client->request('GET', $response->headers->get('Location'));
264
265
        $result = $client->getResults();
266
267
        // unset id as we cannot compare and don't care
268
        $this->assertNotNull($result->id);
269
        unset($result->id);
270
271
        $this->assertJsonStringEqualsJsonString(
272
            json_encode($document),
273
            json_encode($result)
274
        );
275
    }
276
277
    /**
278
     * Provides test sets for the testPost() test.
279
     *
280
     * @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...
281
     */
282
    public function postCreationDataProvider()
283
    {
284
        $basePath = dirname(__FILE__).'/../resources/';
285
286
        return array(
287
            'minimal' => array($basePath.'showcase-minimal.json'),
288
            'complete' => array($basePath.'showcase-complete.json')
289
        );
290
    }
291
292
    /**
293
     * test if we can save & retrieve extrefs inside 'free form objects'
294
     *
295
     * @return void
296
     */
297
    public function testFreeFormExtRefs()
298
    {
299
        $minimalExample = $this->postCreationDataProvider()['minimal'][0];
300
301
        $document = json_decode(
302
            file_get_contents($minimalExample),
303
            false
304
        );
305
306
        $document->id = 'dynextreftest';
307
308
        // insert some refs!
309
        $document->unstructuredObject = new \stdClass();
310
        $document->unstructuredObject->testRef = new \stdClass();
311
        $document->unstructuredObject->testRef->{'$ref'} = 'http://localhost/hans/showcase/500';
312
313
        // let's go more deep..
314
        $document->unstructuredObject->go = new \stdClass();
315
        $document->unstructuredObject->go->more = new \stdClass();
316
        $document->unstructuredObject->go->more->deep = new \stdClass();
317
        $document->unstructuredObject->go->more->deep->{'$ref'} = 'http://localhost/hans/showcase/500';
318
319
        // array?
320
        $document->unstructuredObject->refArray = [];
321
        $document->unstructuredObject->refArray[0] = new \stdClass();
322
        $document->unstructuredObject->refArray[0]->{'$ref'} = 'http://localhost/core/app/dude';
323
        $document->unstructuredObject->refArray[1] = new \stdClass();
324
        $document->unstructuredObject->refArray[1]->{'$ref'} = 'http://localhost/core/app/dude2';
325
326
        $client = static::createRestClient();
327
        $client->put('/hans/showcase/'.$document->id, $document);
328
329
        $this->assertEquals(204, $client->getResponse()->getStatusCode());
330
331
        $client = static::createRestClient();
332
        $client->request('GET', '/hans/showcase/'.$document->id);
333
334
        // all still the same?
335
        $this->assertEquals($document, $client->getResults());
336
    }
337
338
    /**
339
     * are extra fields denied?
340
     *
341
     * @return void
342
     */
343
    public function testExtraFieldPost()
344
    {
345
        ini_set('date.timezone', 'UTC');
346
        $document = json_decode(
347
            file_get_contents(dirname(__FILE__).'/../resources/showcase-minimal.json'),
348
            false
349
        );
350
        $document->extraFields = "nice field";
351
        $document->anotherExtraField = "one more";
352
353
        $client = static::createRestClient();
354
        $client->post('/hans/showcase', $document);
355
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
356
357
        $expectedErrors = [];
358
        $expectedErrors[0] = new \stdClass();
359
        $expectedErrors[0]->propertyPath = "";
360
        $expectedErrors[0]->message = 'The property extraFields is not defined and the definition '.
361
            'does not allow additional properties';
362
        $expectedErrors[1] = new \stdClass();
363
        $expectedErrors[1]->propertyPath = "";
364
        $expectedErrors[1]->message = 'The property anotherExtraField is not defined and the definition '.
365
            'does not allow additional properties';
366
367
        $this->assertJsonStringEqualsJsonString(
368
            json_encode($expectedErrors),
369
            json_encode($client->getResults())
370
        );
371
    }
372
373
    /**
374
     * Test RQL select statement
375
     *
376
     * @return void
377
     */
378
    public function testRqlSelect()
379
    {
380
        $this->loadFixtures(
381
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
382
            null,
383
            'doctrine_mongodb'
384
        );
385
386
        $filtred = json_decode(
387
            file_get_contents(dirname(__FILE__).'/../resources/showcase-rql-select-filtred.json'),
388
            false
389
        );
390
391
        $fields = [
392
            'someFloatyDouble',
393
            'contact.uri',
394
            'contactCode.text.en',
395
            'unstructuredObject.booleanField',
396
            'unstructuredObject.hashField.someField',
397
            'unstructuredObject.nestedArrayField.anotherField',
398
            'nestedCustomers.$ref',
399
            'choices'
400
        ];
401
        $rqlSelect = 'select('.implode(',', array_map([$this, 'encodeRqlString'], $fields)).')';
402
403
        $client = static::createRestClient();
404
        $client->request('GET', '/hans/showcase/?'.$rqlSelect);
405
406
        $this->assertEquals($filtred, $client->getResults());
407
408
409
        foreach ([
410
                     '500' => $filtred[0],
411
                     '600' => $filtred[1],
412
                 ] as $id => $item) {
413
            $client = static::createRestClient();
414
            $client->request('GET', '/hans/showcase/'.$id.'?'.$rqlSelect);
415
            $this->assertEquals($item, $client->getResults());
416
        }
417
    }
418
419
    /**
420
     * Test to see if we can do like() searches on identifier fields
421
     *
422
     * @return void
423
     */
424
    public function testLikeSearchOnIdentifierField()
425
    {
426
        // Load fixtures
427
        $this->loadFixtures(
428
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
429
            null,
430
            'doctrine_mongodb'
431
        );
432
433
        $client = static::createRestClient();
434
        $client->request('GET', '/hans/showcase/?like(id,5*)');
435
436
        // we should only get 1 ;-)
437
        $this->assertEquals(1, count($client->getResults()));
438
439
        $client = static::createRestClient();
440
        $client->request('GET', '/hans/showcase/?like(id,*0)');
441
442
        // this should get both
443
        $this->assertEquals(2, count($client->getResults()));
444
    }
445
446
    /**
447
     * Test PATCH for deep nested attribute
448
     *
449
     * @return void
450
     */
451 View Code Duplication
    public function testPatchDeepNestedProperty()
452
    {
453
        // Load fixtures
454
        $this->loadFixtures(
455
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
456
            null,
457
            'doctrine_mongodb'
458
        );
459
460
        // Apply PATCH request
461
        $client = static::createRestClient();
462
        $patchJson = json_encode(
463
            [
464
                [
465
                    'op' => 'replace',
466
                    'path' => '/unstructuredObject/hashField/anotherField',
467
                    'value' => 'changed nested hash field with patch'
468
                ]
469
            ]
470
        );
471
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
472
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
473
474
        // Get changed showcase
475
        $client = static::createRestClient();
476
        $client->request('GET', '/hans/showcase/500');
477
478
        $result = $client->getResults();
479
        $this->assertEquals(
480
            'changed nested hash field with patch',
481
            $result->unstructuredObject->hashField->anotherField
482
        );
483
    }
484
485
    /**
486
     * Test success PATCH method - response headers contains link to resource
487
     *
488
     * @return void
489
     */
490
    public function testPatchSuccessResponseHeaderContainsResourceLink()
491
    {
492
        // Load fixtures
493
        $this->loadFixtures(
494
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
495
            null,
496
            'doctrine_mongodb'
497
        );
498
499
        // Apply PATCH request
500
        $client = static::createRestClient();
501
        $patchJson = json_encode(
502
            [
503
                [
504
                    'op' => 'replace',
505
                    'path' => '/testField/en',
506
                    'value' => 'changed value'
507
                ]
508
            ]
509
        );
510
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
511
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
512
513
        $this->assertEquals(
514
            '/hans/showcase/500',
515
            $client->getResponse()->headers->get('Content-Location')
516
        );
517
    }
518
519
    /**
520
     * Test PATCH method - remove/change ID not allowed
521
     *
522
     * @return void
523
     */
524
    public function testPatchRemoveAndChangeIdNotAllowed()
525
    {
526
        // Load fixtures
527
        $this->loadFixtures(
528
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
529
            null,
530
            'doctrine_mongodb'
531
        );
532
533
        // Apply PATCH request
534
        $client = static::createRestClient();
535
        $patchJson = json_encode(
536
            [
537
                [
538
                    'op' => 'remove',
539
                    'path' => '/id'
540
                ]
541
            ]
542
        );
543
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
544
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
545
    }
546
547
    /**
548
     * Test PATCH: add property to free object structure
549
     *
550
     * @return void
551
     */
552 View Code Duplication
    public function testPatchAddPropertyToFreeObject()
553
    {
554
        // Load fixtures
555
        $this->loadFixtures(
556
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
557
            null,
558
            'doctrine_mongodb'
559
        );
560
561
        // Apply PATCH request
562
        $client = static::createRestClient();
563
        $patchJson = json_encode(
564
            [
565
                [
566
                    'op' => 'add',
567
                    'path' => '/unstructuredObject/hashField/newAddedField',
568
                    'value' => 'new field value'
569
                ]
570
            ]
571
        );
572
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
573
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
574
575
        // Get changed showcase
576
        $client = static::createRestClient();
577
        $client->request('GET', '/hans/showcase/500');
578
579
        $result = $client->getResults();
580
        $this->assertEquals(
581
            'new field value',
582
            $result->unstructuredObject->hashField->newAddedField
583
        );
584
    }
585
586
    /**
587
     * Test PATCH for $ref attribute
588
     *
589
     * @return void
590
     * @incomplete
591
     */
592 View Code Duplication
    public function testApplyPatchForRefAttribute()
593
    {
594
        // Load fixtures
595
        $this->loadFixtures(
596
            [
597
                'GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'
598
            ],
599
            null,
600
            'doctrine_mongodb'
601
        );
602
603
        // Apply PATCH request
604
        $client = static::createRestClient();
605
        $patchJson = json_encode(
606
            [
607
                [
608
                    'op' => 'replace',
609
                    'path' => '/nestedApps/0/$ref',
610
                    'value' => 'http://localhost/core/app/admin'
611
                ]
612
            ]
613
        );
614
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
615
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
616
617
        // Check patched result
618
        $client = static::createRestClient();
619
        $client->request('GET', '/hans/showcase/500');
620
621
        $result = $client->getResults();
622
        $this->assertEquals(
623
            'http://localhost/core/app/admin',
624
            $result->nestedApps[0]->{'$ref'}
625
        );
626
    }
627
628
    /**
629
     * Test PATCH: apply patch which results to invalid Showcase schema
630
     *
631
     * @return void
632
     */
633
    public function testPatchToInvalidShowcase()
634
    {
635
        // Load fixtures
636
        $this->loadFixtures(
637
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
638
            null,
639
            'doctrine_mongodb'
640
        );
641
642
        // Apply PATCH request, remove required field
643
        $client = static::createRestClient();
644
        $patchJson = json_encode(
645
            [
646
                [
647
                    'op' => 'remove',
648
                    'path' => '/anotherInt'
649
                ]
650
            ]
651
        );
652
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
653
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
654
655
        // Check that Showcase has not been changed
656
        $client = static::createRestClient();
657
        $client->request('GET', '/hans/showcase/500');
658
659
        $result = $client->getResults();
660
        $this->assertObjectHasAttribute('anotherInt', $result);
661
    }
662
663
    /**
664
     * Test PATCH: remove element from array
665
     *
666
     * @return void
667
     */
668 View Code Duplication
    public function testRemoveFromArrayPatch()
669
    {
670
        // Load fixtures
671
        $this->loadFixtures(
672
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
673
            null,
674
            'doctrine_mongodb'
675
        );
676
677
        // Apply PATCH request, remove nested app, initially there are 2 apps
678
        $client = static::createRestClient();
679
        $patchJson = json_encode(
680
            [
681
                [
682
                    'op' => 'remove',
683
                    'path' => '/nestedApps/0'
684
                ]
685
            ]
686
        );
687
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
688
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
689
690
        // Check patched result
691
        $client = static::createRestClient();
692
        $client->request('GET', '/hans/showcase/500');
693
694
        $result = $client->getResults();
695
        $this->assertEquals(1, count($result->nestedApps));
696
        $this->assertEquals('http://localhost/core/app/admin', $result->nestedApps[0]->{'$ref'});
697
    }
698
699
    /**
700
     * Test PATCH: add new element to array
701
     *
702
     * @return void
703
     */
704
    public function testAddElementToSpecificIndexInArrayPatch()
705
    {
706
        // Load fixtures
707
        $this->loadFixtures(
708
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
709
            null,
710
            'doctrine_mongodb'
711
        );
712
713
        // Apply PATCH request, add new element
714
        $client = static::createRestClient();
715
        $newElement = ['name' => 'element three'];
716
        $patchJson = json_encode(
717
            [
718
                [
719
                    'op' => 'add',
720
                    'path' => '/nestedArray/1',
721
                    'value' => $newElement
722
                ]
723
            ]
724
        );
725
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
726
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
727
728
        // Check patched result
729
        $client = static::createRestClient();
730
        $client->request('GET', '/hans/showcase/500');
731
732
        $result = $client->getResults();
733
        $this->assertEquals(3, count($result->nestedArray));
734
        $this->assertJsonStringEqualsJsonString(
735
            json_encode($newElement),
736
            json_encode($result->nestedArray[1])
737
        );
738
    }
739
740
    /**
741
     * Test PATCH: add complex object App to array
742
     *
743
     * @group ref
744
     * @return void
745
     */
746 View Code Duplication
    public function testPatchAddComplexObjectToSpecificIndexInArray()
747
    {
748
        // Load fixtures
749
        $this->loadFixtures(
750
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
751
            null,
752
            'doctrine_mongodb'
753
        );
754
755
        // Apply PATCH request, add new element
756
        $client = static::createRestClient();
757
        $newApp = ['$ref' => 'http://localhost/core/app/admin'];
758
        $patchJson = json_encode(
759
            [
760
                [
761
                    'op' => 'add',
762
                    'path' => '/nestedApps/0',
763
                    'value' => $newApp
764
                ]
765
            ]
766
        );
767
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
768
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
769
770
        // Check patched result
771
        $client = static::createRestClient();
772
        $client->request('GET', '/hans/showcase/500');
773
774
        $result = $client->getResults();
775
        $this->assertEquals(3, count($result->nestedApps));
776
        $this->assertEquals(
777
            'http://localhost/core/app/admin',
778
            $result->nestedApps[0]->{'$ref'}
779
        );
780
    }
781
782
    /**
783
     * Test PATCH: add complex object App to array
784
     *
785
     * @group ref
786
     * @return void
787
     */
788 View Code Duplication
    public function testPatchAddComplexObjectToTheEndOfArray()
789
    {
790
        // Load fixtures
791
        $this->loadFixtures(
792
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
793
            null,
794
            'doctrine_mongodb'
795
        );
796
797
        // Apply PATCH request, add new element
798
        $client = static::createRestClient();
799
        $newApp = ['$ref' => 'http://localhost/core/app/test'];
800
        $patchJson = json_encode(
801
            [
802
                [
803
                    'op' => 'add',
804
                    'path' => '/nestedApps/-',
805
                    'value' => $newApp
806
                ]
807
            ]
808
        );
809
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
810
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
811
812
        // Check patched result
813
        $client = static::createRestClient();
814
        $client->request('GET', '/hans/showcase/500');
815
816
        $result = $client->getResults();
817
        $this->assertEquals(3, count($result->nestedApps));
818
        $this->assertEquals(
819
            'http://localhost/core/app/test',
820
            $result->nestedApps[2]->{'$ref'}
821
        );
822
    }
823
824
    /**
825
     * Test PATCH: test operation to undefined index
826
     *
827
     * @group ref
828
     * @return void
829
     */
830
    public function testPatchTestOperationToUndefinedIndexThrowsException()
831
    {
832
        // Load fixtures
833
        $this->loadFixtures(
834
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
835
            null,
836
            'doctrine_mongodb'
837
        );
838
839
        // Apply PATCH request, add new element
840
        $client = static::createRestClient();
841
        $newApp = ['ref' => 'http://localhost/core/app/test'];
842
        $patchJson = json_encode(
843
            [
844
                [
845
                    'op' => 'test',
846
                    'path' => '/nestedApps/9',
847
                    'value' => $newApp
848
                ]
849
            ]
850
        );
851
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
852
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
853
    }
854
855
    /**
856
     * Test PATCH: add complex object App to array
857
     *
858
     * @group ref
859
     * @return void
860
     */
861
    public function testPatchAddElementToUndefinedIndexResponseAsBadRequest()
862
    {
863
        // Load fixtures
864
        $this->loadFixtures(
865
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
866
            null,
867
            'doctrine_mongodb'
868
        );
869
870
        // Apply PATCH request, add new element
871
        $client = static::createRestClient();
872
        $newApp = ['ref' => 'http://localhost/core/app/admin'];
873
        $patchJson = json_encode(
874
            [
875
                [
876
                    'op' => 'add',
877
                    'path' => '/nestedApps/9',
878
                    'value' => $newApp
879
                ]
880
            ]
881
        );
882
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
883
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
884
885
        // Check that patched document not changed
886
        $client = static::createRestClient();
887
        $client->request('GET', '/hans/showcase/500');
888
889
        $result = $client->getResults();
890
        $this->assertEquals(2, count($result->nestedApps));
891
    }
892
893
    /**
894
     * Encode string value in RQL
895
     *
896
     * @param string $value String value
897
     * @return string
898
     */
899 View Code Duplication
    private function encodeRqlString($value)
900
    {
901
        return strtr(
902
            rawurlencode($value),
903
            [
904
                '-' => '%2D',
905
                '_' => '%5F',
906
                '.' => '%2E',
907
                '~' => '%7E',
908
            ]
909
        );
910
    }
911
912
    /**
913
     * Trigger a 301 Status code
914
     *
915
     * @param string $url         requested url
916
     * @param string $redirectUrl redirected url
917
     * @dataProvider rqlDataProvider
918
     * @return void
919
     */
920
    public function testTrigger301($url, $redirectUrl)
921
    {
922
        $client = static::createRestClient();
923
        $client->request('GET', $url);
924
        $this->assertEquals(301, $client->getResponse()->getStatusCode());
925
        $this->assertEquals($redirectUrl, $client->getResponse()->headers->get('Location'));
926
    }
927
928
    /**
929
     * Provides urls for the testTrigger301() test.
930
     *
931
     * @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...
932
     */
933
    public function rqlDataProvider()
934
    {
935
        return [
936
            'rql' => ['url' => '/hans/showcase?id=blah' , 'redirect_url' => 'http://localhost/hans/showcase/?id=blah'],
937
            'noRql' => ['url' => '/hans/showcase' , 'redirect_url' => 'http://localhost/hans/showcase/']
938
        ];
939
    }
940
941
    /**
942
     * test finding of showcases by ref
943
     *
944
     * @dataProvider findByExtrefProvider
945
     *
946
     * @param string  $field which reference to search in
947
     * @param mixed   $url   ref to search for
948
     * @param integer $count number of results to expect
949
     *
950
     * @return void
951
     */
952
    public function testFindByExtref($field, $url, $count)
953
    {
954
        $this->loadFixtures(
955
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
956
            null,
957
            'doctrine_mongodb'
958
        );
959
960
        $url = sprintf(
961
            '/hans/showcase/?%s=%s',
962
            $this->encodeRqlString($field),
963
            $this->encodeRqlString($url)
964
        );
965
966
        $client = static::createRestClient();
967
        $client->request('GET', $url);
968
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
969
        $this->assertCount($count, $client->getResults());
970
    }
971
972
    /**
973
     * @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...
974
     */
975 View Code Duplication
    public function findByExtrefProvider()
976
    {
977
        return [
978
            'find a linked record when searching for "tablet" ref by array field' => [
979
                'nestedApps.0.$ref',
980
                'http://localhost/core/app/tablet',
981
                1
982
            ],
983
            'find a linked record when searching for "admin" ref by array field' => [
984
                'nestedApps.0.$ref',
985
                'http://localhost/core/app/admin',
986
                1
987
            ],
988
            'find nothing when searching for inextistant (and unlinked) ref by array field' => [
989
                'nestedApps.0.$ref',
990
                'http://localhost/core/app/inexistant',
991
                0
992
            ],
993
            'return nothing when searching with incomplete ref by array field' => [
994
                'nestedApps.0.$ref',
995
                'http://localhost/core/app',
996
                0
997
            ],
998
        ];
999
    }
1000
}
1001