Files
portal/app/tests/Feature/Notifications/BalanceNotificationsTest.php
T
Дмитрий ebca32a212 refactor(billing): Phase 2 — remove legacy ProcessWebhookJob + cascade test cleanup
Удалён рудимент pre-sharing эпохи:
- app/app/Jobs/ProcessWebhookJob.php (job целиком, 342 строки)
- app/tests/Feature/ProcessWebhookJobTest.php (тест целиком, 362 строки)

Каскадная чистка 4 тест-файлов:
- BalanceNotificationsTest: -128 строк (оставлены topup_success/invoice_paid)
- InAppNotificationTest: -168 строк (остался notifyInApp direct)
- NewLeadNotificationTest: целиком удалён (-199 строк)
- DealCreatePdLogTest: -36 строк webhook-кейса (остались API+Route)

Локальный smoke (7 тестов без --parallel): 7 passed / 20 assertions.

Phase 2 плана 2026-05-24-legacy-direct-webhook-removal.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 18:51:12 +03:00

93 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
use App\Mail\InvoicePaidNotification;
use App\Mail\TopupSuccessNotification;
use App\Models\InAppNotification;
use App\Models\Tenant;
use App\Models\User;
use App\Services\NotificationService;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Mail;
uses(DatabaseTransactions::class);
beforeEach(function () {
Mail::fake();
});
function makeUserForBalance(Tenant $tenant, string $email, array $events = []): User
{
return User::factory()->create([
'tenant_id' => $tenant->id,
'email' => $email,
'notification_preferences' => array_merge([
'new_lead' => ['email' => false, 'inapp' => false],
'reminder' => ['email' => true, 'inapp' => true],
'low_balance' => ['email' => true, 'inapp' => true],
'zero_balance' => ['email' => true, 'inapp' => true],
'topup_success' => ['email' => true, 'inapp' => true],
'invoice_paid' => ['email' => true, 'inapp' => true],
'new_device_login' => ['email' => true, 'inapp' => false],
'marketing' => ['email' => false, 'inapp' => false],
], $events),
]);
}
// ============== topup_success ==============
test('topup_success: notifyTopupSuccess создаёт email + inapp', function () {
$tenant = Tenant::factory()->create();
makeUserForBalance($tenant, 'on@example.ru');
app(NotificationService::class)->notifyTopupSuccess($tenant, '5000.00', 100);
Mail::assertSent(TopupSuccessNotification::class, 1);
Mail::assertSent(function (TopupSuccessNotification $m): bool {
return $m->amountRub === '5000.00' && $m->amountLeads === 100 && $m->hasTo('on@example.ru');
});
expect(InAppNotification::query()->where('event', 'topup_success')->count())->toBe(1);
});
test('topup_success: prefs=email:false — только inapp', function () {
$tenant = Tenant::factory()->create();
makeUserForBalance($tenant, 'on@example.ru', [
'topup_success' => ['email' => false, 'inapp' => true],
]);
app(NotificationService::class)->notifyTopupSuccess($tenant, '1000.00', null);
Mail::assertNothingSent();
expect(InAppNotification::query()->where('event', 'topup_success')->count())->toBe(1);
});
// ============== invoice_paid ==============
test('invoice_paid: notifyInvoicePaid создаёт email + inapp', function () {
$tenant = Tenant::factory()->create();
makeUserForBalance($tenant, 'on@example.ru');
app(NotificationService::class)->notifyInvoicePaid($tenant, '990.00', 'INV-2026-0042', 'Команда');
Mail::assertSent(InvoicePaidNotification::class, 1);
Mail::assertSent(function (InvoicePaidNotification $m): bool {
return $m->amountRub === '990.00'
&& $m->invoiceNumber === 'INV-2026-0042'
&& $m->tariffName === 'Команда';
});
expect(InAppNotification::query()->where('event', 'invoice_paid')->count())->toBe(1);
});
test('invoice_paid: prefs=email:false — только inapp', function () {
$tenant = Tenant::factory()->create();
makeUserForBalance($tenant, 'on@example.ru', [
'invoice_paid' => ['email' => false, 'inapp' => true],
]);
app(NotificationService::class)->notifyInvoicePaid($tenant, '990.00');
Mail::assertNothingSent();
expect(InAppNotification::query()->where('event', 'invoice_paid')->count())->toBe(1);
});