Files
portal/app/tests/Unit/Advertising/AdImpressionPricingTest.php
T
Дмитрий c9443dca0c feat(реклама): Часть 1 — денежная модель кампании «за показы» (CPM)
Перевод рекламного модуля с «за клики» на «за показы» (медийная кампания),
Часть 1 из 6 — денежное ядро и модель. На бой не выкачивается.

- AdImpressionPricing: чистый калькулятор (показы=аудитория×частота,
  клиентская сумма по 120₽/1000 с округлением вверх до копейки, маржа); bcmath scale 2.
- ad_settings.client_cpm_rub (default 120.00) — плоская клиентская цена, наценка клиенту не видна.
- ad_campaigns: поля модели «за показы» (frequency, *_impressions, budget_rub,
  yandex_cost_rub, charged_client_rub), weekly_budget_rub → nullable (клик-наследие).
- AdCampaign: fillable/casts + default delivered_impressions=0.
- CHANGELOG_schema v8.96 + требование скрытия маржи (yandex_cost_rub) в клиентской выдаче.

Тесты: 12/12 рекламных зелёные (вкл. регресс кошелька). rls-reviewer: PASS.
Spec: docs/superpowers/specs/2026-07-25-yandex-reklama-medijnaya-pokazy-design.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-26 00:43:26 +03:00

32 lines
1.3 KiB
PHP

<?php
declare(strict_types=1);
use App\Services\Advertising\AdImpressionPricing;
it('оценивает показы как аудитория × частота', function () {
$p = new AdImpressionPricing();
expect($p->impressionsForAudience(1630, 15))->toBe(24450);
expect($p->impressionsForAudience(0, 15))->toBe(0);
expect($p->impressionsForAudience(100, 1))->toBe(100);
});
it('считает клиентскую сумму по 120 ₽ за 1000 показов, округляя ВВЕРХ до копейки', function () {
$p = new AdImpressionPricing();
expect($p->clientCostRub(24450, '120.00'))->toBe('2934.00');
expect($p->clientCostRub(1, '120.00'))->toBe('0.12');
expect($p->clientCostRub(7, '120.00'))->toBe('0.84');
expect($p->clientCostRub(0, '120.00'))->toBe('0.00');
});
it('округляет неровную сумму вверх до копейки (клиент не недоплачивает)', function () {
$p = new AdImpressionPricing();
expect($p->clientCostRub(1, '125.00'))->toBe('0.13');
});
it('считает маржу как списано клиенту минус расход Яндекса', function () {
$p = new AdImpressionPricing();
expect($p->marginRub('2934.00', '1956.00'))->toBe('978.00');
expect($p->marginRub('100.00', '100.00'))->toBe('0.00');
});