user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail()); $repository = Mockery::mock(DingProcessDetailMirrorRepository::class); $repository->shouldReceive('paginate')->once()->andReturn([ 'data' => [ (object) [ 'business_id' => '202601011200000000001', 'line_no' => 1, 'originator_name' => '张三', 'status' => '已完成', 'document_type' => '公摊日常报销', 'purpose' => '办公用品采购', 'account_code' => '5602.04', 'account_name' => '管理费用_办公费', 'amount' => 100.00, 'bank_account_code' => '1002.01.001', 'bank_account_name' => '华夏银行-测试', 'bank_amount' => 100.00, 'payment_method' => '银行卡', 'paid_at' => '2026-01-02 00:00', ], ], 'total' => 1, 'summary' => [ 'rows' => 1, 'approvals' => 1, 'amount_total' => 100.0, 'bank_amount_total' => 100.0, ], 'status' => 'succeeded', 'last_synced_at' => '2026-10-26 15:00:00', 'scope' => 'personal_permission', ]); $repository->shouldReceive('filterOptions')->once()->andReturn([ 'months' => ['2026-01'], 'document_types' => ['公摊日常报销'], 'statuses' => ['已完成'], ]); $this->app->instance(DingProcessDetailMirrorRepository::class, $repository); $financeSection = collect(\App\Utilities\BusinessNavigation::all()) ->firstWhere('slug', 'financial-operations'); $this->assertContains( 'process-details', array_column($financeSection['pages'] ?? [], 'slug'), ); $this->loginAs()->get(route('business.pages.show', [ 'section' => 'financial-operations', 'page' => 'process-details', ]))->assertOk() ->assertSee('流程明细') ->assertSee('审批编号') ->assertSee('发起人') ->assertSee('单据类型') ->assertSee('银行付款金额') ->assertSee('202601011200000000001') ->assertSee('张三') ->assertSee('管理费用_办公费') ->assertSee('100.00') ->assertSee('当前账号权限范围') ->assertSee('导出'); } public function test_page_stays_readable_when_mirror_is_not_ready(): void { $this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail()); $repository = Mockery::mock(DingProcessDetailMirrorRepository::class); $repository->shouldReceive('paginate')->once()->andThrow(new RuntimeException('not ready')); $repository->shouldReceive('scope')->once()->andReturn('personal_permission'); $this->app->instance(DingProcessDetailMirrorRepository::class, $repository); $this->loginAs()->get(route('business.pages.show', [ 'section' => 'financial-operations', 'page' => 'process-details', ]))->assertOk() ->assertSee('流程明细镜像尚未完成导入') ->assertSee('当前账号权限范围'); } public function test_export_streams_filtered_csv(): void { $this->user->attachPermission(Permission::where('name', 'read-admin-panel')->firstOrFail()); $repository = Mockery::mock(DingProcessDetailMirrorRepository::class); $repository->shouldReceive('ready')->once()->andReturn(true); $repository->shouldReceive('exportRows')->once()->andReturnUsing(function (): \Generator { yield [ 'business_id' => '202601011200000000001', 'originator_name' => '张三', 'status' => '已完成', 'document_type' => '公摊日常报销', 'purpose' => '办公用品采购', 'line_no' => 1, 'account_code' => '5602.04', 'account_name' => '管理费用_办公费', 'amount' => '100.00', 'bank_account_code' => '1002.01.001', 'bank_account_name' => '华夏银行-测试', 'bank_amount' => '100.00', 'payment_method' => '银行卡', 'paid_at' => '2026-01-02 00:00', ]; }); $this->app->instance(DingProcessDetailMirrorRepository::class, $repository); $response = $this->loginAs()->get(route('business.process-details.export', [ 'status' => '已完成', ])); $response->assertOk(); $content = $response->streamedContent(); $this->assertStringContainsString('审批编号', $content); $this->assertStringContainsString('202601011200000000001', $content); $this->assertStringContainsString('张三', $content); $this->assertStringContainsString('管理费用_办公费', $content); } }