Completed
Push — feature/evo-2427-file-fix ( c9c58c )
by Adrian
09:10
created

FileControllerTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 10
rs 9.4286
cc 1
eloc 6
nc 1
nop 0
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 resouce
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
        $client = static::createRestClient();
76
        $client->post(
77
            '/file/',
78
            $fixtureData,
79
            [],
80
            [],
81
            ['CONTENT_TYPE' => 'text/plain'],
82
            false
83
        );
84
        $this->assertEmpty($client->getResults());
85
        $response = $client->getResponse();
86
        $this->assertEquals(201, $response->getStatusCode());
87
88
        $fileLocation = $response->headers->get('Location');
89
90
        // update file contents to update mod date
91
        $client = static::createRestClient();
92
        $client->put(
93
            $fileLocation,
94
            $fixtureData,
95
            [],
96
            [],
97
            ['CONTENT_TYPE' => 'text/plain'],
98
            false
99
        );
100
        $this->assertEmpty($client->getResults());
101
        $response = $client->getResponse();
102
        $this->assertEquals(204, $response->getStatusCode());
103
104
        $client = static::createRestClient();
105
        $client->request('GET', $fileLocation);
106
        $data = $client->getResults();
107
108
        // check for valid format
109
        $this->assertNotFalse(\DateTime::createFromFormat(\DateTime::RFC3339, $data->metadata->createDate));
110
        $this->assertNotFalse(\DateTime::createFromFormat(\DateTime::RFC3339, $data->metadata->modificationDate));
111
112
        $data->links = [];
113
        $link = new \stdClass;
114
        $link->{'$ref'} = 'http://localhost/core/app/tablet';
115
        $data->links[] = $link;
116
117
        $filename = "test.txt";
118
        $data->metadata->filename = $filename;
119
120
        $client = static::createRestClient();
121
        $client->put(sprintf('/file/%s', $data->id), $data);
122
123
        // re-fetch
124
        $client = static::createRestClient();
125
        $client->request('GET', sprintf('/file/%s', $data->id));
126
        $results = $client->getResults();
127
128
        $this->assertEquals($link->{'$ref'}, $results->links[0]->{'$ref'});
129
        $this->assertEquals($filename, $results->metadata->filename);
130
131
        $client = static::createClient();
132
        $client->request('GET', sprintf('/file/%s', $data->id), [], [], ['HTTP_ACCEPT' => 'text/plain']);
133
134
        $results = $client->getResponse()->getContent();
135
136
        $this->assertEquals($fixtureData, $results);
137
138
        // change link and add second link
139
        $data->links[0]->{'$ref'} = 'http://localhost/core/app/admin';
140
        $link = new \stdClass;
141
        $link->{'$ref'} = 'http://localhost/core/app/web';
142
        $data->links[] = $link;
143
144
        // also add action command
145
        $command = new \stdClass();
146
        $command->command = 'print';
147
        $data->metadata->action = [$command];
148
149
        // also add additionalInformation
150
        $data->metadata->additionalInformation = 'someInfo';
151
152
        $client = static::createRestClient();
153
        $client->put(sprintf('/file/%s', $data->id), $data);
154
155
        // re-fetch
156
        $client = static::createRestClient();
157
        $client->request('GET', sprintf('/file/%s', $data->id));
158
        $results = $client->getResults();
159
160
        $this->assertEquals($data->links[0]->{'$ref'}, $results->links[0]->{'$ref'});
161
        $this->assertEquals($data->links[1]->{'$ref'}, $results->links[1]->{'$ref'});
162
163
        // check metadata
164
        $this->assertEquals(18, $data->metadata->size);
165
        $this->assertEquals('text/plain', $data->metadata->mime);
166
        $this->assertEquals('test.txt', $data->metadata->filename);
167
        $this->assertEquals('print', $data->metadata->action[0]->command);
168
        $this->assertEquals('someInfo', $data->metadata->additionalInformation);
169
        $this->assertNotNull($data->metadata->createDate);
170
        $this->assertNotNull($data->metadata->modificationDate);
171
172
        // remove a link
173
        unset($data->links[1]);
174
175
        $client = static::createRestClient();
176
        $client->put(sprintf('/file/%s', $data->id), $data);
177
        // re-fetch
178
        $client = static::createRestClient();
179
        $client->request('GET', sprintf('/file/%s', $data->id));
180
        $results = $client->getResults();
