Files
portal/app/tests/Feature/ClientSms/PricingTest.php
T

122 lines
5.4 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
use App\Models\ClientSmsMessage;
use App\Models\Tenant;
use App\Models\User;
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('segments() делегирует калькулятору', function () {
$p = app(ClientSmsPricing::class);
expect($p->segments('короткий'))->toBe(1);
});
/*
|--------------------------------------------------------------------------
| Строка листа 3.8: ступень берётся с учётом УЖЕ отправленного за месяц.
|--------------------------------------------------------------------------
| Прежде цена считалась по объёму одного заказа: клиент, разбивший месяц на
| десять рассылок по сто номеров, платил по самой дорогой ступени, хотя отправил
| тысячу. Теперь ступень берётся для «накоплено за месяц + объём этого заказа».
|
| Помощники с префиксом price* — имена функций в Pest ГЛОБАЛЬНЫЕ.
| Синтетические номера 7999… — реальные НИКОГДА.
*/
/** Уже отправленные в этом месяце СМС (одна строка журнала на $segments штук). */
function priceSentThisMonth(int $tenantId, int $segments): void
{
ClientSmsMessage::create([
'tenant_id' => $tenantId,
'phone' => '79990000001',
'status' => ClientSmsMessage::STATUS_SENT,
'segments' => $segments,
'cost_rub' => '0.00',
]);
}
it('3.8 — ступень берётся для «накоплено за месяц + объём заказа»', function () {
$tenant = Tenant::factory()->create();
$p = app(ClientSmsPricing::class);
// Заказ сам по себе маленький — 200 СМС, это ступень 8.50.
expect($p->pricePerSmsRub(200))->toBe('8.50');
// Но в этом месяце клиент уже отправил 900 — вместе выходит 1 100, ступень 8.00.
priceSentThisMonth((int) $tenant->id, 900);
expect($p->pricePerSmsRubFor((int) $tenant->id, 200))->toBe('8.00');
});
it('3.8 — контрольный: без накопленного цена та же, что была', function () {
// Без этого прогона предыдущий ничего не доказывает: «8.00» могло бы означать
// «теперь всегда самая дешёвая ступень» (урок В-54).
$tenant = Tenant::factory()->create();
expect(app(ClientSmsPricing::class)->pricePerSmsRubFor((int) $tenant->id, 200))->toBe('8.50');
});
it('3.8 — чужие отправки на мою цену не влияют', function () {
$tenant = Tenant::factory()->create();
$other = Tenant::factory()->create();
priceSentThisMonth((int) $other->id, 5000);
expect(app(ClientSmsPricing::class)->pricePerSmsRubFor((int) $tenant->id, 200))->toBe('8.50');
});
it('3.8 — предпросмотр отдаёт цену с учётом отправленного за месяц', function () {
// Проверка НЕ на сервисе, а через настоящий запрос экрана: иначе вырез «вернуть
// старый расчёт в контроллере» прошёл бы незамеченным — сервис-то остался умным.
config(['services.sms.sandbox' => true]);
$tenant = Tenant::factory()->create();
$user = User::factory()->create(['tenant_id' => $tenant->id]);
$this->actingAs($user);
priceSentThisMonth((int) $tenant->id, 5000);
$response = $this->postJson('/api/sms/preview', [
'body' => 'Здравствуйте!',
'source' => 'manual',
'phones' => ['79995550001'],
])->assertOk();
expect($response->json('price_rub_per_sms'))->toBe('8.00')
->and($response->json('estimated_cost_rub'))->toBe('8.00');
});
it('3.8 — контрольный: без отправленного предпросмотр даёт прежнюю цену', function () {
config(['services.sms.sandbox' => true]);
$tenant = Tenant::factory()->create();
$user = User::factory()->create(['tenant_id' => $tenant->id]);
$this->actingAs($user);
$response = $this->postJson('/api/sms/preview', [
'body' => 'Здравствуйте!',
'source' => 'manual',
'phones' => ['79995550001'],
])->assertOk();
expect($response->json('price_rub_per_sms'))->toBe('9.00')
->and($response->json('estimated_cost_rub'))->toBe('9.00');
});