93 lines
3.4 KiB
PHP
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);
|
||
|
|
});
|