3ec722416c
ClientSmsPricing (ступень по объёму получатели×сегменты, наценка не применяется), ClientSmsAudienceBuilder (сделки/база/список, tenant-scope SET LOCAL + явный where, нормализация телефона), ClientSmsRecipientSelector (стоп-лист→дубль→маршрут), ClientSmsPlan DTO. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
36 lines
1.4 KiB
PHP
36 lines
1.4 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
use App\Services\ClientSms\ClientSmsPricing;
|
||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||
|
||
uses(RefreshDatabase::class);
|
||
|
||
it('ступень выбирается по объёму (границы)', function () {
|
||
$p = app(ClientSmsPricing::class);
|
||
expect($p->pricePerSmsRub(99))->toBe('9.00')
|
||
->and($p->pricePerSmsRub(100))->toBe('8.50')
|
||
->and($p->pricePerSmsRub(249))->toBe('8.50')
|
||
->and($p->pricePerSmsRub(250))->toBe('8.30')
|
||
->and($p->pricePerSmsRub(500))->toBe('8.10')
|
||
->and($p->pricePerSmsRub(999))->toBe('8.10')
|
||
->and($p->pricePerSmsRub(1000))->toBe('8.00')
|
||
->and($p->pricePerSmsRub(50000))->toBe('8.00')
|
||
->and($p->pricePerSmsRub(0))->toBe('9.00'); // volume floored to >=1
|
||
});
|
||
|
||
it('смета = объём × цена ступени', function () {
|
||
$p = app(ClientSmsPricing::class);
|
||
// 300 recipients × 1 segment = volume 300 → tier 8.30 → 2490.00
|
||
expect($p->estimateRub(300, 1))->toBe('2490.00')
|
||
// 60 recipients × 2 segments = volume 120 → tier 8.50 → 1020.00
|
||
->and($p->estimateRub(60, 2))->toBe('1020.00')
|
||
->and($p->estimateRub(0, 1))->toBe('0.00'); // no recipients → 0
|
||
});
|
||
|
||
it('segments() делегирует калькулятору', function () {
|
||
$p = app(ClientSmsPricing::class);
|
||
expect($p->segments('короткий'))->toBe(1);
|
||
});
|