Completed
Push — feature/EVO-6779-events-on-uns... ( b3380c )
by Adrian
12:13
created

AppControllerTest   C

Complexity

Total Complexity 34

Size/Duplication

Total Lines 873
Duplicated Lines 6.53 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 34
c 1
b 1
f 0
lcom 1
cbo 2
dl 57
loc 873
rs 5.4117

32 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 14 1
B testFindAll() 0 27 1
B testMalformedPatchAppRequest() 0 29 1
A testNonMatchingIdPutApp() 0 20 1
A testPutAppNoIdInPayload() 0 21 1
A testUpsertApp() 0 13 1
A testDeleteApp() 0 20 1
A testFailingBooleanValidationOnAppUpdate() 0 18 1
A testGetAppSchemaInformation() 9 9 1
A testNoRecordsAreGeneratedOnPreRequests() 12 12 1
A testGetAppSchemaInformationCanonical() 8 8 1
B testGetAppCollectionSchemaInformation() 0 28 1
A testSearchableTranslations() 0 14 1
A searchableTranslationDataProvider() 0 11 1
A testRqlSyntaxError() 14 14 1
A assertIsSchemaResponse() 0 5 1
B assertIsAppSchema() 0 25 1
B testGetAppWithFilteringAndPaging() 0 25 1
A testGetAppPagingWithRql() 0 51 1
A testInvalidPagingPageSize() 0 8 1
A invalidPagingPageSizeProvider() 0 7 1
A testRqlIsParsedOnlyOnGetRequest() 0 51 1
B testOnlyRqlSelectIsAllowedOnGetOne() 0 28 2
A testFindAllEmptyCollection() 14 14 1
A testGetApp() 0 19 1
B testPostApp() 0 29 1
A testPostEmptyApp() 0 16 1
A testPostNonObjectApp() 0 9 1
B testPostMalformedApp() 0 29 2
A testPostWithId() 0 15 1
B testPutApp() 0 27 1
B testPatchAppRequestApplyChanges() 0 38 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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