110 lines
5.9 KiB
PHP
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('Показать на портале');
|
|
});
|