Jwt-auth: $this->token being persisted on phpunit tests

Created on 26 Jun 2015  路  9Comments  路  Source: tymondesigns/jwt-auth

I'm testing my laravel 5.1 rest api with phpunit and somehow the token gets persisted. On one of my tests I have 2 different calls using 2 different tokens for users which I previously authenticate using the uri for doing so. However when I make the second call, the getToken() function retrieves the token set by the first call and so the "authenticated" user is the one from the first call. Is there a way to solve this? Or is this the intended flow and I'm missing something with phpunit?

Most helpful comment

Don't seem to find the documentation on testing.

All 9 comments

You could call $jwtAuth->setToken('foo'); or $jwtAuth->setRequest($request); before each test

Hey thank you, I think that is going to work, but I have no idea how to execute it. If I call $jwtAuth->setToken('foo'); I get an undefined variable error, which is logical. I really don't know how to use your library from the test file. I suppose I could implement a web service to do the setting for the tests but that seems sketchy

you don't need a service for this.. do you have any code to post?

<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class FriendshipTest extends TestCase{

    use DatabaseMigrations;
    public function testAcceptFriend(){
       //creating users with factories
        $user1 = factory('App\User')->create();
        $user2 = factory('App\User')->create();
            //login and saving tokens of both users
        $login1 = ['email' => $user1->email, 'password' => '12345678'];
        $response = $this->call('POST', 'api/signin', $login1);
        $response = json_decode($response->getContent(), true); 
        $token1 = $response['token'];
        $login2 = ['email' => $user2->email, 'password' => '12345678'];
        $response = $this->call('POST', 'api/signin', $login2);
        $response = json_decode($response->getContent(), true); 
        $token2 = $response['token'];
        //generate a friendship request from user1 -> user2
        $response = $this->call('POST', 'api/users/' . $user1->id . '/friendships', ['friend_id' => $user2->id], [], [], ['HTTP_AUTHORIZATION' => 'bearer ' . $token1]);
        $request = json_decode($response->getContent(), true)['friendship'];

        //trying to accept request from user1 -> user2 as user1 (shouldnt be possible)
        $response = $this->call('PUT', 'api/users/' . $user1->id . '/friendships/' . $request['id'] . '/accept', [], [], [], ['HTTP_AUTHORIZATION' => 'bearer ' . $token1]);
        $this->assertResponseStatus(422);

        //accepting request from user1 as user2. Here the validated token is persisted as token1 and so it ends in error since it is trying to accept request as user1
        $response = $this->call('PUT', 'api/users/' . $user2->id . '/friendships/' . $request['id'] . '/accept', [], [], [], ['HTTP_AUTHORIZATION' => 'bearer ' . $token2]);
        $this->assertResponseStatus(200);
    }
}

Just to add a little more of context, I know exactly what is triggering the "error" on the testing enviroment. This function in JWTAuth.php

public function getToken()
{
        if (! $this->token) {
            try {
                $this->parseToken();
            } catch (JWTException $e) {
                return false;
            }
        }

    return $this->token;
}

Somehow in the testing enviroment $this->token is set on every request after the first one and thus I get the same user even though I pass a different token.

I'm also having a bit of trouble using this package in my tests. Specially when trying to hit a url protected by jwt.auth middleware. Have no idea how to do it tbh. Any guidance?

In my Controller __construct method, I have these few lines of code that is running that sorts out this issue.

if ((\App::environment() == 'testing') && array_key_exists("HTTP_Authorization",  Request::server())) {
    JWTAuth::setRequest(\Route::getCurrentRequest());
}

Is there a better solution?

will be updating docs regarding testing methods coinciding with the new release

Don't seem to find the documentation on testing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Rasoul-Karimi picture Rasoul-Karimi  路  3Comments

shah-newaz picture shah-newaz  路  3Comments

functionpointdaniel picture functionpointdaniel  路  3Comments

loic-lopez picture loic-lopez  路  3Comments

lloy0076 picture lloy0076  路  3Comments