Auth::attempt always fails in tests
Hello!
I've written a test that ensures that the registration and authentication both work. However, when I try to login in the tests, it always returns false even though I can var_dump the user that has been added in the step before.
My code:
/**
* @When I register :name :username
* @param $name
* @param $username
*/
public function iRegister($name, $username)
{
$password = bcrypt('password');
(new Registrar)->create(compact('name', 'username', 'password'));
}
/**
* @Then I should have an account
*/
public function iShouldHaveAnAccount()
{
$user = User::find(1);
PHPUnit::assertEquals('John', $user->name);
}
/**
* @Given I have an account :name :email
*/
public function iHaveAnAccount($name, $username)
{
// registers a new user since I'm using in memory DB for tests
$this->iRegister($name, $username);
}
/**
* @When I sign in
*/
public function iSignIn()
{
// this function fakes a call to the controller method, it for some reason also doesn't work as I'm being
// redirected back to the login page instead of the successful authentication page.
// Even if I try to manually do Auth::attempt() here without faking the call, it still returns false.
$data = [
'username' => 'johny',
'password' => 'password',
];
$this->call('POST', 'auth/login', $data);
}
/**
* @Then I should be logged in
*/
public function iShouldBeLoggedIn()
{
// always evaluates to false
PHPUnit::assertTrue(Auth::check());
}
Basically, the call method is taken from TestCase:
private function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
{
$request = Request::create($uri, $method, $parameters, $cookies, $files, $server, $content);
return $this->response = app()->make('Illuminate\Contracts\Http\Kernel')->handle($request);
}
The call methods eventually triggers the postLogin method on the controller:
public function postLogin(Request $request)
{
$this->validate($request, [
'username' => 'required', 'password' => 'required',
]);
$credentials = $request->only('username', 'password');
if ($this->auth->attempt($credentials, $request->has('remember')))
{
return redirect()->intended($this->redirectPath());
}
return redirect('/auth/login')
->withInput($request->only('username'))
->withErrors([
'username' => 'Some message',
]);
}
When I try to dd() the arguments I do get the right arguments in the function. However, when it tries to login the user, it always fails. I've also manually tried to run Auth::attempt() from my tests and still, it fails.
I've changed the default postLogin() method a little bit to check against username and password instead of email and password, I don't believe it should be a reason.
By the way, I've taken care of the CSRF mismatch token exception by adding a middleware before the VerifyCsrfToken:
public function handle($request, Closure $next)
{
if ( 'testing' === $this->app->environment() ) {
$input = $request->all();
$input['_token'] = $request->session()->token();
// we need to update _token value to make sure we get the POST / PUT tests passed.
$request->replace( $input );
}
return $next($request);
}
Any clue why is it happening?
P.S. I've eliminated the possibility that it is because of an in memory DB. I've tried the same code with a simple sqlite3 database and still got the same false result even tho I could view the user in the DB.
P.P.S When I add the user to DB other than my testing one and trying to login using the application UI it works just as expected, no issues there.
Please or to participate in this conversation.