Skip to content

Commit

Permalink
Rework some tests, still missing significant coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
adamwathan committed Dec 27, 2014
1 parent 383c0f4 commit 9b28d0f
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 150 deletions.
48 changes: 9 additions & 39 deletions src/AdamWathan/EloquentOAuth/Authenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,32 @@
class Authenticator
{
protected $auth;
protected $stateManager;
protected $users;
protected $identities;

public function __construct(Auth $auth, StateManager $stateManager, UserStore $users, IdentityStore $identities)
public function __construct(Auth $auth, UserStore $users, IdentityStore $identities)
{
$this->auth = $auth;
$this->stateManager = $stateManager;
$this->users = $users;
$this->identities = $identities;
}

public function login($providerAlias, $provider, Closure $callback = null)
public function login($providerAlias, $userDetails, Closure $callback = null)
{
$this->verifyState();
$details = $provider->getUserDetails();
$user = $this->getUser($providerAlias, $details);
$user = $this->getUser($providerAlias, $userDetails);
if ($callback) {
$callback($user, $details);
$callback($user, $userDetails);
}
$this->updateUser($user, $provider, $details);
$this->updateUser($user, $providerAlias, $userDetails);
$this->auth->login($user);
return $user;
}

protected function verifyState()
{
if (! $this->stateManager->verifyState()) {
throw new InvalidAuthorizationCodeException;
}
}

protected function getUser($provider, $details)
{
if ($this->userExists($provider, $details)) {
$user = $this->getExistingUser($provider, $details);
} else {
$user = $this->createUser();
if ($this->identities->userExists($provider, $details)) {
return $this->getExistingUser($provider, $details);
}
return $user;
return $this->users->create();
}

protected function updateUser($user, $provider, $details)
Expand All @@ -57,28 +43,12 @@ protected function updateUser($user, $provider, $details)
$this->updateAccessToken($user, $provider, $details);
}

protected function userExists($provider, ProviderUserDetails $details)
{
return $this->identities->userExists($provider, $details);
}

protected function getExistingUser($provider, $details)
{
$identity = $this->getIdentity($provider, $details);
$identity = $this->identities->getByProvider($provider, $details);
return $this->users->findByIdentity($identity);
}

protected function getIdentity($provider, ProviderUserDetails $details)
{
return $this->identities->getByProvider($provider, $details);
}

protected function createUser()
{
$user = $this->users->create();
return $user;
}

protected function updateAccessToken($user, $provider, ProviderUserDetails $details)
{
$this->flushAccessTokens($user, $provider);
Expand Down
12 changes: 2 additions & 10 deletions src/AdamWathan/EloquentOAuth/Authorizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,14 @@
class Authorizer
{
protected $redirect;
protected $stateManager;

public function __construct(Redirect $redirect, StateManager $stateManager)
public function __construct(Redirect $redirect)
{
$this->redirect = $redirect;
$this->stateManager = $stateManager;
}

public function authorize(ProviderInterface $provider)
public function authorize(ProviderInterface $provider, $state)
{
$state = $this->generateState();
return $this->redirect->to($provider->authorizeUrl($state));
}

protected function generateState()
{
return $this->stateManager->generateState();
}
}
6 changes: 3 additions & 3 deletions src/AdamWathan/EloquentOAuth/EloquentOAuthServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ protected function registerOAuthManager()
$this->configureOAuthIdentitiesTable();
$users = new UserStore($app['config']['auth.model']);
$stateManager = new StateManager($app['session.store'], $app['request']);
$authorizer = new Authorizer($app['redirect'], $stateManager);
$authenticator = new Authenticator($app['auth'], $stateManager, $users, new IdentityStore);
$oauth = new OAuthManager($authorizer, new ProviderRegistrar, $authenticator);
$authorizer = new Authorizer($app['redirect']);
$authenticator = new Authenticator($app['auth'], $users, new IdentityStore);
$oauth = new OAuthManager($authorizer, $authenticator, $stateManager, new ProviderRegistrar);
$this->registerProviders($oauth);
return $oauth;
});
Expand Down
17 changes: 12 additions & 5 deletions src/AdamWathan/EloquentOAuth/OAuthManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
class OAuthManager
{
protected $authorizer;
protected $providers;
protected $authenticator;
protected $stateManager;
protected $providers;

public function __construct(Authorizer $authorizer, ProviderRegistrar $providers, Authenticator $authenticator)
public function __construct(Authorizer $authorizer, Authenticator $authenticator, StateManager $stateManager, ProviderRegistrar $providers)
{
$this->authorizer = $authorizer;
$this->providers = $providers;
$this->authenticator = $authenticator;
$this->stateManager = $stateManager;
$this->providers = $providers;
}

public function registerProvider($alias, ProviderInterface $provider)
Expand All @@ -26,12 +28,17 @@ public function registerProvider($alias, ProviderInterface $provider)

public function authorize($providerAlias)
{
return $this->authorizer->authorize($this->getProvider($providerAlias));
$state = $this->stateManager->generateState();
return $this->authorizer->authorize($this->getProvider($providerAlias), $state);
}

public function login($providerAlias, Closure $callback = null)
{
return $this->authenticator->login($providerAlias, $this->getProvider($providerAlias), $callback);
if (! $this->stateManager->verifyState()) {
throw new InvalidAuthorizationCodeException;
}
$details = $this->getProvider($providerAlias)->getUserDetails();
return $this->authenticator->login($providerAlias, $details, $callback);
}

protected function getProvider($providerAlias)
Expand Down
53 changes: 53 additions & 0 deletions tests/AuthenticatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

use Mockery as M;
use AdamWathan\EloquentOAuth\Authenticator;

class AuthenticatorTest extends PHPUnit_Framework_TestCase
{
public function tearDown()
{
M::close();
}

public function test_login_creates_new_user_if_no_matching_user_exists()
{
$auth = M::mock('Illuminate\\Auth\\AuthManager');
$users = M::mock('AdamWathan\\EloquentOAuth\\UserStore');
$identities = M::mock('AdamWathan\\EloquentOAuth\\IdentityStore')->shouldIgnoreMissing();

$userDetails = M::mock('AdamWathan\\EloquentOAuth\\ProviderUserDetails');

$user = M::mock('stdClass')->shouldIgnoreMissing();

$authenticator = new Authenticator($auth, $users, $identities);

$users->shouldReceive('create')->andReturn($user);
$users->shouldReceive('store')->once();
$auth->shouldReceive('login')->with($user)->once();

$authenticator->login('provider', $userDetails);
}

public function test_login_uses_existing_user_if_matching_user_exists()
{
$auth = M::mock('Illuminate\\Auth\\AuthManager');
$users = M::mock('AdamWathan\\EloquentOAuth\\UserStore')->shouldIgnoreMissing();
$identities = M::mock('AdamWathan\\EloquentOAuth\\IdentityStore')->shouldIgnoreMissing();

$userDetails = M::mock('AdamWathan\\EloquentOAuth\\ProviderUserDetails');
$identity = M::mock('AdamWathan\\EloquentOAuth\\OAuthIdentity');

$user = M::mock('stdClass')->shouldIgnoreMissing();

$authenticator = new Authenticator($auth, $users, $identities);

$identities->shouldReceive('userExists')->andReturn(true);
$identities->shouldReceive('getByProvider')->andReturn($identity);
$users->shouldReceive('create')->never();
$users->shouldReceive('findByIdentity')->andReturn($user);
$auth->shouldReceive('login')->with($user)->once();

$authenticator->login('provider', $userDetails);
}
}
14 changes: 14 additions & 0 deletions tests/AuthorizerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

use Mockery as M;
use AdamWathan\EloquentOAuth\Authorizer;

class AuthorizerTest extends PHPUnit_Framework_TestCase
{
public function tearDown()
{
M::close();
}

public function test_placeholder() {}
}
42 changes: 42 additions & 0 deletions tests/IdentityStoreTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,46 @@ public function test_store()

$this->assertEquals(1, OAuthIdentity::count());
}

