From 135b7bf30d477470da7271426fd004d2ff7be4c0 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Fri, 19 Apr 2019 20:49:46 +0200 Subject: [PATCH] Improve tests and harmonize permission handling --- Account/Account.php | 113 +---------------------- Account/Group.php | 16 +--- Account/PermissionHandlingTrait.php | 137 ++++++++++++++++++++++++++++ tests/Account/AccountTest.php | 116 ++++++++++++++++++++--- tests/Account/GroupTest.php | 68 +++++++++++++- 5 files changed, 314 insertions(+), 136 deletions(-) create mode 100644 Account/PermissionHandlingTrait.php diff --git a/Account/Account.php b/Account/Account.php index b234a5a16..7c3d90e45 100644 --- a/Account/Account.php +++ b/Account/Account.php @@ -107,14 +107,6 @@ class Account implements ArrayableInterface, \JsonSerializable */ protected $createdAt = null; - /** - * Permissions. - * - * @var PermissionAbstract[] - * @since 1.0.0 - */ - protected $permissions = []; - /** * Groups. * @@ -155,6 +147,8 @@ class Account implements ArrayableInterface, \JsonSerializable */ protected $l11n = null; + use PermissionHandlingTrait; + /** * Constructor. * @@ -241,109 +235,6 @@ class Account implements ArrayableInterface, \JsonSerializable $this->l11n = $l11n; } - /** - * Set permissions. - * - * The method accepts an array of permissions. All existing permissions are replaced. - * - * @param PermissionAbstract[] $permissions Account permissions - * - * @return void - * - * @since 1.0.0 - */ - public function setPermissions(array $permissions) : void - { - $this->permissions = $permissions; - } - - /** - * Add permissions. - * - * Adds permissions to the account - * - * @param array $permissions Array of permissions to add to the account - * - * @return void - * - * @since 1.0.0 - */ - public function addPermissions(array $permissions) : void - { - foreach ($permissions as $permission) { - if (\is_array($permission)) { - $this->permissions = \array_merge($this->permissions, $permission); - } else { - $this->permissions[] = $permission; - } - } - } - - /** - * Add permission. - * - * Adds a single permission to the account - * - * @param PermissionAbstract $permission Permission to add to the account - * - * @return void - * - * @since 1.0.0 - */ - public function addPermission(PermissionAbstract $permission) : void - { - $this->permissions[] = $permission; - } - - /** - * Get permissions. - * - * @return PermissionAbstract[] - * - * @since 1.0.0 - */ - public function getPermissions() : array - { - return $this->permissions; - } - - /** - * Has permissions. - * - * Checks if the account has a permission defined - * - * @param int $permission Permission to check - * @param null|int $unit Unit Unit to check (null if all are acceptable) - * @param null|string $app App App to check (null if all are acceptable) - * @param null|string $module Module Module to check (null if all are acceptable) - * @param null|int $type Type (e.g. customer) (null if all are acceptable) - * @param null|int $element (e.g. customer id) (null if all are acceptable) - * @param null|int $component (e.g. address) (null if all are acceptable) - * - * @return bool Returns true if the account has the permission, false otherwise - * - * @since 1.0.0 - */ - public function hasPermission(int $permission, int $unit = null, string $app = null, string $module = null, int $type = null, int $element = null, int $component = null) : bool - { - $app = $app !== null ? \strtolower($app) : $app; - - foreach ($this->permissions as $p) { - if (($unit === null || $p->getUnit() === $unit || $p->getUnit() === null) - && ($app === null || $p->getApp() === $app || $p->getApp() === null) - && ($module === null || $p->getModule() === $module || $p->getModule() === null) - && ($type === null || $p->getType() === $type || $p->getType() === null) - && ($element === null || $p->getElement() === $element || $p->getElement() === null) - && ($component === null || $p->getComponent() === $component || $p->getComponent() === null) - && ($p->getPermission() | $permission) === $p->getPermission() - ) { - return true; - } - } - - return false; - } - /** * Get name. * diff --git a/Account/Group.php b/Account/Group.php index 633726081..b5636f9cc 100644 --- a/Account/Group.php +++ b/Account/Group.php @@ -29,7 +29,7 @@ class Group implements ArrayableInterface, \JsonSerializable { /** - * Account id. + * Group id. * * @var int * @since 1.0.0 @@ -37,7 +37,7 @@ class Group implements ArrayableInterface, \JsonSerializable protected $id = 0; /** - * Account name. + * Group name. * * @var string * @since 1.0.0 @@ -45,7 +45,7 @@ class Group implements ArrayableInterface, \JsonSerializable protected $name = ''; /** - * Account name. + * Group name. * * @var string * @since 1.0.0 @@ -53,7 +53,7 @@ class Group implements ArrayableInterface, \JsonSerializable protected $description = ''; /** - * Account name. + * Group members. * * @var array * @since 1.0.0 @@ -76,13 +76,7 @@ class Group implements ArrayableInterface, \JsonSerializable */ protected $status = GroupStatus::INACTIVE; - /** - * Permissions. - * - * @var int[] - * @since 1.0.0 - */ - protected $permissions = []; + use PermissionHandlingTrait; /** * Get group id. diff --git a/Account/PermissionHandlingTrait.php b/Account/PermissionHandlingTrait.php new file mode 100644 index 000000000..c9db01de4 --- /dev/null +++ b/Account/PermissionHandlingTrait.php @@ -0,0 +1,137 @@ +permissions = $permissions; + } + + /** + * Add permissions. + * + * Adds permissions + * + * @param array $permissions Array of permissions to add + * + * @return void + * + * @since 1.0.0 + */ + public function addPermissions(array $permissions) : void + { + foreach ($permissions as $permission) { + if (\is_array($permission)) { + $this->permissions = \array_merge($this->permissions, $permission); + } else { + $this->permissions[] = $permission; + } + } + } + + /** + * Add permission. + * + * Adds a single permission + * + * @param PermissionAbstract $permission Permission to add + * + * @return void + * + * @since 1.0.0 + */ + public function addPermission(PermissionAbstract $permission) : void + { + $this->permissions[] = $permission; + } + + /** + * Get permissions. + * + * @return PermissionAbstract[] + * + * @since 1.0.0 + */ + public function getPermissions() : array + { + return $this->permissions; + } + + /** + * Has permissions. + * + * Checks if the permission is defined + * + * @param int $permission Permission to check + * @param null|int $unit Unit Unit to check (null if all are acceptable) + * @param null|string $app App App to check (null if all are acceptable) + * @param null|string $module Module Module to check (null if all are acceptable) + * @param null|int $type Type (e.g. customer) (null if all are acceptable) + * @param null|int $element (e.g. customer id) (null if all are acceptable) + * @param null|int $component (e.g. address) (null if all are acceptable) + * + * @return bool Returns true if the permission is set, false otherwise + * + * @since 1.0.0 + */ + public function hasPermission(int $permission, int $unit = null, string $app = null, string $module = null, int $type = null, int $element = null, int $component = null) : bool + { + $app = $app !== null ? \strtolower($app) : $app; + + foreach ($this->permissions as $p) { + if (($unit === null || $p->getUnit() === $unit || $p->getUnit() === null) + && ($app === null || $p->getApp() === $app || $p->getApp() === null) + && ($module === null || $p->getModule() === $module || $p->getModule() === null) + && ($type === null || $p->getType() === $type || $p->getType() === null) + && ($element === null || $p->getElement() === $element || $p->getElement() === null) + && ($component === null || $p->getComponent() === $component || $p->getComponent() === null) + && ($p->getPermission() | $permission) === $p->getPermission() + ) { + return true; + } + } + + return false; + } +} diff --git a/tests/Account/AccountTest.php b/tests/Account/AccountTest.php index b578ba2c5..bf501fa3b 100644 --- a/tests/Account/AccountTest.php +++ b/tests/Account/AccountTest.php @@ -24,6 +24,9 @@ use phpOMS\Localization\Localization; require_once __DIR__ . '/../Autoloader.php'; +/** + * @testdox phpOMS\tests\Account\Account: Base account/user representation + */ class AccountTest extends \PHPUnit\Framework\TestCase { protected $l11nManager = null; @@ -33,6 +36,9 @@ class AccountTest extends \PHPUnit\Framework\TestCase $this->l11nManager = new L11nManager('Api'); } + /** + * @testdox The account has the expected member variables + */ public function testAttributes() : void { $account = new Account(); @@ -55,6 +61,9 @@ class AccountTest extends \PHPUnit\Framework\TestCase self::assertObjectHasAttribute('l11n', $account); } + /** + * @testdox The account has the expected default values after initialization + */ public function testDefault() : void { $account = new Account(); @@ -99,16 +108,14 @@ class AccountTest extends \PHPUnit\Framework\TestCase self::assertEquals($array, $account->jsonSerialize()); } - public function testSetGet() : void + /** + * @testdox The account names can be set and retrieved correctly + */ + public function testSetAndGetAccountNames() : void { $account = new Account(); - - /* Just test if no error happens */ $account->generatePassword('abcd'); - $account->addGroup(new Group()); - self::assertEquals(1, \count($account->getGroups())); - $account->setName('Login'); self::assertEquals('Login', $account->getName()); @@ -121,17 +128,65 @@ class AccountTest extends \PHPUnit\Framework\TestCase $account->setName3('Duck'); self::assertEquals('Duck', $account->getName3()); - $account->setEmail('d.duck@duckburg.com'); - self::assertEquals('d.duck@duckburg.com', $account->getEmail()); - $account->setName('Login'); self::assertEquals('Login', $account->getName()); + } + + /** + * @testdox Groups can be added to an account + */ + public function testAddAndGetGroup() : void + { + $account = new Account(); + $account->generatePassword('abcd'); + + $account->addGroup(new Group()); + self::assertEquals(1, \count($account->getGroups())); + } + + /** + * @testdox An account can have a valid email address + */ + public function testSetAndGetAccountEmail() : void + { + $account = new Account(); + $account->generatePassword('abcd'); + + $account->setEmail('d.duck@duckburg.com'); + self::assertEquals('d.duck@duckburg.com', $account->getEmail()); + } + + /** + * @testdox The default status of the account can be changed to a different valid status + */ + public function testChangeStatus() : void + { + $account = new Account(); + $account->generatePassword('abcd'); $account->setStatus(AccountStatus::ACTIVE); self::assertEquals(AccountStatus::ACTIVE, $account->getStatus()); + } + + /** + * @testdox The default type of the account can be changed to a different valid type + */ + public function testChangeType() : void + { + $account = new Account(); + $account->generatePassword('abcd'); $account->setType(AccountType::GROUP); self::assertEquals(AccountType::GROUP, $account->getType()); + } + + /** + * @testdox Account permissions can be added and checked for existence + */ + public function testPermissionHandling() : void + { + $account = new Account(); + $account->generatePassword('abcd'); $account->addPermission(new class extends PermissionAbstract {}); self::assertEquals(1, \count($account->getPermissions())); @@ -156,15 +211,36 @@ class AccountTest extends \PHPUnit\Framework\TestCase self::assertFalse($account->hasPermission(PermissionType::READ, 1, 'a', 'a', 1, 1, 1)); self::assertTrue($account->hasPermission(PermissionType::NONE)); + } + + /** + * @testdox An account can have it's own localization + */ + public function testLocalization() : void + { + $account = new Account(); + $account->generatePassword('abcd'); $account->setL11n(new Localization()); self::assertInstanceOf('\phpOMS\Localization\Localization', $account->getL11n()); + } + + /** + * @testdox An account 'last activity' timestamp can be updated and retrieved + */ + public function testLastChange() : void + { + $account = new Account(); + $account->generatePassword('abcd'); $datetime = new \DateTime('now'); $account->updateLastActive(); self::assertEquals($datetime->format('Y-m-d h:i:s'), $account->getLastActive()->format('Y-m-d h:i:s')); } + /** + * @testdox An account can only have a valid email + */ public function testEmailException() : void { self::expectException(\InvalidArgumentException::class); @@ -173,19 +249,37 @@ class AccountTest extends \PHPUnit\Framework\TestCase $account->setEmail('d.duck!@#%@duckburg'); } + /** + * @testdox An account can only have valid account status + */ public function testStatusException() : void { self::expectException(\phpOMS\Stdlib\Base\Exception\InvalidEnumValue::class); $account = new Account(); - $account->setStatus(99); + + $rand = 0; + do { + $rand = \mt_rand(PHP_INT_MIN, PHP_INT_MAX); + } while (AccountStatus::isValidValue($rand)); + + $account->setStatus($rand); } + /** + * @testdox An account can only have valid account types + */ public function testTypeException() : void { self::expectException(\phpOMS\Stdlib\Base\Exception\InvalidEnumValue::class); $account = new Account(); - $account->setType(99); + + $rand = 0; + do { + $rand = \mt_rand(PHP_INT_MIN, PHP_INT_MAX); + } while (AccountType::isValidValue($rand)); + + $account->setType($rand); } } diff --git a/tests/Account/GroupTest.php b/tests/Account/GroupTest.php index 7bcc62a6f..e71f4f69f 100644 --- a/tests/Account/GroupTest.php +++ b/tests/Account/GroupTest.php @@ -15,11 +15,19 @@ namespace phpOMS\tests\Account; use phpOMS\Account\Group; use phpOMS\Account\GroupStatus; +use phpOMS\Account\PermissionAbstract; +use phpOMS\Account\PermissionType; require_once __DIR__ . '/../Autoloader.php'; +/** + * @testdox phpOMS\tests\Account\Group: Base group representation + */ class GroupTest extends \PHPUnit\Framework\TestCase { + /** + * @testdox The group has the expected member variables + */ public function testAttributes() : void { $group = new Group(); @@ -35,6 +43,9 @@ class GroupTest extends \PHPUnit\Framework\TestCase self::assertObjectHasAttribute('status', $group); } + /** + * @testdox The group has the expected default values after initialization + */ public function testDefault() : void { $group = new Group(); @@ -59,7 +70,10 @@ class GroupTest extends \PHPUnit\Framework\TestCase self::assertEquals($array, $group->jsonSerialize()); } - public function testSetGet() : void + /** + * @testdox The group name and description can be set and retrieved correctly + */ + public function testSetAndGetGroupNameDescription() : void { $group = new Group(); @@ -68,16 +82,64 @@ class GroupTest extends \PHPUnit\Framework\TestCase $group->setDescription('Animal'); self::assertEquals('Animal', $group->getDescription()); + } + + /** + * @testdox Group permissions can be added and checked for existence + */ + public function testPermissionHandling() : void + { + $group = new Group(); + $group->addPermission(new class extends PermissionAbstract {}); + self::assertEquals(1, \count($group->getPermissions())); + + $group->setPermissions([ + new class extends PermissionAbstract {}, + new class extends PermissionAbstract {}, + ]); + self::assertEquals(2, \count($group->getPermissions())); + + $group->addPermissions([ + new class extends PermissionAbstract {}, + new class extends PermissionAbstract {}, + ]); + self::assertEquals(4, \count($group->getPermissions())); + + $group->addPermissions([[ + new class extends PermissionAbstract {}, + new class extends PermissionAbstract {}, + ]]); + self::assertEquals(6, \count($group->getPermissions())); + + self::assertFalse($group->hasPermission(PermissionType::READ, 1, 'a', 'a', 1, 1, 1)); + self::assertTrue($group->hasPermission(PermissionType::NONE)); + } + + /** + * @testdox The default status of the group can be changed to a different valid status + */ + public function testChangeStatus() : void + { + $group = new Group(); $group->setStatus(GroupStatus::ACTIVE); self::assertEquals(GroupStatus::ACTIVE, $group->getStatus()); } + /** + * @testdox A group can only have valid group status + */ public function testStatusException() : void { self::expectException(\phpOMS\Stdlib\Base\Exception\InvalidEnumValue::class); - $account = new Group(); - $account->setStatus(99); + $group = new Group(); + + $rand = 0; + do { + $rand = \mt_rand(PHP_INT_MIN, PHP_INT_MAX); + } while (GroupStatus::isValidValue($rand)); + + $group->setStatus($rand); } }