Completed
Push — develop ( a15e86...e115ba )
by Bastian
11s
created

FileControllerTest   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 596
Duplicated Lines 8.72 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 11
c 2
b 0
f 0
lcom 1
cbo 4
dl 52
loc 596
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 10 1
A testFindAllEmptyCollection() 14 14 1
B testPostAndUpdateFile() 0 133 1
A testPostNewFile() 19 19 1
A testPutNewFile() 19 19 1
B testDeleteFile() 0 29 1
B testUpdateFileContent() 0 31 1
B testGetFileCollectionSchemaInformation() 0 27 1
A testPutNewFileViaForm() 0 73 1
B assertIsFileSchema() 0 134 1
A updateFileContent() 0 23 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 /file
4
 */
5
6
namespace Graviton\FileBundle\Tests\Controller;
7
8
use Graviton\TestBundle\Test\RestTestCase;
9
use Symfony\Component\HttpFoundation\File\UploadedFile;
10
use Symfony\Component\HttpFoundation\Response;
11
12
/**
13
 * Basic functional test for /file
14
 *
15
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
16
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
17
 * @link     http://swisscom.ch
18
 */
19
class FileControllerTest extends RestTestCase
20
{
21
    /**
22
     * @const complete content type string expected on a resource
23
     */
24
    const CONTENT_TYPE = 'application/json; charset=UTF-8; profile=http://localhost/schema/file/item';
25
26
    /**
27
     * @const corresponding vendorized schema mime type
28
     */
29
    const COLLECTION_TYPE = 'application/json; charset=UTF-8; profile=http://localhost/schema/file/collection';
30
31
    /**
32
     * setup client and load fixtures
33
     *
34
     * @return void
35
     */
36
    public function setUp()
37
    {
38
        $this->loadFixtures(
39
            array(
40
                'GravitonDyn\FileBundle\DataFixtures\MongoDB\LoadFileData'
41
            ),
42
            null,
43
            'doctrine_mongodb'
44
        );
45
    }
46
47
    /**
48
     * check for empty collections when no fixtures are loaded
49
     *
50
     * @return void
51
     */
52 View Code Duplication
    public function testFindAllEmptyCollection()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
53
    {
54
        // reset fixtures since we already have some from setUp
55
        $this->loadFixtures(array(), null, 'doctrine_mongodb');
56
        $client = static::createRestClient();
57
        $client->request('GET', '/file/');
58
59
        $response = $client->getResponse();
60
        $results = $client->getResults();
61
62
        $this->assertResponseContentType(self::COLLECTION_TYPE, $response);
63
64
        $this->assertEquals(array(), $results);
65
    }
66
67
    /**
68
     * validate that we can post a new file
69
     *
70
     * @return void
71
     */
72
    public function testPostAndUpdateFile()
73
    {
74
        $fixtureData = file_get_contents(__DIR__.'/fixtures/test.txt');
75
        $fileHash = hash('sha256', $fixtureData);
76
        $fileHashCustom = 'some-custom-hash-for-testing';
77
78
        $client = static::createRestClient();
79
        $client->post(
80
            '/file/',
81
            $fixtureData,
82
            [],
83
            [],
84
            ['CONTENT_TYPE' => 'text/plain'],
85
            false
86
        );
87
        $this->assertEmpty($client->getResults());
88
        $response = $client->getResponse();
89
        $this->assertEquals(201, $response->getStatusCode());
90
91
        $fileLocation = $response->headers->get('Location');
92
93
        // update file contents to update mod date
94
        $client = static::createRestClient();
95
        $client->put(
96
            $fileLocation,
97
            $fixtureData,
98
            [],
99
            [],
100
            ['CONTENT_TYPE' => 'text/plain'],
101
            false
102
        );
103
        $this->assertEmpty($client->getResults());
104
        $response = $client->getResponse();
105
        $this->assertEquals(204, $response->getStatusCode());
106
107
        $client = static::createRestClient();
108
        $client->request('GET', $fileLocation);
109
        $data = $client->getResults();
110
111
        // check for valid format
112
        $this->assertNotFalse(\DateTime::createFromFormat(\DateTime::RFC3339, $data->metadata->createDate));
113
        $this->assertNotFalse(\DateTime::createFromFormat(\DateTime::RFC3339, $data->metadata->modificationDate));
114
        // Check valid hash encoding if no hash sent
115
        $this->assertEquals($fileHash, $data->metadata->hash);
116
117
        $data->links = [];
118
        $link = new \stdClass;
119
        $link->{'$ref'} = 'http://localhost/core/app/tablet';
120
        $data->links[] = $link;
121
122
        $filename = "test.txt";
123
        $data->metadata->filename = $filename;
124
        $data->metadata->hash = $fileHashCustom;
125
126
        $client = static::createRestClient();
127
        $client->put(sprintf('/file/%s', $data->id), $data);
128
129
        // re-fetch
130
        $client = static::createRestClient();
131
        $client->request('GET', sprintf('/file/%s', $data->id));
132
        $results = $client->getResults();
133
134
        $this->assertEquals($link->{'$ref'}, $results->links[0]->{'$ref'});
135
        $this->assertEquals($filename, $results->metadata->filename);
136
        $this->assertEquals($fileHashCustom, $data->metadata->hash);
137
138
        $client = static::createClient();
139
        $client->request('GET', sprintf('/file/%s', $data->id), [], [], ['HTTP_ACCEPT' => 'text/plain']);
140
141
        $results = $client->getResponse()->getContent();
142
143
        $this->assertEquals($fixtureData, $results);
144
145
        // change link and add second link
146
        $data->links[0]->{'$ref'} = 'http://localhost/core/app/admin';
147
        $link = new \stdClass;
148
        $link->{'$ref'} = 'http://localhost/core/app/web';
149
        $data->links[] = $link;
150
151
        // also add action command
152
        $command = new \stdClass();
153
        $command->command = 'print';
154
        $data->metadata->action = [$command];
155
156
        // also add additionalInformation
157
        $data->metadata->additionalInformation = 'someInfo';
158
159
        $client = static::createRestClient();
160
        $client->put(sprintf('/file/%s', $data->id), $data);
161
162
        // re-fetch
163
        $client = static::createRestClient();
164
        $client->request('GET', sprintf('/file/%s', $data->id));
165
        $results = $client->getResults();
166
167
        $this->assertEquals($data->links[0]->{'$ref'}, $results->links[0]->{'$ref'});
168
        $this->assertEquals($data->links[1]->{'$ref'}, $results->links[1]->{'$ref'});
169
170
        // check metadata
171
        $this->assertEquals(18, $data->metadata->size);
172
        $this->assertEquals('text/plain', $data->metadata->mime);
173
        $this->assertEquals('test.txt', $data->metadata->filename);
174
        $this->assertEquals('print', $data->metadata->action[0]->command);
175
        $this->assertEquals('someInfo', $data->metadata->additionalInformation);
176
        $this->assertNotNull($data->metadata->createDate);
177
        $this->assertNotNull($data->metadata->modificationDate);
178
179
        // remove a link
180
        unset($data->links[1]);
181
182
        $client = static::createRestClient();
183
        $client->put(sprintf('/file/%s', $data->id), $data);
184
        // re-fetch
185
        $client = static::createRestClient();
186
        $client->request('GET', sprintf('/file/%s', $data->id));
187
        $results = $client->getResults();
188
189
        $this->assertEquals($data->links[0]->{'$ref'}, $results->links[0]->{'$ref'});
190
        $this->assertCount(1, $results->links);
191
192
        // remove last link
193
        $data->links = [];
194
        $client = static::createRestClient();
195
        $client->put(sprintf('/file/%s', $data->id), $data);
196
197
        // re-fetch
198
        $client = static::createRestClient();
199
        $client->request('GET', sprintf('/file/%s', $data->id));
200
201
        $results = $client->getResults();
202
203
        $this->assertEmpty($results->links);
204
    }
205
206
    /**
207
     * validate that we can post a new file
208
     *
209
     * @return void
210
     */
211 View Code Duplication
    public function testPostNewFile()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
212
    {
213
        $client = static::createRestClient();
214
215
        $client->post(
216
            '/file',
217
            file_get_contents(__DIR__.'/fixtures/test.txt'),
218
            [],
219
            [],
220
            ['CONTENT_TYPE' => 'text/plain'],
221
            false
222
        );
223
224
        $response = $client->getResponse();
225
        $linkHeader = $response->headers->get('Link');
226
227
        $this->assertEquals(201, $response->getStatusCode());
228
        $this->assertRegExp('@/file/[a-z0-9]{32}>; rel="self"@', $linkHeader);
229
    }
230
231
    /**
232
     * validate that we can put a new file with a custom id
233
     *
234
     * @return void
235
     */
236 View Code Duplication
    public function testPutNewFile()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
237
    {
238
        $client = static::createRestClient();
239
240
        $client->put(
241
            '/file/testPutNewFile',
242
            file_get_contents(__DIR__ . '/fixtures/test.txt'),
243
            [],
244
            [],
245
            ['CONTENT_TYPE' => 'text/plain'],
246
            false
247
        );
248
249
        $response = $client->getResponse();
250
        $linkHeader = $response->headers->get('Link');
251
252
        $this->assertEquals(204, $response->getStatusCode());
253
        $this->assertContains('file/testPutNewFile>; rel="self"', $linkHeader);
254
    }
255
256
    /**
257
     * validate that we can delete a file
258
     *
259
     * @return void
260
     */
261
    public function testDeleteFile()
262
    {
263
        $fixtureData = file_get_contents(__DIR__.'/fixtures/test.txt');
264
        $client = static::createRestClient();
265
        $client->post(
266
            '/file/',
267
            $fixtureData,
268
            [],
269
            [],
270
            ['CONTENT_TYPE' => 'text/plain'],
271
            false
272
        );
273
        $response = $client->getResponse();
274
        $this->assertEquals(201, $response->getStatusCode());
275
276
        // re-fetch
277
        $client = static::createRestClient();
278
        $client->request('GET', $response->headers->get('Location'));
279
        $data = $client->getResults();
280
281
        $client = static::createRestClient();
282
        $client->request('DELETE', sprintf('/file/%s', $data->id));
283
284
        $client = static::createRestClient();
285
        $client->request('GET', sprintf('/file/%s', $data->id));
286
287
        $response = $client->getResponse();
288
        $this->assertEquals(404, $response->getStatusCode());
289
    }
290
291
    /**
292
     * validate that we can update the content from a file
293
     *
294
     * @return void
295
     */
296
    public function testUpdateFileContent()
297
    {
298
        $fixtureData = file_get_contents(__DIR__.'/fixtures/test.txt');
299
        $contentType = 'text/plain';
300
        $newData = "This is a new text!!!";
301
        $client = static::createRestClient();
302
        $client->post(
303
            '/file/',
304
            $fixtureData,
305
            [],
306
            [],
307
            ['CONTENT_TYPE' => $contentType],
308
            false
309
        );
310
        $response = $client->getResponse();
311
        $this->assertEquals(201, $response->getStatusCode());
312
313
        $linkHeader = $response->headers->get('Link');
314
        $this->assertRegExp('@/file/[a-z0-9]{32}>; rel="self"@', $linkHeader);
315
316
        // re-fetch
317
        $client = static::createRestClient();
318
        $client->request('GET', $response->headers->get('Location'));
319
        $retData = $client->getResults();
320
321
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
322
        $this->assertEquals(strlen($fixtureData), $retData->metadata->size);
323
        $this->assertEquals($contentType, $retData->metadata->mime);
324
325
        $this->updateFileContent($retData->id, $newData, $contentType);
326
    }
327
328
    /**
329
     * test getting collection schema
330
     *
331
     * @return void
332
     */
333
    public function testGetFileCollectionSchemaInformation()
334
    {
335
        $client = static::createRestClient();
336
337
        $client->request('GET', '/schema/file/collection');
338
339
        $response = $client->getResponse();
340
        $results = $client->getResults();
341
342
        $this->assertResponseContentType('application/schema+json', $response);
343
        $this->assertEquals(200, $response->getStatusCode());
344
345
        $this->assertEquals('Array of file objects', $results->title);
346
        $this->assertEquals('array', $results->type);
347
        $this->assertIsFileSchema($results->items);
348
349
        $this->assertCorsHeaders('GET, POST, PUT, PATCH, DELETE, OPTIONS', $response);
350
        $this->assertContains(
351
            'Link',
352
            explode(',', $response->headers->get('Access-Control-Expose-Headers'))
353
        );
354
355
        $this->assertContains(
356
            '<http://localhost/schema/file/collection>; rel="self"',
357
            explode(',', $response->headers->get('Link'))
358
        );
359
    }
360
361
    /**
362
     * test behavior when data sent was multipart/form-data
363
     *
364
     * @return void
365
     */
366
    public function testPutNewFileViaForm()
367
    {
368
        copy(__DIR__ . '/fixtures/test.txt', sys_get_temp_dir() . '/test.txt');
369
        $file = sys_get_temp_dir() . '/test.txt';
370
        $uploadedFile = new UploadedFile($file, 'test.txt', 'text/plain', 15);
371
372
        $jsonData = '{
373
          "id": "myPersonalFile",
374
          "links": [
375
            {
376
              "$ref": "http://localhost/testcase/readonly/101",
377
              "type": "owner"
378
            },
379
            {
380
              "$ref": "http://localhost/testcase/readonly/102",
381
              "type": "module"
382
            }
383
          ],
384
          "metadata": {
385
            "action":[{"command":"print"},{"command":"archive"}],
386
            "additionalInformation": "someInfo",
387
            "additionalProperties": [
388
                {"name": "testName", "value": "testValue"},
389
                {"name": "testName2", "value": "testValue2"}
390
            ],
391
            "filename": "customFileName"
392
          }
393
        }';
394
395
        $client = static::createRestClient();
396
        $client->put(
397
            '/file/myPersonalFile',
398
            [],
399
            [
400
                'metadata' => $jsonData,
401
            ],
402
            [
403
                'upload' => $uploadedFile,
404
            ],
405
            [],
406
            false
407
        );
408
409
        $response = $client->getResponse();
410
411
        $this->assertEquals(Response::HTTP_NO_CONTENT, $response->getStatusCode());
412
        $this->assertNotContains('location', $response->headers->all());
413
414
        $response = $this->updateFileContent('myPersonalFile', "This is a new text!!!");
415
416
        $metaData = json_decode($jsonData, true);
417
        $returnData = json_decode($response->getContent(), true);
418
419
        $this->assertEquals($metaData['links'], $returnData['links']);
420
        $this->assertEquals($metaData['metadata']['action'], $returnData['metadata']['action']);
421
        $this->assertEquals(
422
            $metaData['metadata']['additionalInformation'],
423
            $returnData['metadata']['additionalInformation']
424
        );
425
        $this->assertEquals(
426
            $metaData['metadata']['additionalProperties'],
427
            $returnData['metadata']['additionalProperties']
428
        );
429
        $this->assertCount(2, $returnData['metadata']['additionalProperties']);
430
        $this->assertEquals($metaData['metadata']['filename'], $returnData['metadata']['filename']);
431
432
        // clean up
433
        $client = $this->createClient();
434
        $client->request(
435
            'DELETE',
436
            '/file/myPersonalFile'
437
        );
438
    }