public function test_user_exists_returns_true_when_user_exists()
{
OAuthIdentity::create(array(
'user_id' => 2,
'provider' => 'facebook',
'provider_user_id' => 'bazfoo',
'access_token' => 'def456',
));
$details = new ProviderUserDetails(array(
'accessToken' => 'new-token',
'userId' => 'bazfoo',
'nickname' => 'john.doe',
'firstName' => 'John',
'lastName' => 'Doe',
'email' => '[email protected]',
'imageUrl' => 'http://example.com/photos/john_doe.jpg',
));
$identities = new IdentityStore;
$this->assertTrue($identities->userExists('facebook', $details));
}

public function test_user_exists_returns_false_when_user_doesnt_exist()
{
OAuthIdentity::create(array(
'user_id' => 2,
'provider' => 'facebook',
'provider_user_id' => 'foobar',
'access_token' => 'def456',
));
$details = new ProviderUserDetails(array(
'accessToken' => 'new-token',
'userId' => 'bazfoo',
'nickname' => 'john.doe',
'firstName' => 'John',
'lastName' => 'Doe',
'email' => '[email protected]',
'imageUrl' => 'http://example.com/photos/john_doe.jpg',
));
$identities = new IdentityStore;
$this->assertFalse($identities->userExists('facebook', $details));
}
}
94 changes: 1 addition & 93 deletions tests/OAuthManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,97 +10,5 @@ public function tearDown()
M::close();
}

