Completed
Push — feature/EVO-6659-strict-search... ( 02a1a1 )
by
unknown
12:06
created

testNoRecordsAreGeneratedOnPreRequests()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
dl 12
loc 12
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 9
nc 1
nop 0
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
    /**
115
     * rql limit() should *never* be overwritten by default value
116
     *
117
     * @return void
118
     */
119
    public function testGetAppPagingWithRql()
120
    {
121
        // does limit work?
122
        $client = static::createRestClient();
123
        $client->request('GET', '/core/app/?limit(1)');
124
        $this->assertEquals(1, count($client->getResults()));
125
126
        $response = $client->getResponse();
127
128
        $this->assertContains(
129
            '<http://localhost/core/app/?limit(1)>; rel="self"',
130
            $response->headers->get('Link')
131
        );
132
133
        $this->assertContains(
134
            '<http://localhost/core/app/?limit(1%2C1)>; rel="next"',
135
            $response->headers->get('Link')
136
        );
137
138
        $this->assertContains(
139
            '<http://localhost/core/app/?limit(1%2C1)>; rel="last"',
140
            $response->headers->get('Link')
141
        );
142
143
        $this->assertSame('2', $response->headers->get('X-Total-Count'));
144
145
        /*** pagination tests **/
146
        $client = static::createRestClient();
147
        $client->request('GET', '/core/app/?limit(1,1)');
148
        $this->assertEquals(1, count($client->getResults()));
149
150
        $response = $client->getResponse();
151
152
        $this->assertContains(
153
            '<http://localhost/core/app/?limit(1%2C1)>; rel="self"',
154
            $response->headers->get('Link')
155
        );
156
157
        $this->assertContains(
158
            '<http://localhost/core/app/?limit(1%2C0)>; rel="prev"',
159
            $response->headers->get('Link')
160
        );
161
162
        // we're on the 'last' page - so 'last' should not be in in Link header
163
        $this->assertNotContains(
164
            'rel="last"',
165
            $response->headers->get('Link')
166
        );
167
168
        $this->assertSame('2', $response->headers->get('X-Total-Count'));
169
    }
170
171
    /**
172
     * check for a client error if invalid limit value is provided
173
     *
174
     * @dataProvider invalidPagingPageSizeProvider
175
     *
176
     * @param integer $limit limit value that should fail
177
     * @return void
178
     */
179
    public function testInvalidPagingPageSize($limit)
180
    {
181
        $client = static::createRestClient();
182
        $client->request('GET', sprintf('/core/app/?limit(%s)', $limit));
183
184
        $this->assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
185
        $this->assertContains('negative or null limit in rql', $client->getResults()->message);
186
    }
187
188
    /**
189
     * page size test provides
190
     *
191
     * @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...
192
     */
193
    public function invalidPagingPageSizeProvider()
194
    {
195
        return [
196
            [0],
197
            [-1],
198
        ];
199
    }
200
201
    /**
202
     * RQL is parsed only when we get apps
203
     *
204
     * @return void
205
     */
206
    public function testRqlIsParsedOnlyOnGetRequest()
207
    {
208
        $appData = [
209
            'showInMenu' => false,
210
            'order'      => 100,
211
            'name'      => ['en' => 'Administration'],
212
        ];
213
214
        $client = static::createRestClient();
215
        $client->request('GET', '/core/app/?invalidrqlquery');
216
        $this->assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
217
        $this->assertContains('syntax error in rql', $client->getResults()->message);
218
219
        $client = static::createRestClient();
220
        $client->request('GET', '/core/app/admin?invalidrqlquery');
221
        $this->assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
222
        $this->assertContains('syntax error in rql', $client->getResults()->message);
223
224
        $client = static::createRestClient();
225
        $client->request('OPTIONS', '/core/app/?invalidrqlquery');
226
        $this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
227
228
        $client = static::createRestClient();
229
        $client->request('OPTIONS', '/schema/core/app/collection?invalidrqlquery');
230
        $this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
231
232
        $client = static::createRestClient();
233
        $client->request('OPTIONS', '/schema/core/app/item?invalidrqlquery');
234
        $this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
235
236
        $client = static::createRestClient();
237
        $client->request('GET', '/schema/core/app/collection?invalidrqlquery');
238
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
239
240
        $client = static::createRestClient();
241
        $client->request('GET', '/schema/core/app/item?invalidrqlquery');
242
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
243
244
245
        $client = static::createRestClient();
246
        $client->post('/core/app/?invalidrqlquery', $appData);
247
        $this->assertEquals(Response::HTTP_CREATED, $client->getResponse()->getStatusCode());
248
249
        $client = static::createRestClient();
250
        $client->put('/core/app/admin?invalidrqlquery', $appData);
251
        $this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
252
253
        $client = static::createRestClient();
254
        $client->request('DELETE', '/core/app/admin?invalidrqlquery');
255
        $this->assertEquals(Response::HTTP_NO_CONTENT, $client->getResponse()->getStatusCode());
256
    }
