191 lines
6.4 KiB
PHP
191 lines
6.4 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Modules\ContractorManagement\Models\Contractor;
|
|
use Spatie\Permission\Models\Role;
|
|
use Tests\TestCase;
|
|
|
|
class ContractorOnboardingTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
// Create required roles for tests
|
|
Role::firstOrCreate(['name' => '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);
|
|
}
|
|
}
|