19ab348c58
Капча: добавлен тестовый драйвер CAPTCHA_DRIVER=null и CAPTCHA_FAKE_PASSES в phpunit.xml, иначе тесты наследовали боевой yandex из .env и регистрация падала на проверке я не робот. Плюс изоляция двух тестов от состояния учебной базы: BillingMigrateLeadsToRubTest считает операции своего тенанта, BillingSummaryProviderTest берёт дату вне периода из следующего месяца. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
86 lines
3.0 KiB
PHP
86 lines
3.0 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
use App\Models\BalanceTransaction;
|
||
use App\Models\ReportJob;
|
||
use App\Models\Tenant;
|
||
use App\Services\Reports\Providers\BillingSummaryProvider;
|
||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||
use Illuminate\Support\Carbon;
|
||
|
||
uses(DatabaseTransactions::class);
|
||
|
||
beforeEach(function () {
|
||
$this->tenant = Tenant::factory()->create();
|
||
});
|
||
|
||
function seedBillingTx(int $tenantId, string $type, float $amount, ?Carbon $at = null): void
|
||
{
|
||
BalanceTransaction::create([
|
||
'tenant_id' => $tenantId,
|
||
'type' => $type,
|
||
'amount_rub' => $amount,
|
||
'amount_leads' => 0,
|
||
'description' => 'test',
|
||
'created_at' => $at ?? Carbon::now()->startOfMonth()->addDays(10),
|
||
]);
|
||
}
|
||
|
||
function billingJob(int $tenantId): ReportJob
|
||
{
|
||
return new ReportJob([
|
||
'tenant_id' => $tenantId,
|
||
'type' => 'billing_summary',
|
||
'parameters' => [
|
||
'format' => 'csv',
|
||
'date_from' => Carbon::now()->startOfMonth()->toDateString(),
|
||
'date_to' => Carbon::now()->endOfMonth()->toDateString(),
|
||
],
|
||
]);
|
||
}
|
||
|
||
test('headers: 3 колонки', function () {
|
||
expect((new BillingSummaryProvider)->headers())
|
||
->toBe(['Тип операции', 'Количество', 'Сумма (₽)']);
|
||
});
|
||
|
||
test('slug = billing', function () {
|
||
expect((new BillingSummaryProvider)->slug())->toBe('billing');
|
||
});
|
||
|
||
test('агрегирует balance_transactions по типу: count + сумма', function () {
|
||
seedBillingTx($this->tenant->id, 'topup', 5000);
|
||
seedBillingTx($this->tenant->id, 'topup', 3000);
|
||
seedBillingTx($this->tenant->id, 'lead_charge', -250);
|
||
|
||
$rows = (new BillingSummaryProvider)->rows(billingJob($this->tenant->id));
|
||
|
||
// ORDER BY type → 'lead_charge' < 'topup'.
|
||
expect($rows)->toHaveCount(2);
|
||
expect($rows[0])->toBe(['Списание за лиды', 1, '-250.00']);
|
||
expect($rows[1])->toBe(['Пополнение', 2, '8000.00']);
|
||
});
|
||
|
||
test('исключает транзакции вне периода', function () {
|
||
seedBillingTx($this->tenant->id, 'topup', 5000);
|
||
// «Вне периода» берём из СЛЕДУЮЩЕГО месяца: партиции balance_transactions заводятся
|
||
// наперёд (pg_partman premake), а назад со временем удаляются — past-дата (subMonths)
|
||
// рано или поздно упирается в отсутствующую старую партицию.
|
||
seedBillingTx($this->tenant->id, 'topup', 1000, Carbon::now()->addMonth()->day(15));
|
||
|
||
$rows = (new BillingSummaryProvider)->rows(billingJob($this->tenant->id));
|
||
|
||
expect($rows)->toHaveCount(1);
|
||
expect($rows[0])->toBe(['Пополнение', 1, '5000.00']);
|
||
});
|
||
|
||
test('изолирует по tenant_id', function () {
|
||
$other = Tenant::factory()->create();
|
||
seedBillingTx($other->id, 'topup', 9999);
|
||
|
||
$rows = (new BillingSummaryProvider)->rows(billingJob($this->tenant->id));
|
||
|
||
expect($rows)->toBe([]);
|
||
});
|