Completed
Push — feature/remove-knp-paginator-b... ( c474bb )
by Lucas
230:58 queued 200:01
created

AppControllerTest::testGetAppPagingWithRql()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 80
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
c 1
b 1
f 1
dl 0
loc 80
rs 8.8387
cc 1
eloc 46
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * functional test for /core/app
4
 */
5
6
namespace Graviton\CoreBundle\Tests\Controller;
7
8
use Graviton\TestBundle\Test\RestTestCase;
9
use Symfony\Component\HttpFoundation\Response;
10
11
/**
12
 * Basic functional test for /core/app.
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 AppControllerTest 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/core/app/item';
24
25
    /**
26
     * @const corresponding vendorized schema mime type
27
     */
28
    const COLLECTION_TYPE = 'application/json; charset=UTF-8; profile=http://localhost/schema/core/app/collection';
29
30
    /**
31
     * setup client and load fixtures
32
     *
33
     * @return void
34
     */
35
    public function setUp()
36
    {
37
        $this->loadFixtures(
38
            array(
39
                'Graviton\CoreBundle\DataFixtures\MongoDB\LoadAppData',
40
                'Graviton\I18nBundle\DataFixtures\MongoDB\LoadLanguageData',
41
                'Graviton\I18nBundle\DataFixtures\MongoDB\LoadMultiLanguageData',
42
                'Graviton\I18nBundle\DataFixtures\MongoDB\LoadTranslatableData',
43
                'Graviton\I18nBundle\DataFixtures\MongoDB\LoadTranslatablesApp'
44
            ),
45
            null,
46
            'doctrine_mongodb'
47
        );
48
    }
49
    /**
50
     * check if all fixtures are returned on GET
51
     *
52
     * @return void
53
     */
54
    public function testFindAll()
55
    {
56
        $client = static::createRestClient();
57
        $client->request('GET', '/core/app/');
58
59
        $response = $client->getResponse();
60
        $results = $client->getResults();
61
62
        $this->assertResponseContentType(self::COLLECTION_TYPE, $response);
63
        $this->assertEquals(2, count($results));
64
65
        $this->assertEquals('admin', $results[0]->id);
66
        $this->assertEquals('Administration', $results[0]->name->en);
67
        $this->assertEquals(true, $results[0]->showInMenu);
68
        $this->assertEquals(2, $results[0]->order);
69
70
        $this->assertEquals('tablet', $results[1]->id);
71
        $this->assertEquals('Tablet', $results[1]->name->en);
72
        $this->assertEquals(true, $results[1]->showInMenu);
73
        $this->assertEquals(1, $results[1]->order);
74
75
        $this->assertContains(
76
            '<http://localhost/core/app/>; rel="self"',
77
            $response->headers->get('Link')
78
        );
79
        $this->assertEquals('*', $response->headers->get('Access-Control-Allow-Origin'));
80
    }
81
82
    /**
83
     * test if we can get list of apps, paged and with filters..
84
     *
85
     * @return void
86
     */
87
    public function testGetAppWithFilteringAndPaging()
88
    {
89
        $client = static::createRestClient();
90
        $_SERVER['QUERY_STRING'] = 'eq(showInMenu,true)&limit(1)';
91
        $client->request('GET', '/core/app/?eq(showInMenu,true)&limit(1)');
92
        unset($_SERVER['QUERY_STRING']);
93
        $response = $client->getResponse();
94
95
        $this->assertEquals(1, count($client->getResults()));
96
97
        $this->assertContains(
98
            '<http://localhost/core/app/?eq(showInMenu%2Ctrue)&limit(1)>; rel="self"',
99
            $response->headers->get('Link')
100
        );
101
102
        $this->assertContains(
103
            '<http://localhost/core/app/?eq(showInMenu%2Ctrue)&limit(1%2C1)>; rel="next"',
104
            $response->headers->get('Link')
105
        );
106
107
        $this->assertContains(
108
            '<http://localhost/core/app/?eq(showInMenu%2Ctrue)&limit(1%2C1)>; rel="last"',
109
            $response->headers->get('Link')
110
        );
111
    }
