Files
portal/app/tests/Feature/Sales/SalesPeriodRequestTest.php
T

100 lines
3.6 KiB
PHP
Raw Normal View History

2026-07-18 15:20:44 +03:00
<?php
declare(strict_types=1);
use App\Models\SalesUser;
use Illuminate\Foundation\Testing\DatabaseTransactions;
/**
* TDD: единый разбор периода на ВСЕХ экранах портала продаж.
*
* Владелец пожаловался «выборка по срокам не работает»: выбрав «Произвольный»,
* менеджер отправлял period=custom БЕЗ дат, резолвер бросал InvalidArgumentException,
* и экран получал 500. На «Моих клиентах» это уже починено (422), а экраны
* начальника (сводка отдела, результативность, тарифы, выплаты) и «Мой доход»
* продолжали падать.
*
* Здесь фиксируем инвариант для всех точек сразу:
* 1. period=custom без дат → 422 с понятным текстом, а не 500.
* 2. from позже to → 422.
* 3. Новые периоды (today/yesterday/d7/d30) принимаются везде.
* 4. Период по умолчанию — d30 (как в PeriodPicker), а не месяц.
*
* Изоляция: DatabaseTransactions. DB_DATABASE=liderra_testing обязателен.
*/
uses(DatabaseTransactions::class);
function per_head(): SalesUser
{
return SalesUser::create([
'name' => 'Начальник '.uniqid(),
'email' => 'perhead'.uniqid().'@sales.local',
'password' => bcrypt('secret'),
'role' => 'head',
'is_active' => true,
]);
}
/**
* Все GET-точки, которые принимают период. Начальник видит все,
* поэтому одним пользователем покрываем и менеджерские, и boss-only.
*
* @return list<string>
*/
function per_endpoints(): array
{
return [
'/api/sales/clients',
'/api/sales/dashboard/overview',
'/api/sales/income',
'/api/sales/managers/performance',
'/api/sales/payouts/remaining',
'/api/sales/tariffs',
];
}
it('произвольный период без дат отвечает 422, а не падает', function () {
$head = per_head();
foreach (per_endpoints() as $url) {
$this->actingAs($head, 'sales')
->getJson($url.'?period=custom')
->assertStatus(422)
->assertJsonValidationErrors('period');
}
});
it('произвольный период с одной датой отвечает 422', function () {
$head = per_head();
foreach (per_endpoints() as $url) {
$this->actingAs($head, 'sales')
->getJson($url.'?period=custom&from=2026-07-01')
->assertStatus(422)
->assertJsonValidationErrors('period');
}
});
it('перевёрнутый произвольный период отвечает 422', function () {
$head = per_head();
foreach (per_endpoints() as $url) {
$this->actingAs($head, 'sales')
->getJson($url.'?period=custom&from=2026-07-10&to=2026-07-01')
->assertStatus(422)
->assertJsonValidationErrors('period');
}
});
it('новые периоды календаря принимаются на всех экранах', function () {
$head = per_head();
foreach (per_endpoints() as $url) {
foreach (['today', 'yesterday', 'd7', 'd30'] as $kind) {
$this->actingAs($head, 'sales')
->getJson($url.'?period='.$kind)
->assertOk();
}
}
});