public function test_authorize_returns_correct_redirect_when_provider_is_registered()
{
$auth = M::mock('Illuminate\\Auth\\AuthManager')->shouldIgnoreMissing();
$redirector = M::mock('Illuminate\\Routing\\Redirector')->shouldIgnoreMissing();
$stateManager = M::mock('AdamWathan\\EloquentOAuth\\StateManager')->shouldIgnoreMissing();
$users = M::mock('AdamWathan\\EloquentOAuth\\UserStore')->shouldIgnoreMissing();
$identities = M::mock('AdamWathan\\EloquentOAuth\\IdentityStore')->shouldIgnoreMissing();

$oauth = new OAuthManager($auth, $redirector, $stateManager, $users, $identities);

$redirectResponse = M::mock('Illuminate\\Http\\RedirectResponse');
$redirectUrl = 'http://example.com/authorize';
$provider = M::mock('AdamWathan\\EloquentOAuth\\Providers\\ProviderInterface');
$provider->shouldReceive('authorizeUrl')->andReturn($redirectUrl);
$redirector->shouldReceive('to')->with($redirectUrl)->andReturn($redirectResponse);

$oauth->registerProvider('provider', $provider);

$result = $oauth->authorize('provider');
$expected = $redirectResponse;

$this->assertEquals($expected, $result);
}

/**
* @expectedException AdamWathan\EloquentOAuth\Exceptions\ProviderNotRegisteredException
*/
public function test_authorize_throws_exception_when_provider_is_not_registered()
{
$auth = M::mock('Illuminate\\Auth\\AuthManager')->shouldIgnoreMissing();
$redirector = M::mock('Illuminate\\Routing\\Redirector')->shouldIgnoreMissing();
$stateManager = M::mock('AdamWathan\\EloquentOAuth\\StateManager')->shouldIgnoreMissing();
$users = M::mock('AdamWathan\\EloquentOAuth\\UserStore')->shouldIgnoreMissing();
$identities = M::mock('AdamWathan\\EloquentOAuth\\IdentityStore')->shouldIgnoreMissing();

$oauth = new OAuthManager($auth, $redirector, $stateManager, $users, $identities);

$result = $oauth->authorize('missingProvider');
}

public function test_login_creates_new_user_if_no_matching_user_exists()
{
$auth = M::mock('Illuminate\\Auth\\AuthManager');
$redirector = M::mock('Illuminate\\Routing\\Redirector');
$stateManager = M::mock('AdamWathan\\EloquentOAuth\\StateManager')->shouldIgnoreMissing();
$users = M::mock('AdamWathan\\EloquentOAuth\\UserStore');
$identities = M::mock('AdamWathan\\EloquentOAuth\\IdentityStore')->shouldIgnoreMissing();

$provider = M::mock('AdamWathan\\EloquentOAuth\\Providers\\ProviderInterface');
$userDetails = M::mock('AdamWathan\\EloquentOAuth\\ProviderUserDetails');

$user = M::mock('stdClass')->shouldIgnoreMissing();

$oauth = new OAuthManager($auth, $redirector, $stateManager, $users, $identities);
$oauth->registerProvider('provider', $provider);

$stateManager->shouldReceive('verifyState')->andReturn(true);
$provider->shouldReceive('getUserDetails')->andReturn($userDetails);
$users->shouldReceive('create')->andReturn($user);
$users->shouldReceive('store')->andReturn(true);

$auth->shouldReceive('login')->with($user)->once();
$result = $oauth->login('provider');
}

public function test_login_uses_existing_user_if_matching_user_exists()
{
$auth = M::mock('Illuminate\\Auth\\AuthManager');
$redirector = M::mock('Illuminate\\Routing\\Redirector');
$stateManager = M::mock('AdamWathan\\EloquentOAuth\\StateManager')->shouldIgnoreMissing();
$users = M::mock('AdamWathan\\EloquentOAuth\\UserStore');
$identities = M::mock('AdamWathan\\EloquentOAuth\\IdentityStore')->shouldIgnoreMissing();

$provider = M::mock('AdamWathan\\EloquentOAuth\\Providers\\ProviderInterface');
$freshUserDetails = M::mock('AdamWathan\\EloquentOAuth\\ProviderUserDetails');
$existingUserDetails = M::mock('AdamWathan\\EloquentOAuth\\ProviderUserDetails');

$user = M::mock('stdClass')->shouldIgnoreMissing();

$oauth = new OAuthManager($auth, $redirector, $stateManager, $users, $identities);
$oauth->registerProvider('provider', $provider);

$stateManager->shouldReceive('verifyState')->andReturn(true);
$provider->shouldReceive('getUserDetails')->andReturn($freshUserDetails);
$identities->shouldReceive('userExists')->with('provider', $freshUserDetails)->andReturn(true);
$identities->shouldReceive('getByProvider')->with('provider', $freshUserDetails)->andReturn($existingUserDetails);
$users->shouldReceive('create')->never();
$users->shouldReceive('findByIdentity')->once()->andReturn($user);
$users->shouldReceive('store')->andReturn(true);

$auth->shouldReceive('login')->with($user)->once();
$result = $oauth->login('provider');
}
public function test_placeholder() {}
}

0 comments on commit 9b28d0f

Please sign in to comment.