Passed
Push — master ( 2036b9...d64bc0 )
by Thomas
02:44
created

CmsActionsTest::getTestForm()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 2 Features 2
Metric Value
cc 4
eloc 14
c 5
b 2
f 2
nc 8
nop 2
dl 0
loc 20
rs 9.7998
1
<?php
2
3
namespace LeKoala\CmsActions\Test;
4
5
use SilverStripe\Forms\Form;
6
use SilverStripe\Security\Member;
7
use LeKoala\CmsActions\CustomLink;
8
use SilverStripe\Dev\SapphireTest;
9
use SilverStripe\Admin\LeftAndMain;
10
use SilverStripe\Control\Controller;
11
use SilverStripe\Versioned\Versioned;
12
use SilverStripe\Forms\CompositeField;
13
use SilverStripe\Forms\GridField\GridField;
14
use SilverStripe\Forms\GridField\GridFieldDetailForm;
15
use SilverStripe\Versioned\VersionedGridFieldItemRequest;
16
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
17
use SilverStripe\CMS\Model\SiteTree;
0 ignored issues
show
Bug introduced by
The type SilverStripe\CMS\Model\SiteTree 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...
18
use SilverStripe\ORM\ArrayList;
19
use SilverStripe\View\ArrayData;
20
use SilverStripe\Forms\GridField\GridFieldDataColumns;
21
use SilverStripe\Forms\GridField\GridFieldFilterHeader;
22
use SilverStripe\Forms\FieldList;
23
use SilverStripe\Forms\HiddenField;
24
use SilverStripe\Forms\TextField;
25
use SilverStripe\Forms\GridField\GridFieldViewButton;
26
27
/**
28
 * Tests for Cms Actions module
29
 */
