Commit 08bccaa5 authored by Tino Goratsch's avatar Tino Goratsch

fixed the newsletter subscription and covered it with unit tests

parent 04b5d4d4
......@@ -72,6 +72,7 @@ class Index extends Core\Controller\AbstractFrontendAction
];
$salutations = [
0 => $this->translator->t('newsletter', 'salutation_unspecified'),
1 => $this->translator->t('newsletter', 'salutation_female'),
2 => $this->translator->t('newsletter', 'salutation_male')
];
......
......@@ -104,13 +104,9 @@ class Subscribe
{
$hash = $this->secureHelper->generateSaltedPassword('', mt_rand(0, microtime(true)), 'sha512');
$mailSent = $this->sendDoubleOptInEmail($emailAddress, $hash);
$bool = false;
$result = $this->addNewsletterAccount($emailAddress, $salutation, $firstName, $lastName, $hash);
if ($mailSent === true) {
$bool = $this->addNewsletterAccount($emailAddress, $salutation, $firstName, $lastName, $hash);
}
return $mailSent === true && $bool !== false;
return $mailSent === true && $result !== false;
}
/**
......
......@@ -2,7 +2,7 @@
{block CONTENT_AJAX_FORM}
{include file="asset:System/Partials/form_group.input_email.tpl" name="mail" value=$form.mail required=true maxlength=120 label={lang t="system|email_address"}}
{include file="asset:System/Partials/form_group.select.tpl" options=$salutation columnSelector="col-sm-3" emptyOptionLabel={lang t="newsletter|salutation_unspecified"} label={lang t="newsletter|salutation"}}
{include file="asset:System/Partials/form_group.select.tpl" options=$salutation columnSelector="col-sm-3" label={lang t="newsletter|salutation"}}
{include file="asset:System/Partials/form_group.input_text.tpl" name="first_name" value=$form.first_name maxlength=120 label={lang t="newsletter|first_name"}}
{include file="asset:System/Partials/form_group.input_text.tpl" name="last_name" value=$form.last_name maxlength=120 label={lang t="newsletter|last_name"}}
{event name="captcha.event.display_captcha"}
......
......@@ -32,3 +32,10 @@ services:
- '@newsletter.model.accountrepository'
tags:
- { name: core.validation.validation_rule }
newsletter.validation.validation_rules.account_not_exists_validation_rule:
class: ACP3\Modules\ACP3\Newsletter\Validation\ValidationRules\AccountNotExistsValidationRule
arguments:
- '@newsletter.model.accountrepository'
tags:
- { name: core.validation.validation_rule }
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Newsletter\Test\Validation;
use ACP3\Core\ACL;
use ACP3\Core\Http\Request;
use ACP3\Core\Router\Router;
use ACP3\Core\Session\SessionHandler;
use ACP3\Core\Test\Validation\AbstractFormValidationTest;
use ACP3\Core\Validation\ValidationRules\EmailValidationRule;
use ACP3\Core\Validation\ValidationRules\InArrayValidationRule;
use ACP3\Modules\ACP3\Captcha\Validation\ValidationRules\CaptchaValidationRule;
use ACP3\Modules\ACP3\Newsletter\Model\Repository\AccountRepository;
use ACP3\Modules\ACP3\Newsletter\Validation\SubscribeFormValidation;
use ACP3\Modules\ACP3\Newsletter\Validation\ValidationRules\AccountNotExistsValidationRule;
use ACP3\Modules\ACP3\Users\Model\UserModel;
class SubscribeFormValidationTest extends AbstractFormValidationTest
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $aclMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $accountRepositoryMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $requestMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $routerMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $sessionHandlerMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $userModelMock;
/**
* @return void
*/
protected function initializeFormValidation()
{
$this->formValidation = new SubscribeFormValidation(
$this->translatorMock,
$this->validator
);
}
/**
* @return void
*/
protected function registerValidationRules()
{
$this->validator->registerValidationRule($this->setUpFormTokenRule());
$inArrayRule = new InArrayValidationRule();
$this->validator->registerValidationRule($inArrayRule);
$emailRule = new EmailValidationRule();
$this->validator->registerValidationRule($emailRule);
$this->accountRepositoryMock = $this->getMockBuilder(AccountRepository::class)
->disableOriginalConstructor()
->getMock();
$accountNotExistsRule = new AccountNotExistsValidationRule($this->accountRepositoryMock);
$this->validator->registerValidationRule($accountNotExistsRule);
$this->aclMock = $this->getMockBuilder(ACL::class)
->disableOriginalConstructor()
->getMock();
$this->requestMock = $this->getMockBuilder(Request::class)
->disableOriginalConstructor()
->getMock();
$this->routerMock = $this->getMockBuilder(Router::class)
->disableOriginalConstructor()
->getMock();
$this->sessionHandlerMock = $this->getMockBuilder(SessionHandler::class)
->disableOriginalConstructor()
->getMock();
$this->userModelMock = $this->getMockBuilder(UserModel::class)
->disableOriginalConstructor()
->getMock();
$captchaRule = new CaptchaValidationRule(
$this->aclMock,
$this->requestMock,
$this->routerMock,
$this->sessionHandlerMock,
$this->userModelMock
);
$this->validator->registerValidationRule($captchaRule);
}
/**
* @return array
*/
public function validFormDataProvider()
{
return [
[
\ACP3\Core\Session\SessionHandlerInterface::XSRF_TOKEN_NAME => self::XSRF_FORM_TOKEN,
'mail' => 'test@example.com',
'salutation' => '',
'first_name' => 'Foo',
'last_name' => 'bar'
],
[
\ACP3\Core\Session\SessionHandlerInterface::XSRF_TOKEN_NAME => self::XSRF_FORM_TOKEN,
'mail' => 'test@example.com',
'salutation' => '',
'first_name' => '',
'last_name' => ''
],
[
\ACP3\Core\Session\SessionHandlerInterface::XSRF_TOKEN_NAME => self::XSRF_FORM_TOKEN,
'mail' => 'test@example.com',
'salutation' => '',
'first_name' => '',
'last_name' => '',
'captcha' => '123456'
]
];
}
/**
* @return array
*/
public function invalidFormDataProvider()
{
return [
[
\ACP3\Core\Session\SessionHandlerInterface::XSRF_TOKEN_NAME => self::XSRF_FORM_TOKEN,
'mail' => 'testexample.com',
'salutation' => '',
'first_name' => 'Foo',
'last_name' => 'bar'
],
[
\ACP3\Core\Session\SessionHandlerInterface::XSRF_TOKEN_NAME => self::XSRF_FORM_TOKEN,
'mail' => 'test@example.com',
'salutation' => 3,
'first_name' => '',
'last_name' => ''
]
];
}
}
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Newsletter\Test\Validation\ValidationRules;
use ACP3\Core\Test\Validation\ValidationRules\AbstractValidationRuleTest;
use ACP3\Modules\ACP3\Newsletter\Model\Repository\AccountRepository;
use ACP3\Modules\ACP3\Newsletter\Validation\ValidationRules\AccountExistsValidationRule;
class AccountExistsValidationRuleTest extends AbstractValidationRuleTest
{
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
private $accountRepositoryMock;
protected function setUp()
{
$this->accountRepositoryMock = $this->getMockBuilder(AccountRepository::class)
->disableOriginalConstructor()
->getMock();
$this->validationRule = new AccountExistsValidationRule($this->accountRepositoryMock);
parent::setUp();
}
/**
* @return array
*/
public function validationRuleProvider()
{
return [
'valid-data-simple' => ['info@example.com', '', [], true],
'valid-data-complex' => [['mail' => 'info@example.com'], 'mail', [], true],
'invalid-data-simple' => ['info@example.de', '', [], false],
'invalid-data-complex' => [['mail' => 'info@example.de'], 'mail', [], false],
];
}
/**
* @dataProvider validationRuleProvider
*
* @param mixed $data
* @param array|string $field
* @param array $extra
* @param bool $expected
*/
public function testValidationRule($data, $field, $extra, $expected)
{
$this->setExpectations($expected);
parent::testValidationRule($data, $field, $extra, $expected);
}
/**
* @param bool $expected
*/
private function setExpectations($expected)
{
$this->accountRepositoryMock
->expects($this->once())
->method('accountExists')
->willReturn($expected);
}
/**
* @dataProvider validationRuleProvider
*
* @param mixed $data
* @param array|string $field
* @param array $extra
* @param bool $expected
*/
public function testValidate($data, $field, $extra, $expected)
{
$this->setExpectations($expected);
parent::testValidate($data, $field, $extra, $expected);
}
}
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Newsletter\Test\Validation\ValidationRules;
class AccountNotExistsValidationRuleTest extends AccountExistsValidationRuleTest
{
/**
* @return array
*/
public function validationRuleProvider()
{
return [
'valid-data-simple' => ['info@example.com', '', [], false],
'valid-data-complex' => [['mail' => 'info@example.com'], 'mail', [], false],
'invalid-data-simple' => ['info@example.de', '', [], true],
'invalid-data-complex' => [['mail' => 'info@example.de'], 'mail', [], true],
];
}
}
......@@ -4,7 +4,7 @@ namespace ACP3\Modules\ACP3\Newsletter\Validation;
use ACP3\Core;
use ACP3\Core\Validation\AbstractFormValidation;
use ACP3\Modules\ACP3\Captcha\Validation\ValidationRules\CaptchaValidationRule;
use ACP3\Modules\ACP3\Newsletter\Validation\ValidationRules\AccountExistsValidationRule;
use ACP3\Modules\ACP3\Newsletter\Validation\ValidationRules\AccountNotExistsValidationRule;
/**
* Class SubscribeFormValidation
......@@ -12,7 +12,6 @@ use ACP3\Modules\ACP3\Newsletter\Validation\ValidationRules\AccountExistsValidat
*/
class SubscribeFormValidation extends AbstractFormValidation
{
/**
* @inheritdoc
*/
......@@ -27,7 +26,7 @@ class SubscribeFormValidation extends AbstractFormValidation
'field' => 'salutation',
'message' => $this->translator->t('newsletter', 'select_salutation'),
'extra' => [
'haystack' => [1, 2]
'haystack' => [0, 1, 2]
]
])
->addConstraint(
......@@ -38,11 +37,11 @@ class SubscribeFormValidation extends AbstractFormValidation
'message' => $this->translator->t('system', 'wrong_email_format')
])
->addConstraint(
AccountExistsValidationRule::class,
AccountNotExistsValidationRule::class,
[
'data' => $formData,
'field' => 'mail',
'message' => $this->translator->t('newsletter', 'account_not_exists')
'message' => $this->translator->t('newsletter', 'account_exists')
])
->addConstraint(
CaptchaValidationRule::class,
......
......@@ -34,6 +34,15 @@ class AccountExistsValidationRule extends AbstractValidationRule
return $this->isValid($data[$field], $field, $extra);
}
return $this->checkAccountExists($data);
}
/**
* @param string $data
* @return bool
*/
protected function checkAccountExists($data)
{
return $this->accountRepository->accountExists($data);
}
}
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Newsletter\Validation\ValidationRules;
class AccountNotExistsValidationRule extends AccountExistsValidationRule
{
/**
* @inheritdoc
*/
protected function checkAccountExists($data)
{
return !parent::checkAccountExists($data);
}
}
......@@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- fixed the redirect url when posting a comment
- fixed the URL of delete controller action when performing a mass removal of comments
- fixed the language switcher drop down of the installer
- fixed the newsletter subscription
## [4.1.28] - 2016-10-05
### Fixed
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment