Created by Nicolas Masson and Juan Pablo Ramirez
Press S for speaker view
vierge.noire.info@gmail.com
UsersTable ↔ UsersGroupsTable ↔ PermissionsTable
5 Tables
users
users_users_groups
users_groups
users_groups_permissions
permissions
public function testUserPermission()
{
$user = $this->Users->get(45, [
'contain' => ['UsersGroups.Permissions']
])
$act = $this->Users->hasPermission($user, 'Foo');
$this->assertTrue($act);
}
public function testUserPermission()
{
$user = UserFactory::make()
->with('UsersGroups.Permissions', ['name' => 'Foo'])
->getEntity();
$act = $this->Users->hasPermission($user, 'Foo');
$this->assertTrue($act);
}
Arrange
Act
Assert
Arrange
Create user, user group, permission Foo, pivot tables
Act
Check permission Foo for user
Assert
Expect user to have permission Foo
public function testUserPermission()
{
// Arrange
$user = UserFactory::make()
->with('UsersGroups.Permissions', ['name' => 'Foo'])
->getEntity();
// Act
$act = $this->Users->hasPermission($user, 'Foo');
// Assert
$this->assertTrue($act);
}
public function dataProviderForUserWithPermissionFoo()
{
return [
['Admin', true],
['Guru', true],
['Foo', true],
['Bar', false],
];
}
/** @dataProvider dataProviderForUserWithPermissionFoo */
public function testUserHasPermissionFoo(
string $permission,
bool $expected
)
{
$user = UserFactory::make()
->withPermission($permission)
->getEntity();
$act = $this->Users->hasPermission($user, 'Foo');
$this->assertSame($expected, $act);
}
Feature: User permission
Background:
Given I create a user with id 504
Scenario:
Given I log in with permission 'Users'
When I call get 'users/view/504'
Then I shall be granted access.
Scenario:
Given I log in with permission 'Admin'
When I call get 'users/view/504'
Then I shall be granted access.
Scenario:
Given I log in with permission 'Guru'
When I call get 'users/view/504'
Then I shall be granted access.
Scenario:
Given I log in with permission 'Foo'
When I call get 'users/view/504'
Then I shall be redirected.
CakePHP 4.x
composer require --dev vierge-noire/cakephp-fixture-factories "^2.0"
CakePHP 3.x
composer require --dev vierge-noire/cakephp-fixture-factories "^1.0"
// In Application.php
...
protected function bootstrapCli(): void
{
// Load more plugins here
$this->addPlugin('CakephpFixtureFactories');
}
bin/cake fixture_factories_setup
bin/cake bake fixture_factory -a
In tests/bootstrap.php
\CakephpTestMigrator\Migrator::migrate();
bin/cake bake fixture_factory -a
namespace App\Test\Factory;
use CakephpFixtureFactories\Factory\BaseFactory;
use Faker\Generator;
class UserFactory extends BaseFactory
{
protected function getRootTableRegistryName(): string
{
return "Users";
}
protected function setDefaultTemplate(): void
{
$this->setDefaultData(function (Generator $faker) {
return [
// set the model's default values
// For example:
// 'name' => $faker->lastName
];
});
}
}
namespace App\Test\Factory;
use CakephpFixtureFactories\Factory\BaseFactory;
use Faker\Generator;
class UserFactory extends BaseFactory
{
protected function getRootTableRegistryName(): string
{
return "Users";
}
protected function setDefaultTemplate(): void
{
$this->setDefaultData(function (Generator $faker) {
return [
'username' => $faker->userName
'password' => $faker->password,
'email' => $faker->email,
];
});
}
public function withPermission(string $permission): self
{
return $this->with('UserGroups.Permissions', [
'name' => $permission
]);
}
public function admin(): self
{
return $this->withPermission('Admin');
}
public function inFantasticMood(): self
{
// Make this user happy here
return $this;
}
}
$user = UserFactory::make()->getEntity();
$user = UserFactory::make()->persist();
UserFactory::make(3);
UserFactory::make(['username' => 'Foo'], 2);
UserFactory::make([
['username' => 'Foo'],
['username' => 'Bar'],
]);
UserFactory::make()->with('UserGroups', [
'name' => 'Golfers'
]);
UserFactory::make()->with(
'UserGroups',
UserGroupFactory::make(['name' => 'Golfers'])
);
UserFactory::make()->with('UserGroups', [
['name' => 'Golfers'],
['name' => 'Swimmers'],
]);
UserFactory::make(3)->with('UserGroups[5].Permissions');
Run migrations
Truncate Dirty Tables
Time (Y axis) vs Number of tests (X axis)
CakePHP 3
CakePHP 4
Static fixtures
Mysql - Sqlite - PostgreSQL
composer require --dev vierge-noire/cakephp-fixture-factories
https://github.com/vierge-noire/cakephp-fixture-factories
Go to the presentation
vierge.noire.info@gmail.com
Acknowledgements
Zuluru - Bancer - Dreamingmind
The CakePHP community!