How to mock LDAP Laravel auth for unit testing -
in laravel project use ldap-connector
package authenticate users against ldap
auth works fine out of box.
in /app/providers/authserviceprovider.php have policy defined manage ldap user access, example:
public function boot(gatecontract $gate) { $this->registerpolicies($gate); $gate->define('rewards', function ($user) { return ($user->getadldap()->ingroup('admin') || $user->getadldap()->ingroup('marketing')) ? true : false; }); // other policies // ... }
in controller check policy logged in user like:
class rewardcontroller extends controller { public function __construct($handler = null) { $this->authorize('rewards'); } // other methods // ... }
everything works fine , if logged in user doesn't have marketing
or admin
group, controller throw 403
exception.
now, phpunit
tests need mock ldap auth , provide access controller tests it's methods, otherwise policy throws me this action unauthorized.
error
since ldap auth driver implemented don't think user model app/user
used , can't have done $this->actingas($user)
laravel docs here
i able find solution myself
i switched ldap
connection package adldap2/adldap2-laravel
i used existing unit tests , created own auth admin
group user:
<?php use adldap\auth\guard; use adldap\connections\manager; use adldap\connections\provider; use adldap\contracts\connections\connectioninterface; use adldap\laravel\facades\adldap; use adldap\models\user; use adldap\query\builder; use adldap\schemas\schema; use adldap\search\factory; use illuminate\support\facades\auth; use adldap\models\group; class testcase extends illuminate\foundation\testing\testcase { public function pass_auth() { $mockedprovider = $this->mock(provider::class); $mockedbuilder = $this->mock(builder::class); $mockedsearch = $this->mock(factory::class); $mockedauth = $this->mock(guard::class); $mockedconnection = $this->mock(connectioninterface::class); $mockedconnection->shouldreceive('isbound')->once()->andreturn(true); $mockedbuilder->shouldreceive('getschema')->once()->andreturn(schema::get()); $mockedbuilder->shouldreceive('getconnection')->once()->andreturn($mockedconnection); $aduser = (new user([], $mockedbuilder))->setrawattributes([ 'samaccountname' => ['jdoe'], 'mail' => ['jdoe@email.com'], 'cn' => ['john doe'], ]); $manager = new manager(); $manager->add('default', $mockedprovider); adldap::shouldreceive('getmanager')->andreturn($manager); $mockedprovider->shouldreceive('search')->once()->andreturn($mockedsearch); $mockedprovider->shouldreceive('getschema')->andreturn(schema::get()); $mockedprovider->shouldreceive('auth')->once()->andreturn($mockedauth); $mockedsearch->shouldreceive('users')->once()->andreturn($mockedsearch); $mockedsearch->shouldreceive('select')->once()->andreturn($mockedbuilder); $mockedbuilder->shouldreceive('whereequals')->once()->andreturn($mockedbuilder); $mockedbuilder->shouldreceive('first')->once()->andreturn($aduser); $mockedauth->shouldreceive('attempt')->once()->andreturn(true); $this->asserttrue(auth::attempt(['username' => 'jdoe', 'password' => '12345'])); $mockedgroup = $this->mock(group::class); $mockedgroup->shouldreceive('getname')->once()->andreturn('admin'); $mockedbuilder->shouldreceive('newinstance')->andreturnself(); $mockedbuilder->shouldreceive('newcollection')->andreturn([$mockedgroup]); } }
this part adds admin
group user
mock
$mockedgroup = $this->mock(group::class); $mockedgroup->shouldreceive('getname')->once()->andreturn('admin'); $mockedbuilder->shouldreceive('newinstance')->andreturnself(); $mockedbuilder->shouldreceive('newcollection')->andreturn([$mockedgroup]);
Comments
Post a Comment