Files
daily-meal-api/tests/Feature/NotificationDeliveryTest.php
T
leonm 29e85589b0
CI / 🧪 Tests Laravel (push) Successful in 2m24s
CI / 🐳 Build & Push Image (push) Successful in 1m13s
feat: revenue cat
2026-08-12 16:00:11 +02:00

104 lines
3.6 KiB
PHP

<?php
use App\Actions\ReviewIdentityVerification;
use App\Enums\IdentityVerificationStatus;
use App\Enums\UserRole;
use App\Models\IdentityVerificationRequest;
use App\Models\User;
use App\Notifications\CertificationReviewedNotification;
use App\Notifications\EngagementReminderNotification;
use App\Notifications\NewFollowerNotification;
use App\Notifications\PaymentFailedNotification;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Storage;
use Laravel\Sanctum\Sanctum;
uses(RefreshDatabase::class);
it('respects social and engagement push preferences', function () {
$follower = User::factory()->create();
$user = User::factory()->create([
'social_notifications_enabled' => false,
'engagement_reminders_enabled' => false,
]);
expect((new NewFollowerNotification($follower))->via($user))
->toBe(['database'])
->and((new EngagementReminderNotification('publish_meal'))->via($user))
->toBe([])
->and((new PaymentFailedNotification)->via($user))
->toBe(['database', 'expo']);
$user->notifyNow(new NewFollowerNotification($follower));
$this->assertDatabaseHas('notifications', [
'type' => 'new_follower',
'notifiable_id' => $user->getKey(),
]);
});
it('notifies a user only once when a new follower is attached', function () {
Notification::fake();
$follower = User::factory()->create();
$followed = User::factory()->create();
Sanctum::actingAs($follower);
$this->postJson("/api/users/{$followed->id}/follow")->assertOk();
$this->postJson("/api/users/{$followed->id}/follow")->assertOk();
Notification::assertSentToTimes($followed, NewFollowerNotification::class, 1);
});
it('notifies the user when certification is reviewed', function () {
Notification::fake();
Storage::fake('identity_documents');
$user = User::factory()->create(['certification_purchased_at' => now()]);
$admin = User::factory()->create(['role' => UserRole::ADMIN]);
$verificationRequest = IdentityVerificationRequest::factory()->for($user)->create();
Storage::disk('identity_documents')->put($verificationRequest->document_path, 'identity');
app(ReviewIdentityVerification::class)->execute(
$verificationRequest,
IdentityVerificationStatus::APPROVED,
$admin,
);
Notification::assertSentTo($user, CertificationReviewedNotification::class);
});
it('notifies a user only once when a RevenueCat billing issue is replayed', function () {
Notification::fake();
config()->set('billing.revenuecat.secret_key', 'rc-secret');
config()->set('billing.revenuecat.webhook_authorization', 'Bearer rc-webhook');
$user = User::factory()->create();
Http::fake([
"api.revenuecat.com/v1/subscribers/{$user->id}" => Http::response([
'subscriber' => [
'entitlements' => [],
'subscriptions' => [],
],
]),
]);
$event = [
'event' => [
'id' => 'rc-billing-issue',
'type' => 'BILLING_ISSUE',
'app_user_id' => $user->id,
'product_id' => 'monthly',
'entitlement_ids' => ['bowli Pro'],
'environment' => 'PRODUCTION',
],
];
$this->withHeader('Authorization', 'Bearer rc-webhook')
->postJson('/api/webhooks/revenuecat', $event)
->assertOk();
$this->withHeader('Authorization', 'Bearer rc-webhook')
->postJson('/api/webhooks/revenuecat', $event)
->assertOk();
Notification::assertSentToTimes($user, PaymentFailedNotification::class, 1);
});