112
113
    /**
114
     * rql limit() should *never* be overwritten by default value
115
     *
116
     * @return void
117
     */
118
    public function testGetAppPagingWithRql()
119
    {
120
        // does limit work?
121
        $client = static::createRestClient();
122
        $client->request('GET', '/core/app/?limit(1)');
123
        $this->assertEquals(1, count($client->getResults()));
124
125
        $response = $client->getResponse();
126
127
        $this->assertContains(
128
            '<http://localhost/core/app/?limit(1)>; rel="self"',
129
            $response->headers->get('Link')
130
        );
131
132
        $this->assertContains(
133
            '<http://localhost/core/app/?limit(1%2C1)>; rel="next"',
134
            $response->headers->get('Link')
135
        );
136
137
        $this->assertContains(
138
            '<http://localhost/core/app/?limit(1%2C1)>; rel="last"',
139
            $response->headers->get('Link')
140
        );
141
142
        $this->assertSame('2', $response->headers->get('X-Total-Count'));
143
144
        /*** pagination tests **/
145
        $client = static::createRestClient();
146
        $client->request('GET', '/core/app/?limit(1,1)');
147
        $this->assertEquals(1, count($client->getResults()));
148
149
        $response = $client->getResponse();
150
151
        $this->assertContains(
152
            '<http://localhost/core/app/?limit(1%2C1)>; rel="self"',
153
            $response->headers->get('Link')
154
        );
155
156
        $this->assertContains(
157
            '<http://localhost/core/app/?limit(1%2C0)>; rel="prev"',
158
            $response->headers->get('Link')
159
        );
160
161
        // we're on the 'last' page - so 'last' should not be in in Link header
162
        $this->assertNotContains(
163
            'rel="last"',
164
            $response->headers->get('Link')
165
        );
166
167
        $this->assertSame('2', $response->headers->get('X-Total-Count'));
168
169
        /*** pagination with different rql test **/
170
        $client = static::createRestClient();
171
        $client->request('GET', '/core/app/?limit(1)&select(id)&sort(-order)');
172
        $this->assertEquals(1, count($client->getResults()));
173
174
        $response = $client->getResponse();
175
176
        $this->assertContains(
177
            'http://localhost/core/app/?limit(1)&select(id)&sort(-order)>; rel="self"',
178
            $response->headers->get('Link')
179
        );
180
181
        $this->assertContains(
182
            '<http://localhost/core/app/?limit(1%2C1)&select(id)&sort(-order)>; rel="next"',
183
            $response->headers->get('Link')
184
        );
185
186
        $this->assertContains(
187
            '<http://localhost/core/app/?limit(1%2C1)&select(id)&sort(-order)>; rel="last"',
188
            $response->headers->get('Link')
189
        );
190
191
        $this->assertNotContains(
192
            'rel="prev"',
193
            $response->headers->get('Link')
194
        );
195
196
        $this->assertSame('2', $response->headers->get('X-Total-Count'));
197
    }
198
199
    /**
200
     * check for a client error if invalid limit value is provided
201
     *
202
     * @dataProvider invalidPagingPageSizeProvider
203
     *
204
     * @param integer $limit limit value that should fail
205
     * @return void
206
     */
207
    public function testInvalidPagingPageSize($limit)
208
    {
209
        $client = static::createRestClient();
210
        $client->request('GET', sprintf('/core/app/?limit(%s)', $limit));
211
212
        $this->assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
213
        $this->assertContains('negative or null limit in rql', $client->getResults()->message);
214
    }
215
216
    /**
217
     * page size test provides
218
     *
219
     * @return array[]
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use integer[][].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
220
     */
