Créer un password grant token avec des tests unitaires

151212
,

Bonjour,

Voilà je rencontre un petit problème avec mon code.

Description

Je veux tester mon serveur oauth (avec le paquet laravel/passport).

J'utilise des tests unitaires, j'utilise une base de données mémoire avec PHPUnit, j'ai l'impression que je ne peux donc pas migrer les tables créées par le paquet.

J'aimerais pouvoir appeler les commandes suivantes lors de mon test :

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

Mais j'ai cette erreur :

Mockery\Exception\BadMethodCallException: Received Mockery_1_Illuminate_Console_OutputStyle::askQuestion(), but no expectations were specified

Je suis sûr que cela est dû au fait que passeport n'est pas entièrement installé mais je ne sais pas comment faire.

2 Réponse

108470
,

Bonjour,

avec Passport, j'utilise ça. L'idée étant d'utiliser la méthode actingAs

/** @test */
public function it_gets_the_unit()
{
    $user = factory(App\User::class)->create();
    $this->actingAs($user, 'api');

    $unitCode = '1234';

    $this->json('GET', '/api/units/' . $unitCode)
        ->seeJsonContains(['id' => $unitCode]);
}

Tu peux adapter à ton code :)

151212
,

Salut, merci pour ta réponse, j'utilise déjà cette méthode pour d'autre actions et dans mon cas ce n'est pas de cette méthode que j'ai besoin...

Voici mon test qui pose problème :

/**
 * Disable exception handling
 * Act like a connected user
 * Seed UsersTableSeeder
 * Perform a POST request on `api/users`
 * The response JSON has the expected count of items
 * Check the JSON structure
 * Check if the response is HTTP_CREATED (201)
 * Check if the database contains 1 record on database
 * @test
 */
 public function a_user_is_logged_in_and_create_a_new_user_that_is_returned_in_a_json_format()
{
    $this->withoutExceptionHandling();

    // TODO this method should works !
    $this->artisan('passport:client', ['--password', '--no-interaction' => true]);

    Passport::actingAs(factory(User::class)->create(), ['*']);

    $this->seed('UsersTableSeeder');

    $user = [
        'full_name' => 'John Doe',
        'email' => 'john.doe@gmail.com',
        'password' => 'Password',
        'password_confirmation' => 'Password',
        'role_id' => 1
    ];

    $this->json('POST', 'api/users', $user)
        ->assertJsonCount(7)
        ->assertJsonStructure([
            'access_token',
        ])
        ->assertStatus(Response::HTTP_CREATED);
}

Voici ma méthode pour créer un utilisateur :

/**
 * Store a newly created resource in storage.
 *
 * @param UserRequest $request
 * @return \Symfony\Component\HttpFoundation\Response
 * @throws \Exception
 */
public function store(UserRequest $request)
{
    User::create([
        'full_name' => $request->full_name,
        'username' => strtolower(str_replace(' ', '.', $request->full_name)),
        'email' => $request->email,
        'password' => bcrypt($request->password),
        'role_id' => $request->role_id
    ]);

    return $this->issue_token($request, 'password');
}

Le constructeur de ma classe UserController :

private $client;

public function __construct()
{
    $this->middleware('auth:api')->except(['store']);
    $this->client = Client::find(1);
}

Et la méthode issue_token() :

/**
 * @param $request
 * @param $grant_type
 * @param string $scope
 * @return \Symfony\Component\HttpFoundation\Response
 * @throws \Exception
 */
public function issue_token($request, $grant_type, $scope = '*')
 {
    $proxy = Request::create('/oauth/token', 'POST', [
            'grant_type' => $grant_type,
            'client_id' => $this->client->id,
            'client_secret' => $this->client->secret,
            'username' => $request->email,
            'password' => $request->password,
            'scope' => $scope,
        ]
    );

    return app()->handle($proxy);
}

Lorsque je veux créer un utilisateur, $this->client doit contenur le modèle Client de Passport, mais pour faire ça, la commande php artisan passport:client --password doit être lancée pour créer la table oauth_clients, c'est la raison pour laquelle je veux lancer cette commande avec $this->artisan().