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>
202 lines
5.4 KiB
PHP
202 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace Tests\Browser;
|
|
|
|
use App\Models\FinanceDocument;
|
|
use App\Models\Issue;
|
|
use App\Models\Member;
|
|
use App\Models\MembershipPayment;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Laravel\Dusk\Browser;
|
|
use Tests\DuskTestCase;
|
|
|
|
/**
|
|
* Admin Dashboard Browser Tests
|
|
*
|
|
* Tests the admin dashboard user interface and user experience.
|
|
*/
|
|
class AdminDashboardBrowserTest extends DuskTestCase
|
|
{
|
|
use DatabaseMigrations;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->artisan('db:seed', ['--class' => 'FinancialWorkflowPermissionsSeeder']);
|
|
}
|
|
|
|
/**
|
|
* Create an admin user for testing
|
|
*/
|
|
protected function createAdminUser(): User
|
|
{
|
|
$user = User::factory()->create([
|
|
'email' => 'admin@test.com',
|
|
'password' => Hash::make('password'),
|
|
]);
|
|
|
|
$user->assignRole('admin');
|
|
|
|
return $user;
|
|
}
|
|
|
|
/**
|
|
* Test admin can view dashboard
|
|
*/
|
|
public function test_admin_can_view_dashboard(): void
|
|
{
|
|
$admin = $this->createAdminUser();
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('admin.dashboard'))
|
|
->assertSee('管理儀表板');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test dashboard shows statistics
|
|
*/
|
|
public function test_dashboard_shows_statistics(): void
|
|
{
|
|
$admin = $this->createAdminUser();
|
|
|
|
// Create some data
|
|
Member::factory()->count(5)->create();
|
|
Issue::factory()->count(3)->create(['created_by_user_id' => $admin->id]);
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('admin.dashboard'))
|
|
->assertPresent('.stats-card');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test admin can navigate to members page
|
|
*/
|
|
public function test_admin_can_navigate_to_members_page(): void
|
|
{
|
|
$admin = $this->createAdminUser();
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('admin.dashboard'))
|
|
->clickLink('會員管理')
|
|
->assertPathIs('/admin/members');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test admin can navigate to finance page
|
|
*/
|
|
public function test_admin_can_navigate_to_finance_page(): void
|
|
{
|
|
$admin = $this->createAdminUser();
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('admin.dashboard'))
|
|
->clickLink('財務管理')
|
|
->assertPathIs('/admin/finance*');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test admin can navigate to issues page
|
|
*/
|
|
public function test_admin_can_navigate_to_issues_page(): void
|
|
{
|
|
$admin = $this->createAdminUser();
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('admin.dashboard'))
|
|
->clickLink('議題追蹤')
|
|
->assertPathIs('/admin/issues');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test sidebar navigation works
|
|
*/
|
|
public function test_sidebar_navigation_works(): void
|
|
{
|
|
$admin = $this->createAdminUser();
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('admin.dashboard'))
|
|
->assertPresent('.sidebar')
|
|
->assertPresent('.nav-link');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test pending approvals widget
|
|
*/
|
|
public function test_pending_approvals_widget(): void
|
|
{
|
|
$admin = $this->createAdminUser();
|
|
|
|
MembershipPayment::factory()->count(3)->create([
|
|
'status' => MembershipPayment::STATUS_PENDING,
|
|
]);
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('admin.dashboard'))
|
|
->assertSee('待審核');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test recent activity section
|
|
*/
|
|
public function test_recent_activity_section(): void
|
|
{
|
|
$admin = $this->createAdminUser();
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('admin.dashboard'))
|
|
->assertPresent('.activity-feed');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test admin can search members
|
|
*/
|
|
public function test_admin_can_search_members(): void
|
|
{
|
|
$admin = $this->createAdminUser();
|
|
Member::factory()->create(['full_name' => '測試搜尋會員']);
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('admin.members.index'))
|
|
->type('search', '測試搜尋')
|
|
->press('搜尋')
|
|
->assertSee('測試搜尋會員');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test responsive sidebar collapse
|
|
*/
|
|
public function test_responsive_sidebar_collapse(): void
|
|
{
|
|
$admin = $this->createAdminUser();
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
// Mobile view
|
|
$browser->loginAs($admin)
|
|
->resize(375, 667)
|
|
->visit(route('admin.dashboard'))
|
|
->assertPresent('.sidebar-toggle');
|
|
});
|
|
}
|
|
}
|