Skip to content

Commit

Permalink
Allow time to be set for test purposes (#852)
Browse files Browse the repository at this point in the history
This just adds a static method for test purposes so that downstream code
can more easily assert an exact `AccessToken` object in their tests.

Since the calls to `time()` are non-deterministic, downstream tests are
forced to mock, or do looser assertions on the `expires` property.

Co-authored-by: Ben Ramsey <ben@benramsey.com>
  • Loading branch information
kevinquinnyo and ramsey authored Oct 28, 2020
1 parent 937c0ac commit 2392bf7
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 2 deletions.
38 changes: 36 additions & 2 deletions src/Token/AccessToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,40 @@ class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInter
*/
protected $values = [];

/**
* @var int
*/
private static $timeNow;

/**
* Set the time now. This should only be used for testing purposes.
*
* @param int $timeNow the time in seconds since epoch
* @return void
*/
public static function setTimeNow($timeNow)
{
self::$timeNow = $timeNow;
}

/**
* Reset the time now if it was set for test purposes.
*
* @return void
*/
public static function resetTimeNow()
{
self::$timeNow = null;
}

/**
* @return int
*/
public function getTimeNow()
{
return self::$timeNow ? self::$timeNow : time();
}

/**
* Constructs an access token.
*
Expand Down Expand Up @@ -80,14 +114,14 @@ public function __construct(array $options = [])
throw new \InvalidArgumentException('expires_in value must be an integer');
}

$this->expires = $options['expires_in'] != 0 ? time() + $options['expires_in'] : 0;
$this->expires = $options['expires_in'] != 0 ? $this->getTimeNow() + $options['expires_in'] : 0;
} elseif (!empty($options['expires'])) {
// Some providers supply the seconds until expiration rather than
// the exact timestamp. Take a best guess at which we received.
$expires = $options['expires'];

if (!$this->isExpirationTimestamp($expires)) {
$expires += time();
$expires += $this->getTimeNow();
}

$this->expires = $expires;
Expand Down
75 changes: 75 additions & 0 deletions test/src/Token/AccessTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,27 @@

class AccessTokenTest extends TestCase
{
/**
* BC teardown.
*
* This is for backwards compatibility of older PHP versions. Ideally we would just implement a tearDown() here but
* older PHP versions this library supports don't have return typehint support, so this is the workaround.
*
* @return void
*/
private static function tearDownForBackwardsCompatibility()
{
/* reset the test double time if it was set */
AccessToken::resetTimeNow();
}

public function testInvalidRefreshToken()
{
$this->expectException(InvalidArgumentException::class);

$token = $this->getAccessToken(['invalid_access_token' => 'none']);

self::tearDownForBackwardsCompatibility();
}

protected function getAccessToken($options = [])
Expand All @@ -32,6 +48,49 @@ public function testExpiresInCorrection()
$this->assertNotNull($expires);
$this->assertGreaterThan(time(), $expires);
$this->assertLessThan(time() + 200, $expires);

self::tearDownForBackwardsCompatibility();
}

public function testExpiresInCorrectionUsingSetTimeNow()
{
/* set fake time at 2020-01-01 00:00:00 */
AccessToken::setTimeNow(1577836800);
$options = ['access_token' => 'access_token', 'expires_in' => 100];
$token = $this->getAccessToken($options);

$expires = $token->getExpires();

$this->assertNotNull($expires);
$this->assertEquals(1577836900, $expires);

self::tearDownForBackwardsCompatibility();
}

public function testSetTimeNow()
{
AccessToken::setTimeNow(1577836800);
$timeNow = $this->getAccessToken(['access_token' => 'asdf'])->getTimeNow();

$this->assertEquals(1577836800, $timeNow);

self::tearDownForBackwardsCompatibility();
}

public function testResetTimeNow()
{
AccessToken::setTimeNow(1577836800);
$token = $this->getAccessToken(['access_token' => 'asdf']);

$this->assertEquals(1577836800, $token->getTimeNow());
AccessToken::resetTimeNow();

$this->assertNotEquals(1577836800, $token->getTimeNow());

$timeBeforeAssertion = time();
$this->assertGreaterThanOrEqual($timeBeforeAssertion, $token->getTimeNow());

self::tearDownForBackwardsCompatibility();
}

public function testExpiresPastTimestamp()
Expand All @@ -45,6 +104,8 @@ public function testExpiresPastTimestamp()
$token = $this->getAccessToken($options);

$this->assertFalse($token->hasExpired());

self::tearDownForBackwardsCompatibility();
}

public function testGetRefreshToken()
Expand All @@ -58,6 +119,8 @@ public function testGetRefreshToken()
$refreshToken = $token->getRefreshToken();

$this->assertEquals($options['refresh_token'], $refreshToken);

self::tearDownForBackwardsCompatibility();
}

public function testHasNotExpiredWhenPropertySetInFuture()
Expand All @@ -75,6 +138,8 @@ public function testHasNotExpiredWhenPropertySetInFuture()
->andReturn($expectedExpires);

$this->assertFalse($token->hasExpired());

self::tearDownForBackwardsCompatibility();
}

public function testHasExpiredWhenPropertySetInPast()
Expand All @@ -92,6 +157,8 @@ public function testHasExpiredWhenPropertySetInPast()
->andReturn($expectedExpires);

$this->assertTrue($token->hasExpired());

self::tearDownForBackwardsCompatibility();
}

public function testCannotReportExpiredWhenNoExpirationSet()
Expand All @@ -104,6 +171,8 @@ public function testCannotReportExpiredWhenNoExpirationSet()
$this->expectException(RuntimeException::class);

$hasExpired = $token->hasExpired();

self::tearDownForBackwardsCompatibility();
}

public function testInvalidExpiresIn()
Expand All @@ -116,6 +185,8 @@ public function testInvalidExpiresIn()
$this->expectException(InvalidArgumentException::class);

$token = $this->getAccessToken($options);

self::tearDownForBackwardsCompatibility();
}


Expand All @@ -132,6 +203,8 @@ public function testJsonSerializable()
$jsonToken = json_encode($token);

$this->assertEquals($options, json_decode($jsonToken, true));

self::tearDownForBackwardsCompatibility();
}

public function testValues()
Expand All @@ -151,5 +224,7 @@ public function testValues()
$this->assertTrue(is_array($values));
$this->assertArrayHasKey('custom_thing', $values);
$this->assertSame($options['custom_thing'], $values['custom_thing']);

self::tearDownForBackwardsCompatibility();
}
}

0 comments on commit 2392bf7

Please sign in to comment.