Completed
Push — master ( 77f66b...4247a4 )
by Lucas
10:47
created

ShowcaseControllerTest::testRemoveFromArrayPatch()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 16

Duplication

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