30
class CmsActionsTest extends SapphireTest
31
{
32
    /**
33
     * Defines the fixture file to use for this test class
34
     * @var string
35
     */
36
    protected static $fixture_file = 'CmsActionsTest.yml';
37
    protected static $fixture_file_simple = 'CmsActionsSimpleTest.yml';
38
39
    protected static $extra_dataobjects = array(
40
        Test_CmsActionsModel::class,
41
    );
42
43
    public static function get_fixture_file()
44
    {
45
        if (class_exists(SiteTree::class)) {
46
            return self::$fixture_file;
47
        }
48
        return self::$fixture_file_simple;
49
    }
50
51
    public static function getExtraDataObjects()
52
    {
53
        $arr = parent::getExtraDataObjects();
54
        if (class_exists(SiteTree::class)) {
55
            $arr[] = Test_ActionsPage::class;
56
        }
57
        return $arr;
58
    }
59
60
61
    public function setUp(): void
62
    {
63
        parent::setUp();
64
        $controller = Controller::curr();
65
        $controller->config()->set('url_segment', 'test_controller');
66
    }
67
68
    public function tearDown(): void
69
    {
70
        parent::tearDown();
71
    }
72
73
    /**
74
     * @return Test_ActionsPage
75
     */
76
    public function getTestPage()
77
    {
78
        return $this->objFromFixture(Test_ActionsPage::class, 'demo');
79
    }
80
81
    /**
82
     * @return Test_CmsActionsModel
83
     */
84
    public function getTestModel()
85
    {
86
        return $this->objFromFixture(Test_CmsActionsModel::class, 'demo');
87
    }
88
89
    /**
90
     * @return Member
91
     */
92
    public function getAdminMember()
93
    {
94
        return $this->objFromFixture(Member::class, 'admin');
95
    }
96
97
    /**
98
     * @return Form
99
     */
100
    public function getMemberForm()
101
    {
102
        $controller = Controller::curr();
103
        $form = new Form($controller);
0 ignored issues
show
Unused Code introduced by
The assignment to $form is dead and can be removed.
Loading history...
104
105
        $record = $this->getAdminMember();
106
107
        $list = Member::get();
108
        $gridField = new GridField('testGridfield', null, $list);
109
        $detailForm = new GridFieldDetailForm('testDetailForm');
110
        $GridFieldDetailForm = new GridFieldDetailForm_ItemRequest($gridField, $detailForm, $record, $controller, 'testPopup');
111
        $form = $GridFieldDetailForm->ItemEditForm();
112
        $form->loadDataFrom($record);
0 ignored issues
show
Bug introduced by
The method loadDataFrom() does not exist on SilverStripe\Control\HTTPResponse. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

112
        $form->/** @scrutinizer ignore-call */ 
113
               loadDataFrom($record);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
113
114
        return $form;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $form returns the type SilverStripe\Control\HTTPResponse which is incompatible with the documented return type SilverStripe\Forms\Form.
Loading history...
115
    }
116
117
    /**
118
     * @param Controller $controller
119
     * @param DataObject $record
0 ignored issues
show
Bug introduced by
The type LeKoala\CmsActions\Test\DataObject 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...
120
     * @return Form
121
     */
122
    public function getTestForm($controller = null, $record = null)
123
    {
124
        if (!$controller) {
125
            $controller = Controller::curr();
126
        }
127
        if (!$record) {
128
            $record = $this->getTestModel();
129
        }
130
        $list = Test_CmsActionsModel::get();
131
        $gridField = new GridField('testGridfield', null, $list);
132
        $detailForm = new GridFieldDetailForm('testDetailForm');
133
        if ($record->hasExtension(Versioned::class)) {
134
            $GridFieldDetailForm = new VersionedGridFieldItemRequest($gridField, $detailForm, $record, $controller, 'testPopup');
135
        } else {
136
            $GridFieldDetailForm = new GridFieldDetailForm_ItemRequest($gridField, $detailForm, $record, $controller, 'testPopup');
137
        }
138
        $form = $GridFieldDetailForm->ItemEditForm();
139
        $form->loadDataFrom($record);
140
141
        return $form;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $form returns the type SilverStripe\Control\HTTPResponse which is incompatible with the documented return type SilverStripe\Forms\Form.
Loading history...
142
    }
143
144
    /**
145
     * @param Controller $controller
146
     * @param DataObject $record
147
     * @return Form
148
     */
149
    public function getViewableForm($controller = null, $record = null)
150
    {
151
        $r1 = ArrayData::create([
152
            'ID' => 1,
153
            'FieldName' => 'This is an item',
154
        ]);
155
        $r2 = ArrayData::create([
156
            'ID' => 2,
157
            'FieldName' => 'This is a different item',
158
        ]);
159
160
        if (!$controller) {
161
            $controller = Controller::curr();
162
        }
163
        if (!$record) {
164
            $record = $r1;
165
        }
166
167
        $list = ArrayList::create([
168
            $r1,
169
            $r2,
170
        ]);
171
172
        $gridField = GridField::create('MyData', 'My data', $list);
173
        $gridField->setForm(new Form($controller, "TestForm"));
174
        $gridField->getConfig()->removeComponentsByType(GridFieldFilterHeader::class);
175
        $columns = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
176
        $columns->setDisplayFields([
177
            'FieldName' => 'Column Header Label',
178
        ]);
179
        $detailForm = GridFieldDetailForm::create();
180
        $detailForm->setFields(FieldList::create([
181
            HiddenField::create('ID'),
182
            TextField::create('FieldName', 'View Field Label'),
183
        ]));
184
        $gridField->getConfig()->addComponents([
185
            GridFieldViewButton::create(),
186
            $detailForm,
187
        ]);
188
        $GridFieldDetailForm = new GridFieldDetailForm_ItemRequest($gridField, $detailForm, $record, $controller, 'testPopup');
189
        $form = $GridFieldDetailForm->ItemEditForm();
190
        $form->loadDataFrom($record);
191
192
        return $form;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $form returns the type SilverStripe\Control\HTTPResponse which is incompatible with the documented return type SilverStripe\Forms\Form.
Loading history...
193
    }
194
195
    public function testCustomDeleteTitle()
196
    {
197
        $form = $this->getTestForm();
198
199
        /** @var Test_CmsActionsModel $record */
200
        $record = $form->getRecord();
201
202
        $delete = $form->Actions()->fieldByName("action_doDelete");
203
        $this->assertEquals($delete->Title(), $record->getDeleteButtonTitle());
204
    }
205
206
    public function testHasSaveAndClose()
207
    {
208
        $form = $this->getTestForm();
209
210
        $doSaveAndClose = $form->Actions()->fieldByName("action_doSaveAndClose");
211
        // It can be nested in MajorActions, then we need to use dot notation
212
        if (!$doSaveAndClose) {
213
            $doSaveAndClose = $form->Actions()->fieldByName("MajorActions.action_doSaveAndClose");
214
        }
215
        $this->assertNotEmpty($doSaveAndClose);
216
    }
217
218
    public function testHasDefaultTitle()
219
    {
220
        $customLink = new CustomLink('doTest');
221
        $this->assertEquals('Do test', $customLink->getTitle());
222
    }
223
224
    public function testConfirmationMessage()
225
    {
226
        $customLink = new CustomLink('doTest');
227
        $customLink->setConfirmation(true);
228
        $this->assertStringContainsString('sure', $customLink->getConfirmation());
229
    }
230
231
    public function testGridFieldAction()
232
    {
233
        $form = $this->getTestForm();
0 ignored issues
show
Unused Code introduced by
The assignment to $form is dead and can be removed.
Loading history...
234
        $action = new Test_GridFieldAction;
235
236
        $record = $this->getTestModel();
237
        $list = Test_CmsActionsModel::get();
238
        $gridField = new GridField('testGridfield', null, $list);
239
        $actionName = 'test';
240
        $arguments = ['ID' => $record->ID];
241
        $data = [];
242
243
        $result = $action->doHandle($gridField, $actionName, $arguments, $data);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $result is correct as $action->doHandle($gridF...ame, $arguments, $data) targeting LeKoala\CmsActions\Test\...FieldAction::doHandle() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
244
245
        $this->assertEquals($actionName, $action->performedActionName);
246
        $this->assertEquals($arguments, $action->performedArguments);
247
        $this->assertEquals($data, $action->performedData);
248
    }
249
250
    public function testLeftAndMain()
251
    {
252
        if (!class_exists(SiteTree::class)) {
253
            $this->assertTrue(true); // make phpunit happy
254
            return;
255
        }
256
        $page = $this->getTestPage();
257
        $leftAndMain = LeftAndMain::create();
258
        $form = $this->getTestForm($leftAndMain, $page);
259
260
        // otherwise getRecord complains
261
        $leftAndMain->record = $page;
262
        $result = $leftAndMain->doCustomAction(
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
263
            [
264
                'action_doCustomAction' => [
265
                    'testAction' => 1
266
                ],
267
                'ID' => $page->ID,
268
                'ClassName' => $page->ClassName
269
            ],
270
            $form
271
        );
272
273
        $this->assertEquals($page->testAction(), $form->getMessage());
274
275
        $list = [];
276
        $simpleList = [];
277
        foreach ($form->Actions() as $action) {
278
            if ($action instanceof CompositeField) {
279
                $arr = [];
280
                foreach ($action->getChildren() as $subAction) {
281
                    $arr[] = $subAction->getName() . ' (' . get_class($subAction) . ')';
282
                    $simpleList[] = $subAction->getName();
283
                }
284
                $list[] = $arr;
285
            } else {
286
                $list[] = $action->getName() . ' (' . get_class($action) . ')';
287
                $simpleList[] = $action->getName();
288
            }
289
        }
290
        $filteredSimpleList = array_unique($simpleList);
291
        // We should not have duplicated actions
292
        $this->assertEquals($filteredSimpleList, $simpleList);
293
    }
294
295
    public function testGetModelLink()
296
    {
297
        $action = new CustomLink("testAction", "test");
298
299
        $controller = Controller::curr();
300
301
        // SS5 trailing slashes
302
        // @link https://docs.silverstripe.org/en/5/changelogs/5.0.0/#trailing-slash
303
        $add_trailing_slash = $controller::config()->add_trailing_slash;
304
305
        // Without an url, we link on the current controller
306
        $link = $action->getModelLink("testAction");
307
        if ($add_trailing_slash === null) {
308
            $this->assertEquals('test_controller/testAction/?CustomLink=testAction', $link);
309
        } elseif ($add_trailing_slash === false) {
310
            $this->assertEquals('test_controller/testAction?CustomLink=testAction', $link);
311
        } elseif ($add_trailing_slash === true) {
312
            $this->assertEquals('test_controller/testAction/?CustomLink=testAction', $link);
313
        }
314
315
316
        // in settings
317
        $controller->getRequest()->setUrl('admin/settings/EditForm/field/MyModel/item/1/edit');
318
        $link = $action->getModelLink("testAction");
319
        $this->assertEquals('admin/settings/EditForm/field/MyModel/item/1/doCustomLink?CustomLink=testAction', $link);
320
321
        // in model admin
322
        $controller->getRequest()->setUrl('admin/model_admin/MyModel/EditForm/field/MyModel/item/0/edit');
323
        $link = $action->getModelLink("testAction");
324
        $this->assertEquals('admin/model_admin/MyModel/EditForm/field/MyModel/item/0/doCustomLink?CustomLink=testAction', $link);
325
326
        // in model admin with just an id
327
        $controller->getRequest()->setUrl('admin/model_admin/MyModel/EditForm/field/MyModel/item/0/');
328
        $link = $action->getModelLink("testAction");
329
        $this->assertEquals('admin/model_admin/MyModel/EditForm/field/MyModel/item/0/doCustomLink?CustomLink=testAction', $link);
330
331
        // in nested grid
332
        $controller->getRequest()->setUrl('admin/model_admin/MyModel/EditForm/field/MyModel/item/0/ItemEditForm/field/OtherModel/item/0/edit');
333
        $link = $action->getModelLink("testAction");
334
        $this->assertEquals('admin/model_admin/MyModel/EditForm/field/MyModel/item/0/ItemEditForm/field/OtherModel/item/0/doCustomLink?CustomLink=testAction', $link);
335
336
        $controller->getRequest()->setUrl('');
337
    }
338
339
    public function testViewable()
340
    {
341
        $form = $this->getViewableForm();
342
343
        $doSaveAndClose = $form->Actions()->fieldByName("action_doSaveAndClose");
344
        $this->assertNull($doSaveAndClose); // not available for ViewableData
345
    }
346
}
347