257
258
    /**
259
     * Test only RQL select() operator is allowed for GET one
260
     *
261
     * @return void
262
     * @group tmp
263
     */
264
    public function testOnlyRqlSelectIsAllowedOnGetOne()
265
    {
266
        $client = static::createRestClient();
267
        $client->request('GET', '/core/app/?select(id)');
268
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
269
270
        $client = static::createRestClient();
271
        $client->request('GET', '/core/app/admin?select(id)');
272
        $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
273
274
        foreach ([
275
                     'limit' => 'limit(1)',
276
                     'sort'  => 'sort(+id)',
277
                     'eq'    => 'eq(id,a)',
278
                 ] as $extraRqlOperator => $extraRqlOperatorQuery) {
279
            $client = static::createRestClient();
280
            $client->request('GET', '/core/app/?select(id)&'.$extraRqlOperatorQuery);
281
            $this->assertEquals(Response::HTTP_OK, $client->getResponse()->getStatusCode());
282
283
            $client = static::createRestClient();
284
            $client->request('GET', '/core/app/admin?select(id)&'.$extraRqlOperatorQuery);
285
            $this->assertEquals(Response::HTTP_BAD_REQUEST, $client->getResponse()->getStatusCode());
286
            $this->assertEquals(
287
                sprintf('RQL operator "%s" is not allowed for this request', $extraRqlOperator),
288
                $client->getResults()->message
289
            );
290
        }
291
    }
292
293
    /**
294
     * check for empty collections when no fixtures are loaded
295
     *
296
     * @return void
297
     */
298 View Code Duplication
    public function testFindAllEmptyCollection()
299
    {
300
        // reset fixtures since we already have some from setUp
301
        $this->loadFixtures(array(), null, 'doctrine_mongodb');
302
        $client = static::createRestClient();
303
        $client->request('GET', '/core/app/');
304
305
        $response = $client->getResponse();
306
        $results = $client->getResults();
307
308
        $this->assertResponseContentType(self::COLLECTION_TYPE, $response);
309
310
        $this->assertEquals(array(), $results);
311
    }
312
313
    /**
314
     * test if we can get an app by id
315
     *
316
     * @return void
317
     */
318
    public function testGetApp()
319
    {
320
        $client = static::createRestClient();
321
        $client->request('GET', '/core/app/admin');
322
        $response = $client->getResponse();
323
        $results = $client->getResults();
324
325
        $this->assertResponseContentType(self::CONTENT_TYPE, $response);
326
327
        $this->assertEquals('admin', $results->id);
328
        $this->assertEquals('Administration', $results->name->en);
329
        $this->assertEquals(true, $results->showInMenu);
330
331
        $this->assertContains(
332
            '<http://localhost/core/app/admin>; rel="self"',
333
            $response->headers->get('Link')
334
        );
335
        $this->assertEquals('*', $response->headers->get('Access-Control-Allow-Origin'));
336
    }
337
338
    /**
339
     * test if we can create an app through POST
340
     *
341
     * @return void
342
     */
343
    public function testPostApp()
344
    {
345
        $testApp = new \stdClass;
346
        $testApp->name = new \stdClass;
347
        $testApp->name->en = 'new Test App';
348
        $testApp->showInMenu = true;
349
350
        $client = static::createRestClient();
351
        $client->post('/core/app/', $testApp);
352
        $response = $client->getResponse();
353
        $results = $client->getResults();
354
355
        // we sent a location header so we don't want a body
356
        $this->assertNull($results);
357
        $this->assertContains('/core/app/', $response->headers->get('Location'));
358
359
        $client = static::createRestClient();
360
        $client->request('GET', $response->headers->get('Location'));
361
        $response = $client->getResponse();
362
        $results = $client->getResults();
363
364
        $this->assertResponseContentType(self::CONTENT_TYPE, $response);
365
        $this->assertEquals('new Test App', $results->name->en);
366
        $this->assertTrue($results->showInMenu);
367
        $this->assertContains(
368
            '<http://localhost/core/app/'.$results->id.'>; rel="self"',
369
            explode(',', $response->headers->get('Link'))
370
        );
371
    }
