Files
portal/app/tests/Feature/Bot/ChatToursTest.php
T

110 lines
5.9 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\KnowledgeChunk;
use App\Services\Bot\BotAnswerService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
uses(RefreshDatabase::class);
/**
* Экскурсии «Показать на портале» 13.07.2026 были ВЫКЛЮЧЕНЫ: ссылки уходили не по теме
* вопроса (совпадало одно случайное слово — бот приписывал экскурсию по уведомлениям
* к реплике «первое сообщение подряд»). Правило переписано, экскурсии включены обратно.
*
* Теперь их держат два условия, и оба обязательны:
* 1. Вопрос по теме статьи (KnowledgeSearch::isOnTopic — тесты в ToursRelevanceTest).
* 2. Клиент пишет ИЗ КАБИНЕТА. Гостю с лендинга ссылка внутрь кабинета бесполезна:
* он там ещё не зарегистрирован, и показывать ему нечего.
*
* Этот сторож не даёт незаметно вернуть ссылки гостям.
*/
beforeEach(function () {
config()->set('services.bot.tours_enabled', true);
config()->set('app.url', 'https://lk.liderra.ru');
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,
]);
Http::fake([
'llm.api.cloud.yandex.net/*' => Http::response([
'result' => ['alternatives' => [['message' => ['role' => 'assistant', 'text' => 'Проект создаётся в разделе «Проекты».']]]],
]),
]);
KnowledgeChunk::create([
'source_path' => 'help/create.md', 'title' => 'Как создать проект', 'tour' => 'create-project',
'topics' => 'создать проект, новый проект', 'chunk_index' => 0,
'content' => 'Проект создаётся в разделе «Проекты», кнопка «Создать».',
]);
});
it('клиенту из кабинета экскурсия по теме предлагается', function () {
$answer = app(BotAnswerService::class)->answer('как создать проект?', [], fromPortal: true);
expect($answer->text)->toContain('https://lk.liderra.ru/?tour=create-project');
});
it('гостю с лендинга экскурсию не предлагаем — ему нечего показывать в кабинете', function () {
$answer = app(BotAnswerService::class)->answer('как создать проект?', [], fromPortal: false);
expect($answer->text)->not->toContain('?tour=');
});
/**
* Гостю с лендинга ссылка внутрь кабинета бесполезна, но ему тоже нужно «показать
* на примере» — на лендинге готовится раздел «Как это работает» с якорями показа
* по темам. Карта LANDING_SHOWS в BotAnswerService связывает имя экскурсии
* (то же поле tour, что и для кабинета) с якорем на лендинге.
*/
it('гостю с лендинга даём ссылку на показ ТАМ ЖЕ, где кабинету — экскурсию', function () {
config()->set('services.bot.landing_url', 'https://liderra.ru');
$answer = app(BotAnswerService::class)->answer('как создать проект?', [], fromPortal: false);
expect($answer->text)->toContain('https://liderra.ru/#kak-sozdat-proekt');
expect($answer->text)->not->toContain('Показать на портале');
});
it('вошедшему клиенту по-прежнему только ссылка в кабинет, без ссылки на лендинг', function () {
config()->set('services.bot.landing_url', 'https://liderra.ru');
$answer = app(BotAnswerService::class)->answer('как создать проект?', [], fromPortal: true);
expect($answer->text)->toContain('Показать на портале');
expect($answer->text)->not->toContain('liderra.ru/#');
});
it('гостю не даём ссылку, если у статьи по теме нет показа на лендинге в карте', function () {
config()->set('services.bot.landing_url', 'https://liderra.ru');
KnowledgeChunk::create([
'source_path' => 'help/security.md', 'title' => 'Безопасность аккаунта', 'tour' => 'security',
'topics' => 'пароль, вход в аккаунт',
'chunk_index' => 0,
'content' => 'Смените пароль в разделе «Профиль».',
]);
Http::fake([
'llm.api.cloud.yandex.net/*' => Http::response([
'result' => ['alternatives' => [['message' => ['role' => 'assistant', 'text' => 'Пароль меняется в разделе «Профиль».']]]],
]),
]);
$answer = app(BotAnswerService::class)->answer('как сменить пароль в аккаунте?', [], fromPortal: false);
expect($answer->text)->not->toContain('liderra.ru/#');
expect($answer->text)->not->toContain('?tour=');
});
it('на реплику без вопроса ссылку на лендинг не даём ни гостю, ни вошедшему', function () {
config()->set('services.bot.landing_url', 'https://liderra.ru');
$guest = app(BotAnswerService::class)->answer('привет', [], fromPortal: false);
$client = app(BotAnswerService::class)->answer('привет', [], fromPortal: true);
expect($guest->text)->not->toContain('liderra.ru/#');
expect($client->text)->not->toContain('Показать на портале');
});