'admin']); Role::firstOrCreate(['name' => 'contractor-admin']); } public function test_guest_can_register_as_contractor(): void { $response = $this->post(route('contractors.register.store'), [ 'company_name' => 'Acme Builders', 'contact_person' => 'John Doe', 'email' => 'contact@acme.com', 'phone' => '12345678', 'specialization' => 'general', 'address' => '123 Acme Street', 'tax_id' => 'TX-999', 'payment_terms' => 'net_30', 'admin_name' => 'John Doe', 'admin_email' => 'john@acme.com', 'password' => 'password123', 'password_confirmation' => 'password123', ]); $response->assertRedirect(route('login')); $response->assertSessionHas('success'); // Verify Contractor was created as pending $contractor = Contractor::where('email', 'contact@acme.com')->first(); $this->assertNotNull($contractor); $this->assertEquals('pending', $contractor->status); // Verify Admin User was created as inactive $user = User::where('email', 'john@acme.com')->first(); $this->assertNotNull($user); $this->assertEquals('inactive', $user->status); $this->assertEquals($contractor->id, $user->contractor_id); $this->assertTrue($user->hasRole('contractor-admin')); } public function test_inactive_contractor_admin_cannot_login(): void { // 1. Create a pending contractor and inactive admin user $contractor = Contractor::create([ 'company_name' => 'Acme Builders', 'contact_person' => 'John Doe', 'email' => 'contact@acme.com', 'status' => 'pending', 'payment_terms' => 'net_30', ]); $user = User::factory()->create([ 'contractor_id' => $contractor->id, 'email' => 'john@acme.com', 'password' => Hash::make('password123'), 'status' => 'inactive', ]); // 2. Try logging in $response = $this->post(route('login'), [ 'email' => 'john@acme.com', 'password' => 'password123', ]); // 3. Verify they are blocked and validation error is thrown $response->assertSessionHasErrors('email'); $this->assertFalse(auth()->check()); } public function test_platform_owner_can_approve_pending_contractor(): void { // 1. Create pending contractor and inactive user $contractor = Contractor::create([ 'company_name' => 'Pending Contractor LLC', 'contact_person' => 'John Doe', 'email' => 'contact@acme.com', 'status' => 'pending', 'payment_terms' => 'net_30', ]); $user = User::factory()->create([ 'contractor_id' => $contractor->id, 'status' => 'inactive', ]); // 2. Create Platform Owner $platformOwner = User::factory()->create([ 'contractor_id' => null, 'user_type' => 'admin', 'status' => 'active', ]); $platformOwner->assignRole('admin'); // 3. Authenticate as Platform Owner and approve $response = $this->actingAs($platformOwner) ->post(route('contractors.approve', $contractor)); $response->assertSessionHas('success'); // 4. Verify status is active $this->assertEquals('active', $contractor->refresh()->status); $this->assertEquals('active', $user->refresh()->status); } public function test_platform_owner_can_reject_pending_contractor(): void { // 1. Create pending contractor and inactive user $contractor = Contractor::create([ 'company_name' => 'Rejected LLC', 'contact_person' => 'John Doe', 'email' => 'contact@acme.com', 'status' => 'pending', 'payment_terms' => 'net_30', ]); $user = User::factory()->create([ 'contractor_id' => $contractor->id, 'status' => 'inactive', ]); // 2. Create Platform Owner $platformOwner = User::factory()->create([ 'contractor_id' => null, 'user_type' => 'admin', 'status' => 'active', ]); $platformOwner->assignRole('admin'); // 3. Authenticate as Platform Owner and reject $response = $this->actingAs($platformOwner) ->post(route('contractors.reject', $contractor)); $response->assertSessionHas('success'); // 4. Verify contractor and users are deleted $this->assertNull(Contractor::find($contractor->id)); $this->assertNull(User::find($user->id)); } public function test_non_platform_owners_cannot_access_approvals(): void { $contractor = Contractor::create([ 'company_name' => 'Acme Builders', 'contact_person' => 'John Doe', 'email' => 'contact@acme.com', 'status' => 'pending', 'payment_terms' => 'net_30', ]); $dummyContractor = Contractor::create([ 'company_name' => 'Regular Contractor Ltd', 'contact_person' => 'Jane Doe', 'email' => 'jane@regular.com', 'status' => 'active', 'payment_terms' => 'net_30', ]); $regularUser = User::factory()->create([ 'contractor_id' => $dummyContractor->id, 'status' => 'active', ]); // Trying to approve or reject should abort $this->actingAs($regularUser) ->get(route('contractors.pending')) ->assertStatus(403); $this->actingAs($regularUser) ->post(route('contractors.approve', $contractor)) ->assertStatus(403); $this->actingAs($regularUser) ->post(route('contractors.reject', $contractor)) ->assertStatus(403); } }