Completed
Push — master ( 25b499...2ea727 )
by Lucas
19:04 queued 08:47
created

ShowcaseControllerTest::testExtraFieldPost()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 23
rs 9.0856
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
     * 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
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
336
        $client = static::createRestClient();
337
        $client->post('/hans/showcase', $document);
338
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
339
340
        $expectedErrors = [];
341
        $expectedErrors[0] = new \stdClass();
342
        $expectedErrors[0]->propertyPath = "";
343
        $expectedErrors[0]->message = "This form should not contain extra fields.";
344
345
        $this->assertJsonStringEqualsJsonString(
346
            json_encode($expectedErrors),
347
            json_encode($client->getResults())
348
        );
349
    }
350
351
    /**
352
     * Test RQL select statement
353
     *
354
     * @return void
355
     */
356
    public function testRqlSelect()
357
    {
358
        $this->loadFixtures(
359
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
360
            null,
361
            'doctrine_mongodb'
362
        );
363
364
        $filtred = json_decode(
365
            file_get_contents(dirname(__FILE__).'/../resources/showcase-rql-select-filtred.json'),
366
            false
367
        );
368
369
        $fields = [
370
            'someFloatyDouble',
371
            'contact.uri',
372
            'contactCode.text.en',
373
            'unstructuredObject.booleanField',
374
            'unstructuredObject.hashField.someField',
375
            'unstructuredObject.nestedArrayField.anotherField',
376
            'nestedCustomers.$ref',
377
            'choices'
378
        ];
379
        $rqlSelect = 'select('.implode(',', array_map([$this, 'encodeRqlString'], $fields)).')';
380
381
        $client = static::createRestClient();
382
        $client->request('GET', '/hans/showcase/?'.$rqlSelect);
383
384
        $this->assertEquals($filtred, $client->getResults());
385
386
387
        foreach ([
388
                     '500' => $filtred[0],
389
                     '600' => $filtred[1],
390
                 ] as $id => $item) {
391
            $client = static::createRestClient();
392
            $client->request('GET', '/hans/showcase/'.$id.'?'.$rqlSelect);
393
            $this->assertEquals($item, $client->getResults());
394
        }
395
    }
396
397
    /**
398
     * Test to see if we can do like() searches on identifier fields
399
     *
400
     * @return void
401
     */
402
    public function testLikeSearchOnIdentifierField()
403
    {
404
        // Load fixtures
405
        $this->loadFixtures(
406
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
407
            null,
408
            'doctrine_mongodb'
409
        );
410
411
        $client = static::createRestClient();
412
        $client->request('GET', '/hans/showcase/?like(id,5*)');
413
414
        // we should only get 1 ;-)
415
        $this->assertEquals(1, count($client->getResults()));
416
417
        $client = static::createRestClient();
418
        $client->request('GET', '/hans/showcase/?like(id,*0)');
419
420
        // this should get both
421
        $this->assertEquals(2, count($client->getResults()));
422
    }
423
424
    /**
425
     * Test PATCH for deep nested attribute
426
     *
427
     * @return void
428
     */
429 View Code Duplication
    public function testPatchDeepNestedProperty()
430
    {
431
        // Load fixtures
432
        $this->loadFixtures(
433
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
434
            null,
435
            'doctrine_mongodb'
436
        );
437
438
        // Apply PATCH request
439
        $client = static::createRestClient();
440
        $patchJson = json_encode(
441
            [
442
                [
443
                    'op' => 'replace',
444
                    'path' => '/unstructuredObject/hashField/anotherField',
445
                    'value' => 'changed nested hash field with patch'
446
                ]
447
            ]
448
        );
449
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
450
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
451
452
        // Get changed showcase
453
        $client = static::createRestClient();
454
        $client->request('GET', '/hans/showcase/500');
455
456
        $result = $client->getResults();
457
        $this->assertEquals(
458
            'changed nested hash field with patch',
459
            $result->unstructuredObject->hashField->anotherField
460
        );
461
    }
462
463
    /**
464
     * Test success PATCH method - response headers contains link to resource
465
     *
466
     * @return void
467
     */
468
    public function testPatchSuccessResponseHeaderContainsResourceLink()
469
    {
470
        // Load fixtures
471
        $this->loadFixtures(
472
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
473
            null,
474
            'doctrine_mongodb'
475
        );
476
477
        // Apply PATCH request
478
        $client = static::createRestClient();
479
        $patchJson = json_encode(
480
            [
481
                [
482
                    'op' => 'replace',
483
                    'path' => '/testField/en',
484
                    'value' => 'changed value'
485
                ]
486
            ]
487
        );
488
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
489
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
490
491
        $this->assertEquals(
492
            '/hans/showcase/500',
493
            $client->getResponse()->headers->get('Content-Location')
494
        );
495
    }
