Passed
Push — master ( e2e77c...798396 )
by
unknown
04:46 queued 12s
created

testGetFolderPermissionValidRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 41
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 31
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 41
rs 9.424
1
<?php
2
3
namespace SilverStripe\UserForms\Tests\Control;
4
5
use SilverStripe\Assets\Dev\TestAssetStore;
6
use SilverStripe\Assets\File;
7
use SilverStripe\Assets\Folder;
8
use SilverStripe\Assets\Storage\AssetStore;
9
use SilverStripe\Assets\Upload_Validator;
10
use InvalidArgumentException;
11
use SilverStripe\Control\HTTPRequest;
12
use SilverStripe\Control\HTTPResponse;
13
use SilverStripe\Control\Session;
14
use SilverStripe\Core\Config\Config;
15
use SilverStripe\Core\Injector\Injector;
16
use SilverStripe\Dev\CSSContentParser;
17
use SilverStripe\Dev\FunctionalTest;
18
use SilverStripe\Forms\FieldList;
19
use SilverStripe\Forms\FormAction;
20
use SilverStripe\ORM\DataObject;
21
use SilverStripe\Security\InheritedPermissions;
22
use SilverStripe\Security\Security;
23
use SilverStripe\UserForms\Control\UserDefinedFormAdmin;
24
use SilverStripe\UserForms\Control\UserDefinedFormController;
25
use SilverStripe\UserForms\Model\EditableFormField;
26
use SilverStripe\UserForms\Model\EditableFormField\EditableFileField;
27
use SilverStripe\UserForms\Model\EditableFormField\EditableTextField;
28
use SilverStripe\UserForms\Model\Recipient\EmailRecipient;
29
use SilverStripe\UserForms\Model\Submission\SubmittedFormField;
30
use SilverStripe\UserForms\Model\UserDefinedForm;
31
use SilverStripe\View\ArrayData;
32
use SilverStripe\View\SSViewer;
33
34
/**
35
 * @package userforms
36
 */
