CaiWuXiTong/tests/Feature/Business/FinanceLedgerAccountKeepTodoTest.php

355 lines
14 KiB
PHP

<?php
namespace Tests\Feature\Business;
use App\Models\Auth\Permission;
use App\Models\Auth\Role;
use Illuminate\Support\Facades\DB;
use Tests\Feature\FeatureTestCase;
class FinanceLedgerAccountKeepTodoTest extends FeatureTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->user->attachPermission(
Permission::where('name', 'read-admin-panel')->firstOrFail()
);
}
private function ledgerUrl(): string
{
return route('business.pages.show', [
'company_id' => $this->company->id,
'section' => 'financial-operations',
'page' => 'ledger',
]);
}
private function keepTasksUrl(array $parameters = []): string
{
return route('business.financial-ledger.unretained-accounts', array_merge([
'company_id' => $this->company->id,
], $parameters));
}
private function keepTodoUrl(): string
{
return route('business.financial-ledger.accounts.keep-todo', [
'company_id' => $this->company->id,
]);
}
public function test_ledger_card_follows_account_count_and_links_to_independent_keep_tasks(): void
{
DB::connection('business_mirror')->table('fin_accounts')->insert([
[
'company_name' => '不保留测试公司甲',
'account_short' => '显式不保留账户',
'company_plan' => '保留',
'account_should_keep' => '否',
],
[
'company_name' => '不保留测试公司乙',
'account_short' => '规划不保留账户',
'company_plan' => '待注销',
'account_should_keep' => null,
],
[
'company_name' => '不保留测试公司丙',
'account_short' => '明确保留账户',
'company_plan' => '待注销',
'account_should_keep' => '是',
],
[
'company_name' => '不保留测试公司丁',
'account_short' => '规划保留账户',
'company_plan' => '保留',
'account_should_keep' => null,
],
]);
$response = $this->loginAs()->get($this->ledgerUrl())->assertOk();
$content = $response->getContent();
$this->assertMatchesRegularExpression(
'/<span>账户数<\/span><b>4<\/b><\/div>\s*<a[^>]+aria-label="查看不保留账户处理待办"[^>]*><span>不保留账户数<\/span><b>2<\/b><\/a>/u',
$content,
);
$response->assertSee('href="' . $this->keepTasksUrl() . '"', false);
}
public function test_keep_tasks_page_uses_required_columns_filters_and_retention_rule(): void
{
$connection = DB::connection('business_mirror');
$connection->table('fin_accounts')->insert([
[
'company_name' => '展示测试公司甲',
'account_short' => '显式不保留账户',
'account_type' => '公户',
'account_no' => '6222000000000001',
'bank_name' => '展示测试银行甲',
'bank_city_branch' => '上海 / 测试支行',
'company_plan' => '保留',
'account_should_keep' => '否',
],
[
'company_name' => '展示测试公司乙',
'account_short' => '规划不保留账户',
'account_type' => '个人卡',
'account_no' => null,
'bank_name' => null,
'bank_city_branch' => null,
'company_plan' => '待注销',
'account_should_keep' => null,
],
[
'company_name' => '展示测试公司丙',
'account_short' => '明确保留账户',
'account_type' => '支付宝',
'account_no' => null,
'bank_name' => null,
'bank_city_branch' => null,
'company_plan' => '待注销',
'account_should_keep' => '是',
],
[
'company_name' => '展示测试公司丁',
'account_short' => '规划保留账户',
'account_type' => '网商银行',
'account_no' => null,
'bank_name' => null,
'bank_city_branch' => null,
'company_plan' => '保留',
'account_should_keep' => null,
],
]);
$connection->table('fin_account_statuses')->insert([
'account_short' => '显式不保留账户',
'status' => 'limited',
'updated_by' => 'Test User',
]);
$response = $this->loginAs()->get($this->keepTasksUrl())->assertOk();
$content = $response->getContent();
$response
->assertSee('不保留账户处理待办')
->assertSee('不与其他页面的待办事项合并')
->assertSee('data-keep-account="显式不保留账户"', false)
->assertSee('data-keep-account="规划不保留账户"', false)
->assertDontSee('data-keep-account="明确保留账户"', false)
->assertDontSee('data-keep-account="规划保留账户"', false)
->assertSee('name="keep_short"', false)
->assertSee('name="keep_type"', false)
->assertSee('name="keep_status"', false)
->assertSee('name="keep_method"', false)
->assertSee('name="keep_owner"', false)
->assertSee('name="keep_progress"', false)
->assertSee('按开始时间排序')
->assertSee('按完成时间排序')
->assertSee('线上')
->assertSee('线下')
->assertSee('已完成')
->assertSee('进行中')
->assertSee('待开始')
->assertSee('data-keep-tbody', false)
->assertSee('data-keep-pagination', false)
->assertSee('拖动表头右侧边界可调整列宽')
->assertSee('cursor:col-resize', false)
->assertSee('position:sticky', false)
->assertSee('currentBody.replaceWith', false)
->assertSee('history.replaceState', false)
->assertSee('nextWrap.scrollTop = scrollTop', false);
preg_match_all('/<th data-keep-column-key="([^"]+)"/u', $content, $matches);
$this->assertSame([
'company_name',
'account_short',
'account_type',
'account_status',
'account_no',
'bank_name',
'bank_city_branch',
'account_should_keep',
'handling_method',
'owner_name',
'started_at',
'completed_at',
'current_progress',
], $matches[1]);
}
public function test_keep_tasks_filters_sort_and_ajax_pagination_work(): void
{
$connection = DB::connection('business_mirror');
$connection->table('fin_accounts')->insert([
[
'company_name' => '筛选公司甲',
'account_short' => '筛选账户甲',
'account_type' => '公户',
'company_plan' => '保留',
'account_should_keep' => '否',
],
[
'company_name' => '筛选公司乙',
'account_short' => '筛选账户乙',
'account_type' => '个人卡',
'company_plan' => '待注销',
'account_should_keep' => null,
],
]);
$connection->table('fin_account_statuses')->insert([
'account_short' => '筛选账户甲',
'status' => 'limited',
'updated_by' => 'Test User',
]);
$connection->table('fin_account_keep_todos')->insert([
[
'account_short' => '筛选账户甲',
'handling_method' => 'online',
'owner_name' => '甲负责人',
'started_at' => '2026-10-21 09:00:00',
'current_progress' => 'in_progress',
],
[
'account_short' => '筛选账户乙',
'handling_method' => 'offline',
'owner_name' => '乙负责人',
'started_at' => '2026-10-22 09:00:00',
'current_progress' => 'not_started',
],
]);
$this->loginAs()->get($this->keepTasksUrl([
'keep_short' => '筛选账户甲',
'keep_type' => '公户',
'keep_status' => 'limited',
'keep_method' => 'online',
'keep_owner' => '甲负责人',
'keep_progress' => 'in_progress',
]))
->assertOk()
->assertSee('data-keep-account="筛选账户甲"', false)
->assertDontSee('data-keep-account="筛选账户乙"', false)
->assertSee('value="limited" selected', false)
->assertSee('value="online" selected', false)
->assertSee('value="in_progress" selected', false);
$sortResponse = $this->loginAs()->get($this->keepTasksUrl([
'keep_sort' => 'started_at',
'keep_direction' => 'desc',
]))->assertOk()->assertSee('aria-sort="descending"', false);
preg_match_all('/data-keep-account="([^"]+)"/u', $sortResponse->getContent(), $sortedAccounts);
$this->assertSame(['筛选账户乙', '筛选账户甲'], $sortedAccounts[1]);
$pageRows = [];
for ($index = 1; $index <= 51; $index++) {
$pageRows[] = [
'company_name' => '分页公司',
'account_short' => 'keep-page-' . str_pad((string) $index, 2, '0', STR_PAD_LEFT),
'account_should_keep' => '否',
];
}
$connection->table('fin_accounts')->insert($pageRows);
$this->loginAs()->get($this->keepTasksUrl(['keep_short' => 'keep-page-']))
->assertOk()
->assertSee('1 / 2')
->assertSee('aria-label="下一页"', false)
->assertSee('data-keep-pagination', false);
$this->loginAs()->get($this->keepTasksUrl(['keep_short' => 'keep-page-', 'page' => 2]))
->assertOk()
->assertSee('2 / 2')
->assertSee('data-keep-account="keep-page-51"', false);
}
public function test_keep_todo_save_is_isolated_from_abnormal_tasks_and_permission_protected(): void
{
$connection = DB::connection('business_mirror');
$connection->table('fin_accounts')->insert([
[
'company_name' => '待办保存公司甲',
'account_short' => '待办不保留账户',
'company_plan' => '保留',
'account_should_keep' => '否',
],
[
'company_name' => '待办保存公司乙',
'account_short' => '规划不保留待办账户',
'company_plan' => '待注销',
'account_should_keep' => null,
],
[
'company_name' => '待办保存公司丙',
'account_short' => '待办保留账户',
'company_plan' => '保留',
'account_should_keep' => '是',
],
]);
$payload = [
'account_short' => '待办不保留账户',
'handling_method' => 'online',
'owner_name' => '待办负责人',
'started_at' => '2026-10-21T09:00',
'completed_at' => '2026-10-21T11:30',
'current_progress' => 'in_progress',
];
$this->loginAs()->post($this->keepTodoUrl(), $payload)->assertRedirect();
$this->assertDatabaseHas('fin_account_keep_todos', [
'account_short' => '待办不保留账户',
'handling_method' => 'online',
'owner_name' => '待办负责人',
'current_progress' => 'in_progress',
'updated_by' => 'Test User',
], 'business_mirror');
$this->assertDatabaseCount('fin_account_todos', 0, 'business_mirror');
$this->loginAs()->post($this->keepTodoUrl(), array_merge($payload, [
'current_progress' => 'completed',
]))->assertRedirect();
$this->assertDatabaseCount('fin_account_keep_todos', 1, 'business_mirror');
$this->assertDatabaseHas('fin_account_keep_todos', [
'account_short' => '待办不保留账户',
'current_progress' => 'completed',
], 'business_mirror');
$this->loginAs()->post($this->keepTodoUrl(), [
'account_short' => '规划不保留待办账户',
'current_progress' => 'not_started',
])->assertRedirect();
$this->assertDatabaseHas('fin_account_keep_todos', [
'account_short' => '规划不保留待办账户',
'current_progress' => 'not_started',
], 'business_mirror');
$this->withExceptionHandling()->loginAs()->post($this->keepTodoUrl(), [
'account_short' => '待办保留账户',
'current_progress' => 'not_started',
])->assertStatus(422);
$viewer = user_model_class()::create([
'name' => '不保留账户只读用户',
'email' => 'keep-viewer-' . uniqid() . '@example.com',
'password' => 'local-test-password',
'locale' => 'zh-CN',
'enabled' => 1,
'landing_page' => 'dashboard',
'created_from' => 'core::test',
]);
$viewer->companies()->attach($this->company->id);
$viewer->roles()->attach(Role::where('name', 'user')->firstOrFail()->id);
$viewer->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail());
$this->loginAs($viewer)->get($this->keepTasksUrl())
->assertOk()
->assertSee('disabled', false)
->assertDontSee('title="保存待办"', false);
$this->withExceptionHandling()->loginAs($viewer)->post($this->keepTodoUrl(), $payload)
->assertForbidden();
}
}