496
497
    /**
498
     * Test PATCH method - remove/change ID not allowed
499
     *
500
     * @return void
501
     */
502
    public function testPatchRemoveAndChangeIdNotAllowed()
503
    {
504
        // Load fixtures
505
        $this->loadFixtures(
506
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
507
            null,
508
            'doctrine_mongodb'
509
        );
510
511
        // Apply PATCH request
512
        $client = static::createRestClient();
513
        $patchJson = json_encode(
514
            [
515
                [
516
                    'op' => 'remove',
517
                    'path' => '/id'
518
                ]
519
            ]
520
        );
521
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
522
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
523
    }
524
525
    /**
526
     * Test PATCH: add property to free object structure
527
     *
528
     * @return void
529
     */
530 View Code Duplication
    public function testPatchAddPropertyToFreeObject()
531
    {
532
        // Load fixtures
533
        $this->loadFixtures(
534
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
535
            null,
536
            'doctrine_mongodb'
537
        );
538
539
        // Apply PATCH request
540
        $client = static::createRestClient();
541
        $patchJson = json_encode(
542
            [
543
                [
544
                    'op' => 'add',
545
                    'path' => '/unstructuredObject/hashField/newAddedField',
546
                    'value' => 'new field value'
547
                ]
548
            ]
549
        );
550
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
551
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
552
553
        // Get changed showcase
554
        $client = static::createRestClient();
555
        $client->request('GET', '/hans/showcase/500');
556
557
        $result = $client->getResults();
558
        $this->assertEquals(
559
            'new field value',
560
            $result->unstructuredObject->hashField->newAddedField
561
        );
562
    }
563
564
    /**
565
     * Test PATCH for $ref attribute
566
     *
567
     * @return void
568
     * @incomplete
569
     */
570 View Code Duplication
    public function testApplyPatchForRefAttribute()
571
    {
572
        // Load fixtures
573
        $this->loadFixtures(
574
            [
575
                'GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'
576
            ],
577
            null,
578
            'doctrine_mongodb'
579
        );
580
581
        // Apply PATCH request
582
        $client = static::createRestClient();
583
        $patchJson = json_encode(
584
            [
585
                [
586
                    'op' => 'replace',
587
                    'path' => '/nestedApps/0/$ref',
588
                    'value' => 'http://localhost/core/app/admin'
589
                ]
590
            ]
591
        );
592
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
593
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
594
595
        // Check patched result
596
        $client = static::createRestClient();
597
        $client->request('GET', '/hans/showcase/500');
598
599
        $result = $client->getResults();
600
        $this->assertEquals(
601
            'http://localhost/core/app/admin',
602
            $result->nestedApps[0]->{'$ref'}
603
        );
604
    }
605
606
    /**
607
     * Test PATCH: apply patch which results to invalid Showcase schema
608
     *
609
     * @return void
610
     */
611
    public function testPatchToInvalidShowcase()
612
    {
613
        // Load fixtures
614
        $this->loadFixtures(
615
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
616
            null,
617
            'doctrine_mongodb'
618
        );
619
620
        // Apply PATCH request, remove required field
621
        $client = static::createRestClient();
622
        $patchJson = json_encode(
623
            [
624
                [
625
                    'op' => 'remove',
626
                    'path' => '/anotherInt'
627
                ]
628
            ]
629
        );
630
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
631
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
632
633
        // Check that Showcase has not been changed
634
        $client = static::createRestClient();
635
        $client->request('GET', '/hans/showcase/500');
636
637
        $result = $client->getResults();
638
        $this->assertObjectHasAttribute('anotherInt', $result);
639
    }
640
641
    /**
642
     * Test PATCH: remove element from array
643
     *
644
     * @return void
645
     */
646 View Code Duplication
    public function testRemoveFromArrayPatch()
647
    {
648
        // Load fixtures
649
        $this->loadFixtures(
650
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
651
            null,
652
            'doctrine_mongodb'
653
        );
654
655
        // Apply PATCH request, remove nested app, initially there are 2 apps
656
        $client = static::createRestClient();
657
        $patchJson = json_encode(
658
            [
659
                [
660
                    'op' => 'remove',
661
                    'path' => '/nestedApps/0'
662
                ]
663
            ]
664
        );
665
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
666
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
667
668
        // Check patched result
669
        $client = static::createRestClient();
670
        $client->request('GET', '/hans/showcase/500');
671
672
        $result = $client->getResults();
673
        $this->assertEquals(1, count($result->nestedApps));
674
        $this->assertEquals('http://localhost/core/app/admin', $result->nestedApps[0]->{'$ref'});
675
    }
