"-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC3\n-----END PRIVATE KEY-----", 'client_email' => 'fake-fcm@migrant.iam.gserviceaccount.com', 'project_id' => 'migrant-fe5a7' ])); } // Fake Google OAuth and FCM endpoints Http::fake([ 'https://oauth2.googleapis.com/token' => Http::response(['access_token' => 'fake_token'], 200), 'https://fcm.googleapis.com/v1/projects/*' => Http::response(['name' => 'projects/migrant-fe5a7/messages/1234'], 200), ]); } protected function tearDown(): void { // Clean up temporary credentials file if needed, but since it's inside workspace it's fine. parent::tearDown(); } public function test_employer_registration_and_login_stores_fcm_token_and_sends_notification() { // Register Employer $response = $this->postJson('/api/employers/register', [ 'name' => 'Employer FCM Test', 'email' => 'employer.fcm@example.com', 'phone' => '+971500000001', 'fcm_token' => 'employer_register_fcm_token', 'emirates_id' => [ 'emirates_id_number' => '784-1988-5310327-2', 'name' => 'Employer FCM Test', 'expiry_date' => '2028-04-11', ] ]); $response->assertStatus(201); $user = User::where('email', 'employer.fcm@example.com')->first(); $this->assertEquals('employer_register_fcm_token', $user->fcm_token); $profile = EmployerProfile::where('user_id', $user->id)->first(); $this->assertEquals('784-1988-5310327-2', $profile->emirates_id_number); $this->assertEquals('2028-04-11', $profile->emirates_id_expiry); $sponsor = Sponsor::where('email', 'employer.fcm@example.com')->first(); $this->assertEquals('employer_register_fcm_token', $sponsor->fcm_token); // Verify OTP $otpData = Cache::get('employer_otp_employer.fcm@example.com'); $this->assertNotNull($otpData); $verifyResponse = $this->postJson('/api/employers/verify', [ 'email' => 'employer.fcm@example.com', 'otp' => $otpData['code'], 'fcm_token' => 'employer_verify_fcm_token' ]); $verifyResponse->assertStatus(200); $user->refresh(); $sponsor->refresh(); $this->assertEquals('employer_verify_fcm_token', $user->fcm_token); $this->assertEquals('employer_verify_fcm_token', $sponsor->fcm_token); // Set payment/activate status so password can be set $sponsor->update(['payment_status' => 'paid']); // Set password $passwordResponse = $this->postJson('/api/employers/password', [ 'email' => 'employer.fcm@example.com', 'password' => 'newpassword123', 'password_confirmation' => 'newpassword123', 'fcm_token' => 'employer_password_fcm_token' ]); $passwordResponse->assertStatus(200); $user->refresh(); $sponsor->refresh(); $this->assertEquals('employer_password_fcm_token', $user->fcm_token); $this->assertEquals('employer_password_fcm_token', $sponsor->fcm_token); // Login $loginResponse = $this->postJson('/api/employers/login', [ 'email' => 'employer.fcm@example.com', 'password' => 'newpassword123', 'fcm_token' => 'employer_login_fcm_token' ]); $loginResponse->assertStatus(200); $user->refresh(); $sponsor->refresh(); $this->assertEquals('employer_login_fcm_token', $user->fcm_token); $this->assertEquals('employer_login_fcm_token', $sponsor->fcm_token); } public function test_worker_registration_setup_profile_and_login_stores_fcm_token_and_sends_notification() { // 1. Worker Setup Profile Flow (Requires OTP verified in session cache) $phone = '+971500000002'; Cache::put('worker_otp_verified_' . $phone, true, 60); $responseSetup = $this->postJson('/api/workers/setup-profile', [ 'phone' => $phone, 'name' => 'Worker Setup FCM', 'nationality' => 'Indian', 'language' => 'hi', 'gender' => 'male', 'fcm_token' => 'worker_setup_fcm_token' ]); $responseSetup->assertStatus(201); $worker = Worker::where('phone', $phone)->first(); $this->assertEquals('worker_setup_fcm_token', $worker->fcm_token); // Set password for login $worker->update(['password' => Hash::make('workerpassword123')]); // Login Setup Worker $loginResponse = $this->postJson('/api/workers/login', [ 'phone' => $phone, 'password' => 'workerpassword123', 'fcm_token' => 'worker_login_fcm_token' ]); $loginResponse->assertStatus(200); $worker->refresh(); $this->assertEquals('worker_login_fcm_token', $worker->fcm_token); // 2. Worker Unified Register Flow $passportFile = UploadedFile::fake()->create('passport.pdf', 500, 'application/pdf'); $visaFile = UploadedFile::fake()->create('visa.pdf', 500, 'application/pdf'); $responseRegister = $this->postJson('/api/workers/register', [ 'name' => 'Worker Unified FCM', 'phone' => '+971500000003', 'salary' => 2000, 'password' => 'workerpassword123', 'passport_file' => $passportFile, 'visa_file' => $visaFile, 'fcm_token' => 'worker_register_fcm_token' ]); $responseRegister->assertStatus(201); $workerReg = Worker::where('phone', '+971500000003')->first(); $this->assertEquals('worker_register_fcm_token', $workerReg->fcm_token); } public function test_sponsor_registration_and_login_stores_fcm_token_and_sends_notification() { $response = $this->postJson('/api/sponsors/register', [ 'full_name' => 'Sponsor FCM Org', 'mobile' => '+971500000004', 'password' => 'sponsorpassword123', 'license' => [ 'license_number' => '123456', 'organization_name' => 'Sponsor FCM Co', 'expiry_date' => '2027-01-01', ], 'emirates_id' => [ 'emirates_id_number' => '784-1988-5310327-2', 'name' => 'Sponsor FCM Org', ], 'organization_name' => 'Sponsor FCM Co', 'email' => 'sponsor.fcm@example.com', 'nationality' => 'Emirati', 'city' => 'Dubai', 'address' => 'Test Address', 'country_code' => '+971', 'license_expiry' => '2027-01-01', 'fcm_token' => 'sponsor_register_fcm_token' ]); $response->assertStatus(201); $sponsor = Sponsor::where('mobile', '+971500000004')->first(); $this->assertEquals('sponsor_register_fcm_token', $sponsor->fcm_token); // Login $loginResponse = $this->postJson('/api/sponsors/login', [ 'mobile' => '+971500000004', 'password' => 'sponsorpassword123', 'fcm_token' => 'sponsor_login_fcm_token' ]); $loginResponse->assertStatus(200); $sponsor->refresh(); $this->assertEquals('sponsor_login_fcm_token', $sponsor->fcm_token); } }