— PHPStan не понимает * привязку $this в Pest и ругается на каждое обращение. */ function sms_selector(): SmsRecipientSelector { return new SmsRecipientSelector(new SmsRouter([new FakeSmsProvider])); } function sms_phone(string $phone, array $overrides = []): SalesAdAudiencePhone { return SalesAdAudiencePhone::create(array_merge([ 'phone' => $phone, 'expires_at' => now()->addDays(30), 'state' => 'active', 'operator' => 'МТС', 'phone_type' => 'mobile', ], $overrides)); } it('годный номер попадает в отправку', function () { sms_phone('79990000001'); $plan = sms_selector()->build(['79990000001']); expect($plan->sendable)->toHaveCount(1) ->and($plan->skipped)->toBeEmpty(); }); it('номер из стоп-листа не отправляется никогда', function () { sms_phone('79990000002'); SalesSmsOptout::create(['phone' => '79990000002', 'reason' => 'manual', 'created_at' => now()]); $plan = sms_selector()->build(['79990000002']); expect($plan->sendable)->toBeEmpty() ->and($plan->skipped)->toBe(['79990000002' => SalesSmsMessage::SKIP_OPTOUT]); }); it('городской номер не отправляется — деньги сгорели бы впустую', function () { sms_phone('79990000003', ['phone_type' => 'landline']); $plan = sms_selector()->build(['79990000003']); expect($plan->skipped)->toBe(['79990000003' => SalesSmsMessage::SKIP_NOT_MOBILE]); }); it('погашенный номер не отправляется', function () { sms_phone('79990000004', ['removed_at' => now()]); $plan = sms_selector()->build(['79990000004']); expect($plan->skipped)->toBe(['79990000004' => SalesSmsMessage::SKIP_INACTIVE]); }); it('дубль внутри одного запуска считается один раз', function () { sms_phone('79990000005'); $plan = sms_selector()->build(['79990000005', '79990000005']); expect($plan->sendable)->toHaveCount(1); }); it('без подходящего провайдера номер помечается без маршрута', function () { sms_phone('79990000006'); $selector = new SmsRecipientSelector(new SmsRouter([])); $plan = $selector->build(['79990000006']); expect($plan->skipped)->toBe(['79990000006' => SalesSmsMessage::SKIP_NO_ROUTE]); });