feat: add persistent mobile notifications
CI / 🧪 Tests Laravel (push) Successful in 2m7s
CI / 🐳 Build & Push Image (push) Successful in 42s

This commit is contained in:
2026-08-11 16:46:05 +02:00
parent bd1b4bba20
commit df4f523089
24 changed files with 822 additions and 75 deletions
+19 -26
View File
@@ -3,9 +3,9 @@
use App\Models\MealPosts;
use App\Models\PostReviews;
use App\Models\User;
use App\Notifications\MealPostCommentedNotification;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Notification;
use Laravel\Sanctum\Sanctum;
uses(RefreshDatabase::class);
@@ -43,13 +43,7 @@ it('creates one review per user for a meal post', function () {
});
it('sends a push notification to the meal owner when another user comments on their meal', function () {
Http::fake([
'https://exp.host/*' => Http::response([
'data' => [
['status' => 'ok', 'id' => 'ticket-one'],
],
]),
]);
Notification::fake();
$owner = User::factory()->create();
$owner->deviceTokens()->create([
@@ -68,23 +62,22 @@ it('sends a push notification to the meal owner when another user comments on th
'comment' => 'Très bon repas.',
])->assertCreated();
Http::assertSent(fn (Request $request) => $request->url() === 'https://exp.host/--/api/v2/push/send'
&& $request->data() === [
[
'to' => 'ExponentPushToken[owner]',
'title' => 'New comment',
'body' => 'Alex commented on your meal "Recovery bowl".',
'sound' => 'default',
'channelId' => 'default',
'data' => [
'url' => "bowli://meals/{$mealPost->id}",
],
],
]);
Notification::assertSentTo(
$owner,
MealPostCommentedNotification::class,
function (MealPostCommentedNotification $notification) use ($mealPost, $owner): bool {
$payload = $notification->toExpoPush($owner);
return $payload['title'] === 'New comment'
&& $payload['body'] === 'Alex commented on your meal "Recovery bowl".'
&& $payload['data']['type'] === 'meal_commented'
&& $payload['data']['url'] === "bowli://meals/{$mealPost->id}";
},
);
});
it('does not send a push notification for rating-only reviews', function () {
Http::fake();
Notification::fake();
$owner = User::factory()->create();
$owner->deviceTokens()->create([
@@ -100,11 +93,11 @@ it('does not send a push notification for rating-only reviews', function () {
'rating' => 5,
])->assertCreated();
Http::assertNothingSent();
Notification::assertNothingSent();
});
it('does not notify the owner when they comment on their own meal', function () {
Http::fake();
Notification::fake();
$owner = User::factory()->create();
$owner->deviceTokens()->create([
@@ -120,7 +113,7 @@ it('does not notify the owner when they comment on their own meal', function ()
'comment' => 'Note personnelle.',
])->assertCreated();
Http::assertNothingSent();
Notification::assertNothingSent();
});
it('lists reviews for a single meal post', function () {