token = 'test-token-12345'; $this->worker = Worker::create([ 'name' => 'Jane Smith', 'email' => 'jane@example.com', 'phone' => '+971500000001', 'password' => bcrypt('password'), 'api_token' => $this->token, 'status' => 'Available', 'nationality' => 'Ethiopian', 'age' => 28, 'salary' => 1500.00, 'availability' => 'Immediate', 'experience' => '2 Years', 'religion' => 'Christian', 'bio' => 'Experienced housemaid seeking employment.', ]); // Create an employer user $this->employer = User::create([ 'name' => 'John Employer', 'email' => 'employer_test@example.com', 'password' => bcrypt('password'), 'role' => 'employer', ]); } /** * Test retrieving conversation list for a worker. */ public function test_worker_can_get_conversations() { // Create conversation $conversation = Conversation::create([ 'employer_id' => $this->employer->id, 'worker_id' => $this->worker->id, ]); // Create a message from employer Message::create([ 'conversation_id' => $conversation->id, 'sender_type' => 'employer', 'sender_id' => $this->employer->id, 'text' => 'Hello from employer!', ]); // Request API $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->getJson('/api/workers/conversations'); $response->assertStatus(200) ->assertJsonStructure([ 'success', 'data' => [ 'conversations' => [ '*' => [ 'id', 'employer_id', 'employer_name', 'company_name', 'last_message', 'unread_count', 'sent_at', 'updated_at', ] ] ] ]); $this->assertEquals('Hello from employer!', $response->json('data.conversations.0.last_message')); $this->assertEquals(1, $response->json('data.conversations.0.unread_count')); } /** * Test retrieving messages in a conversation and marking them as read. */ public function test_worker_can_get_messages_and_mark_as_read() { // Create conversation $conversation = Conversation::create([ 'employer_id' => $this->employer->id, 'worker_id' => $this->worker->id, ]); // Create message $message = Message::create([ 'conversation_id' => $conversation->id, 'sender_type' => 'employer', 'sender_id' => $this->employer->id, 'text' => 'Unread message', 'read_at' => null, ]); // Request API $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->getJson('/api/workers/conversations/' . $conversation->id . '/messages'); $response->assertStatus(200) ->assertJsonStructure([ 'success', 'data' => [ 'conversation' => [ 'id', 'employer_name', 'company_name', ], 'messages' => [ '*' => [ 'id', 'sender_type', 'text', 'time', 'read_at', 'created_at', ] ] ] ]); // Verify message marked as read in database $this->assertNotNull($message->fresh()->read_at); } /** * Test worker can send reply. */ public function test_worker_can_send_reply() { // Create conversation $conversation = Conversation::create([ 'employer_id' => $this->employer->id, 'worker_id' => $this->worker->id, ]); // Reply request $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->postJson('/api/workers/conversations/' . $conversation->id . '/messages', [ 'text' => 'Hello Employer, I am available!' ]); $response->assertStatus(201) ->assertJsonStructure([ 'success', 'message', 'data' => [ 'message' => [ 'id', 'sender_type', 'text', 'time', 'created_at', ] ] ]); // Verify message created in database $this->assertDatabaseHas('messages', [ 'conversation_id' => $conversation->id, 'sender_type' => 'worker', 'sender_id' => $this->worker->id, 'text' => 'Hello Employer, I am available!', ]); } /** * Test request fails without authorization token. */ public function test_unauthenticated_requests_are_blocked() { $response = $this->getJson('/api/workers/conversations'); $response->assertStatus(401); } /** * Test worker message triggers push notification. */ public function test_worker_message_triggers_push_notification() { \Illuminate\Support\Facades\Http::fake([ 'https://oauth2.googleapis.com/token' => \Illuminate\Support\Facades\Http::response(['access_token' => 'mocked-fcm-token'], 200), 'https://fcm.googleapis.com/*' => \Illuminate\Support\Facades\Http::response(['name' => 'projects/migrant-fe5a7/messages/mock-id'], 200), ]); // Set fcm_token on employer $this->employer->update(['fcm_token' => 'employer-device-fcm-token-123']); // Create conversation $conversation = Conversation::create([ 'employer_id' => $this->employer->id, 'worker_id' => $this->worker->id, ]); // Reply request $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->postJson('/api/workers/conversations/' . $conversation->id . '/messages', [ 'text' => 'Testing push notification to employer!' ]); $response->assertStatus(201); // Assert Http call was made to FCM endpoint \Illuminate\Support\Facades\Http::assertSent(function ($request) { return str_contains($request->url(), 'fcm.googleapis.com') && $request['message']['token'] === 'employer-device-fcm-token-123' && $request['message']['notification']['body'] === 'Testing push notification to employer!'; }); } }