withoutMiddleware(ThrottleRequests::class); config(['snowflake.datacenter_id' => 1, 'snowflake.worker_id' => 1]); }); function readTestUser(): User { $user = User::factory()->create(['created_at' => now()->subYear()]); $user->refresh(); UserSetting::updateOrCreate(['user_id' => $user->id], ['public_dm' => true]); return $user; } function readTestSend(User $from, User $to, string $text): DmMessage { $service = app(DirectMessageService::class); $sender = Profile::findOrFail($from->profile_id); return $service->sendMessage( $service->findOrCreateDm($sender, Profile::findOrFail($to->profile_id)), $sender, ['body' => $text] ); } describe('POST /api/v1.1/direct/thread/read', function () { it('marks matching messages as read and returns their ids', function () { $recipient = readTestUser(); $sender = readTestUser(); $one = readTestSend($sender, $recipient, 'one'); $two = readTestSend($sender, $recipient, 'two'); Passport::actingAs($recipient, ['write']); $response = $this->postJson('/api/v1.1/direct/thread/read', [ 'pid' => $sender->profile_id, 'sid' => $one->id, ]); $response->assertOk(); $returned = collect($response->json())->map(fn ($id) => (int) $id)->all(); expect($returned)->toContain($one->id)->toContain($two->id); $state = DmConversationParticipant::where('profile_id', $recipient->profile_id)->first(); expect($state->last_read_message_id)->toBe($two->id) ->and($state->unread_count)->toBe(0); }); it('does not report messages below the given id', function () { $recipient = readTestUser(); $sender = readTestUser(); $older = readTestSend($sender, $recipient, 'older'); $newer = readTestSend($sender, $recipient, 'newer'); Passport::actingAs($recipient, ['write']); $returned = collect($this->postJson('/api/v1.1/direct/thread/read', [ 'pid' => $sender->profile_id, 'sid' => $newer->id, ])->assertOk()->json())->map(fn ($id) => (int) $id)->all(); expect($returned)->toBe([$newer->id]); }); it('does not mark another senders messages as read', function () { $recipient = readTestUser(); $sender = readTestUser(); $other = readTestUser(); $fromSender = readTestSend($sender, $recipient, 'hi'); readTestSend($other, $recipient, 'hey'); Passport::actingAs($recipient, ['write']); $this->postJson('/api/v1.1/direct/thread/read', [ 'pid' => $sender->profile_id, 'sid' => $fromSender->id, ])->assertOk(); $states = DmConversationParticipant::where('profile_id', $recipient->profile_id)->get(); expect($states->firstWhere('last_read_message_id', $fromSender->id))->not->toBeNull() ->and($states->sum('unread_count'))->toBe(1); }); });