diff --git a/composer.json b/composer.json index 562ae86..c0d00ec 100644 --- a/composer.json +++ b/composer.json @@ -36,7 +36,8 @@ }, "require-dev": { "fabpot/php-cs-fixer": "^1.9", - "phpunit/phpunit": "~5.1" + "phpunit/phpunit": "~5.1", + "symfony/phpunit-bridge": "^3.0" }, "require": { "php": ">=5.6", diff --git a/composer.lock b/composer.lock index 56f1411..e59629d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "77df1d2735511f683bc3a75e7c4fd630", - "content-hash": "f6b51a231d8fcdf71b3816016f22eb31", + "hash": "13e591ddfbce60f08dea143e413098da", + "content-hash": "490f3823af1a08fe13c4b0be306021c4", "packages": [ { "name": "doctrine/annotations", @@ -555,6 +555,61 @@ ], "time": "2012-12-21 11:40:51" }, + { + "name": "symfony/phpunit-bridge", + "version": "v3.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/phpunit-bridge.git", + "reference": "4580ae86cde5497d38fc971192cd2c37e546eb4f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/4580ae86cde5497d38fc971192cd2c37e546eb4f", + "reference": "4580ae86cde5497d38fc971192cd2c37e546eb4f", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "suggest": { + "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Bridge\\PhpUnit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony PHPUnit Bridge", + "homepage": "https://symfony.com", + "time": "2016-01-21 09:38:31" + }, { "name": "symfony/polyfill-intl-icu", "version": "v1.1.1", diff --git a/src/Majora/Component/OAuth/Entity/AccessToken.php b/src/Majora/Component/OAuth/Entity/AccessToken.php index 417da66..474ed14 100644 --- a/src/Majora/Component/OAuth/Entity/AccessToken.php +++ b/src/Majora/Component/OAuth/Entity/AccessToken.php @@ -8,14 +8,14 @@ use Majora\Component\OAuth\Model\RefreshTokenInterface; use Majora\Framework\Model\CollectionableInterface; use Majora\Framework\Model\CollectionableTrait; -use Majora\Framework\Serializer\Model\SerializableTrait; +use Majora\Framework\Normalizer\Model\NormalizableTrait; /** * Access token class. */ class AccessToken extends Token implements AccessTokenInterface, CollectionableInterface { - use CollectionableTrait, SerializableTrait; + use CollectionableTrait, NormalizableTrait; /** * @var RefreshTokenInterface diff --git a/src/Majora/Component/OAuth/Entity/Account.php b/src/Majora/Component/OAuth/Entity/Account.php index 6ecf4ca..2d01201 100644 --- a/src/Majora/Component/OAuth/Entity/Account.php +++ b/src/Majora/Component/OAuth/Entity/Account.php @@ -5,14 +5,14 @@ use Majora\Component\OAuth\Model\AccountInterface; use Majora\Framework\Model\CollectionableInterface; use Majora\Framework\Model\CollectionableTrait; -use Majora\Framework\Serializer\Model\SerializableTrait; +use Majora\Framework\Normalizer\Model\NormalizableTrait; /** * Basic implementation on AccountInterface. */ class Account implements AccountInterface, CollectionableInterface { - use CollectionableTrait, SerializableTrait; + use CollectionableTrait, NormalizableTrait; /** * @var int @@ -183,9 +183,13 @@ public function getApplications() /** * @param array $applications + * + * @return self */ public function setApplications($applications) { $this->applications = $applications; + + return $this; } } diff --git a/src/Majora/Component/OAuth/Entity/Application.php b/src/Majora/Component/OAuth/Entity/Application.php index fd1e8ad..e44d939 100644 --- a/src/Majora/Component/OAuth/Entity/Application.php +++ b/src/Majora/Component/OAuth/Entity/Application.php @@ -5,14 +5,14 @@ use Majora\Component\OAuth\Model\ApplicationInterface; use Majora\Framework\Model\CollectionableInterface; use Majora\Framework\Model\CollectionableTrait; -use Majora\Framework\Serializer\Model\SerializableTrait; +use Majora\Framework\Normalizer\Model\NormalizableTrait; /** * Basic implementation on ApplicationInterface. */ class Application implements ApplicationInterface, CollectionableInterface { - use CollectionableTrait, SerializableTrait; + use CollectionableTrait, NormalizableTrait; /** * @var int @@ -225,9 +225,13 @@ public function getAccounts() /** * @param array $accounts + * + * @return self */ public function setAccounts($accounts) { $this->accounts = $accounts; + + return $this; } } diff --git a/src/Majora/Component/OAuth/Entity/RefreshToken.php b/src/Majora/Component/OAuth/Entity/RefreshToken.php index 85829b1..6f00a2e 100644 --- a/src/Majora/Component/OAuth/Entity/RefreshToken.php +++ b/src/Majora/Component/OAuth/Entity/RefreshToken.php @@ -5,14 +5,14 @@ use Majora\Component\OAuth\Model\RefreshTokenInterface; use Majora\Framework\Model\CollectionableInterface; use Majora\Framework\Model\CollectionableTrait; -use Majora\Framework\Serializer\Model\SerializableTrait; +use Majora\Framework\Normalizer\Model\NormalizableTrait; /** * Class RefreshToken is the default implementation of RefreshTokenInterface. */ class RefreshToken extends Token implements RefreshTokenInterface, CollectionableInterface { - use CollectionableTrait, SerializableTrait; + use CollectionableTrait, NormalizableTrait; /** * {@inheritdoc} diff --git a/src/Majora/Component/OAuth/Tests/Entity/AccessTokenTest.php b/src/Majora/Component/OAuth/Tests/Entity/AccessTokenTest.php new file mode 100644 index 0000000..41ea6e8 --- /dev/null +++ b/src/Majora/Component/OAuth/Tests/Entity/AccessTokenTest.php @@ -0,0 +1,74 @@ + + */ +class AccessTokenTest extends \PHPUnit_Framework_TestCase +{ + /** + * Test if the refresh token given in constructor is equals to returned by the getter. + */ + public function testConstructorRefreshToken() + { + $application = $this->prophesize(ApplicationInterface::class); + $application + ->getSecret() + ->willReturn('mock_secret') + ->shouldBeCalled(); + + $account = $this->prophesize(AccountInterface::class); + $account + ->getPassword() + ->willReturn('mock_password') + ->shouldBeCalled(); + + $refreshToken = $this->prophesize(RefreshTokenInterface::class); + + $token = new AccessToken( + $application->reveal(), + $account->reveal(), + 42, + null, + null, + $refreshToken->reveal() + ); + + $this->assertEquals($refreshToken->reveal(), $token->getRefreshToken()); + } + + /** + * Test getScopes() method. + */ + public function testScopes() + { + $application = $this->prophesize(ApplicationInterface::class); + $application + ->getSecret() + ->willReturn('mock_secret') + ->shouldBeCalled(); + + $account = $this->prophesize(AccountInterface::class); + $account + ->getPassword() + ->willReturn('mock_password') + ->shouldBeCalled(); + + $token = new AccessToken( + $application->reveal(), + $account->reveal() + ); + + $expectedScopes = [ + 'default' => ['id', 'hash', 'refresh_token', 'expire_in', 'application@id', 'account@id'], + ]; + $this->assertEquals($expectedScopes, $token->getScopes(), '', 0.0, 10, true); + } +} diff --git a/src/Majora/Component/OAuth/Tests/Entity/AccountTest.php b/src/Majora/Component/OAuth/Tests/Entity/AccountTest.php new file mode 100644 index 0000000..c5a6d08 --- /dev/null +++ b/src/Majora/Component/OAuth/Tests/Entity/AccountTest.php @@ -0,0 +1,79 @@ + + */ +class AccountTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Account + */ + protected $account; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->account = new Account(); + } + + /** + * Test getScopes() method. + */ + public function testScopes() + { + $expectedScopes = [ + 'id' => 'id', + 'default' => ['id', 'owner_id', 'username'], + ]; + $this->assertEquals($expectedScopes, $this->account->getScopes(), '', 0.0, 10, true); + } + + /** + * Test the ownerId property. + */ + public function testOwnerId() + { + $self = $this->account->setOwnerId(42); + $this->assertSame($this->account, $self); + $this->assertEquals(42, $this->account->getOwnerId()); + } + + /** + * Test the username property. + */ + public function testUsername() + { + $self = $this->account->setUsername('mocked_username'); + $this->assertSame($this->account, $self); + $this->assertEquals('mocked_username', $this->account->getUsername()); + } + + /** + * Test the password property. + */ + public function testPassword() + { + $self = $this->account->setPassword('mocked_password'); + $this->assertSame($this->account, $self); + $this->assertEquals('mocked_password', $this->account->getPassword()); + } + + public function testSalt() + { + $this->assertNotEmpty($this->account->getSalt()); + } + + public function testApplications() + { + $self = $this->account->setApplications([]); + $this->assertSame($this->account, $self); + $this->assertEquals([], $this->account->getApplications()); + } +} diff --git a/src/Majora/Component/OAuth/Tests/Entity/ApplicationTest.php b/src/Majora/Component/OAuth/Tests/Entity/ApplicationTest.php new file mode 100644 index 0000000..b2074fd --- /dev/null +++ b/src/Majora/Component/OAuth/Tests/Entity/ApplicationTest.php @@ -0,0 +1,107 @@ + + */ +class ApplicationTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Application + */ + protected $application; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->application = new Application(); + } + + /** + * Test getScopes() method. + */ + public function testScopes() + { + $expectedScopes = [ + 'id' => 'id', + 'default' => ['id', 'domain', 'allowed_scopes'], + ]; + $this->assertEquals($expectedScopes, $this->application->getScopes(), '', 0.0, 10, true); + } + + /** + * Test the apiKey property. + */ + public function testApiKey() + { + $self = $this->application->setApiKey('mocked_apikey'); + $this->assertSame($this->application, $self); + $this->assertEquals('mocked_apikey', $this->application->getApiKey()); + } + + /** + * Test the secret property. + */ + public function testSecret() + { + $self = $this->application->setSecret('mocked_secret'); + $this->assertSame($this->application, $self); + $this->assertEquals('mocked_secret', $this->application->getSecret()); + } + + /** + * Test the domain property. + */ + public function testDomain() + { + $self = $this->application->setDomain('mocked_domain'); + $this->assertSame($this->application, $self); + $this->assertEquals('mocked_domain', $this->application->getDomain()); + } + + /** + * Test the allowedScopes property. + */ + public function testAllowedScopes() + { + $self = $this->application->setAllowedScopes([]); + $this->assertSame($this->application, $self); + $this->assertEquals([], $this->application->getAllowedScopes()); + } + + /** + * Test the allowedGrantTypes property. + */ + public function testAllowedGrantTypes() + { + $self = $this->application->setAllowedGrantTypes([]); + $this->assertSame($this->application, $self); + $this->assertEquals([], $this->application->getAllowedGrantTypes()); + } + + /** + * Test roles property. + */ + public function testRoles() + { + $self = $this->application->setRoles([]); + $this->assertSame($this->application, $self); + $this->assertEquals([], $this->application->getRoles()); + } + + /** + * Test accounts property. + */ + public function testAccounts() + { + $self = $this->application->setAccounts([]); + $this->assertSame($this->application, $self); + $this->assertEquals([], $this->application->getAccounts()); + } +} diff --git a/src/Majora/Component/OAuth/Tests/Entity/TokenTest.php b/src/Majora/Component/OAuth/Tests/Entity/TokenTest.php new file mode 100644 index 0000000..fe81945 --- /dev/null +++ b/src/Majora/Component/OAuth/Tests/Entity/TokenTest.php @@ -0,0 +1,221 @@ +prophesize(ApplicationInterface::class); + $application + ->getSecret() + ->willReturn('mock_secret') + ->shouldBeCalled(); + + $account = $this->prophesize(AccountInterface::class); + $account + ->getPassword() + ->willReturn('mock_password') + ->shouldBeCalled(); + + $this->token = new MockedToken( + $this->application = $application->reveal(), + $this->account = $account->reveal(), + 42 + ); + } + + + /** + * Roles testing provider + */ + public function rolesProvider() + { + return [ + [ + ['ROLE_1', 'ROLE_3'], + ['ROLE_1', 'ROLE_2', 'ROLE_3'], + ['ROLE_1', 'ROLE_3'] + ], + [ + ['ROLE_1', 'ROLE_3'], + ['ROLE_1', 'ROLE_2'], + ['ROLE_1'] + ], + [ + ['ROLE_4', 'ROLE_3'], + ['ROLE_1', 'ROLE_2'], + [] + ], + [ + ['ROLE_1', 'ROLE_2', 'ROLE_3'], + ['ROLE_1', 'ROLE_2', 'ROLE_3'], + ['ROLE_1', 'ROLE_2', 'ROLE_3'] + ] + ]; + } + + /** + * Test the getRoles() method. + * + * @dataProvider rolesProvider + */ + public function testRoles(array $applicationRoles, array $accountRoles, array $expectedRoles) + { + $application = $this->prophesize(ApplicationInterface::class); + $application + ->getSecret() + ->shouldBeCalled(); + $application + ->getRoles() + ->willReturn($applicationRoles) + ->shouldBeCalled(); + + $account = $this->prophesize(AccountInterface::class); + $account + ->getPassword() + ->shouldBeCalled(); + $account + ->getRoles() + ->willReturn($accountRoles) + ->shouldBeCalled(); + + $token = new MockedToken( + $application->reveal(), + $account->reveal(), + 42 + ); + + $this->assertEquals($expectedRoles, $token->getRoles(), '', 0.0, 10, true); + } + + /** + * Test the expiration datetime is the datetime when the token expires in. + */ + public function testExpireAt() + { + ClockMock::withClockMock(true); + + $application = $this->prophesize(ApplicationInterface::class); + $application + ->getSecret() + ->willReturn('mock_secret') + ->shouldBeCalled(); + + $account = $this->prophesize(AccountInterface::class); + $account + ->getPassword() + ->willReturn('mock_password') + ->shouldBeCalled(); + + $this->token = new MockedToken( + $application->reveal(), + $account->reveal(), + 42 + ); + + $this->assertEquals(\DateTime::createFromFormat('U', time() + intval(42)), $this->token->getExpireAt()); + } + + /** + * Test if the expiration datetime given in constructor is equals to returned by the getter. + */ + public function testConstructorExpireAt() + { + $application = $this->prophesize(ApplicationInterface::class); + $application + ->getSecret() + ->willReturn('mock_secret') + ->shouldBeCalled(); + + $account = $this->prophesize(AccountInterface::class); + $account + ->getPassword() + ->willReturn('mock_password') + ->shouldBeCalled(); + + $this->token = new MockedToken( + $application->reveal(), + $account->reveal(), + 42, + $expectedExpireAt = \DateTime::createFromFormat('U', time() + intval(42)) + ); + + $this->assertEquals($expectedExpireAt, $this->token->getExpireAt()); + } + + /** + * Test if the account given in constructor is equals to returned by the getter. + */ + public function testConstructorAccount() + { + $this->assertEquals($this->account, $this->token->getAccount()); + } + + /** + * Test if the application given in constructor is equals to returned by the getter. + */ + public function testConstructorApplication() + { + $this->assertEquals($this->application, $this->token->getApplication()); + } + + /** + * Test if the expiration seconds given in constructor is equals to returned by the getter. + */ + public function testConstructorExpireIn() + { + $this->assertEquals(42, $this->token->getExpireIn()); + } + + /** + * Test if the hash given in constructor is equals to returned by the getter. + */ + public function testConstructorHash() + { + $application = $this->prophesize(ApplicationInterface::class); + $account = $this->prophesize(AccountInterface::class); + + $this->token = new MockedToken( + $application->reveal(), + $account->reveal(), + 42, + null, + 'mocked_hash' + ); + + $this->assertEquals('mocked_hash', $this->token->getHash()); + $this->assertEquals('mocked_hash', (string)$this->token); + } +} + +class MockedToken extends Token +{ +}