Skip to content

Instantly share code, notes, and snippets.

@AnatoliyLitinskiy
Created September 20, 2018 12:51
Show Gist options
  • Save AnatoliyLitinskiy/68f32655086ef5ef31c41f7ed92f60b0 to your computer and use it in GitHub Desktop.
Save AnatoliyLitinskiy/68f32655086ef5ef31c41f7ed92f60b0 to your computer and use it in GitHub Desktop.
symfony 2.4 test controllers
<?php
namespace Evolutionnutrition\ApiBundle\Tests\Base;
use Evolutionnutrition\ApiBundle\Tests\Base\BaseUnitTests;
abstract class BaseControllerTests extends BaseUnitTests
{
protected $controllerMethodsList = [
'parseControls',
'getParsedEntityClass',
'getParsedFormClass',
'beginTransaction',
'getUser',
'isAnonym',
'getEM',
'dispatchBeforeCreateEvent',
'dispatchAfterCreateEvent',
'checkDates',
'getFormBuilder',
'secureSearchById',
'getEntityShortName',
'dispatchBeforeUpdateEvent',
'dispatchAfterUpdateEvent',
];
protected function getControllerMock (MockDataMapper $controllerDM, $params)
{
$inParams = $params['in'];
$data = $params['in']['data'];
$isAnonym = $inParams['currentUser'] ? false : true;
$entityName = $controllerDM->getEntityName();
$entityClassFullName = "Evolutionnutrition\\ApiBundle\\Entity\\{$entityName}";
$entityObj = null;
if ('create' === $controllerDM->getAction()) {
$entityObj = new $entityClassFullName;
$controllerDM->setEntity($entityObj);
} elseif ('update' === $controllerDM->getAction()) {
$entityObj = $controllerDM->getEntity();
}
$className = "Evolutionnutrition\\ApiBundle\\Controller\\{$entityName}Controller";
$mockBuilder = $this->getMockBuilder($className);
$controllerDM->addMethods($this->controllerMethodsList);
$methodsList = $controllerDM->getMethods();
$controller = $mockBuilder
->setMethods($methodsList)
->getMock();
$controller->setContainer(static::$container);
$controller
->expects($this->any())
->method('getParsedEntityClass')
->will($this->returnValue($entityClassFullName));
$controller
->expects($this->any())
->method('getEntityShortName')
->will($this->returnValue($entityName));
$controller
->expects($this->any())
->method('getParsedFormClass')
->will($this->returnValue("Evolutionnutrition\\ApiBundle\\Form\\{$entityName}Type"));
$controller
->expects($this->any())
->method('getUser')
->will($this->returnValue($inParams['currentUser']));
$controller
->expects($this->any())
->method('secureSearchById')
->will($this->returnValue($controllerDM->hasKey('dbFoundEntity') ? $controllerDM->getDbFoundEntity() : $entityObj));
$controller
->expects($this->any())
->method('isAnonym')
->will($this->returnValue($isAnonym));
$em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
->setMethods(['persist', 'flush', 'detach', 'getConnection'])
->disableOriginalConstructor()
->getMock();
$connection = $this->getMockBuilder('\Doctrine\DBAL\Connection')
->disableOriginalConstructor()
->getMock();
$em->expects($this->any())
->method('getConnection')
->will($this->returnValue($connection));
$controller
->expects($this->any())
->method('getEM')
->will($this->returnValue($em));
$controllerDM->setEM($em);
$formBuilder = $this->getMockBuilder("Evolutionnutrition\\ApiBundle\\Form\\{$entityName}Type")
// ->setConstructorArgs([static::$container])
// ->disableOriginalConstructor()
->setMethods(['buildForm'])
->getMock();
$controllerDM->setFormBuilder($formBuilder);
$formBuilder
->expects($this->any())
->method('buildForm')
->will($this->returnCallback(function ($builder, $options) use ($formBuilder) {
$formBuilder->afterBuildForm($builder, $options);
}));
$controller
->expects($this->any())
->method('getFormBuilder')
->will($this->returnValue($formBuilder));
$outParams = $params['out'];
if (!empty($outParams['exception'])) {
$this->setExpectedException('\Exception');
}
if (!empty($outParams['expectations'])) {
$outParams['expectations']($entityObj, $controllerDM, $params);
}
$controllerDM->setRunTest(function () use ($controller, $data, $entityObj, $outParams, $controllerDM, $params) {
$action = $controllerDM->getAction();
switch ($action) {
case 'create':
$ret = $controller->$action($data, $entityObj);
break;
case 'update':
$id = $controllerDM->hasKey('id') ? $controllerDM->getId('id') : 'some id';
$ret = $controller->$action($data, $id, $entityObj);
break;
default:
throw new \Exception("Unknown action {$action}", 1);
break;
}
if (!empty($outParams['onFinishChecker'])) {
$outParams['onFinishChecker']($entityObj, $controllerDM, $params);
}
if (!empty($outParams['errorMessage'])) {
$messagesArr = $controller->getErrorMessages();
if ($outParams['errorMessage'] === 'print') {
print_r([
'errors' => $messagesArr,
'ret' => is_object($ret) ? '[object] ' . get_class($ret) : $ret,
]);
} elseif ($outParams['errorMessage'] === -1) {
$this->assertCount(0, $messagesArr, 'Unexpected error message.');
} elseif (is_array($outParams['errorMessage'])) {
foreach ($outParams['errorMessage'] as $message) {
$this->assertContains($message, $messagesArr, 'Wrong error message.');
}
} else {
$this->assertContains($outParams['errorMessage'], $messagesArr, 'Wrong error message.');
}
};
});
return $controller;
}
protected function generateContainerMock ($currentUser)
{
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
$container
->expects($this->any())
->method('get')
->with('security.context')
->will($this->returnValue($this->getSecurityContext($currentUser)));
return $container;
}
private function getSecurityContext ($user)
{
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
$token->expects($this->any())
->method('getUser')
->will($this->returnValue($user));
$securityContext = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface', ['getToken', 'setToken', 'isGranted']);
$securityContext->expects($this->any())
->method('getToken')
->will($this->returnValue($token));
$securityContext->expects($this->any())
->method('setToken')
->will($this->returnValue($token));
return $securityContext;
}
}
<?php
namespace Evolutionnutrition\ApiBundle\Tests\Base;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Evolutionnutrition\ApiBundle\Tests\Base\MockDataMapper;
abstract class BaseUnitTests extends WebTestCase
{
protected static $container;
public function setUp ()
{
// static::$kernel = static::createKernel();
// static::$kernel->boot();
static::bootKernel();
static::$container = static::$kernel->getContainer();
}
protected function generateParams ($successData, $testData)
{
$ret = [];
foreach ($testData as $name => $data) {
if (is_callable($data)) {
$moreData = $data();
foreach ($moreData as $moreDataKey => $moreDataVal) {
if (!empty($moreDataVal['multiply'])) {
$multiplied = $this->multiply($moreDataVal['multiply'], $moreDataVal, $name);
foreach($multiplied as $multipliedKey => $multipliedVal) {
$retVal = $this->arrayMergeRecursive($successData, $multipliedVal);
$retVal = $this->applyDuplicates($retVal);
$ret[$multipliedKey] = $retVal;
}
} else {
$retVal = $this->arrayMergeRecursive($successData, $moreDataVal);
$retVal = $this->applyDuplicates($retVal);
$ret[$moreDataKey] = $retVal;
}
}
} else {
if (!empty($data['multiply'])) {
$moreData = $this->multiply($data['multiply'], $data, $name);
foreach($moreData as $moreDataKey => $moreDataVal) {
$retVal = $this->arrayMergeRecursive($successData, $moreDataVal);
$retVal = $this->applyDuplicates($retVal);
$ret[$moreDataKey] = $retVal;
}
} else {
$retVal = $this->arrayMergeRecursive($successData, $data);
$retVal = $this->applyDuplicates($retVal);
$ret[$name] = $retVal;
}
}
}
return $ret;
}
private function applyDuplicates ($arr) {
if (!empty($arr['duplicate'])) {
$duplicates = $arr['duplicate'];
foreach ($duplicates as $pathFrom => $pathTo) {
$arr = $this->duplicateItem($pathFrom, $pathTo, $arr);
}
}
return $arr;
}
/**
*
* 'duplicate' => [
* 'params.in.currentUser' => 'params.in.updatedUser',
* ]
**/
private function duplicateItem ($pathFrom, $pathTo, $arr)
{
$val = $this->getByPath($pathFrom, $arr);
$arr = $this->setByPath($pathTo, $val, $arr);
return $arr;
}
/**
* f.e. params:
* [
* 'a.b.c' => [1,2,3,4,5],
* 'a.b.x' => [7,8,9,10,11],
* ],
* ['a' => ['b' => []]],
* '%s str %s'
* @return array
* [
* '1 str 7' => ['a' => ['b' => ['c' => 1, 'x' => 7]]],
* '2 str 8' => ['a' => ['b' => ['c' => 2, 'x' => 8]]],
* '3 str 9' => ['a' => ['b' => ['c' => 3, 'x' => 9]]],
* '4 str 10' => ['a' => ['b' => ['c' => 4, 'x' => 10]]],
* '5 str 11' => ['a' => ['b' => ['c' => 5, 'x' => 11]]],
* ]
**/
private function multiply ($parallels, $data, $keyPrefix = '')
{
/**
* ['a.b.c', 'a.b.x']
**/
$pathes = array_keys($parallels);
/**
* [0,1,2,3,4,5]
**/
$valKeys = array_keys(reset($parallels));
$ret = [];
foreach ($valKeys as $valKey) {
$variant = $data;
$nameParts = [$keyPrefix];
foreach ($pathes as $path) {
$val = $parallels[$path][$valKey];
$variant = $this->setByPath($path, $val, $variant);
if (is_object($val)) {
$nameParts[] = $valKey;
} else {
$nameParts[] = $val;
}
}
$name = $valKey;
if (!empty($keyPrefix)) {
$name = call_user_func_array('sprintf', $nameParts);
}
$ret[$name] = $variant;
}
return $ret;
}
private function setByPath ($path, $val, $arr)
{
if (!is_array($arr)) {
$arr = array();
}
$path = $this->pathToArr($path);
if (count($path) === 0) {
return $val;
}
$key = array_shift($path);
$tail = array();
if (array_key_exists($key, $arr)) {
$tail = $arr[$key];
}
$arr[$key] = $this->setByPath($path, $val, $tail);
return $arr;
}
private function getByPath ($path, $arr)
{
$path = $this->pathToArr($path);
$key = array_shift($path);
if (count($path) === 0) {
return $arr[$key];
} else {
return $this->getByPath($path, $arr[$key]);
}
}
private function pathToArr ($path) {
if (!is_array($path)) {
$path = preg_split('/\./', $path);
if (count($path) < 1) {
throw new \Exception("Path has no items", 1);
return null;
}
}
return $path;
}
private function arrayMergeRecursive ($arrExample, $arrData)
{
$ret = array();
foreach ($arrExample as $k => $val) {
if (!array_key_exists($k, $arrData)) {
$ret[$k] = $val;
} elseif (is_array($val)) {
$ret[$k] = $this->arrayMergeRecursive($val, $arrData[$k]);
} else {
$ret[$k] = $arrData[$k];
}
}
/**
* get items from $arrData that not exist in $arrExample
**/
$moreData = array_diff_key($arrData, $arrExample);
foreach ($moreData as $key => $val) {
$ret[$key] = $val;
}
return $ret;
}
}
<?php
namespace Evolutionnutrition\ApiBundle\Tests\Base;
class MockDataMapper implements MockDataMapperInterface
{
private $methods = [];
private $entityName = '';
private $__callData = [];
public function __call ($method, $value)
{
$dataName = $this->getDataName($method);
if (substr($method, 0, 3) === 'set') {
$this->__callData[$dataName] = $value[0];
return $this;
} elseif (substr($method, 0, 3) === 'get') {
if (array_key_exists($dataName, $this->__callData)) {
return $this->__callData[$dataName];
} else {
throw new \Exception("Data '{$dataName}' was not set", 1);
}
} else {
throw new \Exception("No such method '{$method}'", 1);
}
}
public function hasKey ($key)
{
return array_key_exists($key, $this->__callData);
}
private function getDataName ($method)
{
if (in_array(substr($method, 0, 3), ['get', 'set'])) {
return lcfirst(substr($method, 3));
}
return $method;
}
public function setMethods ($methods)
{
$this->methods = $methods;
return $this;
}
public function addMethods (array $methods)
{
foreach ($methods as $m) {
if (!in_array($m, $this->methods)) {
$this->methods[] = $m;
}
}
return $this;
}
public function addMethod ($method)
{
$this->methods[] = $method;
return $this;
}
public function getMethods ()
{
return $this->methods;
}
}
<?php
namespace Evolutionnutrition\ApiBundle\Tests\Base;
interface MockDataMapperInterface
{
}
<?php
namespace Evolutionnutrition\ApiBundle\Tests\Controller;
use Evolutionnutrition\ApiBundle\Tests\Base\BaseControllerTests;
use Evolutionnutrition\ApiBundle\Entity\User;
use Evolutionnutrition\ApiBundle\Entity\InviteToken;
use Evolutionnutrition\ApiBundle\Entity\Subscription;
use Evolutionnutrition\ApiBundle\Controller\UserController;
use Symfony\Component\HttpFoundation\Request;
use Evolutionnutrition\ApiBundle\Tests\Base\MockDataMapper;
class UserControllerTest extends BaseControllerTests
{
/**
* @dataProvider createActionDataProvider
*/
public function testCreateAction ($params)
{
$inParams = $params['in'];
$outParams = $params['out'];
$data = $params['in']['data'];
$inviteToken = null;
if (!empty($inParams['inviteToken'])) {
$inviteToken = $inParams['inviteToken'];
}
$isAnonym = $inParams['currentUser'] ? false : true;
$controllerDM = new MockDataMapper;
$controllerDM
->setMethods(['getUserRegistrator'])
->setEntityName('User')
->setAction('create');
$controller = $this->getControllerMock($controllerDM, $params);
$em = $controllerDM->getEM();
$registrator = $this->getMockBuilder($this->getUserRegistratorClass($data, $isAnonym))
->setConstructorArgs([static::$container, $data, $controller, $em])
->setMethods([
'getInviteTokenById',
'getEvoPermissions',
'createSubscription',
'getNotificationService',
'createClientTrainerConnection',
'getUserById',
])
->getMock();
$controllerDM->setRegistrator($registrator);
$registrator
->expects($this->any())
->method('getInviteTokenById')
->will($this->returnValue($inviteToken));
$notificationService = $this->getMockBuilder($inParams['notificationService'])
->disableOriginalConstructor()
->setMethods(['notify', 'getLastEmailSent'])
->getMock();
$notificationService
->expects($this->any())
->method('notify')
->will($this->returnValue($inParams['notifyReturns']));
$registrator
->expects($this->any())
->method('getNotificationService')
->will($this->returnValue($notificationService));
$newUser = $controllerDM->getEntity();
if (!empty($outParams['registratorExpects'])) {
$outParams['registratorExpects']($newUser, $controllerDM, $params);
}
$permissionsService = $this->getMockBuilder('Evolutionnutrition\ApiBundle\Service\Permissions')
->setMethods(['getCurrentUser'])
->getMock();
$permissionsService->setContainer(static::$container);
$registrator
->expects($this->any())
->method('getEvoPermissions')
->will($this->returnValue($permissionsService));
$registrator
->expects($this->any())
->method('createSubscription')
->will($this->returnCallback(function ($requestData, $newUser) {
return $this->createSubscription($requestData, $newUser);
}));
$permissionsService
->expects($this->any())
->method('getCurrentUser')
->will($this->returnValue($inParams['currentUser']));
$controller
->expects($this->any())
->method('getUserRegistrator')
->will($this->returnValue($registrator));
$run = $controllerDM->getRunTest();
$run();
}
public function createActionDataProvider ()
{
$successData = [
'params' => [
'in' => [
'currentUser' => null,
'inviteToken' => null,
'notifyReturns' => true,
// Evolutionnutrition\ApiBundle\Service\EmailSenderByInviteToken
// Evolutionnutrition\ApiBundle\Service\EmailNotification
'notificationService' => 'Email',
'data' => [
'token' => null,
'first_name' => 'Sam',
'last_name' => 'Jonson',
'email' => 'jms@gmail.com',
'gender' => 'male',
'phone' => '0685055505',
'avatar_url' => '',
'birth_date' => '',
'user_type' => 'account-owner',
'password' => 'asdf',
'subscription_type_id' => 'some id',
'trainer_id' => '',
// 'addresses' => '',
],
],
'out' => [
'errorMessage' => -1,
'onFinishChecker' => function ($newUser, $controllerDM, $params) {},
'exception' => null,
'expectations' => null,
'registratorExpects' => function ($newUser, $controllerDM, $params) {},
],
'duplicate' => [],
],
];
$testData = [
'max length error -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'data' => [
'first_name' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin pellentesque, ipsum quis adipiscing adipiscing, dolor metus varius neque, eu sollicitudin nulla tortor vitae ipsum. Donec eu nulla augue, quis gravida lacus. Suspendisse et elit mauris. Suspendisse potenti. Integer in nisi non urna adipiscing tempus. Etiam malesuada posuere massa, at venenatis odio ultrices non. Integer urna odio, ornare condimentum faucibus eget, euismod nec ante. Morbi vitae erat tortor. Nulla molestie arcu et dolor adipiscing vehicula. Donec et vulputate massa. Suspendisse potenti. Nunc sit amet mollis tellus. Donec a ante vitae ante laoreet porttitor nec vulputate mi.',
'last_name' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin pellentesque, ipsum quis adipiscing adipiscing, dolor metus varius neque, eu sollicitudin nulla tortor vitae ipsum. Donec eu nulla augue, quis gravida lacus. Suspendisse et elit mauris. Suspendisse potenti. Integer in nisi non urna adipiscing tempus. Etiam malesuada posuere massa, at venenatis odio ultrices non. Integer urna odio, ornare condimentum faucibus eget, euismod nec ante. Morbi vitae erat tortor. Nulla molestie arcu et dolor adipiscing vehicula. Donec et vulputate massa. Suspendisse potenti. Nunc sit amet mollis tellus. Donec a ante vitae ante laoreet porttitor nec vulputate mi.',
'email' => 'abcd55555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555@gmail.com',
'phone' => '5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555',
]
],
'out' => [
'errorMessage' => [
'User name is too long. It should have 50 characters or less.',
'Last name is too long. It should have 50 characters or less.',
'Email is too long. It should have 60 characters or less.',
'Phone is too long. It should have 40 characters or less.',
],
]
],
],
'client no token -> [SUCCESS], has no subscription, type client' => [
'params' => [
'in' => [
'data' => [
'user_type' => 'client',
'token' => null,
'subscription_type_id' => null,
],
],
'out' => [
'errorMessage' => null,
],
'onFinishChecker' => function ($newUser) {
$this->assertEquals($newUser->getUserType(), 'client');
$this->assertEquals($newUser->getSubscription(), null);
},
],
],
'%s By User %s registration -> [SUCCESS], random password set, email send, user not active, subscription set from currentUser' => [
'params' => [
'in' => [
'data' => [
'password' => 'pa**word',
],
],
'out' => [
'onFinishChecker' => function ($newUser, $controllerDM, $params) {
$registrator = $controllerDM->getRegistrator();
$this->ensure_passwordIsRandom($newUser, $registrator, $params);
$this->assertFalse($newUser->getIsActive());
$this->ensure_subscriptionSetFromCurrentUser($newUser, $registrator, $params);
},
'registratorExpects' => function ($newUser, $controllerDM, $params) {
$registrator = $controllerDM->getRegistrator();
$registrator->expects($this->once())->method('getNotificationService');
}
],
],
'multiply' => [
'params.in.data.user_type' => [
User::TYPE_CLIENT,
User::TYPE_CLIENT,
User::TYPE_TRAINER,
User::TYPE_NUTRITIONIST,
// User::TYPE_ACCOUNT_OWNER,
],
[
User::TYPE_TRAINER,
User::TYPE_ACCOUNT_OWNER,
User::TYPE_ACCOUNT_OWNER,
User::TYPE_ACCOUNT_OWNER,
// User::TYPE_ACCOUNT_OWNER,
],
'params.in.currentUser' => [
$this->generateUser(User::TYPE_TRAINER),
$this->generateUser(User::TYPE_ACCOUNT_OWNER),
$this->generateUser(User::TYPE_ACCOUNT_OWNER),
$this->generateUser(User::TYPE_ACCOUNT_OWNER),
// $this->generateUser(User::TYPE_ACCOUNT_OWNER),
]
],
],
'Client By Trainer / Owner -> [SUCCESS]: client-trainer connection' => function () {
$registratorExpects = function ($newUser, $controllerDM, $params) {
$registrator = $controllerDM->getRegistrator();
$currentUserType = $params['in']['currentUser']->getUserType();
$newUserType = $params['in']['data']['user_type'];
$clientTrainerConnectionExpected = (
$newUserType == 'client' &&
( $currentUserType == 'trainer' ||
( $currentUserType == 'account-owner' &&
!empty($params['in']['data']['trainer_id'])
)
)
);
if ($clientTrainerConnectionExpected) {
$registrator->expects($this->once())
->method('createClientTrainerConnection')
->with(
$this->isInstanceOf('\Evolutionnutrition\ApiBundle\Entity\User'),
$this->callback(function ($trainer) {
return $trainer->isTrainer() || $trainer->isAccountOwner();
}),
$this->equalTo(['byTrainer' => true])
);
$needTrainerById = !empty($params['in']['data']['trainer_id']) &&
$currentUserType == 'account-owner';
if ($needTrainerById) {
$registrator->expects($this->once())
->method('getUserById')
->will($this->returnValue((new User)->setUserType($currentUserType)));
}
} else {
$registrator->expects($this->never())
->method('createClientTrainerConnection');
}
};
$variants = [
[
'user_type' => 'client',
'currentUser' => $this->generateUser(User::TYPE_TRAINER),
],
[
'user_type' => 'client',
'currentUser' => $this->generateUser(User::TYPE_ACCOUNT_OWNER),
],
[
'user_type' => 'client',
'trainer_id' => 'some id',
'currentUser' => $this->generateUser(User::TYPE_ACCOUNT_OWNER),
],
];
$ret = [];
foreach ($variants as $vData) {
$v = [];
$v['params']['in']['data']['user_type'] = $vData['user_type'];
$v['params']['in']['currentUser'] = $vData['currentUser'];
$v['params']['out']['registratorExpects'] = $registratorExpects;
$v['params']['in']['data']['trainer_id'] = @$vData['trainer_id'];
$currentUserType = $vData['currentUser']->getUserType();
$name = "check client-trainer connection: client by {$currentUserType}";
$name .= empty($vData['trainer_id']) ? ' no trainer id' : ', trainer_id';
$ret[$name] = $v;
}
return $ret;
},
'registration of %s by invitation from %s -> [SUCCESS]' => [
'params' => [
'in' => [
'data' => [
'token' => 'some id',
],
],
'out' => [
'onFinishChecker' => function ($newUser, $controllerDM, $params) {
$inviteToken = $params['in']['inviteToken'];
$this->assertTrue($inviteToken->getUser() === $newUser, 'InvitationToken user should be set and eq new user.');
},
'registratorExpects' => function ($newUser, $controllerDM, $params) {
$registrator = $controllerDM->getRegistrator();
// @todo check it calls realy
$registrator->expects($this->once())
->method('getNotificationService');
$inviteToken = $params['in']['inviteToken'];
$invitationOwner = $inviteToken->getOwner();
$invitedClient = $inviteToken->getUserType() === 'client';
$clientTrainerConnectionExpected = $invitedClient &&
($invitationOwner->isTrainer() || $invitationOwner->isAccountOwner());
if ($clientTrainerConnectionExpected) {
$registrator->expects($this->once())
->method('createClientTrainerConnection')
->with(
$this->isInstanceOf('\Evolutionnutrition\ApiBundle\Entity\User'),
$this->isInstanceOf('\Evolutionnutrition\ApiBundle\Entity\User'),
$this->equalTo(['byTrainer' => true])
);
} else {
$registrator->expects($this->never())
->method('createClientTrainerConnection');
}
},
],
],
'multiply' => [
'params.in.data.user_type' => [
'client',
'client',
'nutritionist',
'trainer',
'account-owner',
],
['trainer', 'account-owner', null, null, null],
'params.in.inviteToken' => [
$this->getInviteTokenWithSubscription('client', 'trainer'),
$this->getInviteTokenWithSubscription('client', 'account-owner'),
$this->getInviteTokenWithSubscription('nutritionist'),
$this->getInviteTokenWithSubscription('trainer'),
$this->getInviteTokenWithSubscription('account-owner'),
],
],
],
//
'%s without invitation -> account-owner, [SUCCESS], subscription created' => [
'params' => [
'out' => [
'onFinishChecker' => function ($newUser) {
$this->assertEquals($newUser->getUserType(), 'account-owner');
$this->checkUserSubscriptionIsSet($newUser);
},
],
],
'multiply' => [
'in.data.user_type' => ['trainer', 'account-owner'],
],
],
// - - - - - - - - - - - - Errors - - - - - - - - - - - - //
'no user type -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'data' => [
'user_type' => null,
],
],
'out' => [
'errorMessage' => 'Please choose user type.',
],
],
],
'no token, no subscription type id, %s -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'data' => [
'token' => null,
'subscription_type_id' => null,
],
],
'out' => [
'errorMessage' => 'Paid Subscription type must be defined.',
],
],
'multiply' => [
'params.in.data.user_type' => ['trainer', 'account-owner'],
],
],
'bad user type -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'currentUser' => (new User)->setUserType(User::TYPE_TRAINER),
'data' => [
'user_type' => 'XXXX --------- XXXX',
],
],
'out' => [
'exception' => 'Bad user type.',
],
],
],
'password required for self / token registration -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'data' => [
'user_type' => 'client',
'password' => '',
],
],
'out' => [
'errorMessage' => 'Please provide password.',
],
],
],
'user by user without subscription registration -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'currentUser' => (new User)->setUserType(User::TYPE_ACCOUNT_OWNER),
'data' => [
'user_type' => 'client',
],
],
'out' => [
'errorMessage' => 'You should have subscription to register new users.',
],
],
],
'not allowed user type variants -> [ERROR_MESSAGE]' => function () {
$errorMessage = 'You are not allowed to create users with this type.';
$variants = [
[
'currentUser' => (new User)->setUserType(User::TYPE_TRAINER),
'badUserTypes' => ['trainer', 'nutritionist', 'account-owner'],
],
[
'currentUser' => (new User)->setUserType(User::TYPE_NUTRITIONIST),
'badUserTypes' => ['client', 'nutritionist', 'trainer', 'account-owner'],
],
[
'currentUser' => (new User)->setUserType(User::TYPE_CLIENT),
'badUserTypes' => ['client', 'nutritionist', 'trainer', 'account-owner'],
],
];
$ret = array();
foreach ($variants as $vData) {
foreach ($vData['badUserTypes'] as $userType) {
$v = [];
$v['params']['in']['currentUser'] = $vData['currentUser'];
$v['params']['in']['data']['user_type'] = $userType;
$v['params']['out']['errorMessage'] = $errorMessage;
$currentUserType = $vData['currentUser']->getUserType();
$name = "not allowed user type {$userType}:by:{$currentUserType} -> [ERROR_MESSAGE]";
$ret[$name] = $v;
}
}
return $ret;
},
'nutritionist without invitation -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'data' => [
'user_type' => 'nutritionist',
],
],
'out' => [
'errorMessage' => 'You should have invitation to register as nutritionist.',
],
],
],
'Invitation token not found. -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'inviteToken' => null,
'data' => [
'token' => 'some id',
'user_type' => 'client',
]
],
'out' => [
'errorMessage' => 'Invitation token not found.',
],
],
],
// invitation used
'%s, invitation used -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'data' => [
'token' => 'some id',
],
],
'out' => [
'errorMessage' => 'Invitation token already used.',
],
],
'multiply' => [
'params.in.data.user_type' => [
'client',
'nutritionist',
'trainer',
'account-owner'
],
'params.in.inviteToken' => [
(new InviteToken)->setUserType('client')->setUser(new User),
(new InviteToken)->setUserType('nutritionist')->setUser(new User),
(new InviteToken)->setUserType('trainer')->setUser(new User),
(new InviteToken)->setUserType('account-owner')->setUser(new User),
],
],
],
// invitation.userType doesn't match request user type.
'user type from request and inviteToken %s doesn\'t match -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'data' => [
'token' => 'some id',
'user_type' => 'account-owner',
],
],
'out' => [
'errorMessage' => 'Invalid invitation user type.',
],
],
'multiply' => [
'params.in.inviteToken' => [
(new InviteToken)->setUserType('client'),
(new InviteToken)->setUserType('nutritionist'),
(new InviteToken)->setUserType('trainer'),
],
],
],
'max length error -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'data' => [
'first_name' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin pellentesque, ipsum quis adipiscing adipiscing, dolor metus varius neque, eu sollicitudin nulla tortor vitae ipsum. Donec eu nulla augue, quis gravida lacus. Suspendisse et elit mauris. Suspendisse potenti. Integer in nisi non urna adipiscing tempus. Etiam malesuada posuere massa, at venenatis odio ultrices non. Integer urna odio, ornare condimentum faucibus eget, euismod nec ante. Morbi vitae erat tortor. Nulla molestie arcu et dolor adipiscing vehicula. Donec et vulputate massa. Suspendisse potenti. Nunc sit amet mollis tellus. Donec a ante vitae ante laoreet porttitor nec vulputate mi.',
'last_name' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin pellentesque, ipsum quis adipiscing adipiscing, dolor metus varius neque, eu sollicitudin nulla tortor vitae ipsum. Donec eu nulla augue, quis gravida lacus. Suspendisse et elit mauris. Suspendisse potenti. Integer in nisi non urna adipiscing tempus. Etiam malesuada posuere massa, at venenatis odio ultrices non. Integer urna odio, ornare condimentum faucibus eget, euismod nec ante. Morbi vitae erat tortor. Nulla molestie arcu et dolor adipiscing vehicula. Donec et vulputate massa. Suspendisse potenti. Nunc sit amet mollis tellus. Donec a ante vitae ante laoreet porttitor nec vulputate mi.',
'email' => 'abcd55555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555@gmail.com',
'phone' => '5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555',
]
],
'out' => [
'errorMessage' => [
'User name is too long. It should have 50 characters or less.',
'Last name is too long. It should have 50 characters or less.',
'Email is too long. It should have 60 characters or less.',
'Phone is too long. It should have 40 characters or less.',
],
]
],
],
'register %s by invitation from %s -> [ERROR_MESSAGE] email not send' => [
'params' => [
'in' => [
'notifyReturns' => false,
'data' => [
'token' => 'some id',
],
],
'out' => [
// 'exception' => 'Failed to send registration email',
'errorMessage' => 'Failed to send registration email.',
],
],
'multiply' => [
'params.in.data.user_type' => [
'client',
'client',
'nutritionist',
'trainer',
'account-owner',
],
['trainer', 'account-owner', null, null, null],
'params.in.inviteToken' => [
$this->getInviteTokenWithSubscription('client', 'trainer'),
$this->getInviteTokenWithSubscription('client', 'account-owner'),
$this->getInviteTokenWithSubscription('nutritionist'),
$this->getInviteTokenWithSubscription('trainer'),
$this->getInviteTokenWithSubscription('account-owner'),
],
],
],
'%s By User %s registration -> [ERROR_MESSAGE] email not send' => [
'params' => [
'in' => [
'notifyReturns' => false,
],
'out' => [
'errorMessage' => 'Failed to send notification.',
],
],
'multiply' => [
'params.in.data.user_type' => [
User::TYPE_CLIENT,
User::TYPE_CLIENT,
User::TYPE_TRAINER,
User::TYPE_NUTRITIONIST,
],
[
User::TYPE_TRAINER,
User::TYPE_ACCOUNT_OWNER,
User::TYPE_ACCOUNT_OWNER,
User::TYPE_ACCOUNT_OWNER,
User::TYPE_ACCOUNT_OWNER
],
'params.in.currentUser' => [
$this->generateUser(User::TYPE_TRAINER),
$this->generateUser(User::TYPE_ACCOUNT_OWNER),
$this->generateUser(User::TYPE_ACCOUNT_OWNER),
$this->generateUser(User::TYPE_ACCOUNT_OWNER),
]
],
],
];
return $this->generateParams($successData, $testData);
}
/**
* @dataProvider updateActionDataProvider
*/
public function testUpdateAction ($params)
{
$inParams = $params['in'];
$outParams = $params['out'];
$data = $params['in']['data'];
$currentUser = null;
if (!empty($inParams['currentUser'])) {
$currentUser = $inParams['currentUser'];
}
$updatedUser = null;
if (!empty($inParams['updatedUser'])) {
$updatedUser = $inParams['updatedUser'];
}
$controllerDM = new MockDataMapper;
$controllerDM
->setMethods([])
->setEntityName('User')
->setAction('update')
->setEntity($updatedUser);
if (array_key_exists('id', $inParams)) {
$controllerDM->setId($inParams['id']);
}
if (array_key_exists('dbFoundEntity', $inParams)) {
$controllerDM->setDbFoundEntity($inParams['dbFoundEntity']);
}
$controller = $this->getControllerMock($controllerDM, $params);
// $em = $controllerDM->getEM();
$run = $controllerDM->getRunTest();
$run();
}
public function updateActionDataProvider ()
{
$successData = [
'params' => [
'in' => [
'currentUser' => null,
'updatedUser' => null,
// 'dbFoundEntity' => null,
'data' => [
'first_name' => 'Sam',
'last_name' => 'Jonson',
'email' => 'jms@gmail.com',
'gender' => 'male',
'phone' => '0685055505',
'avatar_url' => '',
'birth_date' => '',
// 'user_type' => 'account-owner',
// 'password' => 'asdf',
// 'trainer_id' => '',
// 'addresses' => '',
],
],
'out' => [
'errorMessage' => -1,
'onFinishChecker' => function ($updatedUser, $controllerDM, $params) {},
'exception' => null,
'expectations' => null,
'registratorExpects' => function ($updatedUser, $controllerDM, $params) {},
],
],
'duplicate' => null,
];
$testData = [
'self update -> [SUCCESS]' => [
'params' => [
'in' => [
'currentUser' => $this->getSavedUser('client'),
'data' => [
'user_type' => 'trainer',
'password' => 'pa**word',
],
],
'out' => [
'errorMessage' => -1,
'expectations' => function ($updatedUser, $controllerDM, $params) {
$em = $controllerDM->getEM();
$em->expects($this->once())
->method('persist');
$em->expects($this->once())
->method('flush');
},
'onFinishChecker' => function ($updatedUser, $controllerDM, $params) {
$err = "user type not changed.";
$this->assertEquals('client', $updatedUser->getUserType(), $err);
$err = "password not changed.";
$this->assertEquals($updatedUser->getSalt(), $updatedUser->getPassword(), $err);
},
],
],
'duplicate' => ['params.in.currentUser' => 'params.in.updatedUser'],
],
'self update: no id -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'id' => null,
'currentUser' => $this->getSavedUser('client'),
'data' => [
'user_type' => 'client',
],
],
'out' => [
'errorMessage' => "User can't be found without id.",
],
],
'duplicate' => ['params.in.currentUser' => 'params.in.updatedUser'],
],
'self update: entity not found -> [ERROR_MESSAGE]' => [
'params' => [
'in' => [
'currentUser' => $this->getSavedUser('client'),
'dbFoundEntity' => null,
'data' => [
'user_type' => 'client',
],
],
'out' => [
'errorMessage' => "User with id: some id was not found.",
],
],
],
];
return $this->generateParams($successData, $testData);
}
private function getSavedUser ($userType)
{
$user = new User;
$user->setFirstName('Sam')
->setLastName('Jonson')
->setEmail('jms@gmail')
->setGender('male')
->setPhone('0685055505')
->setPassword($user->getSalt())
->setUserType($userType)
->setAvatarUrl('/uploads/images/asdf.jpg')
->setBirthDate(new \DateTime());
return $user;
}
private function ensure_passwordIsRandom ($newUser, $registrator, $params)
{
$validPswd = $registrator->passwordEncode($newUser, $newUser->getSalt());
$notValidPswd = $registrator->passwordEncode($newUser, 'pa**word');
$err = "password not changed";
$this->assertEquals($validPswd, $newUser->getPassword(), $err);
$this->assertNotEquals($notValidPswd, $newUser->getPassword(), $err);
}
function ensure_subscriptionSetFromCurrentUser ($newUser, $registrator, $params)
{
$currentUserSubscription = $params['in']['currentUser']->getSubscription();
$otherwise = 'Subscription set from current user.';
$this->assertTrue($newUser->getSubscription() === $currentUserSubscription, $otherwise);
}
private function createSubscription ($data, $user) {
if (!empty($data['subscription_type_id'])) {
$subscription = new Subscription();
$subscription->setOwnerId($user->getId());
$subscription->setOwner($user);
return $subscription;
} else {
return null;
}
}
private function checkUserSubscriptionIsSet($user) {
$this->assertInstanceOf('Evolutionnutrition\ApiBundle\Entity\Subscription', $user->getSubscription());
}
private function generateUser ($userType = null) {
$user = new User;
$user
->setUserType($userType)
->setSubscription(new Subscription);
return $user;
}
private function getInviteTokenWithSubscription ($userType, $fromUserType = null) {
$inviteToken = (new InviteToken)->setUserType($userType);
$owner = $this->generateUser($fromUserType);
$inviteToken->setOwner($owner);
return $inviteToken;
}
private function getUserRegistratorClass ($requestData, $isAnonym)
{
if (!empty($requestData['token'])) {
return 'Evolutionnutrition\ApiBundle\Service\UserRegister\InvitationUserRegistrator';
} elseif (!$isAnonym) {
return 'Evolutionnutrition\ApiBundle\Service\UserRegister\UserByUserRegistrator';
} else {
return 'Evolutionnutrition\ApiBundle\Service\UserRegister\SelfUserRegistrator';
}
}
}
<?php
namespace Evolutionnutrition\ApiBundle\Tests\Unit;
use Evolutionnutrition\ApiBundle\Tests\Base\BaseUnitTests;
use Symfony\Component\Form\Form;
use CPCS\SfBaseApiBundle\Interfaces\CPCSSfBaseEntity;
use Doctrine\Common\Collections\ArrayCollection;
class validateMethodTest extends BaseUnitTests
{
/**
* @dataProvider validateDataProvider
**/
public function testValidateMethod ($entityName, $entity)
{
$className = "Evolutionnutrition\\ApiBundle\\Controller\\{$entityName}Controller";
$classMockBuilder = $this->getMockBuilder($className);
$methodsList = [];
$controller = $classMockBuilder
->setMethods($methodsList)
->getMock();
$requestData = [];
$form = $this->getFormMock();
$origin = clone $entity;
/**
* meke method public to test it!
**/
// $controller->validate($requestData, $entity, $form, $origin);
/**
* we just check that no Errors was thrown
**/
$this->assertTrue(true);
}
public function validateDataProvider ()
{
$successData = [
'entityName' => null,
'entity' => $this->getEntityMock(),
];
$testData = [
'Characteristic' => [
'entityName' => 'Characteristic',
],
'ExchangeList' => [
'entityName' => 'ExchangeList',
],
'Food' => [
'entityName' => 'Food',
],
'MealPlan' => [
'entityName' => 'MealPlan',
],
'Recipe' => [
'entityName' => 'Recipe',
],
'RecipeIngredient' => [
'entityName' => 'RecipeIngredient',
],
'Serving' => [
'entityName' => 'Serving',
],
];
$ret = $this->generateParams($successData, $testData);
return $ret;
}
private function getEntityMock ()
{
$entityInterface = "CPCS\\SfBaseApiBundle\\Interfaces\\CPCSSfBaseEntity";
$entityMockBuilder = $this->getMockBuilder($entityInterface);
$entity = $entityMockBuilder
->setMethods(['getTitle','getServings','getRecipe','getFoodstuff'])
->getMock();
$entity->expects($this->any())
->method('getServings')
->will($this->returnValue(new ArrayCollection));
$entity->expects($this->any())
->method('getRecipe')
->will($this->returnValue($entity));
$entity->expects($this->any())
->method('getFoodstuff')
->will($this->returnValue($entity));
return $entity;
}
private function getFormMock ()
{
$builder = $this->getMockBuilder("Symfony\\Component\\Form\\Form");
$form = $builder
->setMethods([])
->disableOriginalConstructor()
->getMock();
return $form;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment