grantPermission(); $repository = Mockery::mock(ShippingOrderRepository::class); $repository->shouldReceive('paginate')->once()->withArgs(function (array $filters, int $page, int $limit, string $mode): bool { return $filters === [ 'express_no' => 'EXP-001', 'sourceno' => 'TRADE-001', 'barcode' => 'BAR-001', 'supplier_name' => ['新北供应商'], 'shop_name' => ['测试店铺'], 'warehouse_name' => ['一号仓'], 'express_company' => ['顺丰'], 'ship_from' => '2026-09-01', 'ship_to' => '2026-09-16', ] && $page === 1 && $limit > 0 && $mode === 'detail'; })->andReturn(['data' => [], 'total' => 0]); $repository->shouldReceive('syncStatus')->once()->andReturn([ 'code' => 'succeeded', 'last_succeeded_at' => '2026-09-16 10:16:36', ]); $this->app->instance(ShippingOrderRepository::class, $repository); $this->loginAs()->get(route('business.pages.show', [ 'section' => 'courier-payables', 'page' => 'shipping-data', 'express_no' => 'EXP-001', 'sourceno' => 'TRADE-001', 'barcode' => 'BAR-001', 'supplier_name' => '新北供应商', 'shop_name' => '测试店铺', 'warehouse_name' => '一号仓', 'express_company' => '顺丰', 'ship_from' => '2026-09-01', 'ship_to' => '2026-09-16', 'mode' => 'detail', ])) ->assertOk() ->assertSee('name="barcode"', false) ->assertSee('name="supplier_name[]"', false) ->assertSee('name="shop_name[]"', false) ->assertSee('name="warehouse_name[]"', false) ->assertSee('name="express_company[]"', false) ->assertSee('type="date" name="ship_from"', false) ->assertSee('data-date-picker-input="shipping-from"', false) ->assertSeeText('导出') ->assertSeeText('导出明细'); } public function test_export_uses_current_filters_and_keeps_identifiers_unprefixed(): void { $this->grantPermission(); $repository = Mockery::mock(ShippingOrderRepository::class); $repository->shouldReceive('exportRows')->once()->withArgs(function (array $filters, int $batchSize, string $mode): bool { return $filters['barcode'] === '6901234567890' && $filters['supplier_name'] === ['新北供应商'] && $filters['shop_name'] === ['测试店铺'] && $filters['warehouse_name'] === ['一号仓'] && $filters['express_company'] === ['顺丰'] && $filters['ship_from'] === '2026-09-01' && $filters['ship_to'] === '2026-09-16' && $batchSize === 1000 && $mode === 'merged'; })->andReturn((static function (): \Generator { yield [ 'express_no' => '01234567890123456789', 'trade_no' => 'TRADE-001', 'barcode' => '6901234567890', 'product_name' => '测试商品', 'qty' => 2, 'shop_name' => '测试店铺', 'warehouse_name' => '一号仓', 'supplier_name' => '新北供应商', 'express_name1' => '顺丰速运', 'ship_time' => '2026-09-10 12:00:00', ]; })()); $this->app->instance(ShippingOrderRepository::class, $repository); $response = $this->loginAs()->get(route('business.courier-payables.shipping-data.export', [ 'barcode' => '6901234567890', 'supplier_name' => '新北供应商', 'shop_name' => '测试店铺', 'warehouse_name' => '一号仓', 'express_company' => '顺丰', 'ship_from' => '2026-09-01', 'ship_to' => '2026-09-16', ])); $response->assertOk(); $this->assertStringContainsString('attachment;', (string) $response->headers->get('content-disposition')); $content = $response->streamedContent(); $this->assertStringStartsWith(chr(0xEF) . chr(0xBB) . chr(0xBF), $content); $this->assertStringContainsString('快递单号', $content); $this->assertStringContainsString('01234567890123456789', $content); $this->assertStringContainsString('6901234567890', $content); $this->assertStringNotContainsString("'01234567890123456789", $content); $this->assertStringNotContainsString("'6901234567890", $content); $this->assertStringContainsString('新北供应商', $content); } private function grantPermission(): void { $this->user->attachPermission( Permission::where('name', 'read-admin-panel')->firstOrFail(), ); } }