<?php

use App\Models\WorkspaceApiToken;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

test('admin can view the api tokens page', function () {
    ['user' => $user] = workspaceMember(['role' => 'admin']);

    $this->actingAs($user)
        ->get('/settings/api-tokens')
        ->assertOk()
        ->assertInertia(fn ($page) => $page
            ->component('settings/api-tokens')
            ->has('abilities')
            ->where('abilities.0', 'wp:integration'));
});

test('viewer role cannot view the api tokens page', function () {
    ['user' => $user] = workspaceMember(['role' => 'viewer']);

    $this->actingAs($user)
        ->get('/settings/api-tokens')
        ->assertForbidden();
});

test('admin can issue a token and the plaintext is returned exactly once', function () {
    ['user' => $user, 'workspace' => $workspace] = workspaceMember(['role' => 'admin']);

    $response = $this->actingAs($user)
        ->post('/settings/api-tokens', [
            'name' => 'WordPress: shop.example.com',
            'abilities' => ['wp:integration'],
        ]);

    $response->assertRedirect();
    $response->assertSessionHas('new_token');

    $plaintext = session('new_token');
    expect($plaintext)->toStartWith('pbar_');

    $token = WorkspaceApiToken::query()->where('workspace_id', $workspace->id)->sole();
    expect($token->token_hash)->toBe(hash('sha256', $plaintext));
    expect($token->abilities)->toBe(['wp:integration']);
    expect($token->revoked_at)->toBeNull();
});

test('plaintext is not persisted anywhere', function () {
    ['user' => $user, 'workspace' => $workspace] = workspaceMember(['role' => 'admin']);

    $this->actingAs($user)->post('/settings/api-tokens', [
        'name' => 'test',
        'abilities' => ['wp:integration'],
    ]);

    $token = WorkspaceApiToken::query()->where('workspace_id', $workspace->id)->sole();
    $plaintext = session('new_token');

    expect($token->getRawOriginal('token_hash'))->not()->toBe($plaintext);
    expect(strlen($token->token_hash))->toBe(64); // sha256 hex
});

test('unknown abilities are rejected', function () {
    ['user' => $user] = workspaceMember(['role' => 'admin']);

    $this->actingAs($user)
        ->post('/settings/api-tokens', [
            'name' => 'test',
            'abilities' => ['root:*'],
        ])
        ->assertSessionHasErrors('abilities.0');
});
