2

I am using Laravel 5.1 and I am trying to test my controllers.

I have several roles for my users and policies defined for different actions. Firstly, each of the requests needs to be made by an authenticated user, so running a test with no user returns a 401 Unauthorized, as expected.

But when I want to test the functionality for authorized users, I still get the 401 Unauthorized status code.

It may be worth mentioning that I use basic stateless HTTP authentication on these controllers.

I have tried the following:

public function testViewAllUsersAsAdmin()
{
    $user = UserRepositoryTest::createTestAdmin();

    Auth::login($user);

    $response = $this->call('GET', route('users.index'));
    $this->assertEquals($response->getStatusCode(), Response::HTTP_OK);
}

and

public function testViewAllUsersAsAdmin()
{
    $user = UserRepositoryTest::createTestAdmin();

    $response = $this->actingAs($user)
        ->call('GET', route('users.index'));

    $this->assertEquals($response->getStatusCode(), Response::HTTP_OK);
}

and also this (in case there was anything wrong with my new user, which there shouldn't be)

public function testViewAllUsersAsAdmin()
{
    $user = User::find(1);

    $response = $this->actingAs($user)
        ->call('GET', route('users.index'));

    $this->assertEquals($response->getStatusCode(), Response::HTTP_OK);
}

but in every case I get a 401 response code so my tests fail.

I can access the routes fine using postman when logging in as a dummy user.

I am running out of ideas, so any help would be appreciated.

2 Answers 2

0

Through some experimentation, I found that the problem lay inside my authentication middleware. Since I want the API to be stateless, the authentication looks like this:

public function handle($request, Closure $next)
{
    return Auth::onceBasic() ?: $next($request);
}

And apparently, it's not possible to authenticate a user the way I was doing it.

My solution was simply to disable the middleware, using the WithoutMiddleware trait or $this->withoutMiddleware() at the beginning of each test.

Sign up to request clarification or add additional context in comments.

Comments

0

You need to add Session::start() in the setUp function or in the beginning of the function which user need to log in.

public function setUp()
{
    parent::setUp();

    Session::start();
}

or

public function testViewAllUsersAsAdmin()
{
    Session::start();

    $user = UserRepositoryTest::createTestAdmin();

    Auth::login($user);

    $response = $this->call('GET', route('users.index'));
    $this->assertEquals(Response::HTTP_OK, $response->getStatusCode());
}

1 Comment

I'm afraid this didn't solve the problem. I don't see how starting a session would help, seeing as the point of the api is to be completely stateless, nor do I use sessions anywhere.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.