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>
This commit is contained in:
254
tests/Browser/DocumentManagementBrowserTest.php
Normal file
254
tests/Browser/DocumentManagementBrowserTest.php
Normal file
@@ -0,0 +1,254 @@
|
||||
<?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');
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user