Completed
Push — master ( 9c3bdf...25b499 )
by Lucas
25:24 queued 15:40
created

ShowcaseControllerTest::testMissingFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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