676
677
    /**
678
     * Test PATCH: add new element to array
679
     *
680
     * @return void
681
     */
682
    public function testAddElementToSpecificIndexInArrayPatch()
683
    {
684
        // Load fixtures
685
        $this->loadFixtures(
686
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
687
            null,
688
            'doctrine_mongodb'
689
        );
690
691
        // Apply PATCH request, add new element
692
        $client = static::createRestClient();
693
        $newElement = ['name' => 'element three'];
694
        $patchJson = json_encode(
695
            [
696
                [
697
                    'op' => 'add',
698
                    'path' => '/nestedArray/1',
699
                    'value' => $newElement
700
                ]
701
            ]
702
        );
703
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
704
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
705
706
        // Check patched result
707
        $client = static::createRestClient();
708
        $client->request('GET', '/hans/showcase/500');
709
710
        $result = $client->getResults();
711
        $this->assertEquals(3, count($result->nestedArray));
712
        $this->assertJsonStringEqualsJsonString(
713
            json_encode($newElement),
714
            json_encode($result->nestedArray[1])
715
        );
716
    }
717
718
    /**
719
     * Test PATCH: add complex object App to array
720
     *
721
     * @group ref
722
     * @return void
723
     */
724 View Code Duplication
    public function testPatchAddComplexObjectToSpecificIndexInArray()
725
    {
726
        // Load fixtures
727
        $this->loadFixtures(
728
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
729
            null,
730
            'doctrine_mongodb'
731
        );
732
733
        // Apply PATCH request, add new element
734
        $client = static::createRestClient();
735
        $newApp = ['ref' => 'http://localhost/core/app/admin'];
736
        $patchJson = json_encode(
737
            [
738
                [
739
                    'op' => 'add',
740
                    'path' => '/nestedApps/0',
741
                    'value' => $newApp
742
                ]
743
            ]
744
        );
745
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
746
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
747
748
        // Check patched result
749
        $client = static::createRestClient();
750
        $client->request('GET', '/hans/showcase/500');
751
752
        $result = $client->getResults();
753
        $this->assertEquals(3, count($result->nestedApps));
754
        $this->assertEquals(
755
            'http://localhost/core/app/admin',
756
            $result->nestedApps[0]->{'$ref'}
757
        );
758
    }
759
760
    /**
761
     * Test PATCH: add complex object App to array
762
     *
763
     * @group ref
764
     * @return void
765
     */
766 View Code Duplication
    public function testPatchAddComplexObjectToTheEndOfArray()
767
    {
768
        // Load fixtures
769
        $this->loadFixtures(
770
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
771
            null,
772
            'doctrine_mongodb'
773
        );
774
775
        // Apply PATCH request, add new element
776
        $client = static::createRestClient();
777
        $newApp = ['ref' => 'http://localhost/core/app/test'];
778
        $patchJson = json_encode(
779
            [
780
                [
781
                    'op' => 'add',
782
                    'path' => '/nestedApps/-',
783
                    'value' => $newApp
784
                ]
785
            ]
786
        );
787
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
788
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
789
790
        // Check patched result
791
        $client = static::createRestClient();
792
        $client->request('GET', '/hans/showcase/500');
793
794
        $result = $client->getResults();
795
        $this->assertEquals(3, count($result->nestedApps));
796
        $this->assertEquals(
797
            'http://localhost/core/app/test',
798
            $result->nestedApps[2]->{'$ref'}
799
        );
800
    }
801
802
    /**
803
     * Test PATCH: test operation to undefined index
804
     *
805
     * @group ref
806
     * @return void
807
     */
808
    public function testPatchTestOperationToUndefinedIndexThrowsException()
809
    {
810
        // Load fixtures
811
        $this->loadFixtures(
812
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
813
            null,
814
            'doctrine_mongodb'
815
        );
816
817
        // Apply PATCH request, add new element
818
        $client = static::createRestClient();
819
        $newApp = ['ref' => 'http://localhost/core/app/test'];
820
        $patchJson = json_encode(
821
            [
822
                [
823
                    'op' => 'test',
824
                    'path' => '/nestedApps/9',
825
                    'value' => $newApp
826
                ]
827
            ]
828
        );
829
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
830
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
831
    }