181
182
        $this->assertEquals($data->links[0]->{'$ref'}, $results->links[0]->{'$ref'});
183
        $this->assertCount(1, $results->links);
184
185
        // remove last link
186
        $data->links = [];
187
        $client = static::createRestClient();
188
        $client->put(sprintf('/file/%s', $data->id), $data);
189
190
        // re-fetch
191
        $client = static::createRestClient();
192
        $client->request('GET', sprintf('/file/%s', $data->id));
193
194
        $results = $client->getResults();
195
196
        $this->assertEmpty($results->links);
197
198
        // read only fields
199
        $data->metadata->size = 1;
200
        $data->metadata->createDate = '1984-05-02T00:00:00+0000';
201
        $data->metadata->modificationDate = '1984-05-02T00:00:00+0000';
202
        $data->metadata->mime = 'application/octet-stream';
203
        $client = static::createRestClient();
204
        $client->put(sprintf('/file/%s', $data->id), $data);
205
206
        $expectedErrors = [];
207
        $expectedError = new \stdClass();
208
        $expectedError->propertyPath = "data.metadata.size";
209
        $expectedError->message = "The value \"data.metadata.size\" is read only.";
210
        $expectedErrors[] = $expectedError;
211
        $expectedError = new \stdClass();
212
        $expectedError->propertyPath = "data.metadata.mime";
213
        $expectedError->message = "The value \"data.metadata.mime\" is read only.";
214
        $expectedErrors[] = $expectedError;
215
        $expectedError = new \stdClass();
216
        $expectedError->propertyPath = "data.metadata.createDate";
217
        $expectedError->message = "The value \"data.metadata.createDate\" is read only.";
218
        $expectedErrors[] = $expectedError;
219
        $expectedError = new \stdClass();
220
        $expectedError->propertyPath = "data.metadata.modificationDate";
221
        $expectedError->message = "The value \"data.metadata.modificationDate\" is read only.";
222
        $expectedErrors[] = $expectedError;
223
224
        $this->assertEquals($expectedErrors, $client->getResults());
225
    }
226
227
    /**
228
     * validate that we can post a new file
229
     *
230
     * @return void
231
     */
232 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...
233
    {
234
        $client = static::createRestClient();
235
236
        $client->post(
237
            '/file',
238
            file_get_contents(__DIR__.'/fixtures/test.txt'),
239
            [],
240
            [],
241
            ['CONTENT_TYPE' => 'text/plain'],
242
            false
243
        );
244
245
        $response = $client->getResponse();
246
        $linkHeader = $response->headers->get('Link');
247
248
        $this->assertEquals(201, $response->getStatusCode());
249
        $this->assertRegExp('@/file/[a-z0-9]{32}>; rel="self"@', $linkHeader);
250
    }
251
252 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...
253
    {
254
        $client = static::createRestClient();
255
256
        $client->put(
257
            '/file/testPutNewFile',
258
            file_get_contents(__DIR__ . '/fixtures/test.txt'),
259
            [],
260
            [],
261
            ['CONTENT_TYPE' => 'text/plain'],
262
            false
263
        );
264
265
        $response = $client->getResponse();
266
        $linkHeader = $response->headers->get('Link');
267
268
        $this->assertEquals(204, $response->getStatusCode());
269
        $this->assertContains('file/testPutNewFile>; rel="self"', $linkHeader);
270
    }
271
272
    /**
273
     * validate that we can delete a file
274
     *
275
     * @return void
276
     */
277
    public function testDeleteFile()
278
    {
279
        $fixtureData = file_get_contents(__DIR__.'/fixtures/test.txt');
280
        $client = static::createRestClient();
281
        $client->post(
282
            '/file/',
283
            $fixtureData,
284
            [],
285
            [],
286
            ['CONTENT_TYPE' => 'text/plain'],
287
            false
288
        );
289
        $response = $client->getResponse();
290
        $this->assertEquals(201, $response->getStatusCode());
291
292
        // re-fetch
293
        $client = static::createRestClient();
294
        $client->request('GET', $response->headers->get('Location'));
295
        $data = $client->getResults();
296
297
        $client = static::createRestClient();
298
        $client->request('DELETE', sprintf('/file/%s', $data->id));
299
300
        $client = static::createRestClient();
301
        $client->request('GET', sprintf('/file/%s', $data->id));
302
303
        $response = $client->getResponse();
304
        $this->assertEquals(404, $response->getStatusCode());
305
    }