221
    public function invalidPagingPageSizeProvider()
222
    {
223
        return [
224
            [0],
225
            [-1],
226
        ];
227
    }
228
229
    /**
230
     * RQL is parsed only when we get apps
231
     *
232
     * @return void
233
     */
234
    public function testRqlIsParsedOnlyOnGetRequest()
235
    {
236
        $appData = [
237
            'showInMenu' => false,
238
            'order'      => 100,
239
            'name'      => ['en' => 'Administration'],
240
        ];
241
242
        $client = static::createRestClient();
243
        $client->request('GET', '/core/app/?invalidrqlquery');
244
        $this->assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
245
        $this->assertContains('syntax error in rql', $client->getResults()->message);
246
247
        $client = static::createRestClient();
248
        $client->request('GET', '/core/app/admin?invalidrqlquery');
249
        $this->assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
250
        $this->assertContains('syntax error in rql', $client->getResults()->message);
251
252
        $client = static::createRestClient();
253
        $client->request('OPTIONS', '/core/app/?invalidrqlquery');
254
        $this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
255
256
        $client = static::createRestClient();
257
        $client->request('OPTIONS', '/schema/core/app/collection?invalidrqlquery');
258
        $this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
259
260
        $client = static::createRestClient();
261
        $client->request('OPTIONS', '/schema/core/app/item?invalidrqlquery');
262
        $this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
263
264
        $client = static::createRestClient();
265
        $client->request('GET', '/schema/core/app/collection?invalidrqlquery');
266
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
267
268
        $client = static::createRestClient();
269
        $client->request('GET', '/schema/core/app/item?invalidrqlquery');
270
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
271
272
273
        $client = static::createRestClient();
274
        $client->post('/core/app/?invalidrqlquery', $appData);
275
        $this->assertEquals(Response::HTTP_CREATED, $client->getResponse()->getStatusCode());
276
277
        $client = static::createRestClient();
278
        $client->put('/core/app/admin?invalidrqlquery', $appData);
279
        $this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
280
281
        $client = static::createRestClient();
282
        $client->request('DELETE', '/core/app/admin?invalidrqlquery');
283
        $this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
284
    }
285
286
    /**
287
     * Test only RQL select() operator is allowed for GET one
288
     *
289
     * @return void
290
     * @group tmp
291
     */
292
    public function testOnlyRqlSelectIsAllowedOnGetOne()
293
    {
294
        $client = static::createRestClient();
295
        $client->request('GET', '/core/app/?select(id)');
296
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
297
298
        $client = static::createRestClient();
299
        $client->request('GET', '/core/app/admin?select(id)');
300
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
301
302
        foreach ([
303
                     'limit' => 'limit(1)',
304
                     'sort'  => 'sort(+id)',
305
                     'eq'    => 'eq(id,a)',
306
                 ] as $extraRqlOperator => $extraRqlOperatorQuery) {
307
            $client = static::createRestClient();
308
            $client->request('GET', '/core/app/?select(id)&'.$extraRqlOperatorQuery);
309
            $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
310
311
            $client = static::createRestClient();
312
            $client->request('GET', '/core/app/admin?select(id)&'.$extraRqlOperatorQuery);
313
            $this->assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
314
            $this->assertEquals(
315
                sprintf('RQL operator "%s" is not allowed for this request', $extraRqlOperator),
316
                $client->getResults()->message
317
            );
318
        }
319
    }
320
321
    /**
322
     * check for empty collections when no fixtures are loaded
323
     *
324
     * @return void
325
     */
326 View Code Duplication
    public function testFindAllEmptyCollection()
327
    {
328
        // reset fixtures since we already have some from setUp
329
        $this->loadFixtures(array(), null, 'doctrine_mongodb');
330
        $client = static::createRestClient();
331
        $client->request('GET', '/core/app/');
332
333
        $response = $client->getResponse();
334
        $results = $client->getResults();
335
336
        $this->assertResponseContentType(self::COLLECTION_TYPE, $response);
337
338
        $this->assertEquals(array(), $results);
339
    }