372
373
    /**
374
     * test if we get a correct return if we post empty.
375
     *
376
     * @return void
377
     */
378
    public function testPostEmptyApp()
379
    {
380
        $client = static::createRestClient();
381
382
        // send nothing really..
383
        $client->post('/core/app/', "", array(), array(), array(), false);
384
385
        $response = $client->getResponse();
386
387
        $this->assertContains(
388
            'No input data',
389
            $response->getContent()
390
        );
391
392
        $this->assertEquals(400, $response->getStatusCode());
393
    }
394
395
    /**
396
     * test if we get a correct return if we post empty.
397
     *
398
     * @return void
399
     */
400
    public function testPostNonObjectApp()
401
    {
402
        $client = static::createRestClient();
403
        $client->post('/core/app/', "non-object value");
404
405
        $response = $client->getResponse();
406
        $this->assertContains('JSON request body must be an object', $response->getContent());
407
        $this->assertEquals(400, $response->getStatusCode());
408
    }
409
410
    /**
411
     * test if 500 error is reported when posting an malformed input
412
     *
413
     * @return void
414
     */
415
    public function testPostMalformedApp()
416
    {
417
        $testApp = new \stdClass;
418
        $testApp->name = new \stdClass;
419
        $testApp->name->en = 'new Test App';
420
        $testApp->showInMenu = true;
421
422
        // malform it ;-)
423
        $input = str_replace(":", ";", json_encode($testApp));
424
425
        $client = static::createRestClient();
426
427
        // make sure this is sent as 'raw' input (not json_encoded again)
428
        $client->post('/core/app/', $input, array(), array(), array(), false);
429
430
        $response = $client->getResponse();
431
432
        // Check that error message contains detailed reason
433
        json_decode($input);
434
        $lastJsonError = function_exists('json_last_error_msg')
435
            ? json_last_error_msg()
436
            : 'Unable to decode JSON string';
437
        $this->assertContains(
438
            $lastJsonError,
439
            $client->getResults()->message
440
        );
441
442
        $this->assertEquals(400, $response->getStatusCode());
443
    }
444
445
    /**
446
     * Tests if an error is returned when an id is send in a post
447
     *
448
     * @return void
449
     */
450
    public function testPostWithId()
451
    {
452
        $helloApp = new \stdClass();
453
        $helloApp->id = 101;
454
        $helloApp->name = "tubel";
455
456
        $client = static::createRestClient();
457
        $client->post('/person/customer', $helloApp);
458
459
        $this->assertEquals(
460
            'Bad Request - "id" can not be given on a POST request. '.
461
            'Do a PUT request instead to update an existing record.',
462
            $client->getResults()->message
463
        );
464
    }
465
    /**
466
     * test updating apps
467
     *
468
     * @return void
469
     */
470
    public function testPutApp()
471
    {
472
        $helloApp = new \stdClass();
473
        $helloApp->id = "tablet";
474
        $helloApp->name = new \stdClass();
475
        $helloApp->name->en = "Tablet";
476
        $helloApp->showInMenu = false;
477
478
        $client = static::createRestClient();
479
        $client->put('/core/app/tablet', $helloApp);
480
481
        $this->assertNull($client->getResults());
482
        $this->assertNull($client->getResponse()->headers->get('Location'));
483
484
        $client = static::createRestClient();
485
        $client->request('GET', '/core/app/tablet');
486
        $response = $client->getResponse();
487
        $results = $client->getResults();
488
489
        $this->assertResponseContentType(self::CONTENT_TYPE, $response);
490
        $this->assertEquals('Tablet', $results->name->en);
491
        $this->assertFalse($results->showInMenu);
492
        $this->assertContains(
493
            '<http://localhost/core/app/tablet>; rel="self"',
494
            explode(',', $response->headers->get('Link'))
495
        );
496
497
    }
498
499
    /**
500
     * Test for PATCH Request
501
     *
502
     * @return void
503
     */
504
    public function testPatchAppRequestApplyChanges()
