b8d31e3dc4
- Modules\Shared\Bnfexpress\BnfexpressAdminClient: HMAC-signed HTTP client for bnfexpress's admin API (EV FAQs, agent instructions, chat history), with a bnfexpress:smoke-test command and full unit coverage. - New ai-agent module: Filament pages to manage EV FAQs, publish/roll back agent instruction versions, and browse EV chat history + transcripts. - New manage_ai_agent permission (super_admin/admin). - Recorded .ai/rules for the client's auth scheme and non-Resource Filament page/table testing gotchas.
98 lines
4.1 KiB
PHP
98 lines
4.1 KiB
PHP
<?php
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Http\Client\Request;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Livewire\Livewire;
|
|
use Modules\AiAgent\Filament\Pages\ManageAgentInstructions;
|
|
use Spatie\Permission\Models\Permission;
|
|
|
|
beforeEach(function () {
|
|
config([
|
|
'services.bnfexpress.ai_api_url' => 'https://bnfexpress.test',
|
|
'services.bnfexpress.client_id' => 'ev_admin',
|
|
'services.bnfexpress.client_secret' => 'test-secret',
|
|
]);
|
|
|
|
Permission::findOrCreate('manage_ai_agent', 'web');
|
|
|
|
$this->admin = User::factory()->create()->givePermissionTo(['manage_ai_agent']);
|
|
$this->actingAs($this->admin);
|
|
});
|
|
|
|
test('a user without manage_ai_agent cannot access it', function () {
|
|
$this->actingAs(User::factory()->create());
|
|
|
|
expect(ManageAgentInstructions::canAccess())->toBeFalse();
|
|
});
|
|
|
|
test('it renders the active instruction and version history', function () {
|
|
Http::fake([
|
|
'bnfexpress.test/admin/agent-instructions/active*' => Http::response(['id' => 2, 'content' => 'You are the EV assistant.']),
|
|
'bnfexpress.test/admin/agent-instructions*' => Http::response([
|
|
'total' => 1,
|
|
'instructions' => [['id' => 2, 'is_active' => true, 'content' => 'You are the EV assistant.', 'created_at' => now()->toIso8601String()]],
|
|
]),
|
|
]);
|
|
|
|
Livewire::test(ManageAgentInstructions::class)
|
|
->assertOk()
|
|
->assertSee('You are the EV assistant.')
|
|
->loadTable()
|
|
->assertSee('You are the EV assistant.');
|
|
});
|
|
|
|
test('publishing a new version calls publishInstruction and shows a success notification', function () {
|
|
Http::fake([
|
|
'bnfexpress.test/admin/agent-instructions/active*' => Http::response(['id' => 3, 'content' => 'New instructions.']),
|
|
'bnfexpress.test/admin/agent-instructions*' => fn (Request $request) => match ($request->method()) {
|
|
'POST' => Http::response(['id' => 3, 'content' => 'New instructions.', 'is_active' => true], 201),
|
|
default => Http::response(['total' => 0, 'instructions' => []]),
|
|
},
|
|
]);
|
|
|
|
Livewire::test(ManageAgentInstructions::class)
|
|
->loadTable()
|
|
->callTableAction('publish', data: ['content' => 'New instructions.', 'activate' => true])
|
|
->assertNotified('New instruction version published');
|
|
|
|
Http::assertSent(fn (Request $request) => $request->method() === 'POST'
|
|
&& str_contains($request->url(), '/admin/agent-instructions')
|
|
&& ! str_contains($request->url(), '/active')
|
|
&& $request['content'] === 'New instructions.'
|
|
&& $request['activate'] === true);
|
|
});
|
|
|
|
test('a failed publish surfaces the gateway detail message', function () {
|
|
Http::fake([
|
|
'bnfexpress.test/admin/agent-instructions/active*' => Http::response(['id' => 1, 'content' => 'Old instructions.']),
|
|
'bnfexpress.test/admin/agent-instructions*' => fn (Request $request) => match ($request->method()) {
|
|
'POST' => Http::response(['detail' => 'Content is required.'], 422),
|
|
default => Http::response(['total' => 0, 'instructions' => []]),
|
|
},
|
|
]);
|
|
|
|
Livewire::test(ManageAgentInstructions::class)
|
|
->loadTable()
|
|
->callTableAction('publish', data: ['content' => 'New instructions.', 'activate' => true])
|
|
->assertNotified('Failed to publish instruction');
|
|
});
|
|
|
|
test('activate is hidden on the already-active row and visible on others', function () {
|
|
Http::fake([
|
|
'bnfexpress.test/admin/agent-instructions/active*' => Http::response(['id' => 2, 'content' => 'Current.']),
|
|
'bnfexpress.test/admin/agent-instructions*' => Http::response([
|
|
'total' => 2,
|
|
'instructions' => [
|
|
['id' => 2, 'is_active' => true, 'content' => 'Current.', 'created_at' => now()->toIso8601String()],
|
|
['id' => 1, 'is_active' => false, 'content' => 'Older.', 'created_at' => now()->toIso8601String()],
|
|
],
|
|
]),
|
|
]);
|
|
|
|
Livewire::test(ManageAgentInstructions::class)
|
|
->loadTable()
|
|
->assertTableActionHidden('activate', 2)
|
|
->assertTableActionVisible('activate', 1);
|
|
});
|