AssetAdminTest::testItCreatesFile()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 41
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 30
nc 1
nop 0
dl 0
loc 41
rs 9.44
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\AssetAdmin\Tests\Controller;
4
5
use SilverStripe\AssetAdmin\Forms\FolderFormFactory;
6
use SilverStripe\AssetAdmin\Controller\AssetAdmin;
7
use SilverStripe\AssetAdmin\Tests\Controller\AssetAdminTest\FileExtension;
8
use SilverStripe\AssetAdmin\Tests\Controller\AssetAdminTest\FolderExtension;
9
use SilverStripe\Assets\File;
10
use SilverStripe\Assets\Folder;
11
use Silverstripe\Assets\Dev\TestAssetStore;
12
use SilverStripe\Assets\Upload_Validator;
13
use SilverStripe\Control\Director;
14
use SilverStripe\Control\Session;
15
use SilverStripe\Dev\FunctionalTest;
16
use SilverStripe\Subsites\Extensions\FolderFormFactoryExtension;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Subsites\Ex...derFormFactoryExtension was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use SilverStripe\Versioned\Versioned;
18
use SilverStripe\Security\SecurityToken;
19
20
/**
21
 * Tests {@see AssetAdmin}
22
 * @skipUpgrade
23
 */
24
class AssetAdminTest extends FunctionalTest
25
{
26
27
    protected static $fixture_file = '../fixtures.yml';
28
29
    /**
30
     * @var Session
31
     */
32
    protected $session = null;
33
34
    protected static $illegal_extensions = [
35
        FolderFormFactory::class => [FolderFormFactoryExtension::class],
36
    ];
37
38
    protected function setUp() : void
39
    {
40
        parent::setUp();
41
42
        TestAssetStore::activate('AssetAdminTest');
43
        $memberID = $this->logInWithPermission('ADMIN');
44
        $this->session = new Session([ 'loggedInAs' => $memberID ]);
45
46
        File::add_extension(FileExtension::class);
47
        Folder::add_extension(FolderExtension::class);
48
49
        // Create a test folders for each of the fixture references
50
        foreach (File::get()->filter('ClassName', Folder::class) as $folder) {
51
            /** @var Folder $folder */
52
            $folder->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
53
        }
54
55
        // Create a test files for each of the fixture references
56
        $content = str_repeat('x', 1000000);
57
        foreach (File::get()->exclude('ClassName', Folder::class) as $file) {
58
            /** @var File $file */
59
            $file->setFromString($content, $file->generateFilename());
60
            $file->copyVersionToStage(Versioned::DRAFT, Versioned::LIVE);
61
        }
62
63
        // Override FunctionalTest defaults
64
        SecurityToken::enable();
65
        $this->session->set('SecurityID', SecurityToken::inst()->getValue());
66
67
        // Disable is_uploaded_file() in tests
68
        Upload_Validator::config()->set('use_is_uploaded_file', false);
69
    }
70
71
    protected function tearDown() : void
72
    {
73
        File::remove_extension(FileExtension::class);
74
        Folder::remove_extension(FolderExtension::class);
75
76
        TestAssetStore::reset();
77
        parent::tearDown();
78
    }
79
80
81
    public function testApiHistory()
82
    {
83
        $file = $this->objFromFixture(File::class, 'file1');
84
        $response = Director::test(
85
            'admin/assets/api/history?fileId='. $file->ID,
86
            null,
87
            $this->session,
88
            'GET'
89
        );
90
91
        $this->assertFalse($response->isError());
92
93
        $body = json_decode($response->getBody(), true);
94
95
        $this->assertArrayHasKey('summary', $body[0]);
96
        $this->assertArrayHasKey('versionid', $body[0]);
97
        $this->assertArrayHasKey('summary', $body[0]);
98
99
        // test permission filtering and
100
    }
101
102
    public function testItCreatesFile()
103
    {
104
        $folder1 = $this->objFromFixture(Folder::class, 'folder1');
105
106
        /** @skipUpgrade */
107
        $fileData = array('Upload' => $this->getUploadFile('Upload', 'testItCreatesFile.txt'));
108
        $_FILES = $fileData;
109
        $postedData = array_merge(
110
            $fileData,
111
            [
112
                    'ParentID' => $folder1->ID,
113
                    'SecurityID' => SecurityToken::inst()->getValue(),
114
                ]
115
        );
116
        $response = Director::test(
117
            'admin/assets/api/createFile',
118
            $postedData,
119
            $this->session,
120
            'POST'
121
        );
122
        $this->assertFalse($response->isError());
123
        $responseData = json_decode($response->getBody(), true);
124
        $newFile = File::get()->byID($responseData[0]['id']);
125
        $this->assertNotNull($newFile);
126
        $this->assertEquals($folder1->ID, $newFile->ParentID);
127
        $this->assertEquals('testItCreatesFile.txt', $newFile->Name);
128
129
        // Test that duplicate uploads are renamed
130
        $response = Director::test(
131
            'admin/assets/api/createFile',
132
            $postedData,
133
            $this->session,
134
            'POST'
135
        );
136
        $this->assertFalse($response->isError());
137
        $responseData = json_decode($response->getBody(), true);
138
        $newFile2 = File::get()->byID($responseData[0]['id']);
139
        $this->assertNotNull($newFile2);
140
        $this->assertEquals($folder1->ID, $newFile2->ParentID);
141
        $this->assertNotEquals($newFile->ID, $newFile2->ID);
142
        $this->assertEquals('testItCreatesFile-v2.txt', $newFile2->Name);
143
    }
144
145
    public function testItRestrictsCreateFileOnCanCreate()
146
    {
147
        $folder = $this->objFromFixture(Folder::class, 'folder1');
148
149
        $fileData = array('Upload' => $this->getUploadFile('Upload', 'disallowCanCreate.txt'));
150
        $_FILES = $fileData;
151
        $response = Director::test(
152
            'admin/assets/api/createFile',
153
            array_merge(
154
                $fileData,
155
                [
156
                    'ParentID' => $folder->ID,
157
                    'SecurityID' => SecurityToken::inst()->getValue(),
158
                ]
159
            ),
160
            $this->session,
161
            'POST'
162
        );
163
        $this->assertTrue($response->isError());
164
        $this->assertEquals(403, $response->getStatusCode());
165
    }
166
167
    public function testItRestrictsCreateFileOnCanAddChildren()
168
    {
169
        $folder = $this->objFromFixture(Folder::class, 'disallowCanAddChildren');
170
171
        /** @skipUpgrade */
172
        $fileData = array('Upload' => $this->getUploadFile('Upload', 'test.txt'));
173
        $_FILES = $fileData;
174
        $response = Director::test(
175
            'admin/assets/api/createFile',
176
            array_merge(
177
                $fileData,
178
                [
179
                    'ParentID' => $folder->ID,
180
                    'SecurityID' => SecurityToken::inst()->getValue(),
181
                ]
182
            ),
183
            $this->session,
184
            'POST'
185
        );
186
        $this->assertTrue($response->isError());
187
        $this->assertEquals(403, $response->getStatusCode());
188
    }
189
190
    public function testItRestrictsCreateFileOnExtension()
191
    {
192
        $folder1 = $this->objFromFixture(
193
            Folder::class,
194
            'folder1'
195
        );
196
197
        /** @skipUpgrade */
198
        $fileData = array('Upload' => $this->getUploadFile('Upload', 'disallowed.php'));
199
        $_FILES = $fileData;
200
        $response = Director::test(
201
            'admin/assets/api/createFile',
202
            array_merge(
203
                $fileData,
204
                [
205
                    'ParentID' => $folder1->ID,
206
                    'SecurityID' => SecurityToken::inst()->getValue(),
207
                ]
208
            ),
209
            $this->session,
210
            'POST'
211
        );
212
        $this->assertTrue($response->isError());
213
        $this->assertEquals(400, $response->getStatusCode());
214
        $responseData = json_decode($response->getBody(), true);
215
        $this->assertEquals(
216
            [
217
                'type' => 'error',
218
                'code' => 400,
219
                'value' => "Extension 'php' is not allowed",
220
            ],
221
            $responseData['errors'][0]
222
        );
223
    }
224
225
    public function testItRestrictsUpdateFile()
226
    {
227
        /** @var File $allowedFile */
228
        $allowedFile = $this->objFromFixture(File::class, 'file1');
229
        /** @var File $disallowedFile */
230
        $disallowedFile = $this->objFromFixture(File::class, 'disallowCanEdit');
231
232
        $response = Director::test(
233
            'admin/assets/fileEditForm/' . $allowedFile->ID,
234
            [
235
                'action_save' => 1,
236
                'ID' => $allowedFile->ID,
237
                'Name' => 'disallowCanEdit.txt',
238
                'Title' => 'new',
239
                'SecurityID' => SecurityToken::inst()->getValue(),
240
                'CanViewType' => $allowedFile->CanViewType,
241
                'ViewerGroups' => null,
242
                'CanEditType' => $allowedFile->CanEditType,
243
                'EditorGroups' => null,
244
            ],
245
            $this->session
246
        );
247
        $this->assertFalse($response->isError());
248
249
        $response = Director::test(
250
            'admin/assets/fileEditForm/' . $disallowedFile->ID,
251
            [
252
                'action_save' => 1,
253
                'ID' => $disallowedFile->ID,
254
                'Title' => 'new',
255
                'SecurityID' => SecurityToken::inst()->getValue(),
256
                'CanViewType' => $disallowedFile->CanViewType,
257
                'ViewerGroups' => null,
258
                'CanEditType' => $disallowedFile->CanEditType,
259
                'EditorGroups' => null,
260
            ],
261
            $this->session
262
        );
263
        $this->assertTrue($response->isError());
264
    }
265
266
    /**
267
     * @param string $paramName
268
     * @param string $tmpFileName
269
     * @return array Emulating an entry in the $_FILES superglobal
270
     */
271
    protected function getUploadFile($paramName, $tmpFileName = 'AssetAdminTest.txt')
272
    {
273
        $tmpFilePath = TEMP_PATH . DIRECTORY_SEPARATOR . $tmpFileName;
274
        $tmpFileContent = '';
275
        for ($i = 0; $i < 10000; $i++) {
276
            $tmpFileContent .= '0';
277
        }
278
        file_put_contents($tmpFilePath, $tmpFileContent);
279
280
        // emulates the $_FILES array
281
        return array(
282
            'name' => $tmpFileName,
283
            'type' => 'text/plaintext',
284
            'size' => filesize($tmpFilePath),
285
            'tmp_name' => $tmpFilePath,
286
            'error' => UPLOAD_ERR_OK,
287
        );
288
    }
289
290
    public function testSaveOrPublish()
291
    {
292
        // Test rename folder
293
        $folder1ID = $this->idFromFixture(Folder::class, 'folder1');
294
        $response = $this->post(
295
            'admin/assets/fileEditForm/' . $folder1ID,
296
            [
297
                'ID' => $folder1ID,
298
                'action_save' => 1,
299
                'Name' => 'folder1-renamed',
300
                'SecurityID' => SecurityToken::inst()->getValue(),
301
                'CanViewType' => 'Inherit',
302
                'ViewerGroups' => null,
303
                'CanEditType' => 'Inherit',
304
                'EditorGroups' => null,
305
            ]
306
        );
307
        $this->assertFalse($response->isError());
308
        $folder1 = Folder::get()->byID($folder1ID);
309
        $this->assertEquals('folder1-renamed', $folder1->Name);
310
    }
311
312
    public function testGetMinimalistObjectFromData()
313
    {
314
        $assetAdmin = AssetAdmin::singleton();
315
        $file = $this->objFromFixture(File::class, 'file1');
316
317
        $data = $assetAdmin->getMinimalistObjectFromData($file);
318
319
        // Thumbnail value is hard to predit, so we'll just check that it's there before unseting it.
320
        $this->assertNotEmpty($data['thumbnail']);
321
        unset($data['thumbnail']);
322
323
        $expected = [
324
            "id" => $file->ID,
325
            "parent" => [
326
                "id" => $file->Parent()->ID,
327
                "title" => $file->Parent()->Title,
328
                "filename" => $file->Parent()->Filename,
329
            ],
330
            "title" => $file->Title,
331
            "exists" => $file->exists(),
332
            "category" => $file->appCategory(),
333
            "extension" => $file->Extension,
334
            "size" => $file->AbsoluteSize,
335
            "published" => $file->isPublished(),
336
            "modified" => $file->isModifiedOnDraft(),
337
            "draft" => $file->isOnDraftOnly(),
338
        ];
339
340
        $this->assertEquals($expected, $data);
341
    }
342
343
    public function testGetObjectFromDataFile()
344
    {
345
        $assetAdmin = AssetAdmin::singleton();
346
        $file = $this->objFromFixture(File::class, 'file1');
347
348
349
        $data = $assetAdmin->getObjectFromData($file);
350
351
        // Thumbnail value is hard to predict, so we'll just check that it's there before unseting it.
352
        $this->assertNotEmpty($data['thumbnail']);
353
        unset($data['thumbnail']);
354
355
        $expected = [
356
            "id" => $file->ID,
357
            "parent" => [
358
                "id" => $file->Parent()->ID,
359
                "title" => $file->Parent()->Title,
360
                "filename" => $file->Parent()->Filename,
361
            ],
362
            "title" => $file->Title,
363
            "exists" => $file->exists(),
364
            "category" => $file->appCategory(),
365
            "extension" => $file->Extension,
366
            "size" => $file->AbsoluteSize,
367
            "published" => $file->isPublished(),
368
            "modified" => $file->isModifiedOnDraft(),
369
            "draft" => $file->isOnDraftOnly(),
370
            "inUseCount" => 1,
371
            "created" => $file->Created,
372
            "lastUpdated" => $file->LastEdited,
373
            "owner" => [
374
                "id" => $file->Owner()->ID,
375
                "title" => $file->Owner()->Name
376
            ],
377
            "type" => $file->FileType,
378
            "name" => $file->Name,
379
            "filename" => $file->Filename,
380
            "url" => $file->AbsoluteURL,
381
            "canEdit" => $file->canEdit(),
382
            "canDelete" => $file->canDelete(),
383
        ];
384
385
        $this->assertEquals($expected, $data);
386
    }
387
388
    public function testGetObjectFromDataFileWithFolder()
389
    {
390
        $assetAdmin = AssetAdmin::singleton();
391
        $file = $this->objFromFixture(Folder::class, 'folder1');
392
393
394
        $data = $assetAdmin->getObjectFromData($file);
395
396
        // Thumbnail value is hard to predit, so we'll just check that it's there before unseting it.
397
        $this->assertNotEmpty($data['thumbnail']);
398
        unset($data['thumbnail']);
399
400
        $expected = [
401
            "id" => $file->ID,
402
            "parent" => [
403
                "id" => $file->Parent()->ID,
404
                "title" => $file->Parent()->Title,
405
                "filename" => $file->Parent()->Filename,
406
            ],
407
            "title" => $file->Title,
408
            "exists" => $file->exists(),
409
            "category" => 'folder',
410
            "extension" => $file->Extension,
411
            "size" => $file->AbsoluteSize,
412
            "published" => $file->isPublished(),
413
            "modified" => $file->isModifiedOnDraft(),
414
            "draft" => $file->isOnDraftOnly(),
415
            "inUseCount" => 0,
416
            "created" => $file->Created,
417
            "lastUpdated" => $file->LastEdited,
418
            "owner" => [
419
                "id" => $file->Owner()->ID,
420
                "title" => $file->Owner()->Name
421
            ],
422
            "type" => 'folder',
423
            "name" => $file->Name,
424
            "filename" => $file->Filename,
425
            "url" => $file->AbsoluteURL,
426
            "canEdit" => $file->canEdit(),
427
            "canDelete" => $file->canDelete(),
428
        ];
429
430
        $this->assertEquals($expected, $data);
431
    }
432
}
433