505
    {
506
        $helloApp = new \stdClass();
507
        $helloApp->id = "testapp";
508
        $helloApp->name = new \stdClass();
509
        $helloApp->name->en = "Test App";
510
        $helloApp->showInMenu = false;
511
512
        // 1. Create some App
513
        $client = static::createRestClient();
514
        $client->put('/core/app/' . $helloApp->id, $helloApp);
515
516
        // 2. PATCH request
517
        $client = static::createRestClient();
518
        $patchJson = json_encode(
519
            [
520
                [
521
                    'op' => 'replace',
522
                    'path' => '/name/en',
523
                    'value' => 'Test App Patched'
524
                ]
525
            ]
526
        );
527
        $client->request('PATCH', '/core/app/' . $helloApp->id, array(), array(), array(), $patchJson);
528
        $response = $client->getResponse();
529
530
        $this->assertEquals(200, $response->getStatusCode());
531
532
        // 3. Get changed App and check changed title
533
        $client = static::createRestClient();
534
        $client->request('GET', '/core/app/' . $helloApp->id);
535
536
        $response = $client->getResponse();
537
        $results = $client->getResults();
538
539
        $this->assertResponseContentType(self::CONTENT_TYPE, $response);
540
        $this->assertEquals('Test App Patched', $results->name->en);
541
    }
542
543
    /**
544
     * Test for Malformed PATCH Request
545
     *
546
     * @return void
547
     */
548
    public function testMalformedPatchAppRequest()
549
    {
550
        $helloApp = new \stdClass();
551
        $helloApp->id = "testapp";
552
        $helloApp->title = new \stdClass();
553
        $helloApp->title->en = "Test App";
554
        $helloApp->showInMenu = false;
555
556
        // 1. Create some App
557
        $client = static::createRestClient();
558
        $client->put('/core/app/' . $helloApp->id, $helloApp);
559
560
        // 2. PATCH request
561
        $client = static::createRestClient();
562
        $patchJson = json_encode(
563
            array(
564
                'op' => 'unknown',
565
                'path' => '/title/en'
566
            )
567
        );
568
        $client->request('PATCH', '/core/app/' . $helloApp->id, array(), array(), array(), $patchJson);
569
        $response = $client->getResponse();
570
571
        $this->assertEquals(400, $response->getStatusCode());
572
        $this->assertContains(
573
            'Invalid JSON patch request',
574
            $response->getContent()
575
        );
576
    }
577
578
    /**
579
     * Try to update an app with a non matching ID in GET and req body
580
     *
581
     * @return void
582
     */
583
    public function testNonMatchingIdPutApp()
584
    {
585
        $helloApp = new \stdClass();
586
        $helloApp->id = "tablet";
587
        $helloApp->name = new \stdClass();
588
        $helloApp->name->en = "Tablet";
589
        $helloApp->showInMenu = false;
590
591
        $client = static::createRestClient();
592
        $client->put('/core/app/someotherapp', $helloApp);
593
594
        $response = $client->getResponse();
595
596
        $this->assertContains(
597
            'Record ID in your payload must be the same',
598
            $response->getContent()
599
        );
600
601
        $this->assertEquals(400, $response->getStatusCode());
602
    }
603
604
    /**
605
     * We had an issue when PUTing without ID would create a new record.
606
     * This test ensures that we don't do that, instead we should apply the ID from the GET req.
607
     *
608
     * @return void
609
     */
610
    public function testPutAppNoIdInPayload()
611
    {
612
        $helloApp = new \stdClass();
613
        $helloApp->name = new \stdClass();
614
        $helloApp->name->en = 'New tablet';
615
        $helloApp->showInMenu = false;
616
617
        $client = static::createRestClient();
618
        $client->put('/core/app/tablet', $helloApp);
619
620
        // we sent a location header so we don't want a body
621
        $this->assertNull($client->getResults());
622
623
        $client = static::createRestClient();
624
        $client->request('GET', '/core/app/tablet');
625
        $results = $client->getResults();
626
627
        $this->assertEquals('tablet', $results->id);
628
        $this->assertEquals('New tablet', $results->name->en);
629
        $this->assertFalse($results->showInMenu);
630
    }
631
632
    /**
633
     * test updating an inexistant document (upsert)
634
     *
635
     * @return void
636
     */
637
    public function testUpsertApp()
