set('client_tg.robot', [ 'node' => 'node', 'script' => base_path('tests/fixtures/tg-robot/'.$script), 'cwd' => base_path('tests/fixtures/tg-robot'), 'timeout' => $timeout, ]); } /** @return array */ function sampleTaskParams(): array { return [ 'mode' => 'draft', 'phonesFile' => '/tmp/phones-tg-test.txt', 'adText' => 'Приходите к нам', 'budgetRub' => '1000.00', 'buttonUrl' => 'https://example.test', 'ordCategory' => 'Размещение рекламы', ]; } it('строит task.json со всеми полями задания робота', function () { $runner = app(TelegramRobotRunner::class); $payload = $runner->taskPayload(sampleTaskParams()); expect($payload)->toMatchArray([ 'mode' => 'draft', 'phonesFile' => '/tmp/phones-tg-test.txt', 'adText' => 'Приходите к нам', 'budgetRub' => '1000.00', 'buttonUrl' => 'https://example.test', 'ordCategory' => 'Размещение рекламы', ]); }); it('подставляет дефолты mode=draft и категорию ОРД', function () { $runner = app(TelegramRobotRunner::class); $payload = $runner->taskPayload([ 'phonesFile' => '/tmp/x.txt', 'adText' => 'текст', 'budgetRub' => '500.00', 'buttonUrl' => 'https://a.test', ]); expect($payload['mode'])->toBe('draft') ->and($payload['ordCategory'])->toBe('Размещение рекламы') ->and($payload['mediaFile'])->toBeNull(); }); it('запускает робота и разбирает успешный JSON', function () { useRobotFixture('print-ok.js'); $runner = app(TelegramRobotRunner::class); $res = $runner->run(sampleTaskParams()); expect($res)->toBeInstanceOf(RobotResult::class) ->and($res->ok)->toBeTrue() ->and($res->matched)->toBe(512) ->and($res->launched)->toBeFalse() ->and($res->campaignId)->toBe('draft'); }); it('штатный отказ робота (exit 1) → ok:false с причиной, без исключения', function () { useRobotFixture('print-fail.js'); $runner = app(TelegramRobotRunner::class); $res = $runner->run(sampleTaskParams()); expect($res->ok)->toBeFalse() ->and($res->step)->toBe('upload') ->and($res->reason)->toContain('Недостаточно номеров'); }); it('непарсабельный вывод → аккуратный ok:false, воркер не падает', function () { useRobotFixture('print-garbage.js'); $runner = app(TelegramRobotRunner::class); $res = $runner->run(sampleTaskParams()); expect($res->ok)->toBeFalse() ->and($res->reason)->not->toBeNull(); }); it('таймаут робота → аккуратный ok:false, воркер не падает', function () { useRobotFixture('sleep.js', timeout: 1.0); $runner = app(TelegramRobotRunner::class); $res = $runner->run(sampleTaskParams()); expect($res->ok)->toBeFalse() ->and($res->reason)->not->toBeNull(); }); it('НЕ оставляет временный task-файл после запуска (чистка)', function () { useRobotFixture('print-ok.js'); $runner = app(TelegramRobotRunner::class); $before = glob(sys_get_temp_dir().'/tg-task-*.json') ?: []; $runner->run(sampleTaskParams()); $after = glob(sys_get_temp_dir().'/tg-task-*.json') ?: []; expect(count($after))->toBeLessThanOrEqual(count($before)); });