832
833
    /**
834
     * Test PATCH: add complex object App to array
835
     *
836
     * @group ref
837
     * @return void
838
     */
839
    public function testPatchAddElementToUndefinedIndexResponseAsBadRequest()
840
    {
841
        // Load fixtures
842
        $this->loadFixtures(
843
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
844
            null,
845
            'doctrine_mongodb'
846
        );
847
848
        // Apply PATCH request, add new element
849
        $client = static::createRestClient();
850
        $newApp = ['ref' => 'http://localhost/core/app/admin'];
851
        $patchJson = json_encode(
852
            [
853
                [
854
                    'op' => 'add',
855
                    'path' => '/nestedApps/9',
856
                    'value' => $newApp
857
                ]
858
            ]
859
        );
860
        $client->request('PATCH', '/hans/showcase/500', array(), array(), array(), $patchJson);
861
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
862
863
        // Check that patched document not changed
864
        $client = static::createRestClient();
865
        $client->request('GET', '/hans/showcase/500');
866
867
        $result = $client->getResults();
868
        $this->assertEquals(2, count($result->nestedApps));
869
    }
870
871
    /**
872
     * Encode string value in RQL
873
     *
874
     * @param string $value String value
875
     * @return string
876
     */
877 View Code Duplication
    private function encodeRqlString($value)
878
    {
879
        return strtr(
880
            rawurlencode($value),
881
            [
882
                '-' => '%2D',
883
                '_' => '%5F',
884
                '.' => '%2E',
885
                '~' => '%7E',
886
            ]
887
        );
888
    }
889
890
    /**
891
     * Trigger a 301 Status code
892
     *
893
     * @param string $url         requested url
894
     * @param string $redirectUrl redirected url
895
     * @dataProvider rqlDataProvider
896
     * @return void
897
     */
898 View Code Duplication
    public function testTrigger301($url, $redirectUrl)
899
    {
900
        $client = static::createRestClient();
901
        $client->request('GET', $url);
902
        $this->assertEquals(301, $client->getResponse()->getStatusCode());
903
        $this->assertEquals($redirectUrl, $client->getResponse()->headers->get('Location'));
904
    }
905
906
    /**
907
     * Provides urls for the testTrigger301() test.
908
     *
909
     * @return array
910
     */
911
    public function rqlDataProvider()
912
    {
913
        return [
914
            'rql' => ['url' => '/hans/showcase?id=blah' , 'redirect_url' => 'http://localhost/hans/showcase/?id=blah'],
915
            'noRql' => ['url' => '/hans/showcase' , 'redirect_url' => 'http://localhost/hans/showcase/']
916
        ];
917
    }
918
919
    /**
920
     * test finding of showcases by ref
921
     *
922
     * @dataProvider findByExtrefProvider
923
     *
924
     * @param string  $field which reference to search in
925
     * @param mixed   $url   ref to search for
926
     * @param integer $count number of results to expect
927
     *
928
     * @return void
929
     */
930
    public function testFindByExtref($field, $url, $count)
931
    {
932
        $this->loadFixtures(
933
            ['GravitonDyn\ShowCaseBundle\DataFixtures\MongoDB\LoadShowCaseData'],
934
            null,
935
            'doctrine_mongodb'
936
        );
937
938
        $url = sprintf(
939
            '/hans/showcase/?%s=%s',
940
            $this->encodeRqlString($field),
941
            $this->encodeRqlString($url)
942
        );
943
944
        $client = static::createRestClient();
945
        $client->request('GET', $url);
946
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
947
        $this->assertCount($count, $client->getResults());
948
    }
949
950
    /**
951
     * @return array
952
     */
953 View Code Duplication
    public function findByExtrefProvider()
954
    {
955
        return [
956
            'find a linked record when searching for "tablet" ref by array field' => [
957
                'nestedApps.0.$ref',
958
                'http://localhost/core/app/tablet',
959
                1
960
            ],
961
            'find a linked record when searching for "admin" ref by array field' => [
962
                'nestedApps.0.$ref',
963
                'http://localhost/core/app/admin',
964
                1
965
            ],
966
            'find nothing when searching for inextistant (and unlinked) ref by array field' => [
967
                'nestedApps.0.$ref',
968
                'http://localhost/core/app/inexistant',
969
                0
970
            ],
971
            'return nothing when searching with incomplete ref by array field' => [
972
                'nestedApps.0.$ref',
973
                'http://localhost/core/app',
974
                0
975
            ],
976
        ];
977
    }
978
}
979