638
    {
639
        $isnogudApp = new \stdClass;
640
        $isnogudApp->id = 'isnogud';
641
        $isnogudApp->name = new \stdClass;
642
        $isnogudApp->name->en = 'I don\'t exist';
643
        $isnogudApp->showInMenu = true;
644
645
        $client = static::createRestClient();
646
        $client->put('/core/app/isnogud', $isnogudApp);
647
648
        $this->assertEquals(204, $client->getResponse()->getStatusCode());
649
    }
650
651
    /**
652
     * test deleting an app
653
     *
654
     * @return void
655
     */
656
    public function testDeleteApp()
657
    {
658
        $testApp = new \stdClass;
659
        $testApp->id = 'tablet';
660
        $testApp->name = 'Tablet';
661
        $testApp->showInMenu = true;
662
        $testApp->order = 1;
663
664
        $client = static::createRestClient();
665
        $client->request('DELETE', '/core/app/tablet');
666
667
        $response = $client->getResponse();
668
669
        $this->assertEquals(204, $response->getStatusCode());
670
        $this->assertEquals('*', $response->headers->get('Access-Control-Allow-Origin'));
671
        $this->assertEmpty($response->getContent());
672
673
        $client->request('GET', '/core/app/tablet');
674
        $this->assertEquals(404, $client->getResponse()->getStatusCode());
675
    }
676
677
    /**
678
     * test failing validation on boolean field
679
     *
680
     * @return void
681
     */
682
    public function testFailingBooleanValidationOnAppUpdate()
683
    {
684
        $helloApp = new \stdClass;
685
        $helloApp->id = 'tablet';
686
        $helloApp->name = new \stdClass;
687
        $helloApp->name->en = 'Tablet';
688
        $helloApp->showInMenu = 'false';
689
690
        $client = static::createRestClient();
691
        $client->put('/core/app/tablet', $helloApp);
692
693
        $results = $client->getResults();
694
695
        $this->assertEquals(400, $client->getResponse()->getStatusCode());
696
697
        $this->assertContains('showInMenu', $results[0]->propertyPath);
698
        $this->assertEquals('String value found, but a boolean is required', $results[0]->message);
699
    }
700
701
    /**
702
     * test getting schema information
703
     *
704
     * @return void
705
     */
706 View Code Duplication
    public function testGetAppSchemaInformation()
707
    {
708
        $client = static::createRestClient();
709
        $client->request('OPTIONS', '/core/app/hello');
710
711
        $response = $client->getResponse();
712
713
        $this->assertCorsHeaders('GET, POST, PUT, PATCH, DELETE, OPTIONS', $response);
714
    }
715
716
    /**
717
     * requests on OPTIONS and HEAD shall not lead graviton to get any data from mongodb.
718
     * if we page limit(1) this will lead to presence of the x-total-count header if
719
     * data is generated (asserted by testGetAppPagingWithRql()). thus, if we don't
720
     * have this header, we can safely assume that no data has been processed in RestController.
721
     *
722
     * @return void
723
     */
724 View Code Duplication
    public function testNoRecordsAreGeneratedOnPreRequests()
725
    {
726
        $client = static::createRestClient();
727
        $client->request('OPTIONS', '/core/app/?limit(1)');
728
        $response = $client->getResponse();
729
        $this->assertArrayNotHasKey('x-total-count', $response->headers->all());
730
731
        $client = static::createRestClient();
732
        $client->request('HEAD', '/core/app/?limit(1)');
733
        $response = $client->getResponse();
734
        $this->assertArrayNotHasKey('x-total-count', $response->headers->all());
735
    }
736
737
    /**
738
     * test getting schema information from canonical url
739
     *
740
     * @return void
741
     */
742 View Code Duplication
    public function testGetAppSchemaInformationCanonical()
743
    {
744
        $client = static::createRestClient();
745
        $client->request('GET', '/schema/core/app/item');
746
747
        $this->assertIsSchemaResponse($client->getResponse());
748
        $this->assertIsAppSchema($client->getResults());
749
    }
750
751
    /**
752
     * test getting collection schema
753
     *
754
     * @return void
755
     */
756
    public function testGetAppCollectionSchemaInformation()
