token = 'test-employer-token'; $this->employer = User::create([ 'name' => 'Original Name', 'email' => 'employer@example.com', 'password' => bcrypt('Password@123'), 'role' => 'employer', 'api_token' => $this->token, ]); EmployerProfile::create([ 'user_id' => $this->employer->id, 'address' => 'Original Address', 'phone' => '+971501112222', 'verification_status' => 'approved', 'notifications' => true, ]); } /** * Test employer can retrieve profile. */ public function test_employer_can_get_profile() { $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->getJson('/api/employers/profile'); $response->assertStatus(200) ->assertJsonStructure([ 'success', 'data' => [ 'profile' => [ 'name', 'email', 'phone', 'address', 'notifications', 'verification_status', ] ] ]); $this->assertEquals('Original Name', $response->json('data.profile.name')); $this->assertEquals('Original Address', $response->json('data.profile.address')); } /** * Test employer can update profile details. */ public function test_employer_can_update_profile() { $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->postJson('/api/employers/profile/update', [ 'name' => 'Updated Name', 'email' => 'employer_updated@example.com', 'phone' => '+971509999999', 'address' => 'Updated Address Info', 'notifications' => false, ]); $response->assertStatus(200) ->assertJsonStructure([ 'success', 'message', 'data' => [ 'profile' => [ 'name', 'email', 'phone', 'address', 'notifications', ] ] ]); $this->assertDatabaseHas('users', [ 'id' => $this->employer->id, 'name' => 'Updated Name', 'email' => 'employer_updated@example.com', ]); $this->assertDatabaseHas('employer_profiles', [ 'user_id' => $this->employer->id, 'address' => 'Updated Address Info', 'notifications' => false, ]); } /** * Test employer can update profile with optional Emirates ID fields. */ public function test_employer_can_update_profile_with_emirates_id_fields() { $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->postJson('/api/employers/profile/update', [ 'name' => 'Ahmad', 'email' => 'ahmad@example.com', 'phone' => '+971509990001', 'address' => 'Villa 12, Jumeirah 2', 'notifications' => true, 'id_number' => '784-1987-5493842-5', 'card_number' => '151023946', 'full_name' => 'Mohammad Jobaier Mohammad Abul Kalam', 'date_of_birth' => '14/04/1987', 'nationality' => 'Bangladesh', 'gender' => 'M', 'issue_date' => '12/12/2025', 'expiry_date' => '11/12/2027', 'occupation' => 'Electrician', 'employer' => 'Msj International Technical Services L.L.C UAE', 'issuing_place' => 'Dubai', ]); $response->assertStatus(200) ->assertJson([ 'success' => true, 'data' => [ 'profile' => [ 'name' => 'Ahmad', 'email' => 'ahmad@example.com', 'phone' => '+971509990001', 'address' => 'Villa 12, Jumeirah 2', 'id_number' => '784-1987-5493842-5', 'card_number' => '151023946', 'full_name' => 'Mohammad Jobaier Mohammad Abul Kalam', 'gender' => 'M', ] ] ]); $this->assertDatabaseHas('employer_profiles', [ 'user_id' => $this->employer->id, 'emirates_id_number' => '784-1987-5493842-5', 'emirates_id_card_number' => '151023946', 'emirates_id_name' => 'Mohammad Jobaier Mohammad Abul Kalam', 'emirates_id_gender' => 'M', ]); } /** * Test employer cannot change an existing Emirates ID number. */ public function test_employer_cannot_change_existing_emirates_id_number() { // First, set the Emirates ID $profile = $this->employer->employerProfile; $profile->emirates_id_number = '784-1987-5493842-5'; $profile->save(); // Attempt to change to a different ID $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->postJson('/api/employers/profile/update', [ 'name' => 'Original Name', 'email' => 'employer@example.com', 'phone' => '+971501112222', 'address' => 'Original Address', 'id_number' => '784-9999-0000000-0', ]); $response->assertStatus(422) ->assertJson([ 'success' => false, 'errors' => [ 'id_number' => ['Emirates ID mismatch.'] ] ]); // Verify ID was NOT changed $this->assertEquals('784-1987-5493842-5', $profile->fresh()->emirates_id_number); } /** * Test employer dashboard returns only the latest 2 approved charity drives. */ public function test_employer_dashboard_returns_only_two_charity_drives() { // Create 5 approved announcements for ($i = 1; $i <= 5; $i++) { $ann = new \App\Models\Announcement([ 'title' => "Charity Drive $i", 'body' => "Details of charity drive $i", 'type' => 'charity', 'status' => 'approved', ]); $ann->created_at = now()->subMinutes(6 - $i); $ann->save(); } // Create 1 pending announcement $pendingAnn = new \App\Models\Announcement([ 'title' => "Pending Charity Drive", 'body' => "Details of pending charity drive", 'type' => 'charity', 'status' => 'pending', ]); $pendingAnn->created_at = now(); $pendingAnn->save(); $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->getJson('/api/employers/dashboard'); $response->assertStatus(200) ->assertJson([ 'success' => true, ]); $announcements = $response->json('data.recent_announcements'); $this->assertCount(2, $announcements); // Make sure it contains the latest 2 approved ones $titles = collect($announcements)->pluck('title'); $this->assertTrue($titles->contains('Charity Drive 5')); $this->assertTrue($titles->contains('Charity Drive 4')); $this->assertFalse($titles->contains('Charity Drive 3')); $this->assertFalse($titles->contains('Charity Drive 2')); $this->assertFalse($titles->contains('Charity Drive 1')); $this->assertFalse($titles->contains('Pending Charity Drive')); } public function test_employer_dashboard_returns_total_workers_active() { // Delete any existing workers seeded or created to make count precise \App\Models\Worker::query()->delete(); // Create 3 active workers \App\Models\Worker::create([ 'name' => 'Active 1', 'email' => 'a1@test.com', 'phone' => '+971501110001', 'password' => bcrypt('password'), 'status' => 'active', 'nationality' => 'Indian', 'preferred_location' => 'Dubai', 'age' => 25, 'salary' => 1500, 'experience' => '3 Years', 'availability' => 'Immediate', 'religion' => 'Christian', 'bio' => 'experienced worker', ]); \App\Models\Worker::create([ 'name' => 'Active 2', 'email' => 'a2@test.com', 'phone' => '+971501110002', 'password' => bcrypt('password'), 'status' => 'active', 'nationality' => 'Indian', 'preferred_location' => 'Dubai', 'age' => 26, 'salary' => 1500, 'experience' => '3 Years', 'availability' => 'Immediate', 'religion' => 'Christian', 'bio' => 'experienced worker', ]); \App\Models\Worker::create([ 'name' => 'Active 3', 'email' => 'a3@test.com', 'phone' => '+971501110003', 'password' => bcrypt('password'), 'status' => 'active', 'nationality' => 'Indian', 'preferred_location' => 'Dubai', 'age' => 27, 'salary' => 1500, 'experience' => '3 Years', 'availability' => 'Immediate', 'religion' => 'Christian', 'bio' => 'experienced worker', ]); // Create 2 inactive/hidden workers \App\Models\Worker::create([ 'name' => 'Inactive 1', 'email' => 'i1@test.com', 'phone' => '+971502220001', 'password' => bcrypt('password'), 'status' => 'hidden', 'nationality' => 'Indian', 'preferred_location' => 'Dubai', 'age' => 28, 'salary' => 1500, 'experience' => '3 Years', 'availability' => 'Immediate', 'religion' => 'Christian', 'bio' => 'experienced worker', ]); \App\Models\Worker::create([ 'name' => 'Inactive 2', 'email' => 'i2@test.com', 'phone' => '+971502220002', 'password' => bcrypt('password'), 'status' => 'Hired', 'nationality' => 'Indian', 'preferred_location' => 'Dubai', 'age' => 29, 'salary' => 1500, 'experience' => '3 Years', 'availability' => 'Immediate', 'religion' => 'Christian', 'bio' => 'experienced worker', ]); $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->getJson('/api/employers/dashboard'); $response->assertStatus(200); $this->assertEquals(3, $response->json('data.stats.total_workers')); } /** * Test employer can change password successfully. */ public function test_employer_can_change_password() { // 1. Create a matching sponsor $sponsor = \App\Models\Sponsor::create([ 'full_name' => 'Employer One', 'email' => $this->employer->email, 'mobile' => '+971509990011', 'organization_name' => 'Elite Services', 'address' => 'Dubai', 'role' => 'sponsor', 'password' => bcrypt('Password@123'), ]); // Verify initial password hash is set $this->employer->update([ 'password' => bcrypt('Password@123') ]); // 2. Try with wrong current password $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->postJson('/api/employers/change-password', [ 'current_password' => 'WrongPassword', 'new_password' => 'NewPassword@123', 'new_password_confirmation' => 'NewPassword@123', ]); $response->assertStatus(422) ->assertJsonValidationErrors(['current_password']); // 3. Try with correct current password $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $this->token, ])->postJson('/api/employers/change-password', [ 'current_password' => 'Password@123', 'new_password' => 'NewPassword@123', 'new_password_confirmation' => 'NewPassword@123', ]); $response->assertStatus(200) ->assertJson([ 'success' => true, 'message' => 'Password changed successfully.' ]); // Verify password is updated for both User and Sponsor $this->assertTrue(\Illuminate\Support\Facades\Hash::check('NewPassword@123', $this->employer->fresh()->password)); $this->assertTrue(\Illuminate\Support\Facades\Hash::check('NewPassword@123', $sponsor->fresh()->password)); } }