439
440
    /**
441
     * check if a schema is of the file type
442
     *
443
     * @param \stdClass $schema schema from service to validate
444
     *
445
     * @return void
446
     */
447
    private function assertIsFileSchema(\stdClass $schema)
448
    {
449
        $this->assertEquals('File', $schema->title);
450
        $this->assertEquals('File storage service', $schema->description);
451
        $this->assertEquals('object', $schema->type);
452
453
        $this->assertEquals('string', $schema->properties->id->type);
454
        $this->assertEquals('ID', $schema->properties->id->title);
455
        $this->assertEquals('Unique identifier', $schema->properties->id->description);
456
        $this->assertObjectNotHasAttribute('readOnly', $schema->properties->id);
457
458
        // Metadata
459
        $this->assertEquals('object', $schema->properties->metadata->type);
460
        $this->assertEquals('Metadata', $schema->properties->metadata->title);
461
        $this->assertObjectNotHasAttribute('readOnly', $schema->properties->metadata);
462
463
        // Metadata size
464
        $this->assertEquals('integer', $schema->properties->metadata->properties->size->type);
465
        $this->assertEquals('File size', $schema->properties->metadata->properties->size->title);
466
        $this->assertEquals('Size of file.', $schema->properties->metadata->properties->size->description);
467
468
        // Metadata mime
469
        $this->assertContains('string', $schema->properties->metadata->properties->mime->type);
470
        $this->assertEquals('MIME Type', $schema->properties->metadata->properties->mime->title);
471
        $this->assertEquals('MIME-Type of file.', $schema->properties->metadata->properties->mime->description);
472
473
        // Metadata createDate
474
        $this->assertEquals(['string', 'null'], $schema->properties->metadata->properties->createDate->type);
475
        $this->assertEquals('date-time', $schema->properties->metadata->properties->createDate->format);
476
        $this->assertEquals('Creation date', $schema->properties->metadata->properties->createDate->title);
477
        $this->assertEquals(
478
            'Timestamp of file upload.',
479
            $schema->properties->metadata->properties->createDate->description
480
        );
481
482
        // Metadata modificationDate
483
        $this->assertEquals(['string', 'null'], $schema->properties->metadata->properties->modificationDate->type);
484
        $this->assertEquals('date-time', $schema->properties->metadata->properties->modificationDate->format);
485
        $this->assertEquals('Modification date', $schema->properties->metadata->properties->modificationDate->title);
486
        $this->assertEquals(
487
            'Timestamp of the last file change.',
488
            $schema->properties->metadata->properties->modificationDate->description
489
        );
490
491
        // Metadata filename
492
        $this->assertContains('string', $schema->properties->metadata->properties->filename->type);
493
        $this->assertEquals('File name', $schema->properties->metadata->properties->filename->title);
494
        $this->assertEquals(
495
            'Name of the file as it should get displayed to the user.',
496
            $schema->properties->metadata->properties->filename->description
497
        );
498
        $this->assertObjectNotHasAttribute('readOnly', $schema->properties->metadata->properties->filename);
499
500
        // metadata action.command array
501
        $this->assertContains(
502
            'string',
503
            $schema->properties->metadata->properties->action->items->properties->command->type
504
        );
505
        $this->assertEquals(
506
            'Action command array',
507
            $schema->properties->metadata->properties->action->items->properties->command->title
508
        );
509
        $this->assertObjectNotHasAttribute(
510
            'readOnly',
511
            $schema->properties->metadata->properties->action->items->properties->command
512
        );
513
514
        // metadata additionalInformation
515
        $this->assertContains(
516
            'string',
517
            $schema->properties->metadata->properties->additionalInformation->type
518
        );
519
        $this->assertEquals(
520
            'Additional Information',
521
            $schema->properties->metadata->properties->additionalInformation->title
522
        );
523
        $this->assertObjectNotHasAttribute(
524
            'readOnly',
525
            $schema->properties->metadata->properties->additionalInformation
526
        );
527
528
        // metadata additionalProperties
529
        $additionalPropertiesSchema = $schema->properties->metadata->properties->additionalProperties;
530
        $this->assertEquals('array', $additionalPropertiesSchema->type);
531
        $this->assertEquals('object', $additionalPropertiesSchema->items->type);
532
        $this->assertEquals('string', $additionalPropertiesSchema->items->properties->name->type);
533
        $this->assertEquals('property name', $additionalPropertiesSchema->items->properties->name->title);
534
        $this->assertEquals('string', $additionalPropertiesSchema->items->properties->value->type);
535
        $this->assertEquals('property value', $additionalPropertiesSchema->items->properties->value->title);
536
537
        // Links
538
        $this->assertEquals('array', $schema->properties->links->type);
539
        $this->assertEquals('many', $schema->properties->links->format);
540
        $this->assertEquals('links', $schema->properties->links->title);
541
        $this->assertEquals('@todo replace me', $schema->properties->links->description);
542
        $this->assertObjectNotHasAttribute('readOnly', $schema->properties->links);
543
544
545
        // Links items
546
        $this->assertEquals('object', $schema->properties->links->items->type);
547
        $this->assertEquals('Links', $schema->properties->links->items->title);
548
        $this->assertObjectNotHasAttribute('readOnly', $schema->properties->links->items);
549
550
551
        // Links item type
552
        $this->assertContains('string', $schema->properties->links->items->properties->type->type);
553
        $this->assertEquals('Type', $schema->properties->links->items->properties->type->title);
554
        $this->assertEquals('Type of the link.', $schema->properties->links->items->properties->type->description);
555
        $this->assertObjectNotHasAttribute('readOnly', $schema->properties->links->items->properties->type);
556
557
        // Links item $ref
558
        $this->assertEquals(['string', 'null'], $schema->properties->links->items->properties->{'$ref'}->type);
559
        $this->assertEquals('extref', $schema->properties->links->items->properties->{'$ref'}->format);
560
        $this->assertEquals('Link', $schema->properties->links->items->properties->{'$ref'}->title);
561
        $this->assertEquals(
562
            'Link to any document.',
563
            $schema->properties->links->items->properties->{'$ref'}->description
564
        );
565
        $this->assertEquals(
566
            ['*'],
567
            $schema->properties->links->items->properties->{'$ref'}->{'x-collection'}
568
        );
569
570
        $this->assertEquals(
571
            [
572
                'document.file.file.update',
573
                'document.file.file.create',
574
                'document.file.file.delete'
575
            ],
576
            $schema->{'x-events'}
577
        );
578
579
        $this->assertObjectNotHasAttribute('readOnly', $schema->properties->links->items->properties->{'$ref'});
580
    }
581
582
    /**
583
     * Verifies the update of a file content.
584
     *
585
     * @param string $fileId      identifier of the file to be updated
586
     * @param string $newContent  new content to be stored in the file
587
     * @param string $contentType Content-Type of the file
588
     *
589
     * @return null|Response
0 ignored issues
show
Documentation introduced by
Should the return type not be object|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
590
     */
591
    private function updateFileContent($fileId, $newContent, $contentType = 'text/plain')
592
    {
593
        $client = static::createRestClient();
594
        $client->put(
595
            sprintf('/file/%s', $fileId),
596
            $newContent,
597
            [],
598
            [],
599
            ['CONTENT_TYPE' => $contentType],
600
            false
601
        );
602
603
        $client = static::createRestClient();
604
        $client->request('GET', sprintf('/file/%s', $fileId));
605
606
        $retData = $client->getResults();
607
        $response = $client->getResponse();
608
        $this->assertEquals(200, $response->getStatusCode());
609
        $this->assertEquals(strlen($newContent), $retData->metadata->size);
610
        $this->assertEquals($contentType, $retData->metadata->mime);
611
612
        return $response;
613
    }
614
}
615