37
class UserDefinedFormAdminTest extends FunctionalTest
38
{
39
    protected static $fixture_file = '../UserFormsTest.yml';
40
41
    protected function setUp()
42
    {
43
        parent::setUp();
44
45
        $submissionFolder = Folder::find('Form-submissions');
46
        if ($submissionFolder) {
0 ignored issues
show
introduced by
$submissionFolder is of type SilverStripe\Assets\File, thus it always evaluated to true.
Loading history...
47
            $submissionFolder->delete();
48
        }
49
50
        foreach (Folder::get() as $folder) {
51
            $folder->publishSingle();
52
        }
53
    }
54
55
    public function testConfirmfolderformInvalidRequest()
56
    {
57
        $this->logInWithPermission(['CMS_ACCESS_CMSMain']);
58
59
        $url = 'admin/user-forms/confirmfolderformschema?';
60
        $fieldID = $this->idFromFixture(EditableFileField::class, 'file-field-1');
0 ignored issues
show
Unused Code introduced by
The assignment to $fieldID is dead and can be removed.
Loading history...
61
62
        $response = $this->get($url);
63
        $this->assertEquals(400, $response->getStatusCode(), 'Request without ID parameter is invalid');
64
65
        $response = $this->get($url . http_build_query(['ID' => -1]));
66
        $this->assertEquals(400, $response->getStatusCode(), 'Request with unknown ID and known UserFormID is invalid');
67
    }
68
69
    public function testConfirmfolderformAccessControl()
70
    {
71
        $url = 'admin/user-forms/confirmfolderformschema?';
72
        $fieldID = $this->idFromFixture(EditableFileField::class, 'file-field-1');
73
        $restrictedFieldID = $this->idFromFixture(EditableFileField::class, 'file-field-2');
74
75
        $this->logInWithPermission(['CMS_ACCESS_CMSMain']);
76
77
        $response = $this->get($url . http_build_query(['ID' => $fieldID]));
78
        $this->assertEquals(200, $response->getStatusCode(), 'CMS editors can access confirm folder form ');
79
80
        $response = $this->get($url . http_build_query(['ID' => $restrictedFieldID]));
81
        $this->assertEquals(
82
            403,
83
            $response->getStatusCode(),
84
            'CMS editors can\'t access confirm folder form for restricted form'
85
        );
86
87
        $this->logInWithPermission('ADMIN');
88
89
        $response = $this->get($url . http_build_query(['ID' => $restrictedFieldID]));
90
        $this->assertEquals(
91
            200,
92
            $response->getStatusCode(),
93
            'Admins can access confirm folder form for restricted form'
94
        );
95
    }
96
97
    public function testConfirmfolderformFields()
98
    {
99
        $url = 'admin/user-forms/confirmfolderformschema?';
100
        $fieldID = $this->idFromFixture(EditableFileField::class, 'file-field-1');
101
        $folderID = $this->idFromFixture(Folder::class, 'unrestricted');
102
        $this->logInWithPermission('ADMIN');
103
104
        $response = $this->get(
105
            $url . http_build_query(['ID' => $fieldID]),
106
            null,
107
            ['X-FormSchema-Request' => 'auto,schema,state,errors']
108
        );
109
        $schemaData = json_decode($response->getBody(), true);
110
111
        $this->assertEquals('ConfirmFolderForm', $schemaData['schema']['name']);
112
        $this->assertField($schemaData, 'FolderOptions', ['component' => 'OptionsetField']);
113
        $this->assertField($schemaData, 'FolderID', ['component' => 'TreeDropdownField']);
114
        $this->assertField($schemaData, 'ID', ['schemaType' =>'Hidden']);
115
116
        $this->assertStateValue($schemaData, ['ID' => $fieldID, 'FolderID' => $folderID]);
117
    }
118
119
    public function testConfirmfolderformDefaultFolder()
120
    {
121
        $url = 'admin/user-forms/confirmfolderformschema?';
122
        $fieldID = $this->idFromFixture(EditableFileField::class, 'file-field-2');
123
124
        $this->logInWithPermission('ADMIN');
125
126
        $response = $this->get(
127
            $url . http_build_query(['ID' => $fieldID]),
128
            null,
129
            ['X-FormSchema-Request' => 'auto,schema,state,errors']
130
        );
131
        $schemaData = json_decode($response->getBody(), true);
132
133
        $this->assertEquals('ConfirmFolderForm', $schemaData['schema']['name']);
134
        $this->assertField($schemaData, 'FolderOptions', ['component' => 'OptionsetField']);
135
        $this->assertField($schemaData, 'FolderID', ['component' => 'TreeDropdownField']);
136
        $this->assertField($schemaData, 'ID', ['schemaType' =>'Hidden']);
137
138
        $folder = Folder::find('Form-submissions');
139
        $this->assertNotEmpty($folder, 'Default submission folder has been created');
140
141
        $this->assertStateValue($schemaData, ['ID' => $fieldID, 'FolderID' => $folder->ID]);
142
143
        $this->logOut();
144
        $this->assertFalse($folder->canView(), 'Default submission folder is protected');
145
    }
146
147
    public function testConfirmfolderInvalidRequest()
148
    {
149
        $this->logInWithPermission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_AssetAdmin']);
150
151
        $url = 'admin/user-forms/ConfirmFolderForm';
152
        $response = $this->post($url, ['ID' => -1]);
153
        $this->assertEquals(400, $response->getStatusCode(), 'Request without ID parameter is invalid');
154
    }
155
156
    public function testConfirmfolderAccessControl()
157
    {
158
        $url = 'admin/user-forms/ConfirmFolderForm';
159
        $fieldID = $this->idFromFixture(EditableFileField::class, 'file-field-1');
160
        $restrictedFieldID = $this->idFromFixture(EditableFileField::class, 'file-field-2');
161
162
        $this->logInWithPermission(['CMS_ACCESS_CMSMain']);
163
        $response = $this->post($url, ['ID' => $fieldID]);
164
        $this->assertEquals(
165
            403,
166
            $response->getStatusCode(),
167
            'Users without CMS_ACCESS_AssetAdmin can\'t confirm folder'
168
        );
169
170
        $this->logInWithPermission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_AssetAdmin']);
171
        $response = $this->post($url, ['ID' => $fieldID]);
172
        $this->assertEquals(200, $response->getStatusCode(), 'CMS editors can access confirm folder form ');
173
174
        $response = $this->post($url, ['ID' => $restrictedFieldID]);
175
        $this->assertEquals(
176
            403,
177
            $response->getStatusCode(),
178
            'CMS editors can\'t confirm folder form for restricted form'
179
        );
180
181
        $this->logInWithPermission('ADMIN');
182
183
        $response = $this->post($url, ['ID' => $restrictedFieldID]);
184
        $this->assertEquals(
185
            200,
186
            $response->getStatusCode(),
187
            'Admins can confirm folder form for restricted form'
188
        );
189
    }
190
191
    public function testConfirmfolderExistingFolder()
192
    {
193
        $this->logInWithPermission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_AssetAdmin']);
194
195
        $url = 'admin/user-forms/ConfirmFolderForm';
196
        $fieldID = $this->idFromFixture(EditableFileField::class, 'file-field-1');
197
        $folderID = $this->idFromFixture(Folder::class, 'restricted');
198
199
        $response = $this->post($url, ['ID' => $fieldID, 'FolderOptions' => 'existing', 'FolderID' => $folderID]);
200
        $this->assertEquals(200, $response->getStatusCode(), 'Valid request to confirm an existing folder is successful');
201
        $this->assertEquals(
202
            $folderID,
203
            EditableFileField::get()->byID($fieldID)->FolderID,
204
            'FileField points to restricted folder'
205
        );
206
    }
207
208
    public function testConfirmfolderInexistingFolder()
209
    {
210
        $this->logInWithPermission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_AssetAdmin']);
211
212
        $url = 'admin/user-forms/ConfirmFolderForm';
213
        $fieldID = $this->idFromFixture(EditableFileField::class, 'file-field-1');
214
215
        $response = $this->post($url, ['ID' => $fieldID, 'FolderOptions' => 'existing', 'FolderID' => -1]);
216
        $this->assertEquals(400, $response->getStatusCode(), 'Confirm a non-existant folder fails with 400');
217
    }
218
219
    public function testConfirmfolderRootFolder()
220
    {
221
        $this->logInWithPermission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_AssetAdmin']);
222
223
        $url = 'admin/user-forms/ConfirmFolderForm';
224
        $fieldID = $this->idFromFixture(EditableFileField::class, 'file-field-1');
225
226
        $response = $this->post($url, ['ID' => $fieldID, 'FolderOptions' => 'existing', 'FolderID' => 0]);
227
        $this->assertEquals(200, $response->getStatusCode(), 'Valid request to confirm an root folder is successful');
228
        $this->assertEquals(0, EditableFileField::get()->byID($fieldID)->FolderID, 'FileField points to root folder');
229
    }
230
231
    public function testConfirmfolderNewFolder()
232
    {
233
        $this->logInWithPermission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_AssetAdmin']);
234
235
        $url = 'admin/user-forms/ConfirmFolderForm';
236
        $fieldID = $this->idFromFixture(EditableFileField::class, 'file-field-1');
237
238
        $response = $this->post($url, ['ID' => $fieldID, 'FolderOptions' => 'new']);
239
        $this->assertEquals(200, $response->getStatusCode(), 'Valid request to confirm folder by creating a new one is valid');
240
241
        $folder = Folder::find('Form-submissions/Form-with-upload-field');
242
        $this->assertNotEmpty($folder, 'New folder has been created based on the UserFormPage\'s title');
243
244
        $this->logOut();
245
        $this->assertFalse($folder->canView(), 'New folder is restricted');
246
    }
247
248
    public function testConfirmfolderNewFolderWithSpecificName()
249
    {
250
        $this->logInWithPermission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_AssetAdmin']);
251
252
        $url = 'admin/user-forms/ConfirmFolderForm';
253
        $fieldID = $this->idFromFixture(EditableFileField::class, 'file-field-1');
254
255
        $response = $this->post(
256
            $url,
257
            ['ID' => $fieldID, 'FolderOptions' => 'new', 'CreateFolder' => 'My-Custom-Folder->\'Pow']
258
        );
259
        $this->assertEquals(200, $response->getStatusCode(), 'Valid request to confirm folder by creating a new one is valid');
260
261
        $folder = Folder::find('Form-submissions/My-Custom-Folder-Pow');
262
        $this->assertNotEmpty($folder, 'New folder has been created based the provided CreateFolder value');
263
264
        $this->logOut();
265
        $this->assertFalse($folder->canView(), 'New folder is restricted');
266
    }
267
268
    public function testConfirmfolderWithFieldTypeConversion()
269
    {
270
        $this->logInWithPermission('ADMIN');
271
272
        $url = 'admin/user-forms/ConfirmFolderForm?';
273
        $fieldID = $this->idFromFixture(EditableTextField::class, 'become-file-upload');
274
275
        $response = $this->post($url, ['ID' => $fieldID, 'FolderOptions' => 'new']);
276
        $this->assertEquals(200, $response->getStatusCode(), 'Valid request to confirm folder by creating a new one is valid');
277
278
        $folder = Folder::find('Form-submissions/Form-editable-only-by-admin');
279
        $this->assertNotEmpty($folder, 'New folder has been created based on the UserFormPage\'s title');
280
281
        $this->logOut();
282
        $this->assertFalse($folder->canView(), 'New folder is restricted');
283
284
        $field = EditableFormField::get()->byID($fieldID);
285
        $this->assertEquals(
286
            EditableFileField::class,
287
            $field->ClassName,
288
            'EditableTextField has been converted to EditableFileField'
289
        );
290
    }
291
292
    public function testPreserveSubmissionFolderPermission()
293
    {
294
        $folder = Folder::find_or_make('Form-submissions');
295
        $folder->CanViewType = InheritedPermissions::ANYONE;
296
        $folder->write();
297
298
299
        $this->logInWithPermission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_AssetAdmin']);
300
        $url = 'admin/user-forms/ConfirmFolderForm?';
301
        $fieldID = $this->idFromFixture(EditableFileField::class, 'file-field-1');
302
303
        $this->post($url, ['ID' => $fieldID, 'FolderOptions' => 'new']);
304
305
        $folder = Folder::find('Form-submissions');
306
307
        $this->assertEquals(
308
            InheritedPermissions::ANYONE,
309
            $folder->CanViewType,
310
            'Submission folder permissions are preserved'
311
        );
312
    }
313
314
    /**
315
     * Assert that a field with the provided attribute exists in $schema.
316
     *
317
     * @param array $schema
318
     * @param string $name
319
     * @param string $component
320
     * @param $value
321
     * @param string $message
322
     */
323
    private function assertField(array $schema, string $name, array $attributes, $message = '')
324
    {
325
        $message = $message ?: sprintf('A %s field exists with %s', $name, var_export($attributes, true));
326
        $fields = $schema['schema']['fields'];
327
        $state = $schema['state']['fields'];
0 ignored issues
show
Unused Code introduced by
The assignment to $state is dead and can be removed.
Loading history...
328
        $this->assertNotEmpty($fields, $message);
329
        $foundField = false;
330
        foreach ($fields as $field) {
331
            if ($field['name'] === $name) {
332
                $foundField = true;
333
                foreach ($attributes as $attr => $expectedValue) {
334
                    $this->assertEquals($expectedValue, $field[$attr]);
335
                }
336
                break;
337
            }
338
        }
339
        $this->assertTrue($foundField, $message);
340
    }
341
342
    private function assertStateValue(array $schema, $values)
343
    {
344
        $fields = $schema['state']['fields'];
345
        $this->assertNotEmpty($fields);
346
        $foundField = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $foundField is dead and can be removed.
Loading history...
347
        foreach ($fields as $field) {
348
            $key = $field['name'];
349
            if (isset($values[$key])) {
350
                $this->assertEquals($values[$key], $field['value'], sprintf('%s is %s', $key, $values[$key]));
351
            }
352
        }
353
    }
354
355
    public function testGetFolderPermissionAccessControl()
356
    {
357
        $this->logOut();
358
        $url = 'admin/user-forms/getfoldergrouppermissions?';
359
360
        $this->logInWithPermission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_AssetAdmin']);
361
        $adminOnlyFolder = Folder::find('admin-only');
362
        $response = $this->get($url . http_build_query(['FolderID' => $adminOnlyFolder->ID]));
363
        $this->assertEquals(
364
            403,
365
            $response->getStatusCode(),
366
            'Access denied for getting permission of Folder user does not have read access on'
367
        );
368
369
        $this->logInWithPermission('ADMIN');
370
        $adminOnlyFolder = Folder::find('admin-only');
371
        $response = $this->get($url . http_build_query(['FolderID' => $adminOnlyFolder->ID]));
372
        $this->assertEquals(
373
            200,
374
            $response->getStatusCode(),
375
            'Access denied for getting permission of Folder user does not have read access on'
376
        );
377
    }
378
379
    public function testGetFolderPermissionNonExistentFolder()
380
    {
381
        $this->logInWithPermission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_AssetAdmin']);
382
        $url = 'admin/user-forms/getfoldergrouppermissions?';
383
384
        $response = $this->get($url . http_build_query(['FolderID' => -1]));
385
        $this->assertEquals(
386
            400,
387
            $response->getStatusCode(),
388
            'Non existent folder should fail'
389
        );
390
    }
391
392
    public function testGetFolderPermissionValidRequest()
393
    {
394
        $url = 'admin/user-forms/getfoldergrouppermissions?';
395
        $this->logInWithPermission(['CMS_ACCESS_CMSMain', 'CMS_ACCESS_AssetAdmin']);
396
397
        $folder = Folder::find('unrestricted');
398
        $response = $this->get($url . http_build_query(['FolderID' => $folder->ID]));
399
        $this->assertEquals(
400
            200,
401
            $response->getStatusCode(),
402
            'Valid request is successfull'
403
        );
404
        $this->assertContains('Unrestricted access, uploads will be visible to anyone', $response->getBody());
405
406
        $folder = Folder::find('restricted-folder');
0 ignored issues
show
Unused Code introduced by
The assignment to $folder is dead and can be removed.
Loading history...
407
        $response = $this->get($url . http_build_query(['FolderID' => 0]));
408
        $this->assertEquals(
409
            200,
410
            $response->getStatusCode(),
411
            'Valid request for root folder is successful'
412
        );
413
        $this->assertContains('Unrestricted access, uploads will be visible to anyone', $response->getBody());
414
415
        $folder = Folder::find('restricted-folder');
416
        $response = $this->get($url . http_build_query(['FolderID' => $folder->ID]));
417
        $this->assertEquals(
418
            200,
419
            $response->getStatusCode(),
420
            'Valid request for root folder is successful'
421
        );
422
        $this->assertContains('Restricted access, uploads will be visible to logged-in users ', $response->getBody());
423
424
        $this->logInWithPermission('ADMIN');
425
        $adminOnlyFolder = Folder::find('admin-only');
426
        $response = $this->get($url . http_build_query(['FolderID' => $adminOnlyFolder->ID]));
427
        $this->assertEquals(
428
            200,
429
            $response->getStatusCode(),
430
            'Valid request for folder restricted to group is successful'
431
        );
432
        $this->assertContains('Restricted access, uploads will be visible to the following groups: Administrators', $response->getBody());
433
    }
434
435
    public function testGetFormSubmissionFolder()
436
    {
437
        $submissionFolder = Folder::find('Form-submissions');
438
        $this->assertEmpty($submissionFolder, 'Submission folder does not exists initially.');
439
440
        // No parameters
441
        $submissionFolder = UserDefinedFormAdmin::getFormSubmissionFolder();
442
        $this->assertNotEmpty($submissionFolder, 'Submission folder exists after getFormSubmissionFolder call');
443
        $this->assertEquals('Form-submissions/', $submissionFolder->getFilename(), 'Submission folder got created under correct name');
444
445
        $this->assertEquals(InheritedPermissions::ONLY_THESE_USERS, $submissionFolder->CanViewType, 'Submission folder has correct permissions');
446
        $this->assertNotEmpty($submissionFolder->ViewerGroups()->find('Code', 'administrators'), 'Submission folder is limited to administrators');
447
448
        // subfolder name
449
        $submissionSubFolder = UserDefinedFormAdmin::getFormSubmissionFolder('test-form');
450
        $this->assertNotEmpty($submissionSubFolder, 'Submission subfolder has been created');
451
        $this->assertEquals('Form-submissions/test-form/', $submissionSubFolder->getFilename(), 'Submission sub folder got created under correct name');
452
        $this->assertEquals(InheritedPermissions::INHERIT, $submissionSubFolder->CanViewType, 'Submission sub folder inherit permission from parent');
453
454
        // make sure parent folder permission don't get overridden
455
        $submissionFolder = Folder::find('Form-submissions');
456
        $submissionFolder->CanViewType = InheritedPermissions::INHERIT;
457
        $submissionFolder->write();
458
459
        $submissionSubFolder = UserDefinedFormAdmin::getFormSubmissionFolder('test-form-2');
0 ignored issues
show
Unused Code introduced by
The assignment to $submissionSubFolder is dead and can be removed.
Loading history...
460
        $submissionFolder = Folder::find('Form-submissions');
461
        $this->assertEquals(InheritedPermissions::INHERIT, $submissionFolder->CanViewType, 'Submission sub folder inherit permission from parent');
462
463
        // Submission folder get recreated
464
        $submissionFolder->delete();
465
        $submissionFolder = Folder::find('Form-submissions');
466
        $this->assertEmpty($submissionFolder, 'Submission folder does has been deleted.');
467
468
        $submissionSubFolder = UserDefinedFormAdmin::getFormSubmissionFolder('test-form-3');
469
        $submissionFolder = Folder::find('Form-submissions');
470
        $this->assertNotEmpty($submissionFolder, 'Submission folder got recreated');
471
        $this->assertEquals('Form-submissions/', $submissionFolder->getFilename(), 'Submission folder got recreated under correct name');
472
473
        $this->assertEquals(InheritedPermissions::ONLY_THESE_USERS, $submissionFolder->CanViewType, 'Submission folder has correct permissions');
474
        $this->assertNotEmpty($submissionFolder->ViewerGroups()->find('Code', 'administrators'), 'Submission folder is limited to administrators');
475
    }
476
}
477