Completed
Push — feature/evo-2695-choices ( fdf929...b6176f )
by
unknown
37:53 queued 26:04
created

ShowcaseControllerTest::testErrorsInFixtures()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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