From c6bbb207b4512ee1cb11a53019dad697d592d0c0 Mon Sep 17 00:00:00 2001 From: Ronald Drenth Date: Sat, 7 Jul 2018 15:53:16 +0200 Subject: [PATCH] Improve file token storage and add tests --- composer.json | 7 +- phpunit.xml.dist | 18 +++ src/ApiAccessToken.php | 9 +- src/TokenStorage/FileTokenStorage.php | 12 +- tests/TokenStorage/FileTokenStorageTest.php | 118 ++++++++++++++++++++ 5 files changed, 156 insertions(+), 8 deletions(-) create mode 100644 phpunit.xml.dist create mode 100644 tests/TokenStorage/FileTokenStorageTest.php diff --git a/composer.json b/composer.json index 1c08c87..66e222e 100644 --- a/composer.json +++ b/composer.json @@ -19,8 +19,9 @@ "guzzlehttp/guzzle": "^6.3" }, "require-dev": { - "phpunit/phpunit": "^6.3", - "illuminate/support": "5.6.*" + "illuminate/support": "5.6.*", + "mikey179/vfsStream": "^1.6", + "phpunit/phpunit": "^7.0" }, "config": { "preferred-install": "dist", @@ -40,7 +41,7 @@ }, "autoload-dev": { "psr-4": { - "Tests\\": "tests/" + "AdrenthTests\\Raindrop\\": "tests/" } } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..3e03a5b --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,18 @@ + + + + + + + src/ + tests/ + + + + diff --git a/src/ApiAccessToken.php b/src/ApiAccessToken.php index 6fe7cd6..f27d306 100644 --- a/src/ApiAccessToken.php +++ b/src/ApiAccessToken.php @@ -11,6 +11,8 @@ */ class ApiAccessToken { + public const EXPIRE_OFFSET = 60; + /** * @var string */ @@ -37,8 +39,11 @@ public function __construct(string $token, int $expiresIn) * @param int $expireOffset * @return ApiAccessToken */ - public static function create(string $token, int $expiresIn, int $expireOffset = 60): ApiAccessToken - { + public static function create( + string $token, + int $expiresIn, + int $expireOffset = self::EXPIRE_OFFSET + ): ApiAccessToken { return new self( $token, $expiresIn - $expireOffset diff --git a/src/TokenStorage/FileTokenStorage.php b/src/TokenStorage/FileTokenStorage.php index 3672182..af37a23 100644 --- a/src/TokenStorage/FileTokenStorage.php +++ b/src/TokenStorage/FileTokenStorage.php @@ -31,11 +31,15 @@ public function __construct(string $filename) */ public function getAccessToken(): ?ApiAccessToken { + if (!is_readable($this->filename)) { + return null; + } + $data = file_get_contents($this->filename); - if (!empty($data)) { + if (!empty($data) && substr_count($data, '|') === 1) { $data = explode('|', $data); - return new ApiAccessToken($data[0] ?? '', (int) ($data[1] ?? 0)); + return ApiAccessToken::create($data[0] ?? '', (int) ($data[1] ?? 0)); } return null; @@ -54,6 +58,8 @@ public function setAccessToken(ApiAccessToken $token): void */ public function unsetAccessToken(): void { - unlink($this->filename); + if (file_exists($this->filename)) { + unlink($this->filename); + } } } diff --git a/tests/TokenStorage/FileTokenStorageTest.php b/tests/TokenStorage/FileTokenStorageTest.php new file mode 100644 index 0000000..a653697 --- /dev/null +++ b/tests/TokenStorage/FileTokenStorageTest.php @@ -0,0 +1,118 @@ +root = vfsStream::setup(); + } + + /** + * @test + */ + public function itShouldReturnNullWhenFileDoesNotExist(): void + { + $storage = new FileTokenStorage(vfsStream::url('root/token.txt')); + + self::assertNull($storage->getAccessToken()); + } + + /** + * @test + */ + public function itShouldReturnNullWhenFileIsEmpty(): void + { + $this->root->addChild((new vfsStreamFile('token.txt'))->withContent('')); + + $storage = new FileTokenStorage(vfsStream::url('root/token.txt')); + + self::assertNull($storage->getAccessToken()); + } + + /** + * @test + */ + public function itShouldReturnNullWhenFileIsInvalid(): void + { + $this->root->addChild((new vfsStreamFile('token.txt'))->withContent('invalid_contents')); + + $storage = new FileTokenStorage(vfsStream::url('root/token.txt')); + + self::assertNull($storage->getAccessToken()); + } + + /** + * @test + */ + public function itShouldReturnAnAccessToken(): void + { + $token = 'access_token'; + $expiresIn = 3600; + + $this->root->addChild((new vfsStreamFile('token.txt'))->withContent("$token|$expiresIn")); + + $storage = new FileTokenStorage(vfsStream::url('root/token.txt')); + $accessToken = $storage->getAccessToken(); + + self::assertNotNull($accessToken); + self::assertEquals($token, $accessToken->getToken()); + self::assertEquals($expiresIn - ApiAccessToken::EXPIRE_OFFSET, $accessToken->getExpiresIn()); + } + + /** + * @test + */ + public function itShouldCreateAnFileWhenSettingTheAccessToken(): void + { + $token = 'access_token'; + $expiresIn = 3600; + + $storage = new FileTokenStorage(vfsStream::url('root/token.txt')); + $storage->setAccessToken(ApiAccessToken::create($token, $expiresIn)); + + self::assertTrue($this->root->hasChild('root/token.txt')); + + /** @var vfsStreamFile $child */ + $child = $this->root->getChild('root/token.txt'); + self::assertEquals($token . '|' . ($expiresIn - ApiAccessToken::EXPIRE_OFFSET), $child->getContent()); + } + + /** + * @test + */ + public function itShouldDeleteTheFileWhenUnsettingTheAccessToken(): void + { + $storage = new FileTokenStorage(vfsStream::url('root/token.txt')); + $storage->setAccessToken(ApiAccessToken::create('token', 3600)); + + self::assertTrue($this->root->hasChild('root/token.txt')); + + $storage->unsetAccessToken(); + + self::assertFalse($this->root->hasChild('root/token.txt')); + } +}