340
341
    /**
342
     * test if we can get an app by id
343
     *
344
     * @return void
345
     */
346
    public function testGetApp()
347
    {
348
        $client = static::createRestClient();
349
        $client->request('GET', '/core/app/admin');
350
        $response = $client->getResponse();
351
        $results = $client->getResults();
352
353
        $this->assertResponseContentType(self::CONTENT_TYPE, $response);
354
355
        $this->assertEquals('admin', $results->id);
356
        $this->assertEquals('Administration', $results->name->en);
357
        $this->assertEquals(true, $results->showInMenu);
358
359
        $this->assertContains(
360
            '<http://localhost/core/app/admin>; rel="self"',
361
            $response->headers->get('Link')
362
        );
363
        $this->assertEquals('*', $response->headers->get('Access-Control-Allow-Origin'));
364
    }
365
366
    /**
367
     * test if we can create an app through POST
368
     *
369
     * @return void
370
     */
371
    public function testPostApp()
372
    {
373
        $testApp = new \stdClass;
374
        $testApp->name = new \stdClass;
375
        $testApp->name->en = 'new Test App';
376
        $testApp->showInMenu = true;
377
378
        $client = static::createRestClient();
379
        $client->post('/core/app/', $testApp);
380
        $response = $client->getResponse();
381
        $results = $client->getResults();
382
383
        // we sent a location header so we don't want a body
384
        $this->assertNull($results);
385
        $this->assertContains('/core/app/', $response->headers->get('Location'));
386
387
        $client = static::createRestClient();
388
        $client->request('GET', $response->headers->get('Location'));
389
        $response = $client->getResponse();
390
        $results = $client->getResults();
391
392
        $this->assertResponseContentType(self::CONTENT_TYPE, $response);
393
        $this->assertEquals('new Test App', $results->name->en);
394
        $this->assertTrue($results->showInMenu);
395
        $this->assertContains(
396
            '<http://localhost/core/app/'.$results->id.'>; rel="self"',
397
            explode(',', $response->headers->get('Link'))
398
        );
399
    }
400
401
    /**
402
     * test if we get a correct return if we post empty.
403
     *
404
     * @return void
405
     */
406
    public function testPostEmptyApp()
407
    {
408
        $client = static::createRestClient();
409
410
        // send nothing really..
411
        $client->post('/core/app/', "", array(), array(), array(), false);
412
413
        $response = $client->getResponse();
414
415
        $this->assertContains(
416
            'No input data',
417
            $response->getContent()
418
        );
419
420
        $this->assertEquals(400, $response->getStatusCode());
421
    }
422
423
    /**
424
     * test if we get a correct return if we post empty.
425
     *
426
     * @return void
427
     */
428
    public function testPostNonObjectApp()
429
    {
430
        $client = static::createRestClient();
431
        $client->post('/core/app/', "non-object value");
432
433
        $response = $client->getResponse();
434
        $this->assertContains('JSON request body must be an object', $response->getContent());
435
        $this->assertEquals(400, $response->getStatusCode());
436
    }
437
438
    /**
439
     * test if 500 error is reported when posting an malformed input
440
     *
441
     * @return void
442
     */
443
    public function testPostMalformedApp()
444
    {
445
        $testApp = new \stdClass;
446
        $testApp->name = new \stdClass;
447
        $testApp->name->en = 'new Test App';
448
        $testApp->showInMenu = true;
449
450
        // malform it ;-)
451
        $input = str_replace(":", ";", json_encode($testApp));
452
453
        $client = static::createRestClient();
454
455
        // make sure this is sent as 'raw' input (not json_encoded again)
456
        $client->post('/core/app/', $input, array(), array(), array(), false);
457
458
        $response = $client->getResponse();
459
460
        // Check that error message contains detailed reason
461
        json_decode($input);
462
        $lastJsonError = function_exists('json_last_error_msg')
463
            ? json_last_error_msg()
464
            : 'Unable to decode JSON string';
465
        $this->assertContains(
466
            $lastJsonError,
467
            $client->getResults()->message
468
        );
469
470
        $this->assertEquals(400, $response->getStatusCode());
471
    }
