61 lines
2.5 KiB
PHP
61 lines
2.5 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
use App\Jobs\Bot\ProcessJivoMessageJob;
|
||
use App\Models\BotDialog;
|
||
use App\Models\KnowledgeChunk;
|
||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||
use Illuminate\Support\Facades\Http;
|
||
|
||
uses(RefreshDatabase::class);
|
||
|
||
beforeEach(function () {
|
||
config()->set('services.jivo_bot.outbound_url', 'https://bot.jivosite.com/webhooks/p/t');
|
||
config()->set('services.yandexgpt', [
|
||
'api_key' => 'k', 'folder_id' => 'f', 'model' => 'yandexgpt-lite/latest',
|
||
'endpoint' => 'https://llm.api.cloud.yandex.net/foundationModels/v1/completion',
|
||
'timeout_seconds' => 8,
|
||
]);
|
||
KnowledgeChunk::create([
|
||
'source_path' => 'help/p.md', 'title' => 'Что такое проект', 'tour' => null,
|
||
'topics' => 'создать проект', 'chunk_index' => 0,
|
||
'content' => 'Проект — это заявка на поток клиентов.',
|
||
]);
|
||
});
|
||
|
||
it('happy path: ответ уходит в Jivo, журнал пишет in+out с latency', function () {
|
||
Http::fake([
|
||
'llm.api.cloud.yandex.net/*' => Http::response([
|
||
'result' => ['alternatives' => [['message' => ['role' => 'assistant', 'text' => 'Проект — это…']]]],
|
||
]),
|
||
'bot.jivosite.com/*' => Http::response(['ok' => true]),
|
||
]);
|
||
|
||
(new ProcessJivoMessageJob('chat-1', 'client-1', 'что такое проект?'))->handle();
|
||
|
||
Http::assertSent(fn ($r) => str_contains($r->url(), 'bot.jivosite.com') && $r['event'] === 'BOT_MESSAGE');
|
||
|
||
$out = BotDialog::where('direction', 'out')->firstOrFail();
|
||
expect(BotDialog::where('direction', 'in')->count())->toBe(1)
|
||
->and($out->latency_ms)->toBeGreaterThanOrEqual(0)
|
||
->and($out->escalated)->toBeFalse()
|
||
->and($out->matched_chunks)->not->toBeNull();
|
||
});
|
||
|
||
it('эскалация: BOT_MESSAGE-прощание + INVITE_AGENT, журнал escalated=true', function () {
|
||
Http::fake(['bot.jivosite.com/*' => Http::response(['ok' => true])]);
|
||
|
||
(new ProcessJivoMessageJob('chat-2', 'client-2', 'какой у меня баланс?'))->handle();
|
||
|
||
Http::assertSent(fn ($r) => ($r['event'] ?? '') === 'INVITE_AGENT');
|
||
expect(BotDialog::where('direction', 'out')->firstOrFail()->escalated)->toBeTrue();
|
||
});
|
||
|
||
it('джоба объявлена с queue=bot и timeout ≤ 12 сек', function () {
|
||
$job = new ProcessJivoMessageJob('c', 'c', 'q');
|
||
|
||
expect($job->queue)->toBe('bot')
|
||
->and($job->timeout)->toBeLessThanOrEqual(12);
|
||
});
|