757
    {
758
        $client = static::createRestClient();
759
760
        $client->request('GET', '/schema/core/app/collection');
761
762
        $response = $client->getResponse();
763
        $results = $client->getResults();
764
765
        $this->assertResponseContentType('application/schema+json', $response);
766
        $this->assertEquals(200, $response->getStatusCode());
767
768
        $this->assertEquals('Array of app objects', $results->title);
769
        $this->assertEquals('array', $results->type);
770
        $this->assertIsAppSchema($results->items);
771
        $this->assertEquals('en', $results->items->properties->name->required[0]);
772
773
        $this->assertCorsHeaders('GET, POST, PUT, PATCH, DELETE, OPTIONS', $response);
774
        $this->assertContains(
775
            'Link',
776
            explode(',', $response->headers->get('Access-Control-Expose-Headers'))
777
        );
778
779
        $this->assertContains(
780
            '<http://localhost/schema/core/app/collection>; rel="self"',
781
            explode(',', $response->headers->get('Link'))
782
        );
783
    }
784
785
    /**
786
     * Test for searchable translations
787
     *
788
     * @dataProvider searchableTranslationDataProvider
789
     *
790
     * @param string $expr     expression
791
     * @param int    $expCount count
792
     *
793
     * @return void
794
     */
795
    public function testSearchableTranslations($expr, $expCount)
796
    {
797
        $client = static::createRestClient();
798
        $client->request(
799
            'GET',
800
            '/core/app/?'.$expr,
801
            array(),
802
            array(),
803
            array('HTTP_ACCEPT_LANGUAGE' => 'en, de')
804
        );
805
806
        $result = $client->getResults();
807
        $this->assertCount($expCount, $result);
808
    }
809
810
    /**
811
     * data provider for searchable translations
812
     *
813
     * @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...
814
     */
815
    public function searchableTranslationDataProvider()
816
    {
817
        return [
818
            'simple-de' => array('eq(name.de,Die%20Administration)', 1),
819
            'non-existent' => array('eq(name.de,Administration)', 0),
820
            'english' => array('eq(name.en,Administration)', 1),
821
            'no-lang' => array('eq(name,Administration)', 1),
822
            'glob' => array('like(name.de,*Administr*)', 1),
823
            'all-glob' => array('like(name.de,*a*)', 2)
824
        ];
825
    }
826
827
    /**
828
     * ensure we have nice parse error output in rql parse failure
829
     *
830
     * @return void
831
     */
832 View Code Duplication
    public function testRqlSyntaxError()
833
    {
834
        $client = static::createRestClient();
835
836
        $client->request('GET', '/core/app/?eq(name)');
837
838
        $response = $client->getResponse();
839
        $results = $client->getResults();
840
841
        $this->assertEquals(400, $response->getStatusCode());
842
843
        $this->assertContains('syntax error in rql: ', $results->message);
844
        $this->assertContains('Unexpected token', $results->message);
845
    }
846
847
    /**
848
     * check if response looks like schema
849
     *
850
     * @param object $response response
851
     *
852
     * @return void
853
     */
854
    private function assertIsSchemaResponse($response)
855
    {
856
        $this->assertResponseContentType('application/schema+json', $response);
857
        $this->assertEquals(200, $response->getStatusCode());
858
    }
859
860
    /**
861
     * check if a schema is of the app type
862
     *
863
     * @param \stdClass $schema schema from service to validate
864
     *
865
     * @return void
866
     */
867
    private function assertIsAppSchema(\stdClass $schema)
868
    {
869
        $this->assertEquals('App', $schema->title);
870
        $this->assertEquals('A graviton based app.', $schema->description);
871
        $this->assertEquals('object', $schema->type);
872
873
        $this->assertEquals('string', $schema->properties->id->type);
874
        $this->assertEquals('ID', $schema->properties->id->title);
875
        $this->assertEquals('Unique identifier for an app.', $schema->properties->id->description);
876
        $this->assertContains('id', $schema->required);
877
878
        $this->assertEquals('object', $schema->properties->name->type);
879
        $this->assertEquals('translatable', $schema->properties->name->format);
880
        $this->assertEquals('Name', $schema->properties->name->title);
881
        $this->assertEquals('Display name for an app.', $schema->properties->name->description);
882
        $this->assertEquals('string', $schema->properties->name->properties->en->type);
883
        $this->assertContains('name', $schema->required);
884
885
        $this->assertEquals('boolean', $schema->properties->showInMenu->type);
886
        $this->assertEquals('Show in Menu', $schema->properties->showInMenu->title);
887
        $this->assertEquals(
888
            'Define if an app should be exposed on the top level menu.',
889
            $schema->properties->showInMenu->description
890
        );
891
    }
892
}
893