2010-09-03 07:06:13 +02:00
|
|
|
<?php
|
|
|
|
|
2017-10-09 21:48:16 +02:00
|
|
|
namespace SilverStripe\UserForms\Tests\Control;
|
2017-08-09 01:55:09 +02:00
|
|
|
|
2023-05-17 05:54:29 +02:00
|
|
|
use ReflectionClass;
|
2020-05-27 02:26:14 +02:00
|
|
|
use SilverStripe\Assets\Dev\TestAssetStore;
|
|
|
|
use SilverStripe\Assets\File;
|
2020-06-10 06:59:01 +02:00
|
|
|
use SilverStripe\Assets\Folder;
|
2020-05-27 02:26:14 +02:00
|
|
|
use SilverStripe\Assets\Storage\AssetStore;
|
|
|
|
use SilverStripe\Assets\Upload_Validator;
|
2020-06-10 06:59:01 +02:00
|
|
|
use SilverStripe\Control\HTTPRequest;
|
2018-03-19 03:09:13 +01:00
|
|
|
use SilverStripe\Control\HTTPResponse;
|
2020-05-27 02:26:14 +02:00
|
|
|
use SilverStripe\Control\Session;
|
2017-08-13 23:26:53 +02:00
|
|
|
use SilverStripe\Core\Config\Config;
|
2020-05-27 02:26:14 +02:00
|
|
|
use SilverStripe\Core\Injector\Injector;
|
2017-08-11 02:20:12 +02:00
|
|
|
use SilverStripe\Dev\CSSContentParser;
|
|
|
|
use SilverStripe\Dev\FunctionalTest;
|
|
|
|
use SilverStripe\Forms\FieldList;
|
|
|
|
use SilverStripe\Forms\FormAction;
|
|
|
|
use SilverStripe\ORM\DataObject;
|
2020-06-10 06:59:01 +02:00
|
|
|
use SilverStripe\Security\InheritedPermissions;
|
2018-01-25 03:38:54 +01:00
|
|
|
use SilverStripe\UserForms\Control\UserDefinedFormController;
|
2020-05-27 02:26:14 +02:00
|
|
|
use SilverStripe\UserForms\Model\EditableFormField\EditableFileField;
|
2017-08-09 01:55:09 +02:00
|
|
|
use SilverStripe\UserForms\Model\EditableFormField\EditableTextField;
|
2019-01-28 05:28:55 +01:00
|
|
|
use SilverStripe\UserForms\Model\Recipient\EmailRecipient;
|
2017-08-09 01:55:09 +02:00
|
|
|
use SilverStripe\UserForms\Model\Submission\SubmittedFormField;
|
|
|
|
use SilverStripe\UserForms\Model\UserDefinedForm;
|
2020-10-31 09:15:00 +01:00
|
|
|
use SilverStripe\UserForms\Tests\Control\fixtures\SizeStringTestableController;
|
2022-05-13 06:25:51 +02:00
|
|
|
use SilverStripe\Versioned\Versioned;
|
2024-09-23 04:40:23 +02:00
|
|
|
use SilverStripe\Model\ArrayData;
|
2017-08-16 01:57:50 +02:00
|
|
|
use SilverStripe\View\SSViewer;
|
2021-04-06 15:46:37 +02:00
|
|
|
use function filesize;
|
2024-09-10 01:28:45 +02:00
|
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
2017-08-09 01:55:09 +02:00
|
|
|
|
2010-09-03 07:06:13 +02:00
|
|
|
/**
|
|
|
|
* @package userforms
|
|
|
|
*/
|
2016-07-21 07:53:59 +02:00
|
|
|
class UserDefinedFormControllerTest extends FunctionalTest
|
|
|
|
{
|
2017-10-15 23:13:01 +02:00
|
|
|
protected static $fixture_file = '../UserFormsTest.yml';
|
2010-09-03 07:06:13 +02:00
|
|
|
|
2018-06-01 07:01:45 +02:00
|
|
|
protected static $disable_themes = true;
|
|
|
|
|
2021-11-01 21:52:58 +01:00
|
|
|
protected function setUp(): void
|
2017-08-16 01:57:50 +02:00
|
|
|
{
|
|
|
|
parent::setUp();
|
|
|
|
|
2020-05-27 02:26:14 +02:00
|
|
|
// Set backend and base url
|
|
|
|
TestAssetStore::activate('AssetStoreTest');
|
|
|
|
|
2020-10-31 09:15:00 +01:00
|
|
|
$config = Config::modify();
|
|
|
|
$config->set(UserDefinedFormController::class, 'maximum_email_attachment_size', "1M");
|
|
|
|
$config->merge(SSViewer::class, 'themes', ['simple', '$default']);
|
2017-08-16 01:57:50 +02:00
|
|
|
}
|
|
|
|
|
2021-11-01 21:52:58 +01:00
|
|
|
protected function tearDown(): void
|
2020-05-27 02:26:14 +02:00
|
|
|
{
|
|
|
|
TestAssetStore::reset();
|
|
|
|
parent::tearDown();
|
|
|
|
}
|
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
public function testProcess()
|
|
|
|
{
|
|
|
|
$form = $this->setupFormFrontend();
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-08-11 02:20:12 +02:00
|
|
|
$controller = new UserDefinedFormController($form);
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->autoFollowRedirection = false;
|
|
|
|
$this->clearEmails();
|
2015-08-11 22:57:19 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// load the form
|
|
|
|
$this->get($form->URLSegment);
|
2015-08-11 22:57:19 +02:00
|
|
|
|
2021-01-28 04:20:26 +01:00
|
|
|
/** @var EditableTextField $field */
|
2017-08-09 01:55:09 +02:00
|
|
|
$field = $this->objFromFixture(EditableTextField::class, 'basic-text');
|
2015-08-11 22:57:19 +02:00
|
|
|
|
2021-01-28 04:20:26 +01:00
|
|
|
$data = [$field->Name => 'Basic Value <b>HTML</b>'];
|
|
|
|
$response = $this->submitForm('UserForm_Form_' . $form->ID, null, $data);
|
2010-09-03 07:06:13 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// should have a submitted form field now
|
2019-01-28 05:28:55 +01:00
|
|
|
$submitted = DataObject::get(SubmittedFormField::class, "\"Name\" = 'basic_text_name'");
|
2018-01-25 03:38:54 +01:00
|
|
|
$this->assertListAllMatch(
|
2017-08-11 02:20:12 +02:00
|
|
|
[
|
2019-01-28 05:28:55 +01:00
|
|
|
'Name' => 'basic_text_name',
|
2021-01-28 04:20:26 +01:00
|
|
|
'Value' => 'Basic Value <b>HTML</b>',
|
2017-08-11 02:20:12 +02:00
|
|
|
'Title' => 'Basic Text Field'
|
|
|
|
],
|
|
|
|
$submitted
|
|
|
|
);
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// check emails
|
|
|
|
$this->assertEmailSent('test@example.com', 'no-reply@example.com', 'Email Subject');
|
|
|
|
$email = $this->findEmail('test@example.com', 'no-reply@example.com', 'Email Subject');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// assert that the email has the field title and the value html email
|
2017-08-15 00:49:13 +02:00
|
|
|
$parser = new CSSContentParser($email['Content']);
|
2016-07-21 07:53:59 +02:00
|
|
|
$title = $parser->getBySelector('strong');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->assertEquals('Basic Text Field', (string) $title[0], 'Email contains the field name');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2021-01-28 04:20:26 +01:00
|
|
|
// submitted html tags are escaped for the html value
|
|
|
|
$value = 'class="readonly">My body html Basic Value <b>HTML</b></span>';
|
2022-04-13 03:52:56 +02:00
|
|
|
$this->assertTrue(strpos($email['Content'] ?? '', $value ?? '') !== false, 'Email contains the merge field value');
|
2021-01-28 04:20:26 +01:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$value = $parser->getBySelector('dd');
|
2021-01-28 04:20:26 +01:00
|
|
|
$this->assertEquals('Basic Value <b>HTML</b>', (string) $value[0], 'Email contains the value');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// no html
|
|
|
|
$this->assertEmailSent('nohtml@example.com', 'no-reply@example.com', 'Email Subject');
|
|
|
|
$nohtml = $this->findEmail('nohtml@example.com', 'no-reply@example.com', 'Email Subject');
|
2010-09-03 07:06:13 +02:00
|
|
|
|
2022-12-13 05:42:43 +01:00
|
|
|
$this->assertStringContainsString('* Basic Value <b>HTML</b>', $nohtml['Content'], 'Email contains no html');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2021-01-28 04:20:26 +01:00
|
|
|
// submitted html tags are not escaped because the email is being sent as text/plain
|
|
|
|
$value = 'My body text Basic Value <b>HTML</b>';
|
2021-11-01 21:52:58 +01:00
|
|
|
$this->assertStringContainsString($value, $nohtml['Content'], 'Email contains the merge field value');
|
2021-01-28 04:20:26 +01:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// no data
|
|
|
|
$this->assertEmailSent('nodata@example.com', 'no-reply@example.com', 'Email Subject');
|
|
|
|
$nodata = $this->findEmail('nodata@example.com', 'no-reply@example.com', 'Email Subject');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-08-15 00:49:13 +02:00
|
|
|
$parser = new CSSContentParser($nodata['Content']);
|
2016-07-21 07:53:59 +02:00
|
|
|
$list = $parser->getBySelector('dl');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2018-01-25 03:38:54 +01:00
|
|
|
$this->assertEmpty($list, 'Email contains no fields');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// check to see if the user was redirected (301)
|
|
|
|
$this->assertEquals($response->getStatusCode(), 302);
|
2018-03-25 23:46:09 +02:00
|
|
|
$location = $response->getHeader('Location');
|
2021-11-01 21:52:58 +01:00
|
|
|
$this->assertStringContainsString('finished', $location);
|
2018-03-25 23:46:09 +02:00
|
|
|
$this->assertStringEndsWith('#uff', $location);
|
2018-01-28 21:56:44 +01:00
|
|
|
|
|
|
|
// check that multiple email addresses are supported in to and from
|
|
|
|
$this->assertEmailSent(
|
2022-12-13 05:42:43 +01:00
|
|
|
'test1@example.com, test2@example.com',
|
|
|
|
'test3@example.com, test4@example.com',
|
2018-01-28 21:56:44 +01:00
|
|
|
'Test Email'
|
|
|
|
);
|
2016-07-21 07:53:59 +02:00
|
|
|
}
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
public function testValidation()
|
|
|
|
{
|
|
|
|
$form = $this->setupFormFrontend('email-form');
|
2015-12-11 05:38:31 +01:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// Post with no fields
|
|
|
|
$this->get($form->URLSegment);
|
2018-03-19 03:09:13 +01:00
|
|
|
/** @var HTTPResponse $response */
|
2017-08-11 02:20:12 +02:00
|
|
|
$response = $this->submitForm('UserForm_Form_' . $form->ID, null, []);
|
2021-11-01 21:52:58 +01:00
|
|
|
$this->assertStringContainsString('This field is required', $response->getBody());
|
2015-12-11 05:38:31 +01:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// Post with all fields, but invalid email
|
|
|
|
$this->get($form->URLSegment);
|
2018-03-19 03:09:13 +01:00
|
|
|
/** @var HTTPResponse $response */
|
|
|
|
$response = $this->submitForm('UserForm_Form_' . $form->ID, null, [
|
2016-07-21 07:53:59 +02:00
|
|
|
'required-email' => 'invalid',
|
|
|
|
'required-text' => 'bob'
|
2017-08-11 02:20:12 +02:00
|
|
|
]);
|
2021-11-01 21:52:58 +01:00
|
|
|
$this->assertStringContainsString('Please enter an email address', $response->getBody());
|
2015-12-11 05:38:31 +01:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// Post with only required
|
|
|
|
$this->get($form->URLSegment);
|
2018-03-19 03:09:13 +01:00
|
|
|
/** @var HTTPResponse $response */
|
|
|
|
$response = $this->submitForm('UserForm_Form_' . $form->ID, null, [
|
2016-07-21 07:53:59 +02:00
|
|
|
'required-text' => 'bob'
|
2017-08-11 02:20:12 +02:00
|
|
|
]);
|
2021-11-01 21:52:58 +01:00
|
|
|
$this->assertStringContainsString("Thanks, we've received your submission.", $response->getBody());
|
2016-07-21 07:53:59 +02:00
|
|
|
}
|
2015-12-11 05:38:31 +01:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
public function testFinished()
|
|
|
|
{
|
|
|
|
$form = $this->setupFormFrontend();
|
2014-01-06 03:15:01 +01:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// set formProcessed and SecurityID to replicate the form being filled out
|
2017-08-11 02:20:12 +02:00
|
|
|
$this->session()->set('SecurityID', 1);
|
|
|
|
$this->session()->set('FormProcessed', 1);
|
2014-01-06 03:15:01 +01:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$response = $this->get($form->URLSegment.'/finished');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2021-11-01 21:52:58 +01:00
|
|
|
$this->assertStringContainsString($form->OnCompleteMessage, $response->getBody());
|
2016-07-21 07:53:59 +02:00
|
|
|
}
|
2014-01-06 03:15:01 +01:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
public function testAppendingFinished()
|
|
|
|
{
|
|
|
|
$form = $this->setupFormFrontend();
|
2014-01-06 03:15:01 +01:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// replicate finished being added to the end of the form URL without the form being filled out
|
2017-08-11 02:20:12 +02:00
|
|
|
$this->session()->set('SecurityID', 1);
|
|
|
|
$this->session()->set('FormProcessed', null);
|
2014-01-06 03:15:01 +01:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$response = $this->get($form->URLSegment.'/finished');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2021-11-01 21:52:58 +01:00
|
|
|
$this->assertStringNotContainsString($form->OnCompleteMessage, $response->getBody());
|
2016-07-21 07:53:59 +02:00
|
|
|
}
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
public function testForm()
|
|
|
|
{
|
2017-08-09 01:55:09 +02:00
|
|
|
$form = $this->objFromFixture(UserDefinedForm::class, 'basic-form-page');
|
2015-08-10 07:03:36 +02:00
|
|
|
|
2017-08-11 02:20:12 +02:00
|
|
|
$controller = new UserDefinedFormController($form);
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// test form
|
2017-04-18 03:11:32 +02:00
|
|
|
$this->assertEquals($controller->Form()->getName(), 'Form_' . $form->ID, 'The form is referenced as Form');
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->assertEquals($controller->Form()->Fields()->Count(), 1); // disabled SecurityID token fields
|
|
|
|
$this->assertEquals($controller->Form()->Actions()->Count(), 1);
|
2022-04-13 03:52:56 +02:00
|
|
|
$this->assertEquals(count($controller->Form()->getValidator()->getRequired() ?? []), 0);
|
2010-09-03 07:06:13 +02:00
|
|
|
|
2017-08-09 01:55:09 +02:00
|
|
|
$requiredForm = $this->objFromFixture(UserDefinedForm::class, 'validation-form');
|
2017-08-11 02:20:12 +02:00
|
|
|
$controller = new UserDefinedFormController($requiredForm);
|
2010-09-03 07:06:13 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->assertEquals($controller->Form()->Fields()->Count(), 1); // disabled SecurityID token fields
|
|
|
|
$this->assertEquals($controller->Form()->Actions()->Count(), 1);
|
2022-04-13 03:52:56 +02:00
|
|
|
$this->assertEquals(count($controller->Form()->getValidator()->getRequired() ?? []), 1);
|
2016-07-21 07:53:59 +02:00
|
|
|
}
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
public function testGetFormFields()
|
|
|
|
{
|
|
|
|
// generating the fieldset of fields
|
2017-08-09 01:55:09 +02:00
|
|
|
$form = $this->objFromFixture(UserDefinedForm::class, 'basic-form-page');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-08-11 02:20:12 +02:00
|
|
|
$controller = new UserDefinedFormController($form);
|
2016-07-21 07:53:59 +02:00
|
|
|
|
|
|
|
$formSteps = $controller->Form()->getFormFields();
|
|
|
|
$firstStep = $formSteps->first();
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->assertEquals($formSteps->Count(), 1);
|
|
|
|
$this->assertEquals($firstStep->getChildren()->Count(), 1);
|
2015-08-10 07:03:36 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// custom error message on a form field
|
2017-08-09 01:55:09 +02:00
|
|
|
$requiredForm = $this->objFromFixture(UserDefinedForm::class, 'validation-form');
|
2017-08-11 02:20:12 +02:00
|
|
|
$controller = new UserDefinedFormController($requiredForm);
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-08-11 02:20:12 +02:00
|
|
|
Config::modify()->set(UserDefinedForm::class, 'required_identifier', '*');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$formSteps = $controller->Form()->getFormFields();
|
|
|
|
$firstStep = $formSteps->first();
|
|
|
|
$firstField = $firstStep->getChildren()->first();
|
2015-08-10 07:03:36 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->assertEquals('Custom Error Message', $firstField->getCustomValidationMessage());
|
|
|
|
$this->assertEquals($firstField->Title(), 'Required Text Field <span class=\'required-identifier\'>*</span>');
|
2015-08-10 07:03:36 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// test custom right title
|
|
|
|
$field = $form->Fields()->limit(1, 1)->First();
|
|
|
|
$field->RightTitle = 'Right Title';
|
|
|
|
$field->write();
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-08-11 02:20:12 +02:00
|
|
|
$controller = new UserDefinedFormController($form);
|
2016-07-21 07:53:59 +02:00
|
|
|
$formSteps = $controller->Form()->getFormFields();
|
|
|
|
$firstStep = $formSteps->first();
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->assertEquals($firstStep->getChildren()->First()->RightTitle(), "Right Title");
|
2010-09-08 00:44:43 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// test empty form
|
2017-08-09 01:55:09 +02:00
|
|
|
$emptyForm = $this->objFromFixture(UserDefinedForm::class, 'empty-form');
|
2017-08-11 02:20:12 +02:00
|
|
|
$controller = new UserDefinedFormController($emptyForm);
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->assertFalse($controller->Form()->getFormFields()->exists());
|
|
|
|
}
|
2015-07-24 04:37:48 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
public function testGetFormActions()
|
|
|
|
{
|
|
|
|
// generating the fieldset of actions
|
2017-08-09 01:55:09 +02:00
|
|
|
$form = $this->objFromFixture(UserDefinedForm::class, 'basic-form-page');
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-08-11 02:20:12 +02:00
|
|
|
$controller = new UserDefinedFormController($form);
|
2016-07-21 07:53:59 +02:00
|
|
|
$actions = $controller->Form()->getFormActions();
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// by default will have 1 submit button which links to process
|
|
|
|
$expected = new FieldList(new FormAction('process', 'Submit'));
|
|
|
|
$expected->setForm($controller->Form());
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->assertEquals($actions, $expected);
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// the custom popup should have a reset button and a custom text
|
2017-08-09 01:55:09 +02:00
|
|
|
$custom = $this->objFromFixture(UserDefinedForm::class, 'form-with-reset-and-custom-action');
|
2017-08-11 02:20:12 +02:00
|
|
|
$controller = new UserDefinedFormController($custom);
|
2016-07-21 07:53:59 +02:00
|
|
|
$actions = $controller->Form()->getFormActions();
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$expected = new FieldList(new FormAction('process', 'Custom Button'));
|
2020-10-31 09:15:00 +01:00
|
|
|
$clearAction = new FormAction('clearForm', 'Clear');
|
|
|
|
$expected->push($clearAction->setAttribute('type', 'reset'));
|
2016-07-21 07:53:59 +02:00
|
|
|
$expected->setForm($controller->Form());
|
2010-09-03 07:06:13 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->assertEquals($actions, $expected);
|
|
|
|
}
|
2015-07-24 04:37:48 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
public function testRenderingIntoFormTemplate()
|
|
|
|
{
|
|
|
|
$form = $this->setupFormFrontend();
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-08-13 23:26:53 +02:00
|
|
|
$this->logInWithPermission('ADMIN');
|
2016-07-21 07:53:59 +02:00
|
|
|
$form->Content = 'This is some content without a form nested between it';
|
2017-08-13 23:26:53 +02:00
|
|
|
$form->publishRecursive();
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-08-11 02:20:12 +02:00
|
|
|
$controller = new UserDefinedFormController($form);
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2018-07-05 08:08:19 +02:00
|
|
|
// check to see if $Form is placed in the template
|
2016-07-21 07:53:59 +02:00
|
|
|
$index = new ArrayData($controller->index());
|
2017-08-11 02:20:12 +02:00
|
|
|
$parser = new CSSContentParser($index->renderWith(__CLASS__));
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-04-18 03:11:32 +02:00
|
|
|
$this->checkTemplateIsCorrect($parser, $form);
|
2016-07-21 07:53:59 +02:00
|
|
|
}
|
2010-09-03 07:06:13 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
public function testRenderingIntoTemplateWithSubstringReplacement()
|
|
|
|
{
|
|
|
|
$form = $this->setupFormFrontend();
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-08-11 02:20:12 +02:00
|
|
|
$controller = new UserDefinedFormController($form);
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// check to see if $Form is replaced to inside the content
|
|
|
|
$index = new ArrayData($controller->index());
|
2017-08-11 02:20:12 +02:00
|
|
|
$parser = new CSSContentParser($index->renderWith(__CLASS__));
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-04-18 03:11:32 +02:00
|
|
|
$this->checkTemplateIsCorrect($parser, $form);
|
2016-07-21 07:53:59 +02:00
|
|
|
}
|
2018-07-05 08:08:19 +02:00
|
|
|
|
|
|
|
public function testRenderingIntoTemplateWithDisabledInterpolation()
|
|
|
|
{
|
|
|
|
$form = $this->setupFormFrontend();
|
|
|
|
|
|
|
|
$controller = new UserDefinedFormController($form);
|
2018-07-09 04:32:34 +02:00
|
|
|
$controller->config()->set('disable_form_content_shortcode', true);
|
2018-07-05 08:08:19 +02:00
|
|
|
// check to see if $Form is replaced to inside the content
|
|
|
|
$index = new ArrayData($controller->index());
|
|
|
|
$html = $index->renderWith(__CLASS__);
|
|
|
|
$parser = new CSSContentParser($html);
|
|
|
|
|
2018-07-09 04:32:34 +02:00
|
|
|
// Assert Content has been rendered with the shortcode in place
|
2021-11-01 21:52:58 +01:00
|
|
|
$this->assertStringContainsString('<p>Here is my form</p><p>$UserDefinedForm</p><p>Thank you for filling it out</p>', $html);
|
2018-07-09 04:32:34 +02:00
|
|
|
// And the form in the $From area
|
|
|
|
$this->assertArrayHasKey(0, $parser->getBySelector('form#UserForm_Form_' . $form->ID));
|
2018-07-05 09:01:45 +02:00
|
|
|
// check for the input
|
2018-07-09 04:32:34 +02:00
|
|
|
$this->assertArrayHasKey(0, $parser->getBySelector('input.text'));
|
2018-07-05 08:08:19 +02:00
|
|
|
}
|
2018-07-06 01:28:16 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
/**
|
|
|
|
* Publish a form for use on the frontend
|
|
|
|
*
|
|
|
|
* @param string $fixtureName
|
|
|
|
* @return UserDefinedForm
|
|
|
|
*/
|
|
|
|
protected function setupFormFrontend($fixtureName = 'basic-form-page')
|
|
|
|
{
|
2017-08-09 01:55:09 +02:00
|
|
|
$form = $this->objFromFixture(UserDefinedForm::class, $fixtureName);
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2018-01-25 03:38:54 +01:00
|
|
|
$this->actWithPermission('ADMIN', function () use ($form) {
|
|
|
|
$form->publishRecursive();
|
|
|
|
});
|
2010-09-03 07:06:13 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
return $form;
|
|
|
|
}
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2017-04-18 03:11:32 +02:00
|
|
|
public function checkTemplateIsCorrect($parser, $form)
|
2016-07-21 07:53:59 +02:00
|
|
|
{
|
2017-04-18 03:11:32 +02:00
|
|
|
$this->assertArrayHasKey(0, $parser->getBySelector('form#UserForm_Form_' . $form->ID));
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// check for the input
|
|
|
|
$this->assertArrayHasKey(0, $parser->getBySelector('input.text'));
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// check for the label and the text
|
|
|
|
$label = $parser->getBySelector('label.left');
|
|
|
|
$this->assertArrayHasKey(0, $label);
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->assertEquals((string) $label[0][0], "Basic Text Field", "Label contains correct field name");
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
// check for the action
|
|
|
|
$action = $parser->getBySelector('input.action');
|
|
|
|
$this->assertArrayHasKey(0, $action);
|
2015-09-11 00:20:06 +02:00
|
|
|
|
2016-07-21 07:53:59 +02:00
|
|
|
$this->assertEquals((string) $action[0]['value'], "Submit", "Submit button has default text");
|
|
|
|
}
|
2019-01-28 05:28:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
public function testRecipientSubjectMergeFields()
|
|
|
|
{
|
|
|
|
$form = $this->setupFormFrontend();
|
|
|
|
|
|
|
|
$recipient = $this->objFromFixture(EmailRecipient::class, 'recipient-1');
|
|
|
|
$recipient->EmailSubject = 'Email Subject: $basic_text_name';
|
|
|
|
$recipient->write();
|
|
|
|
|
|
|
|
$this->autoFollowRedirection = false;
|
|
|
|
$this->clearEmails();
|
|
|
|
|
|
|
|
// load the form
|
|
|
|
$this->get($form->URLSegment);
|
|
|
|
|
|
|
|
$field = $this->objFromFixture(EditableTextField::class, 'basic-text');
|
|
|
|
|
|
|
|
$response = $this->submitForm('UserForm_Form_' . $form->ID, null, [$field->Name => 'Basic Value']);
|
|
|
|
|
|
|
|
// should have a submitted form field now
|
|
|
|
$submitted = DataObject::get(SubmittedFormField::class, "\"Name\" = 'basic_text_name'");
|
|
|
|
$this->assertListAllMatch(
|
|
|
|
[
|
|
|
|
'Name' => 'basic_text_name',
|
|
|
|
'Value' => 'Basic Value',
|
|
|
|
'Title' => 'Basic Text Field'
|
|
|
|
],
|
|
|
|
$submitted
|
|
|
|
);
|
|
|
|
|
|
|
|
// check emails
|
|
|
|
$this->assertEmailSent('test@example.com', 'no-reply@example.com', 'Email Subject: Basic Value');
|
|
|
|
}
|
2020-05-27 02:26:14 +02:00
|
|
|
|
|
|
|
public function testImageThumbnailCreated()
|
|
|
|
{
|
|
|
|
Config::modify()->set(Upload_Validator::class, 'use_is_uploaded_file', false);
|
|
|
|
|
|
|
|
$userForm = $this->setupFormFrontend('upload-form');
|
2020-10-31 09:15:00 +01:00
|
|
|
$controller = new UserDefinedFormController($userForm);
|
2020-05-27 02:26:14 +02:00
|
|
|
$field = $this->objFromFixture(EditableFileField::class, 'file-field-1');
|
|
|
|
|
|
|
|
$path = realpath(__DIR__ . '/fixtures/testfile.jpg');
|
|
|
|
$data = [
|
|
|
|
$field->Name => [
|
|
|
|
'name' => 'testfile.jpg',
|
|
|
|
'type' => 'image/jpeg',
|
|
|
|
'tmp_name' => $path,
|
|
|
|
'error' => 0,
|
2022-04-13 03:52:56 +02:00
|
|
|
'size' => filesize($path ?? ''),
|
2020-05-27 02:26:14 +02:00
|
|
|
]
|
|
|
|
];
|
|
|
|
$_FILES[$field->Name] = $data[$field->Name];
|
|
|
|
|
|
|
|
$controller->getRequest()->setSession(new Session([]));
|
|
|
|
$controller->process($data, $controller->Form());
|
|
|
|
|
|
|
|
/** @var File $image */
|
|
|
|
// Getting File instead of Image so that we still delete the physical file in case it was
|
|
|
|
// created with the wrong ClassName
|
|
|
|
// Using StartsWith in-case of existing file so was created as testfile-v2.jpg
|
|
|
|
$image = File::get()->filter(['Name:StartsWith' => 'testfile'])->last();
|
|
|
|
$this->assertNotNull($image);
|
|
|
|
|
|
|
|
// Assert thumbnail variant created
|
|
|
|
/** @var AssetStore $store */
|
|
|
|
$store = Injector::inst()->get(AssetStore::class);
|
|
|
|
$this->assertTrue($store->exists($image->getFilename(), $image->getHash(), 'FitMaxWzM1MiwyNjRd'));
|
|
|
|
}
|
2021-04-06 15:46:37 +02:00
|
|
|
|
|
|
|
public function testRecipientAttachment()
|
|
|
|
{
|
|
|
|
Config::modify()->set(Upload_Validator::class, 'use_is_uploaded_file', false);
|
|
|
|
|
|
|
|
$userForm = $this->setupFormFrontend('upload-form');
|
2020-10-31 09:15:00 +01:00
|
|
|
$controller = new UserDefinedFormController($userForm);
|
2021-04-06 15:46:37 +02:00
|
|
|
$field = $this->objFromFixture(EditableFileField::class, 'file-field-1');
|
|
|
|
|
|
|
|
$path = realpath(__DIR__ . '/fixtures/testfile.jpg');
|
|
|
|
$data = [
|
|
|
|
$field->Name => [
|
|
|
|
'name' => 'testfile.jpg',
|
|
|
|
'type' => 'image/jpeg',
|
|
|
|
'tmp_name' => $path,
|
|
|
|
'error' => 0,
|
2022-04-13 03:52:56 +02:00
|
|
|
'size' => filesize($path ?? ''),
|
2021-04-06 15:46:37 +02:00
|
|
|
]
|
|
|
|
];
|
|
|
|
$_FILES[$field->Name] = $data[$field->Name];
|
|
|
|
|
|
|
|
$controller->getRequest()->setSession(new Session([]));
|
|
|
|
$controller->process($data, $controller->Form());
|
|
|
|
|
|
|
|
// check emails
|
|
|
|
$this->assertEmailSent('test@example.com', 'no-reply@example.com', 'Email Subject');
|
|
|
|
$email = $this->findEmail('test@example.com', 'no-reply@example.com', 'Email Subject');
|
|
|
|
$this->assertNotEmpty($email['AttachedFiles'], 'Recipients receive attachment by default');
|
|
|
|
|
|
|
|
// no data
|
|
|
|
$this->assertEmailSent('nodata@example.com', 'no-reply@example.com', 'Email Subject');
|
|
|
|
$nodata = $this->findEmail('nodata@example.com', 'no-reply@example.com', 'Email Subject');
|
|
|
|
$this->assertEmpty($nodata['AttachedFiles'], 'Recipients with HideFormData do not receive attachment');
|
|
|
|
}
|
2022-05-13 06:25:51 +02:00
|
|
|
|
|
|
|
public function testMissingFolderCreated()
|
|
|
|
{
|
|
|
|
Config::modify()->set(Upload_Validator::class, 'use_is_uploaded_file', false);
|
|
|
|
$userForm = $this->setupFormFrontend('upload-form-without-folder');
|
|
|
|
$controller = UserDefinedFormController::create($userForm);
|
|
|
|
$field = $this->objFromFixture(EditableFileField::class, 'file-field-3');
|
|
|
|
|
|
|
|
$path = realpath(__DIR__ . '/fixtures/testfile.jpg');
|
|
|
|
$data = [
|
|
|
|
$field->Name => [
|
|
|
|
'name' => 'testfile.jpg',
|
|
|
|
'type' => 'image/jpeg',
|
|
|
|
'tmp_name' => $path,
|
|
|
|
'error' => 0,
|
|
|
|
'size' => filesize($path ?? ''),
|
|
|
|
]
|
|
|
|
];
|
|
|
|
$_FILES[$field->Name] = $data[$field->Name];
|
|
|
|
|
|
|
|
$controller->getRequest()->setSession(new Session([]));
|
|
|
|
|
|
|
|
$folderExistBefore = $field->getFolderExists();
|
|
|
|
$stageBefore = Versioned::get_stage();
|
|
|
|
|
|
|
|
$controller->process($data, $controller->Form());
|
|
|
|
|
|
|
|
$field = EditableFileField::get_by_id($field->ID);
|
|
|
|
$filter = [
|
|
|
|
'ParentID' => $field->Folder()->ID,
|
|
|
|
'Name' => 'testfile.jpg',
|
|
|
|
];
|
|
|
|
$fileDraftCount = Versioned::get_by_stage(File::class, Versioned::DRAFT)->filter($filter)->count();
|
|
|
|
$fileLiveCount = Versioned::get_by_stage(File::class, Versioned::LIVE)->filter($filter)->count();
|
|
|
|
|
|
|
|
$folderExistAfter = $field->getFolderExists();
|
|
|
|
|
|
|
|
$this->assertFalse($folderExistBefore);
|
|
|
|
$this->assertTrue($folderExistAfter);
|
|
|
|
$this->assertEquals($stageBefore, Versioned::get_stage());
|
|
|
|
$this->assertEquals(1, $fileDraftCount);
|
|
|
|
$this->assertEquals(0, $fileLiveCount);
|
|
|
|
}
|
2020-10-31 09:15:00 +01:00
|
|
|
|
|
|
|
public function testEmailAttachmentMaximumSizeCanBeConfigured()
|
|
|
|
{
|
|
|
|
$udfController = new UserDefinedFormController();
|
|
|
|
$config = Config::modify();
|
|
|
|
$config->set(UserDefinedFormController::class, 'maximum_email_attachment_size', '1M');
|
|
|
|
$this->assertSame(1 * 1024 * 1024, $udfController->getMaximumAllowedEmailAttachmentSize());
|
|
|
|
$config->set(UserDefinedFormController::class, 'maximum_email_attachment_size', '5M');
|
|
|
|
$this->assertSame(5 * 1024 * 1024, $udfController->getMaximumAllowedEmailAttachmentSize());
|
|
|
|
}
|
|
|
|
|
2024-09-10 01:28:45 +02:00
|
|
|
public static function getParseByteSizeStringTestValues()
|
2020-10-31 09:15:00 +01:00
|
|
|
{
|
|
|
|
return [
|
|
|
|
['9846', 9846],
|
|
|
|
['1048576', 1048576],
|
|
|
|
['1k', 1024],
|
|
|
|
['1K', 1024],
|
|
|
|
['4k', 4096],
|
|
|
|
['4K', 4096],
|
|
|
|
['1kb', 1024],
|
|
|
|
['1KB', 1024],
|
|
|
|
['4kB', 4096],
|
|
|
|
['4Kb', 4096],
|
|
|
|
['1m', 1048576],
|
|
|
|
['1M', 1048576],
|
|
|
|
['4mb', 4194304],
|
|
|
|
['4MB', 4194304],
|
|
|
|
['25mB', 26214400],
|
|
|
|
['25Mb', 26214400],
|
|
|
|
['1g', 1073741824],
|
|
|
|
['2GB', 2147483648],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2024-09-10 01:28:45 +02:00
|
|
|
#[DataProvider('getParseByteSizeStringTestValues')]
|
2020-10-31 09:15:00 +01:00
|
|
|
public function testParseByteSizeString($input, $expectedOutput)
|
|
|
|
{
|
|
|
|
$controller = new SizeStringTestableController(); // extends UserDefinedFormController
|
|
|
|
$this->assertSame($expectedOutput, $controller->convertSizeStringToBytes($input));
|
|
|
|
}
|
|
|
|
|
2024-09-10 01:28:45 +02:00
|
|
|
public static function getParseByteSizeStringTestBadValues()
|
2020-10-31 09:15:00 +01:00
|
|
|
{
|
|
|
|
return [
|
|
|
|
['1234b'],
|
|
|
|
['9846B'],
|
|
|
|
['1kilobyte'],
|
|
|
|
['1 K'],
|
|
|
|
['Four kilobytes'],
|
|
|
|
['4Mbs'],
|
|
|
|
['12Gigs'],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @expectedException \InvalidArgumentException
|
|
|
|
*/
|
2024-09-10 01:28:45 +02:00
|
|
|
#[DataProvider('getParseByteSizeStringTestBadValues')]
|
2020-10-31 09:15:00 +01:00
|
|
|
public function testParseByteSizeStringBadValuesThrowException($input)
|
|
|
|
{
|
|
|
|
$this->expectException('\InvalidArgumentException');
|
|
|
|
$controller = new SizeStringTestableController(); // extends UserDefinedFormController
|
|
|
|
$controller->convertSizeStringToBytes($input);
|
|
|
|
}
|
2023-05-17 05:54:29 +02:00
|
|
|
|
2024-09-10 01:28:45 +02:00
|
|
|
public static function provideValidEmailsToArray()
|
2023-05-17 05:54:29 +02:00
|
|
|
{
|
|
|
|
return [
|
|
|
|
[[], [null]],
|
|
|
|
[[], [' , , ']],
|
|
|
|
[[], ['broken.email, broken@.email, broken2.@email']],
|
|
|
|
[
|
|
|
|
['broken@email', 'correctemail@email.com'],
|
|
|
|
[', broken@email, email@-email.com,correctemail@email.com,']
|
|
|
|
],
|
|
|
|
[
|
|
|
|
['correctemail1@email.com', 'correctemail2@email.com', 'correctemail3@email.com'],
|
|
|
|
['correctemail1@email.com, correctemail2@email.com, correctemail3@email.com']
|
|
|
|
]
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test that provided email is valid
|
|
|
|
*/
|
2024-09-10 01:28:45 +02:00
|
|
|
#[DataProvider('provideValidEmailsToArray')]
|
2023-05-17 05:54:29 +02:00
|
|
|
public function testValidEmailsToArray(array $expectedOutput, array $input)
|
|
|
|
{
|
|
|
|
$class = new ReflectionClass(UserDefinedFormController::class);
|
|
|
|
$method = $class->getMethod('validEmailsToArray');
|
|
|
|
$method->setAccessible(true);
|
|
|
|
|
|
|
|
$controller = new UserDefinedFormController();
|
|
|
|
|
|
|
|
$this->assertEquals($expectedOutput, $method->invokeArgs($controller, $input));
|
|
|
|
}
|
2010-11-01 03:22:29 +01:00
|
|
|
}
|