Testing redirect links to external sites

I have a link on a page /my/example/page which links to a laravel route my.route.

Route

Route::group(['middleware' => ['auth']], function () {
    Route::group(['middleware' => ['Some\Custom\Auth\Middleware:1']], function () {
        Route::match(['GET', 'POST'], '/my/route/to/external/controller', '[email protected]')->name('my.route');
    }
}    

Link on /my/example/page

<a href="/my/route/to/external/controller" rel="nofollow noreferrer noopener">Link</a>

This route /my/route/to/external/controller points to this controller method externalLink in the exampleController controller, which returns the url for the href to use

public function externalLink()
{
    return $this->redirect->away('www.externalsite.com');
}

My test is

$this->visit(/my/example/page)
     ->click('Link')
     ->assertRedirectedToRoute('my.route');

I constantly get the error

Symfony\Component\HttpKernel\Exception\NotFoundHttpException

when I use the click() testing method.

I can catch this using @expectedException but his doesn’t help as I am expecting to see a different page.

I have also tried (not together);

->assertResponseStatus(200);
->seePageIs('www.externalsite.com');
->assertRedirect();
->followRedirects();

From browser inspection, when the url is clicked I get

http://www.example.com/my/route/to/external      302
http://www.externalsite.com                      200

How can I functionally test the button being clicked and redirecting to an external site?

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

I am struggling with a similar problem right now, and I have just about given up on testing the endpoint directly. Opting for a solution like this…

Test that the link contains proper information in the view:

$this->visit('/my/example/page')
    ->seeElement('a', ['href' => route('my.route')]);

Moving the logic in the controller to something you can test directly. The Laravel\Socialite package has some interesting tests that might be helpful if you do this…

class ExternalLinkRedirect {
    public function __construct($request){
        $this->request = $request;
    }

    public function redirect()
    {
        return redirect()->away('exteranlsite.com');
    }
}

Then test it directly

    $route = route('my.route');
    $request = \Illuminate\Http\Request::create($route);
    $redirector = new ExternalLinkRedirect($request);
    $response = $redirector->redirect();
    $this->assertEquals('www.externalsite.com', $response->getTargetUrl());

Solution 2

A simple way is to use the get method instead of visit.

An example:

$this->get('/facebook')
->assertRedirectedTo('https://www.facebook.com/Les-Teachers-du-NET-516952535045054');

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply