Passed
Pull Request — master (#793)
by
unknown
02:32
created

testRenderingIntoTemplateWithSubstringReplacement()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\UserForms\Tests\Control;
4
5
use SilverStripe\Control\HTTPResponse;
6
use SilverStripe\Core\Config\Config;
7
use SilverStripe\Dev\CSSContentParser;
8
use SilverStripe\Dev\FunctionalTest;
9
use SilverStripe\Forms\FieldList;
10
use SilverStripe\Forms\FormAction;
11
use SilverStripe\ORM\DataObject;
12
use SilverStripe\UserForms\Control\UserDefinedFormController;
13
use SilverStripe\UserForms\Model\EditableFormField\EditableTextField;
14
use SilverStripe\UserForms\Model\Submission\SubmittedFormField;
15
use SilverStripe\UserForms\Model\UserDefinedForm;
16
use SilverStripe\View\ArrayData;
17
use SilverStripe\View\SSViewer;
18
19
/**
20
 * @package userforms
21
 */
22
class UserDefinedFormControllerTest extends FunctionalTest
23
{
24
    protected static $fixture_file = '../UserFormsTest.yml';
25
26
    protected static $use_draft_site = true;
27
28
    protected static $disable_themes = true;
29
30
    protected function setUp()
31
    {
32
        parent::setUp();
33
34
        Config::modify()->merge(SSViewer::class, 'themes', ['simple', '$default']);
35
    }
36
37
    public function testProcess()
38
    {
39
        $form = $this->setupFormFrontend();
40
41
        $controller = new UserDefinedFormController($form);
0 ignored issues
show
Unused Code introduced by
The assignment to $controller is dead and can be removed.
Loading history...
42
43
        $this->autoFollowRedirection = false;
44
        $this->clearEmails();
45
46
        // load the form
47
        $this->get($form->URLSegment);
48
49
        $field = $this->objFromFixture(EditableTextField::class, 'basic-text');
50
51
        $response = $this->submitForm('UserForm_Form_' . $form->ID, null, [$field->Name => 'Basic Value']);
52
53
        // should have a submitted form field now
54
        $submitted = DataObject::get(SubmittedFormField::class, "\"Name\" = 'basic-text-name'");
55
        $this->assertListAllMatch(
56
            [
57
                'Name' => 'basic-text-name',
58
                'Value' => 'Basic Value',
59
                'Title' => 'Basic Text Field'
60
            ],
61
            $submitted
62
        );
63
64
        // check emails
65
        $this->assertEmailSent('[email protected]', '[email protected]', 'Email Subject');
66
        $email = $this->findEmail('[email protected]', '[email protected]', 'Email Subject');
67
68
        // assert that the email has the field title and the value html email
69
        $parser = new CSSContentParser($email['Content']);
70
        $title = $parser->getBySelector('strong');
71
72
        $this->assertEquals('Basic Text Field', (string) $title[0], 'Email contains the field name');
73
74
        $value = $parser->getBySelector('dd');
75
        $this->assertEquals('Basic Value', (string) $value[0], 'Email contains the value');
76
77
        // no html
78
        $this->assertEmailSent('[email protected]', '[email protected]', 'Email Subject');
79
        $nohtml = $this->findEmail('[email protected]', '[email protected]', 'Email Subject');
80
81
        $this->assertContains('Basic Text Field: Basic Value', $nohtml['Content'], 'Email contains no html');
82
83
        // no data
84
        $this->assertEmailSent('[email protected]', '[email protected]', 'Email Subject');
85
        $nodata = $this->findEmail('[email protected]', '[email protected]', 'Email Subject');
86
87
        $parser = new CSSContentParser($nodata['Content']);
88
        $list = $parser->getBySelector('dl');
89
90
        $this->assertEmpty($list, 'Email contains no fields');
91
92
        // check to see if the user was redirected (301)
93
        $this->assertEquals($response->getStatusCode(), 302);
94
        $location = $response->getHeader('Location');
95
        $this->assertContains('finished', $location);
96
        $this->assertStringEndsWith('#uff', $location);
97
98
        // check that multiple email addresses are supported in to and from
99
        $this->assertEmailSent(
100
            '[email protected]; [email protected]',
101
            '[email protected]; [email protected]',
102
            'Test Email'
103
        );
104
    }
105
106
    public function testValidation()
107
    {
108
        $form = $this->setupFormFrontend('email-form');
109
110
        // Post with no fields
111
        $this->get($form->URLSegment);
112
        /** @var HTTPResponse $response */
113
        $response = $this->submitForm('UserForm_Form_' . $form->ID, null, []);
114
        $this->assertContains('This field is required', $response->getBody());
115
116
        // Post with all fields, but invalid email
117
        $this->get($form->URLSegment);
118
        /** @var HTTPResponse $response */
119
        $response = $this->submitForm('UserForm_Form_' . $form->ID, null, [
120
            'required-email' => 'invalid',
121
            'required-text' => 'bob'
122
        ]);
123
        $this->assertContains('Please enter an email address', $response->getBody());
124
125
        // Post with only required
126
        $this->get($form->URLSegment);
127
        /** @var HTTPResponse $response */
128
        $response = $this->submitForm('UserForm_Form_' . $form->ID, null, [
129
            'required-text' => 'bob'
130
        ]);
131
        $this->assertContains("Thanks, we've received your submission.", $response->getBody());
132
    }
133
134
    public function testFinished()
135
    {
136
        $form = $this->setupFormFrontend();
137
138
        // set formProcessed and SecurityID to replicate the form being filled out
139
        $this->session()->set('SecurityID', 1);
140
        $this->session()->set('FormProcessed', 1);
141
142
        $response = $this->get($form->URLSegment.'/finished');
143
144
        $this->assertContains($form->OnCompleteMessage, $response->getBody());
145
    }
146
147
    public function testAppendingFinished()
148
    {
149
        $form = $this->setupFormFrontend();
150
151
        // replicate finished being added to the end of the form URL without the form being filled out
152
        $this->session()->set('SecurityID', 1);
153
        $this->session()->set('FormProcessed', null);
154
155
        $response = $this->get($form->URLSegment.'/finished');
156
157
        $this->assertNotContains($form->OnCompleteMessage, $response->getBody());
158
    }
159
160
    public function testForm()
161
    {
162
        $form = $this->objFromFixture(UserDefinedForm::class, 'basic-form-page');
163
164
        $controller = new UserDefinedFormController($form);
165
166
        // test form
167
        $this->assertEquals($controller->Form()->getName(), 'Form_' . $form->ID, 'The form is referenced as Form');
168
        $this->assertEquals($controller->Form()->Fields()->Count(), 1); // disabled SecurityID token fields
169
        $this->assertEquals($controller->Form()->Actions()->Count(), 1);
170
        $this->assertEquals(count($controller->Form()->getValidator()->getRequired()), 0);
171
172
        $requiredForm = $this->objFromFixture(UserDefinedForm::class, 'validation-form');
173
        $controller = new UserDefinedFormController($requiredForm);
174
175
        $this->assertEquals($controller->Form()->Fields()->Count(), 1); // disabled SecurityID token fields
176
        $this->assertEquals($controller->Form()->Actions()->Count(), 1);
177
        $this->assertEquals(count($controller->Form()->getValidator()->getRequired()), 1);
178
    }
179
180
    public function testGetFormFields()
181
    {
182
        // generating the fieldset of fields
183
        $form = $this->objFromFixture(UserDefinedForm::class, 'basic-form-page');
184
185
        $controller = new UserDefinedFormController($form);
186
187
        $formSteps = $controller->Form()->getFormFields();
188
        $firstStep = $formSteps->first();
189
190
        $this->assertEquals($formSteps->Count(), 1);
191
        $this->assertEquals($firstStep->getChildren()->Count(), 1);
192
193
        // custom error message on a form field
194
        $requiredForm = $this->objFromFixture(UserDefinedForm::class, 'validation-form');
195
        $controller = new UserDefinedFormController($requiredForm);
196
197
        Config::modify()->set(UserDefinedForm::class, 'required_identifier', '*');
198
199
        $formSteps = $controller->Form()->getFormFields();
200
        $firstStep = $formSteps->first();
201
        $firstField = $firstStep->getChildren()->first();
202
203
        $this->assertEquals('Custom Error Message', $firstField->getCustomValidationMessage());
204
        $this->assertEquals($firstField->Title(), 'Required Text Field <span class=\'required-identifier\'>*</span>');
205
206
        // test custom right title
207
        $field = $form->Fields()->limit(1, 1)->First();
208
        $field->RightTitle = 'Right Title';
209
        $field->write();
210
211
        $controller = new UserDefinedFormController($form);
212
        $formSteps = $controller->Form()->getFormFields();
213
        $firstStep = $formSteps->first();
214
215
        $this->assertEquals($firstStep->getChildren()->First()->RightTitle(), "Right Title");
216
217
        // test empty form
218
        $emptyForm = $this->objFromFixture(UserDefinedForm::class, 'empty-form');
219
        $controller = new UserDefinedFormController($emptyForm);
220
221
        $this->assertFalse($controller->Form()->getFormFields()->exists());
222
    }
223
224
    public function testGetFormActions()
225
    {
226
        // generating the fieldset of actions
227
        $form = $this->objFromFixture(UserDefinedForm::class, 'basic-form-page');
228
229
        $controller = new UserDefinedFormController($form);
230
        $actions = $controller->Form()->getFormActions();
231
232
        // by default will have 1 submit button which links to process
233
        $expected = new FieldList(new FormAction('process', 'Submit'));
234
        $expected->setForm($controller->Form());
235
236
        $this->assertEquals($actions, $expected);
237
238
        // the custom popup should have a reset button and a custom text
239
        $custom = $this->objFromFixture(UserDefinedForm::class, 'form-with-reset-and-custom-action');
240
        $controller = new UserDefinedFormController($custom);
241
        $actions = $controller->Form()->getFormActions();
242
243
        $expected = new FieldList(new FormAction('process', 'Custom Button'));
244
        $expected->push(FormAction::create('clearForm', 'Clear')->setAttribute('type', 'reset'));
245
        $expected->setForm($controller->Form());
246
247
        $this->assertEquals($actions, $expected);
248
    }
249
250
    public function testRenderingIntoFormTemplate()
251
    {
252
        $form = $this->setupFormFrontend();
253
254
        $this->logInWithPermission('ADMIN');
255
        $form->Content = 'This is some content without a form nested between it';
256
        $form->publishRecursive();
257
258
        $controller = new UserDefinedFormController($form);
259
260
        // check to see if $Form is placed in the template
261
        $index = new ArrayData($controller->index());
262
        $parser = new CSSContentParser($index->renderWith(__CLASS__));
263
264
        $this->checkTemplateIsCorrect($parser, $form);
265
    }
266
267
    public function testRenderingIntoTemplateWithSubstringReplacement()
268
    {
269
        $form = $this->setupFormFrontend();
270
271
        $controller = new UserDefinedFormController($form);
272
273
        // check to see if $Form is replaced to inside the content
274
        $index = new ArrayData($controller->index());
275
        $parser = new CSSContentParser($index->renderWith(__CLASS__));
276
277
        $this->checkTemplateIsCorrect($parser, $form);
278
    }
279
280
    public function testRenderingIntoTemplateWithDisabledInterpolation()
281
    {
282
        $form = $this->setupFormFrontend();
283
284
        $controller = new UserDefinedFormController($form);
285
        $controller->config()->set('disable_form_content_shortcode', true);
286
        // check to see if $Form is replaced to inside the content
287
        $index = new ArrayData($controller->index());
288
        $html = $index->renderWith(__CLASS__);
289
        $parser = new CSSContentParser($html);
290
291
        // Assert Content has been rendered with the shortcode in place
292
        $this->assertContains('<p>Here is my form</p><p>$UserDefinedForm</p><p>Thank you for filling it out</p>', $html);
293
        // And the form in the $From area
294
        $this->assertArrayHasKey(0, $parser->getBySelector('form#UserForm_Form_' . $form->ID));
295
        // check for the input
296
        $this->assertArrayHasKey(0, $parser->getBySelector('input.text'));
297
    }
298
299
    /**
300
     * Publish a form for use on the frontend
301
     *
302
     * @param string $fixtureName
303
     * @return UserDefinedForm
304
     */
305
    protected function setupFormFrontend($fixtureName = 'basic-form-page')
306
    {
307
        $form = $this->objFromFixture(UserDefinedForm::class, $fixtureName);
308
309
        $this->actWithPermission('ADMIN', function () use ($form) {
310
            $form->publishRecursive();
311
        });
312
313
        return $form;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $form returns the type SilverStripe\ORM\DataObject which is incompatible with the documented return type SilverStripe\UserForms\Model\UserDefinedForm.
Loading history...
314
    }
315
316
    public function checkTemplateIsCorrect($parser, $form)
317
    {
318
        $this->assertArrayHasKey(0, $parser->getBySelector('form#UserForm_Form_' . $form->ID));
319
320
        // check for the input
321
        $this->assertArrayHasKey(0, $parser->getBySelector('input.text'));
322
323
        // check for the label and the text
324
        $label = $parser->getBySelector('label.left');
325
        $this->assertArrayHasKey(0, $label);
326
327
        $this->assertEquals((string) $label[0][0], "Basic Text Field", "Label contains correct field name");
328
329
        // check for the action
330
        $action = $parser->getBySelector('input.action');
331
        $this->assertArrayHasKey(0, $action);
332
333
        $this->assertEquals((string) $action[0]['value'], "Submit", "Submit button has default text");
334
    }
335
}
336