Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Generate a Token when testing with PHPunit #28

Closed
hfalucas opened this issue Jan 13, 2015 · 3 comments
Closed

[Question] Generate a Token when testing with PHPunit #28

hfalucas opened this issue Jan 13, 2015 · 3 comments

Comments

@hfalucas
Copy link

Hello,

I would like to know if you can give a little hand here. Im using your package (L5 branch) to secure some of my API uri's.
So now decided to dive in the testing world(nood here) and I can't seem to get this right when testing a protected uri.

$this->call('GET', 'v1/me', [], [], [], ['HTTP_Authorization' => 'Bearer <token here>' ]);

If I hard code the token in the call method it works fine but off course I first wanna get a User from my testing DB and then generate a token to pass it the call method(if this even make sense for a test)

Do you have a small example on how to this or point me in some direction?

Thanks in advance,
Helder

@Gwynnbleid1
Copy link

Hi. Did you managed to get your tests working ? I have the same problem and could use some help.

@elynnaie
Copy link

Not OP, but here's how I did this in my code.

For most tests, I need to be logged in but I don't want to test auth, so I have this function in my base TestCase class that logs in as a specific user that I call before running each test:

    protected function login($user_id = 1)
    {   
        $user = User::find($user_id);
        $this->token = JWTAuth::fromUser($user);

        JWTAuth::setToken($this->token);

        Auth::login($user);
    }

Every time I call a route, I then pass in the token in the headers:

    protected function callRoute($method, $route, $data = [], $headers = [])
    {
        if ($this->token && !isset($headers['Authorization'])) {
            $headers['HTTP_Authorization'] = "Bearer: $this->token";
        }

        return $this->call(
            $method,
            "/api$route",
            [],
            [],
            [],
            $headers,
            json_encode($data)
        );
    }

For testing auth itself, I do this:

    public function testLogin()
    {
        $this->seed('UserSeeder');

        // callRoute's parameters: 1. Method  2. Url  3. Data  4. Headers
        $resp = $this->callRoute('POST', '/auth', ['email' => 'test@test.com', 'password' => 'password']);
        $this->assertOk($resp);

        // Get the token
        $data = json_decode($resp->getContent(), true);
        $this->assertArrayHasKey('token', $data);

        // At this point, I could call another api endpoint and pass in the token. Something like this:
        // $this->callRoute('POST', '/example', $data, ['HTTP_Authorization' => 'Bearer: ' . $data['token']]);
    }

$this->callRoute and $this->assertOk are custom shortcut functions that I wrote to avoid lots of boilerplate.

@bayssmekanique
Copy link

Thank you @denaje for the code. That helped a ton. Here is a slightly revised version that functions more like the parent call method.

Extend the TestCase class with:

    protected function createAuthenticatedUser()
    {
        $this->user  = factory(App\Models\User::class, 'test')->create();
        $this->token = JWTAuth::fromUser($this->user);
        JWTAuth::setToken($this->token);
        Auth::attempt(['username' => $this->user->username, 'password' => $this->user->password]);
    }

    protected function callAuthenticated($method, $uri, array $data = [], array $headers = [])
    {
        if ($this->token && !isset($headers['Authorization'])) {
            $headers['Authorization'] = "Bearer: $this->token";
        }

        $server = $this->transformHeadersToServerVars($headers);

        $this->call(strtoupper($method), $uri, $data, [], [], $server);

        return $this;
    }

Then use in tests like any other method:

    public function testGetUser()
    {
        $this->createAuthenticatedUser();
        $this->callAuthenticated('GET', route('auth::user'))->seeJsonStructure(['id']);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants