delete(); }); afterEach(fn () => Carbon::setTestNow()); it('пишет run-сводку даже когда нет eligible-проектов (groups_total=0, status=ok)', function (): void { (new SyncSupplierProjectsJob)->handle(app(AjaxProjectChannel::class)); $run = DB::table('supplier_sync_runs')->latest('id')->first(); expect($run)->not->toBeNull(); expect((int) $run->groups_total)->toBe(0); expect((int) $run->synced_ok)->toBe(0); expect($run->status)->toBe('ok'); expect($run->started_at)->not->toBeNull(); expect($run->finished_at)->not->toBeNull(); }); it('считает синхронизированную группу в синку run-сводки (groups_total=1, synced_ok=1)', function (): void { $tenant = Tenant::factory()->create(); $project = Project::factory()->create([ 'tenant_id' => $tenant->id, 'is_active' => true, 'signal_type' => 'site', 'signal_identifier' => 'okna-run.example.com', 'daily_limit_target' => 9, 'delivery_days_mask' => 127, 'regions' => [82, 83], ]); insertSnapshotForTomorrow($project, regions: '{82,83}'); Http::fake([ 'crm.bp-gr.ru/admin/visit/rt-project-save' => Http::response( ['status' => 'OK', 'message' => '', 'result' => null, 'id' => '2001'], 200, ), 'crm.bp-gr.ru/admin/visit/rt-projects-load*' => Http::response( ['projects' => [ ['id' => '2001', 'src' => 'rt', 'name' => 'okna-run.example.com', 'tag' => 'РФ', 'type' => 'hosts', 'content' => 'okna-run.example.com'], ['id' => '2002', 'src' => 'bl', 'name' => 'okna-run.example.com', 'tag' => 'РФ', 'type' => 'hosts', 'content' => 'okna-run.example.com'], ['id' => '2003', 'src' => 'mt', 'name' => 'okna-run.example.com', 'tag' => 'РФ', 'type' => 'hosts', 'content' => 'okna-run.example.com'], ]], 200, ), ]); (new SyncSupplierProjectsJob)->handle(app(AjaxProjectChannel::class)); // Группа реально создалась у поставщика. expect(SupplierProject::on('pgsql_supplier')->where('unique_key', 'okna-run.example.com')->count())->toBe(3); $run = DB::table('supplier_sync_runs')->latest('id')->first(); expect($run)->not->toBeNull(); expect((int) $run->groups_total)->toBe(1); expect((int) $run->synced_ok)->toBe(1); expect((int) $run->failed)->toBe(0); expect($run->status)->toBe('ok'); });