Completed
Push — develop ( 0703cb...681e92 )
by Lucas
08:24
created

FileControllerTest::updateFileContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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