extend(TestCase::class) // ->use(RefreshDatabase::class) ->in('Feature'); pest()->extend(TestCase::class)->in('Browser'); /* |-------------------------------------------------------------------------- | Expectations |-------------------------------------------------------------------------- | | When you're writing tests, you often need to check that values meet certain conditions. The | "expect()" function gives you access to a set of "expectations" methods that you can use | to assert different things. Of course, you may extend the Expectation API at any time. | */ expect()->extend('toBeOne', function () { return $this->toBe(1); }); /* |-------------------------------------------------------------------------- | Functions |-------------------------------------------------------------------------- | | While Pest is very powerful out-of-the-box, you may have some testing code specific to your | project that you don't want to repeat in every file. Here you can also expose helpers as | global functions to help you to reduce the number of lines of code in your test files. | */ function something() { // .. } /** * Link a Лидерра-project to a supplier_project via the M:N pivot * (Plan 1 model). Post-Plan-2 LeadRouter eligibility queries the pivot * only; legacy supplier_b{1,2,3}_project_id FK is ignored for routing. * * Single source — replaces previous duplicated declarations in * LeadRouterTest.php / RouteSupplierLeadJobTest.php (Plan 2 cleanup). * pivot created_at has DEFAULT NOW(); supplier->subject_code may be null. */ function linkProjectToSupplier(Project $project, SupplierProject $supplier): void { DB::table('project_supplier_links')->insert([ 'project_id' => $project->id, 'supplier_project_id' => $supplier->id, 'platform' => $supplier->platform, 'subject_code' => $supplier->subject_code, ]); } /** * Pest helper для slepok-routing тестов (Task 2.5). * * Создаёт строку в `project_routing_snapshots` за активную дату слепка, * отражающую "идеальное" состояние live-проекта. Используется тестами, * которым нужен только факт «маршрутизация возможна», а не сам snapshot * mechanism. * * Активная дата по умолчанию — сегодняшняя МСК (до 21:00 МСК). Передайте * `$date` явно, если тест использует `Carbon::setTestNow` с другой датой. * * NB: signal_type/signal_identifier берутся ЯВНО из аргументов, а не из * `$project->signal_type` — на Windows-native PG факториальный override * этого поля не персистится (см. memory project_slepok_protection.md). */ /** * Pest helper для SyncSupplierProjectsJob тестов (Task 2.9). * * Вставляет snapshot в `project_routing_snapshots` за активную дату слепка * для tomorrow МСК (cron 18:02 МСК ежедневно создаёт slepok на завтра). * * После Task 2.9 sync-job читает snapshot, не live `projects.is_active` — * без снимка проект не попадает в группировку для подачи поставщику. */ function insertSnapshotForTomorrow( Project $project, string $signalType = 'call', ?string $signalIdentifier = '79161234567', ?int $dailyLimit = null, ?int $deliveryDaysMask = null, string $regions = '{}', ): void { $tomorrow = Carbon::tomorrow('Europe/Moscow')->toDateString(); DB::table('project_routing_snapshots')->insert([ 'snapshot_date' => $tomorrow, 'project_id' => $project->id, 'tenant_id' => $project->tenant_id, 'daily_limit' => $dailyLimit ?? (int) ($project->daily_limit_target ?? 10), 'delivery_days_mask' => $deliveryDaysMask ?? (int) ($project->delivery_days_mask ?? 127), 'regions' => $regions, 'signal_type' => $signalType, 'signal_identifier' => $signalIdentifier, 'sms_senders' => null, 'sms_keyword' => null, 'expected_volume' => $dailyLimit ?? (int) ($project->daily_limit_target ?? 10), 'delivered_count' => 0, 'created_at' => Date::now(), ]); } function createRoutingSnapshotFromProject( Project $project, ?string $date = null, string $signalType = 'call', ?string $signalIdentifier = null, ?int $dailyLimit = null, ): void { DB::table('project_routing_snapshots')->insert([ 'snapshot_date' => $date ?? Carbon::today('Europe/Moscow')->toDateString(), 'project_id' => $project->id, 'tenant_id' => $project->tenant_id, 'daily_limit' => $dailyLimit ?? (int) ($project->effective_daily_limit_today ?? $project->daily_limit_target), 'delivery_days_mask' => (int) ($project->delivery_days_mask ?? 127), 'regions' => '{}', 'signal_type' => $signalType, 'signal_identifier' => $signalIdentifier, 'sms_senders' => null, 'sms_keyword' => null, 'expected_volume' => $dailyLimit ?? (int) ($project->effective_daily_limit_today ?? $project->daily_limit_target), 'delivered_count' => 0, 'created_at' => Date::now(), ]); }