$tenantId, 'enabled' => $enabled, 'ad_text' => 'Заходите в наш канал', 'ad_link' => 'https://t.me/example_channel', 'ord_category' => 'Размещение рекламы', 'budget_cap_rub' => '2500.00', ]); } function tgAccumulator(): TelegramAutoAccumulator { return app(TelegramAutoAccumulator::class); } /** @return list */ function tgFakePhones(int $n, int $offset = 0): array { $out = []; for ($i = 1; $i <= $n; $i++) { // 7999 + 7 цифр — синтетический номер (ПДн реальных клиентов не касаемся). $out[] = '7999'.str_pad((string) ($offset + $i), 7, '0', STR_PAD_LEFT); } return $out; } beforeEach(function () { Queue::fake(); $this->tenant = Tenant::factory()->create(); config(['client_tg.auto_batch_threshold' => 3]); // в тестах порог занижен }); it('правило выключено — ничего не копит и не запускает', function () { makeTgAutoRule($this->tenant->id, enabled: false); tgAccumulator()->accumulate($this->tenant->id, '79990000001'); expect(Campaign::where('tenant_id', $this->tenant->id)->count())->toBe(0); Queue::assertNothingPushed(); }); it('нет правила вовсе — тихо выходим', function () { tgAccumulator()->accumulate($this->tenant->id, '79990000001'); expect(Campaign::where('tenant_id', $this->tenant->id)->count())->toBe(0); Queue::assertNothingPushed(); }); it('ниже порога — копим в один черновик, в очередь не ставим', function () { makeTgAutoRule($this->tenant->id); tgAccumulator()->accumulate($this->tenant->id, '79990000001'); tgAccumulator()->accumulate($this->tenant->id, '79990000002'); $campaigns = Campaign::where('tenant_id', $this->tenant->id)->get(); expect($campaigns)->toHaveCount(1); $draft = $campaigns->first(); expect($draft->status)->toBe(Campaign::STATUS_DRAFT); expect($draft->audience_kind)->toBe(Campaign::AUDIENCE_LIST); expect($draft->created_by)->toBeNull(); // авто-кампания — без автора expect($draft->phones()->count())->toBe(2); Queue::assertNothingPushed(); }); it('повторный номер не задваивает пачку', function () { makeTgAutoRule($this->tenant->id); tgAccumulator()->accumulate($this->tenant->id, '79990000001'); tgAccumulator()->accumulate($this->tenant->id, '79990000001'); $draft = Campaign::where('tenant_id', $this->tenant->id)->first(); expect($draft->planned_count)->toBe(1); // кандидат один Queue::assertNothingPushed(); }); it('достигли порога — кампания в очереди, budget_cap из правила соблюдён', function () { $rule = makeTgAutoRule($this->tenant->id); foreach (tgFakePhones(3) as $phone) { tgAccumulator()->accumulate($this->tenant->id, $phone); } $campaign = Campaign::where('tenant_id', $this->tenant->id)->first(); expect($campaign->status)->toBe(Campaign::STATUS_QUEUED); expect($campaign->planned_count)->toBe(3); expect((string) $campaign->budget_cap_rub)->toBe((string) $rule->budget_cap_rub); Queue::assertPushed(RunTelegramCampaignJob::class, 1); }); it('после запуска пачки следующий лид открывает новую пачку', function () { makeTgAutoRule($this->tenant->id); foreach (tgFakePhones(3) as $phone) { // первая пачка → в очередь tgAccumulator()->accumulate($this->tenant->id, $phone); } tgAccumulator()->accumulate($this->tenant->id, '79991110001'); // новый лид $drafts = Campaign::where('tenant_id', $this->tenant->id) ->where('status', Campaign::STATUS_DRAFT)->get(); expect($drafts)->toHaveCount(1); expect($drafts->first()->phones()->count())->toBe(1); }); it('порог пачки по умолчанию — 367', function () { expect(config('client_tg.auto_batch_threshold'))->not->toBeNull(); // Значение по умолчанию читаем из свежесобранного конфига (без тестового override). $default = require config_path('client_tg.php'); expect($default['auto_batch_threshold'])->toBe(367); });