'Rahul Sharma', 'email' => 'rahul@example.com', 'phone' => '+971501234567', 'language' => 'HI', 'password' => bcrypt('password'), 'nationality' => 'Indian', 'age' => 25, 'salary' => 1500, 'availability' => 'Immediate', 'experience' => 'Not Specified', 'religion' => 'Not Specified', 'bio' => 'Test', 'verified' => true, 'status' => 'active', 'api_token' => 'worker-test-token', ]); // Create passport document to prevent pending 404 WorkerDocument::create([ 'worker_id' => $worker->id, 'type' => 'passport', 'number' => '123456', 'file_path' => 'passports/test.pdf', ]); // Create an employer $employer = User::create([ 'name' => 'Employer One', 'email' => 'emp1@example.com', 'password' => bcrypt('password'), 'role' => 'employer', ]); EmployerProfile::create([ 'user_id' => $employer->id, 'company_name' => 'Ahmad Tech Ltd', 'nationality' => 'UAE', 'city' => 'Dubai', ]); // Create an accepted job offer (current employer) JobOffer::create([ 'employer_id' => $employer->id, 'worker_id' => $worker->id, 'work_date' => now()->subDays(10), 'location' => 'Dubai', 'salary' => 2500, 'status' => 'accepted', 'notes' => 'Current Active Job', ]); // Hit the worker dashboard API $response = $this->withHeaders([ 'Authorization' => 'Bearer worker-test-token', ])->getJson('/api/workers/dashboard'); $response->assertStatus(200) ->assertJson([ 'success' => true, 'data' => [ 'current_employer' => [ 'id' => $employer->id, 'name' => 'Employer One', 'company_name' => 'Ahmad Tech Ltd', 'city' => 'Dubai', 'nationality' => 'UAE', ], 'currently_working_sponsor' => [ 'id' => $employer->id, 'name' => 'Employer One', 'company_name' => 'Ahmad Tech Ltd', 'city' => 'Dubai', 'nationality' => 'UAE', ] ] ]); } public function test_worker_employers_list_pagination_and_sorting() { // Create worker $worker = Worker::create([ 'name' => 'Rahul Sharma', 'email' => 'rahul@example.com', 'phone' => '+971501234567', 'language' => 'HI', 'password' => bcrypt('password'), 'nationality' => 'Indian', 'age' => 25, 'salary' => 1500, 'availability' => 'Immediate', 'experience' => 'Not Specified', 'religion' => 'Not Specified', 'bio' => 'Test', 'verified' => true, 'status' => 'active', 'api_token' => 'worker-test-token', ]); WorkerDocument::create([ 'worker_id' => $worker->id, 'type' => 'passport', 'number' => '123456', 'file_path' => 'passports/test.pdf', ]); // Create 3 employers $emp1 = User::create([ 'name' => 'Employer One', 'email' => 'emp1@example.com', 'password' => bcrypt('password'), 'role' => 'employer' ]); EmployerProfile::create(['user_id' => $emp1->id, 'company_name' => 'Tech One']); $emp2 = User::create([ 'name' => 'Employer Two', 'email' => 'emp2@example.com', 'password' => bcrypt('password'), 'role' => 'employer' ]); EmployerProfile::create(['user_id' => $emp2->id, 'company_name' => 'Tech Two']); $emp3 = User::create([ 'name' => 'Employer Three', 'email' => 'emp3@example.com', 'password' => bcrypt('password'), 'role' => 'employer' ]); EmployerProfile::create(['user_id' => $emp3->id, 'company_name' => 'Tech Three']); // Create JobOffers: // Offer 1: Completed status, joining 20 days ago JobOffer::create([ 'employer_id' => $emp1->id, 'worker_id' => $worker->id, 'work_date' => now()->subDays(20), 'location' => 'Abu Dhabi', 'salary' => 2000, 'status' => 'completed', 'notes' => 'Past job', ]); // Offer 2: Cancelled status, joining 30 days ago JobOffer::create([ 'employer_id' => $emp2->id, 'worker_id' => $worker->id, 'work_date' => now()->subDays(30), 'location' => 'Sharjah', 'salary' => 1800, 'status' => 'cancelled', 'notes' => 'Cancelled job', ]); // Offer 3: Accepted (Active) status, joining 10 days ago JobOffer::create([ 'employer_id' => $emp3->id, 'worker_id' => $worker->id, 'work_date' => now()->subDays(10), 'location' => 'Dubai', 'salary' => 3000, 'status' => 'accepted', 'notes' => 'Active job', ]); // List all employers (should return 3) // With Active employer at the top, then previous employers sorted by work_date desc: // 1st: Emp 3 (Active) // 2nd: Emp 1 (Completed, 20 days ago) // 3rd: Emp 2 (Cancelled, 30 days ago) $response = $this->withHeaders([ 'Authorization' => 'Bearer worker-test-token', ])->getJson('/api/workers/employers'); $response->assertStatus(200); $data = $response->json('data.employers'); $this->assertCount(3, $data); $this->assertEquals('Active', $data[0]['status']); $this->assertEquals('Employer Three', $data[0]['employer']['name']); $this->assertEquals('Completed', $data[1]['status']); $this->assertEquals('Employer One', $data[1]['employer']['name']); $this->assertEquals('Cancelled', $data[2]['status']); $this->assertEquals('Employer Two', $data[2]['employer']['name']); // Test filtering by status Completed $responseFiltered = $this->withHeaders([ 'Authorization' => 'Bearer worker-test-token', ])->getJson('/api/workers/employers?status=completed'); $responseFiltered->assertStatus(200); $filteredData = $responseFiltered->json('data.employers'); $this->assertCount(1, $filteredData); $this->assertEquals('Completed', $filteredData[0]['status']); $this->assertEquals('Employer One', $filteredData[0]['employer']['name']); // Test filtering by status Active $responseActive = $this->withHeaders([ 'Authorization' => 'Bearer worker-test-token', ])->getJson('/api/workers/employers?status=active'); $responseActive->assertStatus(200); $activeData = $responseActive->json('data.employers'); $this->assertCount(1, $activeData); $this->assertEquals('Active', $activeData[0]['status']); $this->assertEquals('Employer Three', $activeData[0]['employer']['name']); // Test pagination $responsePaginated = $this->withHeaders([ 'Authorization' => 'Bearer worker-test-token', ])->getJson('/api/workers/employers?per_page=2'); $responsePaginated->assertStatus(200); $paginatedData = $responsePaginated->json('data.employers'); $this->assertCount(2, $paginatedData); $this->assertEquals(3, $responsePaginated->json('data.pagination.total')); $this->assertEquals(2, $responsePaginated->json('data.pagination.per_page')); } public function test_worker_can_view_employer_profile_with_permissions_and_reviews() { // Create worker $worker = Worker::create([ 'name' => 'Rahul Sharma', 'email' => 'rahul@example.com', 'phone' => '+971501234567', 'language' => 'HI', 'password' => bcrypt('password'), 'nationality' => 'Indian', 'age' => 25, 'salary' => 1500, 'availability' => 'Immediate', 'experience' => 'Not Specified', 'religion' => 'Not Specified', 'bio' => 'Test', 'verified' => true, 'status' => 'active', 'api_token' => 'worker-test-token', ]); WorkerDocument::create([ 'worker_id' => $worker->id, 'type' => 'passport', 'number' => '123456', 'file_path' => 'passports/test.pdf', ]); // Create an employer $employer = User::create([ 'name' => 'Employer One', 'email' => 'emp1@example.com', 'password' => bcrypt('password'), 'role' => 'employer', ]); EmployerProfile::create([ 'user_id' => $employer->id, 'company_name' => 'Ahmad Tech Ltd', 'phone' => '+971500000001', 'nationality' => 'UAE', 'city' => 'Dubai', 'accommodation' => 'Provided', 'language' => 'English', ]); // Create active job post \App\Models\JobPost::create([ 'employer_id' => $employer->id, 'title' => 'Housekeeper Needed', 'location' => 'Dubai Marina', 'salary' => 2500, 'workers_needed' => 1, 'job_type' => 'Full Time', 'start_date' => now()->addDays(5)->toDateString(), 'description' => 'Clean house', 'status' => 'active', ]); // Create an accepted job offer (connection exists) JobOffer::create([ 'employer_id' => $employer->id, 'worker_id' => $worker->id, 'work_date' => now()->subDays(10), 'location' => 'Dubai', 'salary' => 2500, 'status' => 'accepted', ]); // Create a review submitted by another worker $otherWorker = Worker::create([ 'name' => 'John Doe', 'email' => 'john@example.com', 'phone' => '+971501234568', 'password' => bcrypt('password'), 'nationality' => 'Filipino', 'age' => 25, 'salary' => 1500, 'availability' => 'Immediate', 'experience' => 'Not Specified', 'religion' => 'Not Specified', 'bio' => 'Test', 'passport_status' => 'valid', ]); \App\Models\EmployerReview::create([ 'worker_id' => $otherWorker->id, 'employer_id' => $employer->id, 'rating' => 5, 'title' => 'Excellent sponsor', 'comment' => 'Very polite and pays on time.', ]); // Hit the new API endpoint $response = $this->withHeaders([ 'Authorization' => 'Bearer worker-test-token', ])->getJson("/api/workers/employers/{$employer->id}"); $response->assertStatus(200); $response->assertJsonPath('success', true); $response->assertJsonPath('data.employer.name', 'Employer One'); $response->assertJsonPath('data.employer.email', 'emp1@example.com'); // Contact info visible because of JobOffer connection $response->assertJsonPath('data.employer.phone', '+971500000001'); $response->assertJsonPath('data.employer.company_name', 'Ahmad Tech Ltd'); $response->assertJsonPath('data.employer.rating', 5); $response->assertJsonPath('data.employer.reviews_count', 1); $response->assertJsonPath('data.employer.review_summary.stars.5', 1); $response->assertJsonCount(1, 'data.employer.active_jobs'); $response->assertJsonPath('data.employer.active_jobs.0.title', 'Housekeeper Needed'); $response->assertJsonCount(1, 'data.reviews.data'); $response->assertJsonPath('data.reviews.data.0.worker.name', 'John Doe'); $response->assertJsonPath('data.reviews.data.0.title', 'Excellent sponsor'); } public function test_worker_can_view_employer_profile_without_permissions_masks_contact() { // Create worker $worker = Worker::create([ 'name' => 'Rahul Sharma', 'email' => 'rahul@example.com', 'phone' => '+971501234567', 'language' => 'HI', 'password' => bcrypt('password'), 'nationality' => 'Indian', 'age' => 25, 'salary' => 1500, 'availability' => 'Immediate', 'experience' => 'Not Specified', 'religion' => 'Not Specified', 'bio' => 'Test', 'verified' => true, 'status' => 'active', 'api_token' => 'worker-test-token', ]); WorkerDocument::create([ 'worker_id' => $worker->id, 'type' => 'passport', 'number' => '123456', 'file_path' => 'passports/test.pdf', ]); // Create an employer $employer = User::create([ 'name' => 'Employer One', 'email' => 'emp1@example.com', 'password' => bcrypt('password'), 'role' => 'employer', ]); EmployerProfile::create([ 'user_id' => $employer->id, 'company_name' => 'Ahmad Tech Ltd', 'phone' => '+971500000001', ]); // Hit the API (no connection exists) $response = $this->withHeaders([ 'Authorization' => 'Bearer worker-test-token', ])->getJson("/api/workers/employers/{$employer->id}"); $response->assertStatus(200); $response->assertJsonPath('success', true); $response->assertJsonPath('data.employer.name', 'Employer One'); $response->assertJsonPath('data.employer.email', null); // Masked/null since no connection exists $response->assertJsonPath('data.employer.phone', null); } }