306
307
    /**
308
     * validate that we can update the content from a file
309
     *
310
     * @return void
311
     */
312
    public function testUpdateFileContent()
313
    {
314
        $fixtureData = file_get_contents(__DIR__.'/fixtures/test.txt');
315
        $contentType = 'text/plain';
316
        $newData = "This is a new text!!!";
317
        $client = static::createRestClient();
318
        $client->post(
319
            '/file/',
320
            $fixtureData,
321
            [],
322
            [],
323
            ['CONTENT_TYPE' => $contentType],
324
            false
325
        );
326
        $response = $client->getResponse();
327
        $this->assertEquals(201, $response->getStatusCode());
328
329
        $linkHeader = $response->headers->get('Link');
330
        $this->assertRegExp('@/file/[a-z0-9]{32}>; rel="self"@', $linkHeader);
331
332
        // re-fetch
333
        $client = static::createRestClient();
334
        $client->request('GET', $response->headers->get('Location'));
335
        $retData = $client->getResults();
336
337
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
338
        $this->assertEquals(strlen($fixtureData), $retData->metadata->size);
339
        $this->assertEquals($contentType, $retData->metadata->mime);
340
341
        $this->updateFileContent($retData->id, $newData, $contentType);
342
    }
343
344
    /**
345
     * test getting collection schema
346
     *
347
     * @return void
348
     */
349
    public function testGetFileCollectionSchemaInformation()
350
    {
351
        $client = static::createRestClient();
352
353
        $client->request('GET', '/schema/file/collection');
354
355
        $response = $client->getResponse();
356
        $results = $client->getResults();
357
358
        $this->assertResponseContentType('application/schema+json', $response);
359
        $this->assertEquals(200, $response->getStatusCode());
360
361
        $this->assertEquals('Array of file objects', $results->title);
362
        $this->assertEquals('array', $results->type);
363
        $this->assertIsFileSchema($results->items);
364
365
        $this->assertCorsHeaders('GET, POST, PUT, PATCH, DELETE, OPTIONS', $response);
366
        $this->assertContains(
367
            'Link',
368
            explode(',', $response->headers->get('Access-Control-Expose-Headers'))
369
        );
370
371
        $this->assertContains(
372
            '<http://localhost/schema/file/collection>; rel="self"',
373
            explode(',', $response->headers->get('Link'))
374
        );
375
    }
376
377
    /**
378
     * test behavior when data sent was multipart/form-data
379
     *
380
     * @return void
381
     */
382
    public function testPutNewFileViaForm()
383
    {
384
        copy(__DIR__ . '/fixtures/test.txt', sys_get_temp_dir() . '/test.txt');
385
        $file = sys_get_temp_dir() . '/test.txt';
386
        $uploadedFile = new UploadedFile($file, 'test.txt', 'text/plain', 15);
387
388
        $jsonData = '{
389
          "id": "myPersonalFile",
390
          "links": [
391
            {
392
              "$ref": "http://localhost/testcase/readonly/101",
393
              "type": "owner"
394
            },
395
            {
396
              "$ref": "http://localhost/testcase/readonly/102",
397
              "type": "module"
398
            }
399
          ],
400
          "metadata": {
401
            "action":[{"command":"print"},{"command":"archive"}],
402
            "additionalInformation": "someInfo"
403
          }
404
        }';
405
406
        $client = static::createRestClient();
407
        $client->put(
408
            '/file/myPersonalFile',
409
            [],
410
            [
411
                'metadata' => $jsonData,
412
            ],
413
            [
414
                'upload' => $uploadedFile,
415
            ],
416
            [],
417
            false
418
        );
419
420
        $response = $client->getResponse();
421
422
        $this->assertEquals(Response::HTTP_NO_CONTENT, $response->getStatusCode());
423
        $this->assertNotContains('location', $response->headers->all());
424
425
        $response = $this->updateFileContent('myPersonalFile', "This is a new text!!!");
426
427
        $metaData = json_decode($jsonData, true);
428
        $returnData = json_decode($response->getContent(), true);
429
430
        $this->assertEquals($metaData['links'], $returnData['links']);
431
        $this->assertEquals($metaData['metadata']['action'], $returnData['metadata']['action']);
432
        $this->assertEquals(
433
            $metaData['metadata']['additionalInformation'],
434
            $returnData['metadata']['additionalInformation']
435
        );
436
437
        // clean up
438
        $client = $this->createClient();