472
473
    /**
474
     * Tests if an error is returned when an id is send in a post
475
     *
476
     * @return void
477
     */
478
    public function testPostWithId()
479
    {
480
        $helloApp = new \stdClass();
481
        $helloApp->id = 101;
482
        $helloApp->name = "tubel";
483
484
        $client = static::createRestClient();
485
        $client->post('/person/customer', $helloApp);
486
487
        $this->assertEquals(
488
            'Bad Request - "id" can not be given on a POST request. '.
489
            'Do a PUT request instead to update an existing record.',
490
            $client->getResults()->message
491
        );
492
    }
493
    /**
494
     * test updating apps
495
     *
496
     * @return void
497
     */
498
    public function testPutApp()
499
    {
500
        $helloApp = new \stdClass();
501
        $helloApp->id = "tablet";
502
        $helloApp->name = new \stdClass();
503
        $helloApp->name->en = "Tablet";
504
        $helloApp->showInMenu = false;
505
506
        $client = static::createRestClient();
507
        $client->put('/core/app/tablet', $helloApp);
508
509
        $this->assertNull($client->getResults());
510
        $this->assertNull($client->getResponse()->headers->get('Location'));
511
512
        $client = static::createRestClient();
513
        $client->request('GET', '/core/app/tablet');
514
        $response = $client->getResponse();
515
        $results = $client->getResults();
516
517
        $this->assertResponseContentType(self::CONTENT_TYPE, $response);
518
        $this->assertEquals('Tablet', $results->name->en);
519
        $this->assertFalse($results->showInMenu);
520
        $this->assertContains(
521
            '<http://localhost/core/app/tablet>; rel="self"',
522
            explode(',', $response->headers->get('Link'))
523
        );
524
    }
525
526
    /**
527
     * Test for PATCH Request
528
     *
529
     * @return void
530
     */
531
    public function testPatchAppRequestApplyChanges()
532
    {
533
        $helloApp = new \stdClass();
534
        $helloApp->id = "testapp";
535
        $helloApp->name = new \stdClass();
536
        $helloApp->name->en = "Test App";
537
        $helloApp->showInMenu = false;
538
539
        // 1. Create some App
540
        $client = static::createRestClient();
541
        $client->put('/core/app/' . $helloApp->id, $helloApp);
542
543
        // 2. PATCH request
544
        $client = static::createRestClient();
545
        $patchJson = json_encode(
546
            [
547
                [
548
                    'op' => 'replace',
549
                    'path' => '/name/en',
550
                    'value' => 'Test App Patched'
551
                ]
552
            ]
553
        );
554
        $client->request('PATCH', '/core/app/' . $helloApp->id, array(), array(), array(), $patchJson);
555
        $response = $client->getResponse();
556
557
        $this->assertEquals(200, $response->getStatusCode());
558
559
        // 3. Get changed App and check changed title
560
        $client = static::createRestClient();
561
        $client->request('GET', '/core/app/' . $helloApp->id);
562
563
        $response = $client->getResponse();
564
        $results = $client->getResults();
565
566
        $this->assertResponseContentType(self::CONTENT_TYPE, $response);
567
        $this->assertEquals('Test App Patched', $results->name->en);
568
    }
569
570
    /**
571
     * Test for Malformed PATCH Request
572
     *
573
     * @return void
574
     */
575
    public function testMalformedPatchAppRequest()
