309 lines
12 KiB
PHP
309 lines
12 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\User;
|
|
use App\Models\Worker;
|
|
use App\Notifications\DocumentExpiryNotification;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class NotificationApiTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
private function createTestWorker(array $overrides = []): Worker
|
|
{
|
|
return Worker::create(array_merge([
|
|
'name' => 'John Worker',
|
|
'email' => 'worker@example.com',
|
|
'password' => bcrypt('password'),
|
|
'phone' => '971500000001',
|
|
'nationality' => 'Indian',
|
|
'status' => 'active',
|
|
'api_token' => 'worker_api_token',
|
|
'age' => 25,
|
|
'salary' => 2000,
|
|
'availability' => 'Immediate',
|
|
'experience' => '2 Years',
|
|
'religion' => 'Christian',
|
|
'bio' => 'Helper info',
|
|
'passport_status' => 'valid',
|
|
], $overrides));
|
|
}
|
|
|
|
private function createTestEmployer(array $overrides = []): User
|
|
{
|
|
return User::create(array_merge([
|
|
'name' => 'Alice Employer',
|
|
'email' => 'employer@example.com',
|
|
'password' => bcrypt('password'),
|
|
'role' => 'employer',
|
|
'api_token' => 'employer_api_token',
|
|
'subscription_status' => 'active',
|
|
], $overrides));
|
|
}
|
|
|
|
public function test_worker_can_list_notifications_with_filters()
|
|
{
|
|
$worker = $this->createTestWorker();
|
|
|
|
// Send two notifications
|
|
$worker->notify(new DocumentExpiryNotification('Passport', '2026-12-31', 30, '30_days'));
|
|
$worker->notify(new DocumentExpiryNotification('Visa', '2026-12-31', 7, '7_days'));
|
|
|
|
// Mark the Passport notification as read deterministically
|
|
$passportNotification = $worker->unreadNotifications()->where('data->document_type', 'Passport')->first();
|
|
$passportNotification->markAsRead();
|
|
|
|
// 1. Fetch all notifications
|
|
$response = $this->getJson('/api/workers/notifications', [
|
|
'Authorization' => 'Bearer worker_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonPath('success', true);
|
|
$response->assertJsonCount(2, 'data.notifications');
|
|
|
|
// 2. Fetch unread notifications
|
|
$response = $this->getJson('/api/workers/notifications?filter=unread', [
|
|
'Authorization' => 'Bearer worker_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonCount(1, 'data.notifications');
|
|
$response->assertJsonPath('data.notifications.0.data.document_type', 'Visa');
|
|
|
|
// 3. Fetch read notifications
|
|
$response = $this->getJson('/api/workers/notifications?filter=read', [
|
|
'Authorization' => 'Bearer worker_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonCount(1, 'data.notifications');
|
|
$response->assertJsonPath('data.notifications.0.data.document_type', 'Passport');
|
|
}
|
|
|
|
public function test_worker_can_mark_single_and_all_notifications_as_read()
|
|
{
|
|
$worker = $this->createTestWorker();
|
|
|
|
// Send two notifications
|
|
$worker->notify(new DocumentExpiryNotification('Passport', '2026-12-31', 30, '30_days'));
|
|
$worker->notify(new DocumentExpiryNotification('Visa', '2026-12-31', 7, '7_days'));
|
|
|
|
$unread = $worker->unreadNotifications;
|
|
$this->assertEquals(2, $unread->count());
|
|
|
|
// 1. Mark single notification as read
|
|
$notificationId = $unread->first()->id;
|
|
$response = $this->putJson("/api/workers/notifications/{$notificationId}/read", [], [
|
|
'Authorization' => 'Bearer worker_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonPath('success', true);
|
|
$this->assertEquals(1, $worker->fresh()->unreadNotifications->count());
|
|
|
|
// 2. Mark all notifications as read
|
|
$response = $this->putJson('/api/workers/notifications/read', [], [
|
|
'Authorization' => 'Bearer worker_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonPath('success', true);
|
|
$this->assertEquals(0, $worker->fresh()->unreadNotifications->count());
|
|
}
|
|
|
|
public function test_worker_can_delete_single_and_all_notifications()
|
|
{
|
|
$worker = $this->createTestWorker();
|
|
|
|
// Send two notifications
|
|
$worker->notify(new DocumentExpiryNotification('Passport', '2026-12-31', 30, '30_days'));
|
|
$worker->notify(new DocumentExpiryNotification('Visa', '2026-12-31', 7, '7_days'));
|
|
|
|
$this->assertEquals(2, $worker->notifications()->count());
|
|
|
|
// 1. Delete single notification
|
|
$notificationId = $worker->notifications->first()->id;
|
|
$response = $this->deleteJson("/api/workers/notifications/{$notificationId}", [], [
|
|
'Authorization' => 'Bearer worker_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonPath('success', true);
|
|
$this->assertEquals(1, $worker->fresh()->notifications()->count());
|
|
|
|
// 2. Delete all notifications
|
|
$response = $this->deleteJson('/api/workers/notifications', [], [
|
|
'Authorization' => 'Bearer worker_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonPath('success', true);
|
|
$this->assertEquals(0, $worker->fresh()->notifications()->count());
|
|
}
|
|
|
|
public function test_employer_can_list_notifications_with_filters()
|
|
{
|
|
$employer = $this->createTestEmployer();
|
|
|
|
// Send two notifications
|
|
$employer->notify(new DocumentExpiryNotification('Emirates ID', '2026-12-31', 30, '30_days'));
|
|
$employer->notify(new DocumentExpiryNotification('Trade License', '2026-12-31', 7, '7_days'));
|
|
|
|
// Mark the Emirates ID notification as read deterministically
|
|
$emiratesIdNotification = $employer->unreadNotifications()->where('data->document_type', 'Emirates ID')->first();
|
|
$emiratesIdNotification->markAsRead();
|
|
|
|
// 1. Fetch all notifications
|
|
$response = $this->getJson('/api/employers/notifications', [
|
|
'Authorization' => 'Bearer employer_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonPath('success', true);
|
|
$response->assertJsonCount(2, 'data.notifications');
|
|
|
|
// 2. Fetch unread notifications
|
|
$response = $this->getJson('/api/employers/notifications?filter=unread', [
|
|
'Authorization' => 'Bearer employer_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonCount(1, 'data.notifications');
|
|
$response->assertJsonPath('data.notifications.0.data.document_type', 'Trade License');
|
|
|
|
// 3. Fetch read notifications
|
|
$response = $this->getJson('/api/employers/notifications?filter=read', [
|
|
'Authorization' => 'Bearer employer_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonCount(1, 'data.notifications');
|
|
$response->assertJsonPath('data.notifications.0.data.document_type', 'Emirates ID');
|
|
}
|
|
|
|
public function test_employer_can_mark_single_and_all_notifications_as_read()
|
|
{
|
|
$employer = $this->createTestEmployer();
|
|
|
|
// Send two notifications
|
|
$employer->notify(new DocumentExpiryNotification('Emirates ID', '2026-12-31', 30, '30_days'));
|
|
$employer->notify(new DocumentExpiryNotification('Trade License', '2026-12-31', 7, '7_days'));
|
|
|
|
$unread = $employer->unreadNotifications;
|
|
$this->assertEquals(2, $unread->count());
|
|
|
|
// 1. Mark single notification as read
|
|
$notificationId = $unread->first()->id;
|
|
$response = $this->putJson("/api/employers/notifications/{$notificationId}/read", [], [
|
|
'Authorization' => 'Bearer employer_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonPath('success', true);
|
|
$this->assertEquals(1, $employer->fresh()->unreadNotifications->count());
|
|
|
|
// 2. Mark all notifications as read
|
|
$response = $this->putJson('/api/employers/notifications/read', [], [
|
|
'Authorization' => 'Bearer employer_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonPath('success', true);
|
|
$this->assertEquals(0, $employer->fresh()->unreadNotifications->count());
|
|
}
|
|
|
|
public function test_employer_can_delete_single_and_all_notifications()
|
|
{
|
|
$employer = $this->createTestEmployer();
|
|
|
|
// Send two notifications
|
|
$employer->notify(new DocumentExpiryNotification('Emirates ID', '2026-12-31', 30, '30_days'));
|
|
$employer->notify(new DocumentExpiryNotification('Trade License', '2026-12-31', 7, '7_days'));
|
|
|
|
$this->assertEquals(2, $employer->notifications()->count());
|
|
|
|
// 1. Delete single notification
|
|
$notificationId = $employer->notifications->first()->id;
|
|
$response = $this->deleteJson("/api/employers/notifications/{$notificationId}", [], [
|
|
'Authorization' => 'Bearer employer_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonPath('success', true);
|
|
$this->assertEquals(1, $employer->fresh()->notifications()->count());
|
|
|
|
// 2. Delete all notifications
|
|
$response = $this->deleteJson('/api/employers/notifications', [], [
|
|
'Authorization' => 'Bearer employer_api_token'
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertJsonPath('success', true);
|
|
$this->assertEquals(0, $employer->fresh()->notifications()->count());
|
|
}
|
|
|
|
public function test_push_notification_sent_when_job_status_changes()
|
|
{
|
|
$worker = $this->createTestWorker();
|
|
$employer = $this->createTestEmployer();
|
|
|
|
$jobPost = \App\Models\JobPost::create([
|
|
'employer_id' => $employer->id,
|
|
'title' => 'Test Maid Job',
|
|
'main_profession' => 'Housekeeper',
|
|
'workers_needed' => 1,
|
|
'job_type' => 'Full Time',
|
|
'location' => 'Dubai',
|
|
'salary' => 2000,
|
|
'start_date' => now()->addDays(7),
|
|
'description' => 'Test description',
|
|
'status' => 'active',
|
|
]);
|
|
|
|
\App\Models\JobApplication::create([
|
|
'worker_id' => $worker->id,
|
|
'job_id' => $jobPost->id,
|
|
'status' => 'applied'
|
|
]);
|
|
|
|
$this->assertEquals(0, $worker->notifications()->count());
|
|
|
|
// Update JobPost status
|
|
$jobPost->update(['status' => 'closed']);
|
|
|
|
$notifications = $worker->fresh()->notifications;
|
|
$this->assertEquals(1, $notifications->count());
|
|
$notification = $notifications->first();
|
|
$this->assertEquals('Job Status Changed', $notification->data['title']);
|
|
$this->assertEquals('job_status_change', $notification->data['type']);
|
|
$this->assertEquals($jobPost->id, $notification->data['job_id']);
|
|
$this->assertEquals('active', $notification->data['old_status']);
|
|
$this->assertEquals('closed', $notification->data['new_status']);
|
|
}
|
|
|
|
public function test_push_notification_sent_when_worker_status_changes()
|
|
{
|
|
$worker = $this->createTestWorker([
|
|
'status' => 'active'
|
|
]);
|
|
|
|
$this->assertEquals(0, $worker->notifications()->count());
|
|
|
|
// Update Worker status
|
|
$worker->update(['status' => 'Hired']);
|
|
|
|
$notifications = $worker->fresh()->notifications;
|
|
$this->assertEquals(1, $notifications->count());
|
|
$notification = $notifications->first();
|
|
$this->assertEquals('Profile Status Update', $notification->data['title']);
|
|
$this->assertEquals('worker_status_change', $notification->data['type']);
|
|
$this->assertEquals($worker->id, $notification->data['worker_id']);
|
|
$this->assertEquals('active', $notification->data['old_status']);
|
|
$this->assertEquals('Hired', $notification->data['new_status']);
|
|
}
|
|
}
|