439
        $client->request(
440
            'DELETE',
441
            $response->headers->get('location')
442
        );
443
    }
444
445
    /**
446
     * check if a schema is of the file type
447
     *
448
     * @param \stdClass $schema schema from service to validate
449
     *
450
     * @return void
451
     */
452
    private function assertIsFileSchema(\stdClass $schema)
453
    {
454
        $this->assertEquals('File', $schema->title);
455
        $this->assertEquals('File storage service', $schema->description);
456
        $this->assertEquals('object', $schema->type);
457
458
        $this->assertEquals('string', $schema->properties->id->type);
459
        $this->assertEquals('ID', $schema->properties->id->title);
460
        $this->assertEquals('Unique identifier', $schema->properties->id->description);
461
        $this->assertObjectNotHasAttribute('readOnly', $schema->properties->id);
462
463
        // Metadata
464
        $this->assertEquals('object', $schema->properties->metadata->type);
465
        $this->assertEquals('Metadata', $schema->properties->metadata->title);
466
        $this->assertObjectNotHasAttribute('readOnly', $schema->properties->metadata);
467
468
        // Metadata size
469
        $this->assertEquals('integer', $schema->properties->metadata->properties->size->type);
470
        $this->assertEquals('File size', $schema->properties->metadata->properties->size->title);
471
        $this->assertEquals('Size of file.', $schema->properties->metadata->properties->size->description);
472
        $this->assertEquals(true, $schema->properties->metadata->properties->size->readOnly);
473
474
        // Metadata mime
475
        $this->assertEquals('string', $schema->properties->metadata->properties->mime->type);
476
        $this->assertEquals('MIME Type', $schema->properties->metadata->properties->mime->title);
477
        $this->assertEquals('MIME-Type of file.', $schema->properties->metadata->properties->mime->description);
478
        $this->assertEquals(true, $schema->properties->metadata->properties->mime->readOnly);
479
480
        // Metadata createDate
481
        $this->assertEquals('string', $schema->properties->metadata->properties->createDate->type);
482
        $this->assertEquals('date', $schema->properties->metadata->properties->createDate->format);
483
        $this->assertEquals('Creation date', $schema->properties->metadata->properties->createDate->title);
484
        $this->assertEquals(
485
            'Timestamp of file upload.',
486
            $schema->properties->metadata->properties->createDate->description
487
        );
488
        $this->assertEquals(true, $schema->properties->metadata->properties->createDate->readOnly);
489
490
        // Metadata modificationDate
491
        $this->assertEquals('string', $schema->properties->metadata->properties->modificationDate->type);
492
        $this->assertEquals('date', $schema->properties->metadata->properties->modificationDate->format);
493
        $this->assertEquals('Modification date', $schema->properties->metadata->properties->modificationDate->title);
494
        $this->assertEquals(
495
            'Timestamp of the last file change.',
496
            $schema->properties->metadata->properties->modificationDate->description
497
        );
498
        $this->assertEquals(true, $schema->properties->metadata->properties->modificationDate->readOnly);
499
500
        // Metadata filename
501
        $this->assertEquals('string', $schema->properties->metadata->properties->filename->type);
502
        $this->assertEquals('File name', $schema->properties->metadata->properties->filename->title);
503
        $this->assertEquals(
504
            'Name of the file as it should get displayed to the user.',
505
            $schema->properties->metadata->properties->filename->description
506
        );
507
        $this->assertObjectNotHasAttribute('readOnly', $schema->properties->metadata->properties->filename);
508
509
        // metadata action.command array
510
        $this->assertEquals(
511
            'string',
512
            $schema->properties->metadata->properties->action->items->properties->command->type
513
        );
514
        $this->assertEquals(
515
            'Action command array',
516
            $schema->properties->metadata->properties->action->items->properties->command->title
517
        );
518
        $this->assertObjectNotHasAttribute(
519
            'readOnly',
520
            $schema->properties->metadata->properties->action->items->properties->command
521
        );
522
523
        // metadata additionalInformation
524
        $this->assertEquals(
525
            'string',
526
            $schema->properties->metadata->properties->additionalInformation->type
527
        );
528
        $this->assertEquals(
529
            'Additional Information',
530
            $schema->properties->metadata->properties->additionalInformation->title
531
        );
532
        $this->assertObjectNotHasAttribute(
533
            'readOnly',
534
            $schema->properties->metadata->properties->additionalInformation
535
        );
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->assertEquals('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', $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
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