karolf's avatar
Level 10

How to test auth flow with Passport

Hi guys,

I want to implement super simple auth flow with the following assumptions:

  1. I have simple Vue.js app hosted on vueapp.example.com
  2. I have simple REST Laravel API hosted on api.example.com
  3. Vue.js app should consume Laravel API
  4. The whole project (app and api) is a simple SAAS platform in which administrator can create account for users which should be able to logg-in via Vue.js login form (for example)

I see that Passport provides useful helpers for testing stuff as authenticated user (https://laravel.com/docs/5.4/passport#testing) but I want to test the whole auth flow somethink like that:

  1. Given a user with "email" and "password" exists
  2. When I send"email" and "password" to "oauth/token"
  3. Then I should have token and refresh token in the json response

If I understand correctly, I should use password grant token which is described here: https://laravel.com/docs/5.4/passport#password-grant-tokens but then how can I run artisan command in my test?

0 likes
3 replies
karolf's avatar
karolf
OP
Best Answer
Level 10

Ok guys, that code works for me :)

<?php

namespace Tests\Feature;

use App\User;

class AuthApiTest extends ApiTestCase
{
    /** @test */
    public function it_should_return_access_and_refresh_token_if_user_with_given_email_and_password_exists()
    {
        // create password grant client
        // https://laravel.com/docs/5.4/passport#password-grant-tokens
        $this->artisan('passport:client', ['--password' => null, '--no-interaction' => true]);

        // create user
        factory(User::class)->create([
            'email' => '[email protected]',
            'password' => bcrypt('example')
        ]);

        // fetch client for id and secret
        $client = \DB::table('oauth_clients')->where('password_client', 1)->first();

        $this->post('/oauth/token', [
            'grant_type' => 'password',
            'client_id' => $client->id,
            'client_secret' => $client->secret,
            'username' => '[email protected]',
            'password' => 'example',
            'scope' => ''
        ])->assertJsonStructure(['access_token', 'refresh_token']);
    }
}

6 likes
katjam's avatar

I also had to add the --no-interaction option so the test doesn't hang at the 'What should we name the password grant client?' prompt.

$this->artisan('passport:client', [
    '--no-interaction' => true,
    '--password' => null
]);

karolf's avatar
Level 10

Yes, thanks for info. It seems this prompt have been added in new version of Laravel.

Please or to participate in this conversation.