Files
usher-manage-stack/tests/Feature/Roles/RolePermissionTest.php
Gbanyan 642b879dd4 Add membership fee system with disability discount and fix document permissions
Features:
- Implement two fee types: entrance fee and annual fee (both NT$1,000)
- Add 50% discount for disability certificate holders
- Add disability certificate upload in member profile
- Integrate disability verification into cashier approval workflow
- Add membership fee settings in system admin

Document permissions:
- Fix hard-coded role logic in Document model
- Use permission-based authorization instead of role checks

Additional features:
- Add announcements, general ledger, and trial balance modules
- Add income management and accounting entries
- Add comprehensive test suite with factories
- Update UI translations to Traditional Chinese

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 09:56:01 +08:00

216 lines
6.2 KiB
PHP

<?php
namespace Tests\Feature\Roles;
use App\Models\FinanceDocument;
use App\Models\Member;
use App\Models\MembershipPayment;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Storage;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
use Tests\TestCase;
use Tests\Traits\CreatesFinanceData;
use Tests\Traits\CreatesMemberData;
use Tests\Traits\SeedsRolesAndPermissions;
/**
* Role Permission Tests
*
* Tests role-based access control and permissions.
*/
class RolePermissionTest extends TestCase
{
use RefreshDatabase, SeedsRolesAndPermissions, CreatesMemberData, CreatesFinanceData;
protected function setUp(): void
{
parent::setUp();
Storage::fake('private');
Storage::fake('local');
$this->seedRolesAndPermissions();
}
/**
* Test admin can access admin dashboard
*/
public function test_admin_can_access_admin_dashboard(): void
{
$admin = $this->createAdmin();
$response = $this->actingAs($admin)->get(route('admin.dashboard'));
$response->assertStatus(200);
}
/**
* Test member cannot access admin dashboard
*/
public function test_member_cannot_access_admin_dashboard(): void
{
$user = User::factory()->create();
$user->assignRole('member');
$response = $this->actingAs($user)->get(route('admin.dashboard'));
$response->assertStatus(403);
}
/**
* Test cashier can approve payments
*/
public function test_cashier_can_approve_payments(): void
{
$cashier = $this->createCashier();
$data = $this->createMemberWithPendingPayment();
$response = $this->actingAs($cashier)->post(
route('admin.membership-payments.approve', $data['payment'])
);
$data['payment']->refresh();
$this->assertEquals(MembershipPayment::STATUS_APPROVED_CASHIER, $data['payment']->status);
}
/**
* Test accountant cannot approve pending payment directly
*/
public function test_accountant_cannot_approve_pending_payment_directly(): void
{
$accountant = $this->createAccountant();
$data = $this->createMemberWithPendingPayment();
$response = $this->actingAs($accountant)->post(
route('admin.membership-payments.approve', $data['payment'])
);
// Should be forbidden or redirect with error
$data['payment']->refresh();
$this->assertNotEquals(MembershipPayment::STATUS_APPROVED_ACCOUNTANT, $data['payment']->status);
}
/**
* Test chair can approve after accountant
*/
public function test_chair_can_approve_after_accountant(): void
{
$chair = $this->createChair();
$data = $this->createMemberWithPaymentAtStage('accountant_approved');
$response = $this->actingAs($chair)->post(
route('admin.membership-payments.approve', $data['payment'])
);
$data['payment']->refresh();
$this->assertEquals(MembershipPayment::STATUS_APPROVED_CHAIR, $data['payment']->status);
}
/**
* Test finance_cashier can approve finance documents
*/
public function test_finance_cashier_can_approve_finance_documents(): void
{
$cashier = $this->createCashier();
$document = $this->createFinanceDocument([
'status' => FinanceDocument::STATUS_PENDING,
]);
$response = $this->actingAs($cashier)->post(
route('admin.finance-documents.approve', $document)
);
$document->refresh();
$this->assertEquals(FinanceDocument::STATUS_APPROVED_CASHIER, $document->status);
}
/**
* Test unauthorized user cannot approve
*/
public function test_unauthorized_user_cannot_approve(): void
{
$user = User::factory()->create();
$data = $this->createMemberWithPendingPayment();
$response = $this->actingAs($user)->post(
route('admin.membership-payments.approve', $data['payment'])
);
$response->assertStatus(403);
}
/**
* Test role can be assigned to user
*/
public function test_role_can_be_assigned_to_user(): void
{
$admin = $this->createAdmin();
$user = User::factory()->create();
$response = $this->actingAs($admin)->post(
route('admin.users.assign-role', $user),
['role' => 'finance_cashier']
);
$this->assertTrue($user->hasRole('finance_cashier'));
}
/**
* Test role can be removed from user
*/
public function test_role_can_be_removed_from_user(): void
{
$admin = $this->createAdmin();
$user = User::factory()->create();
$user->assignRole('finance_cashier');
$response = $this->actingAs($admin)->post(
route('admin.users.remove-role', $user),
['role' => 'finance_cashier']
);
$this->assertFalse($user->hasRole('finance_cashier'));
}
/**
* Test permission check for member management
*/
public function test_permission_check_for_member_management(): void
{
$admin = $this->createAdmin();
$member = $this->createPendingMember();
$response = $this->actingAs($admin)->patch(
route('admin.members.update-status', $member),
['membership_status' => Member::STATUS_ACTIVE]
);
$member->refresh();
$this->assertEquals(Member::STATUS_ACTIVE, $member->membership_status);
}
/**
* Test super admin has all permissions
*/
public function test_super_admin_has_all_permissions(): void
{
$superAdmin = User::factory()->create();
$superAdmin->assignRole('super_admin');
$this->assertTrue($superAdmin->can('manage-members'));
$this->assertTrue($superAdmin->can('approve-payments'));
$this->assertTrue($superAdmin->can('manage-finance'));
}
/**
* Test role hierarchy for approvals
*/
public function test_role_hierarchy_for_approvals(): void
{
// Chair should be able to do everything accountant can
$chair = $this->createChair();
$this->assertTrue($chair->hasRole('finance_chair'));
}
}