5a4c0e0235
Часть 5c — баннеры: клиент грузит свой готовый файл на каждый из 15 размеров вместо автогенерации из одной картинки. Частичное утверждение флагом included, замена и удаление отдельного баннера, валидация точного размера и веса. Админ-поле цены за 1000 показов. Пример CSV для скачивания и подъём лимита загрузки. Часть 5d — два режима сбора аудитории. Авто: скользящее окно, обновляется ежедневно, только контакты системы. Ручной: снимок сделок за период плюс свой список номеров и срок показа. Клиент сам задаёт цену за 1000 показов с дефолтом из админки. Наценка настраивается в админке, по умолчанию 40 процентов, в Директ уходит меньше, клиенту не видна нигде. Миграции: ad_campaign_banners += included; ad_campaigns += mode/snapshot_from/snapshot_to/run_days/client_cpm_rub; ad_settings += ad_margin_percent. RLS-ревью PASS на всех миграциях. Backend 166 тестов, фронт 123 теста, сборка чистая. Маржа и yandex_cost_rub клиенту не сериализуются. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
66 lines
2.5 KiB
PHP
66 lines
2.5 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||
use Illuminate\Support\Facades\DB;
|
||
|
||
uses(DatabaseTransactions::class);
|
||
|
||
/**
|
||
* SaaS-admin: «цена клиенту за 1000 показов» — ad_settings.client_cpm_rub
|
||
* (глобальная single-row настройка, как markup_percent).
|
||
*/
|
||
test('GET /api/admin/advertising/settings отдаёт текущий client_cpm_rub (дефолт 120.00)', function () {
|
||
$r = $this->getJson('/api/admin/advertising/settings');
|
||
|
||
$r->assertStatus(200);
|
||
expect($r->json('client_cpm_rub'))->toBe('120.00');
|
||
});
|
||
|
||
test('PUT /api/admin/advertising/settings обновляет client_cpm_rub, GET показывает новое значение', function () {
|
||
$r = $this->putJson('/api/admin/advertising/settings', ['client_cpm_rub' => '90.00']);
|
||
|
||
$r->assertStatus(200);
|
||
expect($r->json('client_cpm_rub'))->toBe('90.00');
|
||
|
||
expect(DB::table('ad_settings')->value('client_cpm_rub'))->toBe('90.00');
|
||
|
||
$get = $this->getJson('/api/admin/advertising/settings');
|
||
expect($get->json('client_cpm_rub'))->toBe('90.00');
|
||
});
|
||
|
||
test('PUT /api/admin/advertising/settings с client_cpm_rub=0 → 422', function () {
|
||
$this->putJson('/api/admin/advertising/settings', ['client_cpm_rub' => '0'])
|
||
->assertStatus(422);
|
||
});
|
||
|
||
test('PUT /api/admin/advertising/settings без поля client_cpm_rub → 422', function () {
|
||
$this->putJson('/api/admin/advertising/settings', [])
|
||
->assertStatus(422);
|
||
});
|
||
|
||
test('GET /api/admin/advertising/settings отдаёт ad_margin_percent (дефолт 40.00)', function () {
|
||
$r = $this->getJson('/api/admin/advertising/settings');
|
||
|
||
$r->assertStatus(200);
|
||
expect($r->json('ad_margin_percent'))->toBe('40.00');
|
||
});
|
||
|
||
test('PUT /api/admin/advertising/settings обновляет ad_margin_percent, GET показывает новое значение', function () {
|
||
$r = $this->putJson('/api/admin/advertising/settings', ['ad_margin_percent' => '35']);
|
||
|
||
$r->assertStatus(200);
|
||
expect($r->json('ad_margin_percent'))->toBe('35.00');
|
||
|
||
expect(DB::table('ad_settings')->value('ad_margin_percent'))->toBe('35.00');
|
||
|
||
$get = $this->getJson('/api/admin/advertising/settings');
|
||
expect($get->json('ad_margin_percent'))->toBe('35.00');
|
||
});
|
||
|
||
test('PUT /api/admin/advertising/settings с ad_margin_percent=95 → 422 (>90)', function () {
|
||
$this->putJson('/api/admin/advertising/settings', ['ad_margin_percent' => '95'])
|
||
->assertStatus(422);
|
||
});
|