migrant-web/tests/Feature/WorkerMessageApiTest.php
2026-06-15 11:59:05 +05:30

236 lines
7.5 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Conversation;
use App\Models\Message;
use App\Models\User;
use App\Models\Worker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class WorkerMessageApiTest extends TestCase
{
use RefreshDatabase;
protected $worker;
protected $employer;
protected $token;
protected function setUp(): void
{
parent::setUp();
// Create a test worker with an API token
$this->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!';
});
}
}