Files
HRM-System/tests/Feature/TenantModuleProvisioningTest.php

122 lines
4.4 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Inquiry;
use App\Models\CentralTenantModule;
use App\Models\TenantModule;
use App\Jobs\ProvisionTenantJob;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Models\Tenant;
use Tests\TestCase;
class TenantModuleProvisioningTest extends TestCase
{
use RefreshDatabase;
public function test_provisioning_enables_only_selected_inquiry_modules_in_central_and_tenant_db(): void
{
$inquiry = Inquiry::create([
'company_name' => 'Payroll Only Corp',
'contact_name' => 'Payroll Admin',
'email' => 'payrolladmin@payrollcorp.com',
'desired_subdomain' => 'payroll-only-tenant',
'employee_count' => 50,
'requested_features' => ['payroll', 'documents'], // Only Payroll & Documents selected
'email_verified_at' => now(),
'status' => 'approved',
]);
$job = new ProvisionTenantJob($inquiry);
$job->handle();
$tenant = Tenant::find('payroll-only-tenant');
$this->assertNotNull($tenant);
// Check Central database storage (Single source of truth)
$this->assertDatabaseHas('central_tenant_modules', [
'tenant_id' => 'payroll-only-tenant',
'module_key' => 'payroll',
'enabled' => true,
]);
$this->assertDatabaseHas('central_tenant_modules', [
'tenant_id' => 'payroll-only-tenant',
'module_key' => 'attendance',
'enabled' => false,
]);
// Check exact real Spatie permissions within tenant DB
$tenant->run(function () {
$user = \App\Models\User::where('email', 'payrolladmin@payrollcorp.com')->first();
$this->assertNotNull($user);
// Selected module permissions must exist on user
$userPermissions = $user->getAllPermissions()->pluck('name')->toArray();
$this->assertContains('manage-payrolls', $userPermissions);
$this->assertContains('manage-hr-documents', $userPermissions);
// Unselected module permissions must NOT exist on user
$this->assertNotContains('manage-candidates', $userPermissions);
$this->assertNotContains('manage-biometric-attendance', $userPermissions);
});
}
public function test_ensure_tenant_module_enabled_middleware_returns_403_for_disabled_module(): void
{
$inquiry = Inquiry::create([
'company_name' => 'No Attendance Corp',
'contact_name' => 'Admin User',
'email' => 'admin@noattendance.com',
'desired_subdomain' => 'no-attendance-tenant',
'requested_features' => ['payroll'],
'email_verified_at' => now(),
'status' => 'approved',
]);
$job = new ProvisionTenantJob($inquiry);
$job->handle();
$middleware = new \App\Http\Middleware\EnsureTenantModuleEnabled();
// Simulate tenant context request
$request = \Illuminate\Http\Request::create('/attendances', 'GET');
$request->headers->set('Accept', 'application/json');
$request->headers->set('X-Tenant', 'no-attendance-tenant');
$response = $middleware->handle($request, function () {
return response()->json(['success' => true]);
}, 'attendance');
$this->assertEquals(403, $response->getStatusCode());
}
public function test_cannot_reprovision_active_tenant(): void
{
$user = \App\Models\User::factory()->create(['type' => 'company']);
$role = \Spatie\Permission\Models\Role::findOrCreate('company', 'web');
$permission = \Spatie\Permission\Models\Permission::findOrCreate('manage-contacts', 'web');
$role->givePermissionTo($permission);
$user->assignRole($role);
Inquiry::create([
'company_name' => 'Active Tenant Co',
'contact_name' => 'Active User',
'email' => 'active@tenant.com',
'desired_subdomain' => 'active-tenant-slug',
'status' => 'active',
]);
$response = $this->actingAs($user)
->postJson('/contacts/provision-subdomain', [
'company_name' => 'Active Tenant Co',
'contact_name' => 'Active User',
'email' => 'active@tenant.com',
'desired_subdomain' => 'active-tenant-slug',
]);
$response->assertStatus(422)
->assertJson(['success' => false]);
}
}