576
    {
577
        $helloApp = new \stdClass();
578
        $helloApp->id = "testapp";
579
        $helloApp->title = new \stdClass();
580
        $helloApp->title->en = "Test App";
581
        $helloApp->showInMenu = false;
582
583
        // 1. Create some App
584
        $client = static::createRestClient();
585
        $client->put('/core/app/' . $helloApp->id, $helloApp);
586
587
        // 2. PATCH request
588
        $client = static::createRestClient();
589
        $patchJson = json_encode(
590
            array(
591
                'op' => 'unknown',
592
                'path' => '/title/en'
593
            )
594
        );
595
        $client->request('PATCH', '/core/app/' . $helloApp->id, array(), array(), array(), $patchJson);
596
        $response = $client->getResponse();
597
598
        $this->assertEquals(400, $response->getStatusCode());
599
        $this->assertContains(
600
            'Invalid JSON patch request',
601
            $response->getContent()
602
        );
603
    }
604
605
    /**
606
     * Try to update an app with a non matching ID in GET and req body
607
     *
608
     * @return void
609
     */
610
    public function testNonMatchingIdPutApp()
611
    {
612
        $helloApp = new \stdClass();
613
        $helloApp->id = "tablet";
614
        $helloApp->name = new \stdClass();
615
        $helloApp->name->en = "Tablet";
616
        $helloApp->showInMenu = false;
617
618
        $client = static::createRestClient();
619
        $client->put('/core/app/someotherapp', $helloApp);
620
621
        $response = $client->getResponse();
622
623
        $this->assertContains(
624
            'Record ID in your payload must be the same',
625
            $response->getContent()
626
        );
627
628
        $this->assertEquals(400, $response->getStatusCode());
629
    }
630
631
    /**
632
     * We had an issue when PUTing without ID would create a new record.
633
     * This test ensures that we don't do that, instead we should apply the ID from the GET req.
634
     *
635
     * @return void
636
     */
637
    public function testPutAppNoIdInPayload()
638
    {
639
        $helloApp = new \stdClass();
640
        $helloApp->name = new \stdClass();
641
        $helloApp->name->en = 'New tablet';
642
        $helloApp->showInMenu = false;
643
644
        $client = static::createRestClient();
645
        $client->put('/core/app/tablet', $helloApp);
646
647
        // we sent a location header so we don't want a body
648
        $this->assertNull($client->getResults());
649
650
        $client = static::createRestClient();
651
        $client->request('GET', '/core/app/tablet');
652
        $results = $client->getResults();
653
654
        $this->assertEquals('tablet', $results->id);
655
        $this->assertEquals('New tablet', $results->name->en);
656
        $this->assertFalse($results->showInMenu);
657
    }
658
659
    /**
660
     * test updating an inexistant document (upsert)
661
     *
662
     * @return void
663
     */
664
    public function testUpsertApp()
665
    {
666
        $isnogudApp = new \stdClass;
667
        $isnogudApp->id = 'isnogud';
668
        $isnogudApp->name = new \stdClass;
669
        $isnogudApp->name->en = 'I don\'t exist';
670
        $isnogudApp->showInMenu = true;
671
672
        $client = static::createRestClient();
673
        $client->put('/core/app/isnogud', $isnogudApp);
674
675
        $this->assertEquals(204, $client->getResponse()->getStatusCode());
676
    }
677
678
    /**
679
     * test deleting an app
680
     *
681
     * @return void
682
     */
683
    public function testDeleteApp()
684
    {
685
        $testApp = new \stdClass;
686
        $testApp->id = 'tablet';
687
        $testApp->name = 'Tablet';
688
        $testApp->showInMenu = true;
689
        $testApp->order = 1;
690
691
        $client = static::createRestClient();
692
        $client->request('DELETE', '/core/app/tablet');
693
694
        $response = $client->getResponse();
695
696
        $this->assertEquals(204, $response->getStatusCode());
697
        $this->assertEquals('*', $response->headers->get('Access-Control-Allow-Origin'));
698
        $this->assertEmpty($response->getContent());
699
700
        $client->request('GET', '/core/app/tablet');
701
        $this->assertEquals(404, $client->getResponse()->getStatusCode());
702
    }
