Passed
Push — pulls/good-things-from-phpstan ( 7312f2...8f8b5f )
by Sam
10:36
created

TreeMultiselectFieldTest::buildFormMock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 0
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\Forms\Tests;
4
5
use SilverStripe\Assets\File;
6
use SilverStripe\Dev\SapphireTest;
7
use SilverStripe\Forms\Form;
8
use SilverStripe\Forms\FormTemplateHelper;
9
use SilverStripe\Forms\TreeMultiselectField;
10
use SilverStripe\ORM\Tests\HierarchyTest\TestObject;
11
use SilverStripe\View\SSViewer;
12
13
class TreeMultiselectFieldTest extends SapphireTest
14
{
15
    protected static $fixture_file = 'TreeDropdownFieldTest.yml';
16
17
    protected static $extra_dataobjects = [
18
        TestObject::class,
19
    ];
20
21
    protected $formId = 'TheFormID';
22
    protected $fieldName = 'TestTree';
23
24
    /**
25
     * Mock object of a generic form
26
     *
27
     * @var Form
28
     */
29
    protected $form;
30
31
    /**
32
     * Instance of the TreeMultiselectField
33
     *
34
     * @var TreeMultiselectField
35
     */
36
    protected $field;
37
38
    /**
39
     * The File objects of folders loaded from the fixture
40
     *
41
     * @var File[]
42
     */
43
    protected $folders;
44
45
    /**
46
     * The array of folder ids
47
     *
48
     * @var int[]
49
     */
50
    protected $folderIds;
51
52
    /**
53
     * Concatenated folder ids for use as a value for the field
54
     *
55
     * @var string
56
     */
57
    protected $fieldValue;
58
59
    protected function setUp()
60
    {
61
        parent::setUp();
62
63
        // Don't let other themes interfere with these tests
64
        SSViewer::set_themes([]);
65
66
        $this->form = $this->buildFormMock();
67
        $this->field = $this->buildField($this->form);
68
        $this->folders = $this->loadFolders();
69
70
        $this->folderIds = array_map(
71
            static function ($f) {
72
                return $f->ID;
73
            },
74
            $this->folders
75
        );
76
        $this->fieldValue = implode(',', $this->folderIds);
77
    }
78
79
    /**
80
     * Build a new mock object of a Form
81
     *
82
     * @return Form
83
     */
84
    protected function buildFormMock()
85
    {
86
        $form = $this->createMock(Form::class);
87
88
        $form->method('getTemplateHelper')
89
            ->willReturn(FormTemplateHelper::singleton());
90
91
        $form->method('getHTMLID')
92
            ->willReturn($this->formId);
93
94
        return $form;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $form returns the type PHPUnit_Framework_MockObject_MockObject which is incompatible with the documented return type SilverStripe\Forms\Form.
Loading history...
95
    }
96
97
    /**
98
     * Build a new instance of TreeMultiselectField
99
     *
100
     * @param Form $form The field form
101
     *
102
     * @return TreeMultiselectField
103
     */
104
    protected function buildField(Form $form)
105
    {
106
        $field = new TreeMultiselectField($this->fieldName, 'Test tree', File::class);
107
        $field->setForm($form);
108
109
        return $field;
110
    }
111
112
    /**
113
     * Load several files from the fixtures and return them in an array
114
     *
115
     * @return File[]
116
     */
117
    protected function loadFolders()
118
    {
119
        $asdf = $this->objFromFixture(File::class, 'asdf');
120
        $subfolderfile1 = $this->objFromFixture(File::class, 'subfolderfile1');
121
122
        return [$asdf, $subfolderfile1];
123
    }
124
125
    /**
126
     * Test the TreeMultiselectField behaviour with no selected values
127
     */
128
    public function testEmpty()
129
    {
130
        $field = $this->field;
131
132
        $fieldId = $field->ID();
133
        $this->assertEquals($fieldId, sprintf('%s_%s', $this->formId, $this->fieldName));
134
135
        $schemaStateDefaults = $field->getSchemaStateDefaults();
136
        $this->assertArraySubset(
137
            [
138
                'id' => $fieldId,
139
                'name' => $this->fieldName,
140
                'value' => 'unchanged'
141
            ],
142
            $schemaStateDefaults,
143
            true
144
        );
145
146
        $schemaDataDefaults = $field->getSchemaDataDefaults();
147
        $this->assertArraySubset(
148
            [
149
                'id' => $fieldId,
150
                'name' => $this->fieldName,
151
                'type' => 'text',
152
                'schemaType' => 'SingleSelect',
153
                'component' => 'TreeDropdownField',
154
                'holderId' => sprintf('%s_Holder', $fieldId),
155
                'title' => 'Test tree',
156
                'extraClass' => 'treemultiselect multiple searchable',
157
                'data' => [
158
                    'urlTree' => 'field/TestTree/tree',
159
                    'showSearch' => true,
160
                    'emptyString' => '(Search or choose File)',
161
                    'hasEmptyDefault' => false,
162
                    'multiple' => true
163
                ]
164
            ],
165
            $schemaDataDefaults,
166
            true
167
        );
168
169
        $items = $field->getItems();
170
        $this->assertCount(0, $items, 'there must be no items selected');
171
172
        $html = $field->Field();
173
        $this->assertContains($field->ID(), $html);
174
        $this->assertContains('unchanged', $html);
175
    }
176
177
178
    /**
179
     * Test the field with some values set
180
     */
181
    public function testChanged()
182
    {
183
        $field = $this->field;
184
185
        $field->setValue($this->fieldValue);
186
187
        $schemaStateDefaults = $field->getSchemaStateDefaults();
188
        $this->assertArraySubset(
189
            [
190
                'id' => $field->ID(),
191
                'name' => 'TestTree',
192
                'value' => $this->folderIds
193
            ],
194
            $schemaStateDefaults,
195
            true
196
        );
197
198
        $items = $field->getItems();
199
        $this->assertCount(2, $items, 'there must be exactly 2 items selected');
200
201
        $html = $field->Field();
202
        $this->assertContains($field->ID(), $html);
203
        $this->assertContains($this->fieldValue, $html);
204
    }
205
206
    /**
207
     * Test empty field in readonly mode
208
     */
209
    public function testEmptyReadonly()
210
    {
211
        $field = $this->field->performReadonlyTransformation();
212
213
        $schemaStateDefaults = $field->getSchemaStateDefaults();
214
        $this->assertArraySubset(
215
            [
216
                'id' => $field->ID(),
217
                'name' => 'TestTree',
218
                'value' => 'unchanged'
219
            ],
220
            $schemaStateDefaults,
221
            true
222
        );
223
224
        $schemaDataDefaults = $field->getSchemaDataDefaults();
225
        $this->assertArraySubset(
226
            [
227
                'id' => $field->ID(),
228
                'name' => $this->fieldName,
229
                'type' => 'text',
230
                'schemaType' => 'SingleSelect',
231
                'component' => 'TreeDropdownField',
232
                'holderId' => sprintf('%s_Holder', $field->ID()),
233
                'title' => 'Test tree',
234
                'extraClass' => 'treemultiselectfield_readonly multiple  searchable',
235
                'data' => [
236
                    'urlTree' => 'field/TestTree/tree',
237
                    'showSearch' => true,
238
                    'emptyString' => '(Search or choose File)',
239
                    'hasEmptyDefault' => false,
240
                    'multiple' => true
241
                ]
242
            ],
243
            $schemaDataDefaults,
244
            true
245
        );
246
247
        $items = $field->getItems();
248
        $this->assertCount(0, $items, 'there must be 0 selected items');
249
250
        $html = $field->Field();
251
        $this->assertContains($field->ID(), $html);
252
    }
253
254
    /**
255
     * Test changed field in readonly mode
256
     */
257
    public function testChangedReadonly()
258
    {
259
        $field = $this->field;
260
        $field->setValue($this->fieldValue);
261
        $field = $field->performReadonlyTransformation();
262
263
        $schemaStateDefaults = $field->getSchemaStateDefaults();
264
        $this->assertArraySubset(
265
            [
266
                'id' => $field->ID(),
267
                'name' => 'TestTree',
268
                'value' => $this->folderIds
269
            ],
270
            $schemaStateDefaults,
271
            true
272
        );
273
274
        $schemaDataDefaults = $field->getSchemaDataDefaults();
275
        $this->assertArraySubset(
276
            [
277
                'id' => $field->ID(),
278
                'name' => $this->fieldName,
279
                'type' => 'text',
280
                'schemaType' => 'SingleSelect',
281
                'component' => 'TreeDropdownField',
282
                'holderId' => sprintf('%s_Holder', $field->ID()),
283
                'title' => 'Test tree',
284
                'extraClass' => 'treemultiselectfield_readonly multiple  searchable',
285
                'data' => [
286
                    'urlTree' => 'field/TestTree/tree',
287
                    'showSearch' => true,
288
                    'emptyString' => '(Search or choose File)',
289
                    'hasEmptyDefault' => false,
290
                    'multiple' => true
291
                ]
292
            ],
293
            $schemaDataDefaults,
294
            true
295
        );
296
297
        $items = $field->getItems();
298
        $this->assertCount(2, $items, 'there must be exactly 2 selected items');
299
300
        $html = $field->Field();
301
        $this->assertContains($field->ID(), $html);
302
        $this->assertContains($this->fieldValue, $html);
303
    }
304
305
    public function testGetItems()
306
    {
307
        // Default items scaffolded from 'unchanged' value (empty)
308
        $field = $this->field;
309
        $this->assertListEquals(
310
            [],
311
            $field->getItems()
312
        );
313
314
        $expectedItem = array_map(
315
            function ($folder) {
316
                return [
317
                    'Filename' => $folder->Filename,
318
                ];
319
            },
320
            $this->loadFolders()
321
        );
322
323
        // Set list of items by array of ids
324
        $field->setValue($this->folderIds);
325
        $this->assertListEquals(
326
            $expectedItem,
327
            $field->getItems()
328
        );
329
330
        // Set list of items by comma separated ids
331
        $field->setValue($this->fieldValue);
332
        $this->assertListEquals(
333
            $expectedItem,
334
            $field->getItems()
335
        );
336
337
        // Handle legacy empty value (form submits 'unchanged')
338
        $field->setValue('unchanged');
339
        $this->assertListEquals(
340
            [],
341
            $field->getItems()
342
        );
343
    }
344
}
345