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>
255 lines
7.0 KiB
PHP
255 lines
7.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\Browser;
|
|
|
|
use App\Models\Document;
|
|
use App\Models\DocumentCategory;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\DatabaseMigrations;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Laravel\Dusk\Browser;
|
|
use Tests\DuskTestCase;
|
|
|
|
/**
|
|
* Document Management Browser Tests
|
|
*
|
|
* Tests the document management user interface and user experience.
|
|
*/
|
|
class DocumentManagementBrowserTest extends DuskTestCase
|
|
{
|
|
use DatabaseMigrations;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
Storage::fake('local');
|
|
$this->artisan('db:seed', ['--class' => 'FinancialWorkflowPermissionsSeeder']);
|
|
}
|
|
|
|
/**
|
|
* Create an admin user
|
|
*/
|
|
protected function createAdmin(): User
|
|
{
|
|
$user = User::factory()->create([
|
|
'email' => 'admin@test.com',
|
|
'password' => Hash::make('password'),
|
|
]);
|
|
$user->assignRole('admin');
|
|
|
|
return $user;
|
|
}
|
|
|
|
/**
|
|
* Test document list page loads
|
|
*/
|
|
public function test_document_list_page_loads(): void
|
|
{
|
|
$admin = $this->createAdmin();
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('documents.index'))
|
|
->assertSee('文件管理');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test can upload document
|
|
*/
|
|
public function test_can_upload_document(): void
|
|
{
|
|
$admin = $this->createAdmin();
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('documents.create'))
|
|
->assertSee('上傳文件')
|
|
->assertPresent('input[name="title"]')
|
|
->assertPresent('input[type="file"]');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test document categories are displayed
|
|
*/
|
|
public function test_document_categories_are_displayed(): void
|
|
{
|
|
$admin = $this->createAdmin();
|
|
DocumentCategory::factory()->create(['name' => '會議紀錄']);
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('documents.index'))
|
|
->assertSee('會議紀錄');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test can filter by category
|
|
*/
|
|
public function test_can_filter_by_category(): void
|
|
{
|
|
$admin = $this->createAdmin();
|
|
|
|
$category1 = DocumentCategory::factory()->create(['name' => '類別A']);
|
|
$category2 = DocumentCategory::factory()->create(['name' => '類別B']);
|
|
|
|
Document::factory()->create([
|
|
'title' => '文件A',
|
|
'category_id' => $category1->id,
|
|
'uploaded_by' => $admin->id,
|
|
]);
|
|
|
|
Document::factory()->create([
|
|
'title' => '文件B',
|
|
'category_id' => $category2->id,
|
|
'uploaded_by' => $admin->id,
|
|
]);
|
|
|
|
$this->browse(function (Browser $browser) use ($admin, $category1) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('documents.index'))
|
|
->select('category_id', $category1->id)
|
|
->press('篩選')
|
|
->assertSee('文件A')
|
|
->assertDontSee('文件B');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test can search documents
|
|
*/
|
|
public function test_can_search_documents(): void
|
|
{
|
|
$admin = $this->createAdmin();
|
|
|
|
Document::factory()->create([
|
|
'title' => '特殊搜尋文件',
|
|
'uploaded_by' => $admin->id,
|
|
]);
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('documents.index'))
|
|
->type('search', '特殊搜尋')
|
|
->press('搜尋')
|
|
->assertSee('特殊搜尋文件');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test can view document details
|
|
*/
|
|
public function test_can_view_document_details(): void
|
|
{
|
|
$admin = $this->createAdmin();
|
|
|
|
$document = Document::factory()->create([
|
|
'title' => '詳細資料文件',
|
|
'description' => '這是文件描述',
|
|
'uploaded_by' => $admin->id,
|
|
]);
|
|
|
|
$this->browse(function (Browser $browser) use ($admin, $document) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('documents.show', $document))
|
|
->assertSee('詳細資料文件')
|
|
->assertSee('這是文件描述');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test download button is present
|
|
*/
|
|
public function test_download_button_is_present(): void
|
|
{
|
|
$admin = $this->createAdmin();
|
|
|
|
$document = Document::factory()->create([
|
|
'uploaded_by' => $admin->id,
|
|
]);
|
|
|
|
$this->browse(function (Browser $browser) use ($admin, $document) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('documents.show', $document))
|
|
->assertSee('下載');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test can delete document
|
|
*/
|
|
public function test_can_delete_document(): void
|
|
{
|
|
$admin = $this->createAdmin();
|
|
|
|
$document = Document::factory()->create([
|
|
'title' => '待刪除文件',
|
|
'uploaded_by' => $admin->id,
|
|
]);
|
|
|
|
$this->browse(function (Browser $browser) use ($admin, $document) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('documents.show', $document))
|
|
->press('刪除')
|
|
->acceptDialog()
|
|
->waitForLocation('/documents')
|
|
->assertDontSee('待刪除文件');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test file size is displayed
|
|
*/
|
|
public function test_file_size_is_displayed(): void
|
|
{
|
|
$admin = $this->createAdmin();
|
|
|
|
$document = Document::factory()->create([
|
|
'uploaded_by' => $admin->id,
|
|
'file_size' => 1024 * 1024, // 1MB
|
|
]);
|
|
|
|
$this->browse(function (Browser $browser) use ($admin, $document) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('documents.show', $document))
|
|
->assertSee('MB');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test upload date is displayed
|
|
*/
|
|
public function test_upload_date_is_displayed(): void
|
|
{
|
|
$admin = $this->createAdmin();
|
|
|
|
$document = Document::factory()->create([
|
|
'uploaded_by' => $admin->id,
|
|
]);
|
|
|
|
$this->browse(function (Browser $browser) use ($admin, $document) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('documents.show', $document))
|
|
->assertPresent('.upload-date');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test grid and list view toggle
|
|
*/
|
|
public function test_grid_and_list_view_toggle(): void
|
|
{
|
|
$admin = $this->createAdmin();
|
|
|
|
$this->browse(function (Browser $browser) use ($admin) {
|
|
$browser->loginAs($admin)
|
|
->visit(route('documents.index'))
|
|
->assertPresent('.view-toggle');
|
|
});
|
|
}
|
|
}
|