703
704
    /**
705
     * test failing validation on boolean field
706
     *
707
     * @return void
708
     */
709
    public function testFailingBooleanValidationOnAppUpdate()
710
    {
711
        $helloApp = new \stdClass;
712
        $helloApp->id = 'tablet';
713
        $helloApp->name = new \stdClass;
714
        $helloApp->name->en = 'Tablet';
715
        $helloApp->showInMenu = 'false';
716
717
        $client = static::createRestClient();
718
        $client->put('/core/app/tablet', $helloApp);
719
720
        $results = $client->getResults();
721
722
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
723
724
        $this->assertContains('showInMenu', $results[0]->propertyPath);
725
        $this->assertEquals('String value found, but a boolean is required', $results[0]->message);
726
    }
727
728
    /**
729
     * test getting schema information
730
     *
731
     * @return void
732
     */
733 View Code Duplication
    public function testGetAppSchemaInformation()
734
    {
735
        $client = static::createRestClient();
736
        $client->request('OPTIONS', '/core/app/hello');
737
738
        $response = $client->getResponse();
739
740
        $this->assertCorsHeaders('GET, POST, PUT, PATCH, DELETE, OPTIONS', $response);
741
    }
742
743
    /**
744
     * requests on OPTIONS and HEAD shall not lead graviton to get any data from mongodb.
745
     * if we page limit(1) this will lead to presence of the x-total-count header if
746
     * data is generated (asserted by testGetAppPagingWithRql()). thus, if we don't
747
     * have this header, we can safely assume that no data has been processed in RestController.
748
     *
749
     * @return void
750
     */
751 View Code Duplication
    public function testNoRecordsAreGeneratedOnPreRequests()
752
    {
753
        $client = static::createRestClient();
754
        $client->request('OPTIONS', '/core/app/?limit(1)');
755
        $response = $client->getResponse();
756
        $this->assertArrayNotHasKey('x-total-count', $response->headers->all());
757
758
        $client = static::createRestClient();
759
        $client->request('HEAD', '/core/app/?limit(1)');
760
        $response = $client->getResponse();
761
        $this->assertArrayNotHasKey('x-total-count', $response->headers->all());
762
    }
763
764
    /**
765
     * test getting schema information from canonical url
766
     *
767
     * @return void
768
     */
769 View Code Duplication
    public function testGetAppSchemaInformationCanonical()
770
    {
771
        $client = static::createRestClient();
772
        $client->request('GET', '/schema/core/app/item');
773
774
        $this->assertIsSchemaResponse($client->getResponse());
775
        $this->assertIsAppSchema($client->getResults());
776
    }
777
778
    /**
779
     * test getting collection schema
780
     *
781
     * @return void
782
     */
783
    public function testGetAppCollectionSchemaInformation()
784
    {
785
        $client = static::createRestClient();
786
787
        $client->request('GET', '/schema/core/app/collection');
788
789
        $response = $client->getResponse();
790
        $results = $client->getResults();
791
792
        $this->assertResponseContentType('application/schema+json', $response);
793
        $this->assertEquals(200, $response->getStatusCode());
794
795
        $this->assertEquals('Array of app objects', $results->title);
796
        $this->assertEquals('array', $results->type);
797
        $this->assertIsAppSchema($results->items);
798
        $this->assertEquals('en', $results->items->properties->name->required[0]);
799
800
        $this->assertCorsHeaders('GET, POST, PUT, PATCH, DELETE, OPTIONS', $response);
801
        $this->assertContains(
802
            'Link',
803
            explode(',', $response->headers->get('Access-Control-Expose-Headers'))
804
        );
805
806
        $this->assertContains(
807
            '<http://localhost/schema/core/app/collection>; rel="self"',
808
            explode(',', $response->headers->get('Link'))
809
        );
810
    }
