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>
228 lines
5.9 KiB
PHP
228 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Search;
|
|
|
|
use App\Models\Document;
|
|
use App\Models\FinanceDocument;
|
|
use App\Models\Issue;
|
|
use App\Models\Member;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Tests\TestCase;
|
|
use Tests\Traits\CreatesFinanceData;
|
|
use Tests\Traits\CreatesMemberData;
|
|
use Tests\Traits\SeedsRolesAndPermissions;
|
|
|
|
/**
|
|
* Search Tests
|
|
*
|
|
* Tests search functionality across different modules.
|
|
*/
|
|
class SearchTest extends TestCase
|
|
{
|
|
use RefreshDatabase, SeedsRolesAndPermissions, CreatesMemberData, CreatesFinanceData;
|
|
|
|
protected User $admin;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
Storage::fake('private');
|
|
Storage::fake('local');
|
|
$this->seedRolesAndPermissions();
|
|
$this->admin = $this->createAdmin();
|
|
}
|
|
|
|
/**
|
|
* Test member search by name
|
|
*/
|
|
public function test_member_search_by_name(): void
|
|
{
|
|
$this->createMember(['full_name' => '張三']);
|
|
$this->createMember(['full_name' => '李四']);
|
|
$this->createMember(['full_name' => '王五']);
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.members.index', ['search' => '張三'])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertSee('張三');
|
|
$response->assertDontSee('李四');
|
|
}
|
|
|
|
/**
|
|
* Test member search by email
|
|
*/
|
|
public function test_member_search_by_email(): void
|
|
{
|
|
$this->createMember(['full_name' => 'Test']);
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.members.index', ['search' => 'test'])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
}
|
|
|
|
/**
|
|
* Test member search by member number
|
|
*/
|
|
public function test_member_search_by_member_number(): void
|
|
{
|
|
$member = $this->createMember();
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.members.index', ['search' => $member->member_number])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
}
|
|
|
|
/**
|
|
* Test issue search by title
|
|
*/
|
|
public function test_issue_search_by_title(): void
|
|
{
|
|
Issue::factory()->create([
|
|
'created_by_user_id' => $this->admin->id,
|
|
'title' => '重要議題標題',
|
|
]);
|
|
|
|
Issue::factory()->create([
|
|
'created_by_user_id' => $this->admin->id,
|
|
'title' => '其他議題',
|
|
]);
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.issues.index', ['search' => '重要議題'])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
$response->assertSee('重要議題標題');
|
|
}
|
|
|
|
/**
|
|
* Test issue search by issue number
|
|
*/
|
|
public function test_issue_search_by_issue_number(): void
|
|
{
|
|
$issue = Issue::factory()->create([
|
|
'created_by_user_id' => $this->admin->id,
|
|
]);
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.issues.index', ['search' => $issue->issue_number])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
}
|
|
|
|
/**
|
|
* Test finance document search by title
|
|
*/
|
|
public function test_finance_document_search_by_title(): void
|
|
{
|
|
$this->createFinanceDocument(['title' => '辦公用品採購']);
|
|
$this->createFinanceDocument(['title' => '差旅費報銷']);
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.finance-documents.index', ['search' => '辦公用品'])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
}
|
|
|
|
/**
|
|
* Test finance document search by document number
|
|
*/
|
|
public function test_finance_document_search_by_document_number(): void
|
|
{
|
|
$document = $this->createFinanceDocument();
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.finance-documents.index', ['search' => $document->document_number])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
}
|
|
|
|
/**
|
|
* Test search with Chinese characters
|
|
*/
|
|
public function test_search_with_chinese_characters(): void
|
|
{
|
|
$this->createMember(['full_name' => '測試中文名稱']);
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.members.index', ['search' => '中文'])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
}
|
|
|
|
/**
|
|
* Test search with special characters
|
|
*/
|
|
public function test_search_with_special_characters(): void
|
|
{
|
|
$this->createMember(['full_name' => "O'Connor"]);
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.members.index', ['search' => "O'Connor"])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
}
|
|
|
|
/**
|
|
* Test empty search returns all
|
|
*/
|
|
public function test_empty_search_returns_all(): void
|
|
{
|
|
$this->createMember(['full_name' => 'Member 1']);
|
|
$this->createMember(['full_name' => 'Member 2']);
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.members.index', ['search' => ''])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
}
|
|
|
|
/**
|
|
* Test search is case insensitive
|
|
*/
|
|
public function test_search_is_case_insensitive(): void
|
|
{
|
|
Issue::factory()->create([
|
|
'created_by_user_id' => $this->admin->id,
|
|
'title' => 'TEST ISSUE',
|
|
]);
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.issues.index', ['search' => 'test issue'])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
}
|
|
|
|
/**
|
|
* Test search pagination
|
|
*/
|
|
public function test_search_pagination(): void
|
|
{
|
|
// Create many members
|
|
for ($i = 0; $i < 30; $i++) {
|
|
$this->createMember(['full_name' => "搜尋會員{$i}"]);
|
|
}
|
|
|
|
$response = $this->actingAs($this->admin)->get(
|
|
route('admin.members.index', ['search' => '搜尋會員', 'page' => 2])
|
|
);
|
|
|
|
$response->assertStatus(200);
|
|
}
|
|
}
|