haakym's avatar

Log in a user test, failed login redirects to `/` instead of back to `/login`?

I've written the following test to check incorrect credentials do not log a user in.

/** @test */
public function logging_in_with_invalid_credentials()
{
    $user = factory(User::class)->states('verified')->create([
        'email' => '[email protected]',
        'password' => bcrypt('123456'),
    ]);

    $response = $this->post('/login', [
        'email' => '[email protected]',
        'password' => 'wrong-password',
    ]);

    $response->assertRedirect('/login');
}

However, when running the test it fails because it redirects to home / instead of back to /login.

PHPUnit 6.4.3 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

Time: 761 ms, Memory: 18.00MB

There was 1 failure:

1) Tests\Feature\LoginTest::logging_in_with_invalid_credentials
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'http://localhost/login'
+'http://localhost'

C:\laragon\www\attestation\vendor\laravel\framework\src\Illuminate\Foundation\Testing\TestResponse.php:96
C:\laragon\www\attestation\tests\Feature\Auth\LoginTest.php:55

Any idea why this is happening? When I run the code through my browser it works as expected which I find odd.

When looking at the ValidationException which is handled by the exception handler and the invalid() method on the Illuminate\Foundation\Exceptions\Handler class which decides the URL, url()->previous() returns http://localhost.

protected function invalid($request, ValidationException $exception)
{
    $url = $exception->redirectTo ?? url()->previous();

    return redirect($url)
            ->withInput($request->except($this->dontFlash))
            ->withErrors(
                $exception->errors(),
                $exception->errorBag
            );
}

I would have thought /login would have been the previous URL? Do I need to set the previous URL manually session()->setPreviousUrl()?

Any help here would be appreciated.

0 likes
4 replies
haakym's avatar
haakym
OP
Best Answer
Level 8

session()->setPreviousUrl('login')

did the trick! Happy to hear any alternative approaches to this.

1 like
Priet's avatar

session()->setPreviousUrl('login')

Won't that mess up the intended() url?

My approache:

In App\Http\Controllers\Auth\LoginController:

    use AuthenticatesUsers {
        sendFailedLoginResponse as protected traitSendFailedLoginResponse;
    }
    protected function sendFailedLoginResponse(Request $request) {
        try {
            $this->traitSendFailedLoginResponse($request);
        }
        catch (ValidationException $e) {
            $e->redirectTo(route("auth.login"));
            
            throw $e;
        }
    }
Priet's avatar

Update:

Seems a new header I added in my nginx configuration caused to issue of back() not working properly.

Before:

add_header Referrer-Policy "origin";

After:

add_header Referrer-Policy "strict-origin-when-cross-origin";

Saneesh's avatar

Try like this:

// Came from `/login`
$response = $this->from('/login')->post('/login', [
        'email' => '[email protected]',
        'password' => 'wrong-password',
    ]);
3 likes

Please or to participate in this conversation.