811
812
    /**
813
     * Test for searchable translations
814
     *
815
     * @dataProvider searchableTranslationDataProvider
816
     *
817
     * @param string $expr     expression
818
     * @param int    $expCount count
819
     *
820
     * @return void
821
     */
822
    public function testSearchableTranslations($expr, $expCount)
823
    {
824
        $client = static::createRestClient();
825
        $client->request(
826
            'GET',
827
            '/core/app/?'.$expr,
828
            array(),
829
            array(),
830
            array('HTTP_ACCEPT_LANGUAGE' => 'en, de')
831
        );
832
833
        $result = $client->getResults();
834
        $this->assertCount($expCount, $result);
835
    }
836
837
    /**
838
     * data provider for searchable translations
839
     *
840
     * @return array data
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,array<string|integer>>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
841
     */
842
    public function searchableTranslationDataProvider()
843
    {
844
        return [
845
            'simple-de' => array('eq(name.de,Die%20Administration)', 1),
846
            'non-existent' => array('eq(name.de,Administration)', 0),
847
            'english' => array('eq(name.en,Administration)', 1),
848
            'no-lang' => array('eq(name,Administration)', 1),
849
            'glob' => array('like(name.de,*Administr*)', 1),
850
            'all-glob' => array('like(name.de,*a*)', 2)
851
        ];
852
    }
853
854
    /**
855
     * ensure we have nice parse error output in rql parse failure
856
     *
857
     * @return void
858
     */
859 View Code Duplication
    public function testRqlSyntaxError()
860
    {
861
        $client = static::createRestClient();
862
863
        $client->request('GET', '/core/app/?eq(name)');
864
865
        $response = $client->getResponse();
866
        $results = $client->getResults();
867
868
        $this->assertEquals(400, $response->getStatusCode());
869
870
        $this->assertContains('syntax error in rql: ', $results->message);
871
        $this->assertContains('Unexpected token', $results->message);
872
    }
873
874
    /**
875
     * check if response looks like schema
876
     *
877
     * @param object $response response
878
     *
879
     * @return void
880
     */
881
    private function assertIsSchemaResponse($response)
882
    {
883
        $this->assertResponseContentType('application/schema+json', $response);
884
        $this->assertEquals(200, $response->getStatusCode());
885
    }
886
887
    /**
888
     * check if a schema is of the app type
889
     *
890
     * @param \stdClass $schema schema from service to validate
891
     *
892
     * @return void
893
     */
894
    private function assertIsAppSchema(\stdClass $schema)
895
    {
896
        $this->assertEquals('App', $schema->title);
897
        $this->assertEquals('A graviton based app.', $schema->description);
898
        $this->assertEquals('object', $schema->type);
899
900
        $this->assertEquals('string', $schema->properties->id->type);
901
        $this->assertEquals('ID', $schema->properties->id->title);
902
        $this->assertEquals('Unique identifier for an app.', $schema->properties->id->description);
903
        $this->assertContains('id', $schema->required);
904
905
        $this->assertEquals('object', $schema->properties->name->type);
906
        $this->assertEquals('translatable', $schema->properties->name->format);
907
        $this->assertEquals('Name', $schema->properties->name->title);
908
        $this->assertEquals('Display name for an app.', $schema->properties->name->description);
909
        $this->assertEquals('string', $schema->properties->name->properties->en->type);
910
        $this->assertContains('name', $schema->required);
911
912
        $this->assertEquals('boolean', $schema->properties->showInMenu->type);
913
        $this->assertEquals('Show in Menu', $schema->properties->showInMenu->title);
914
        $this->assertEquals(
915
            'Define if an app should be exposed on the top level menu.',
916
            $schema->properties->showInMenu->description
917
        );
918
    }
919
}
920