1, 'leads_in_tier' => null, 'price_per_lead_kopecks' => 10000, 'is_active' => true, 'effective_from' => now()->toDateString(), ]); }); it('creates project even when balance insufficient (201, launch deferred)', function () { $t = Tenant::factory()->withRequisites()->create(['balance_rub' => '100.00', 'delivered_in_month' => 0]); $u = User::factory()->for($t)->create(); $resp = $this->actingAs($u)->postJson('/api/projects', [ 'name' => 'A', 'signal_type' => 'site', 'signal_identifier' => 'a.ru', 'daily_limit_target' => 5, 'delivery_days_mask' => 127, 'regions' => [], ]); $resp->assertCreated(); $resp->assertJsonPath('launch.launched', 0); $resp->assertJsonPath('launch.deferred', 1); $resp->assertJsonPath('launch.balance.topup_rub', '400.00'); // не хватает 4 лида × 100 ₽ expect($t->projects()->first()->is_active)->toBeFalse(); }); it('creates project and launches immediately when balance sufficient (201, launched)', function () { $t = Tenant::factory()->withRequisites()->create(['balance_rub' => '1000.00', 'delivered_in_month' => 0]); $u = User::factory()->for($t)->create(); $resp = $this->actingAs($u)->postJson('/api/projects', [ 'name' => 'B', 'signal_type' => 'site', 'signal_identifier' => 'b.ru', 'daily_limit_target' => 5, 'delivery_days_mask' => 127, 'regions' => [], ]); $resp->assertCreated(); $resp->assertJsonPath('launch.launched', 1); $resp->assertJsonPath('launch.deferred', 0); expect($t->projects()->first()->is_active)->toBeTrue(); }); it('returns 422 requisites_required when first project without requisites', function () { $t = Tenant::factory()->create(['balance_rub' => '1000.00']); $u = User::factory()->for($t)->create(); $resp = $this->actingAs($u)->postJson('/api/projects', [ 'name' => 'C', 'signal_type' => 'site', 'signal_identifier' => 'c.ru', 'daily_limit_target' => 5, 'delivery_days_mask' => 127, 'regions' => [], ]); $resp->assertStatus(422); $resp->assertJsonPath('error', 'requisites_required'); });