Completed
Push — master ( 2d310a...df918c )
by
unknown
24s queued 10s
created

testRecipientSubjectMergeFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 31
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

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