user->attachPermission( Permission::where('name', 'read-admin-panel')->firstOrFail() ); } public function testStoreReceivingAccountPageUsesRebuiltTabsFiltersAndSharedStoreSeed(): void { $synchronizer = Mockery::mock(StoreReceivingAccountSynchronizer::class); $synchronizer->shouldReceive('sync')->once()->with((int) $this->company->id)->andReturn([ 'created' => 0, 'updated' => 0, 'skipped' => 0, 'by_platform' => ['天猫' => 1], ]); $this->app->instance(StoreReceivingAccountSynchronizer::class, $synchronizer); StoreReceivingAccount::query()->create([ 'company_id' => $this->company->id, 'store_platform' => '天猫', 'erp_store_name' => '天猫-测试ERP店', 'shop_name' => '测试店铺名', 'store_status' => '正常', 'store_entity_name' => '测试主体', 'receiving_method' => '支付宝', ]); $this->loginAs()->get(route('business.pages.show', [ 'section' => 'fund-management', 'page' => 'store-receiving-accounts', 'tab' => 'taobao', ])) ->assertOk() ->assertSeeText('淘宝') ->assertSeeText('ERP店铺名称') ->assertSeeText('测试店铺名') ->assertSeeText('测试主体') ->assertSeeText('下载淘宝模板') ->assertSee('aria-label="店铺收款账户筛选"', false) ->assertDontSeeText('安装明细汇总'); } public function testInstallationDetailsRendersWorkbookHeadersAndImportedRows(): void { $mirror = Mockery::mock(InstallationDetailMirrorRepository::class); $mirror->shouldReceive('paginate')->once()->andReturn([ 'ready' => true, 'total' => 1, 'data' => [array_replace(array_fill_keys(array_keys(InstallationDetail::columnLabels()), null), [ 'id' => 1, 'installation_no' => 'INSTALL-TEST-001', 'installation_company' => '测试安装公司', 'store_name' => '测试店铺', 'requested_amount' => '120.50', 'settled_amount' => '100.00', 'item_quantity' => 2, 'related_guid' => 'guid-install-test', ])], ]); $this->app->instance(InstallationDetailMirrorRepository::class, $mirror); $this->loginAs() ->get(route('business.pages.show', [ 'section' => 'financial-operations', 'page' => 'installation-details', ])) ->assertOk() ->assertSeeText('安装明细 · 数据列表') ->assertSeeText('安装单号') ->assertSeeText('申请总金额') ->assertSeeText('商品名称(1)') ->assertSeeText('创建日期:') ->assertSeeText('客服审核时间:') ->assertSeeText('财务审核时间:') ->assertSeeText('推送状态:') ->assertSeeText('选择店铺:') ->assertSeeText('选择删除:') ->assertSeeText('订单类型:') ->assertSeeText('商品ID:') ->assertSeeText('导出') ->assertSeeText('INSTALL-TEST-001') ->assertSeeText('测试安装公司') ->assertSeeText('120.50') ->assertSeeText('共 1 条'); } public function testInstallationDetailsExportUsesFiltersAndMirrorRows(): void { $row = array_fill_keys(array_keys(InstallationDetail::columnLabels()), null); $row['installation_no'] = 'INSTALL-EXPORT-001'; $mirror = Mockery::mock(InstallationDetailMirrorRepository::class); $mirror->shouldReceive('paginate')->once()->with(1, 100, ['created_from' => '2026-08-01'])->andReturn([ 'ready' => true, 'total' => 1, 'data' => [$row], ]); $this->app->instance(InstallationDetailMirrorRepository::class, $mirror); $response = $this->loginAs()->get(route('business.installation-details.export', [ 'created_from' => '2026-08-01', ])); $response->assertOk()->assertHeader('content-type', 'text/csv; charset=UTF-8'); $this->assertStringContainsString('INSTALL-EXPORT-001', $response->streamedContent()); } public function testInstallationDetailsEndpointReturnsChildItemsForMainRecord(): void { $mirror = Mockery::mock(InstallationDetailMirrorRepository::class); $mirror->shouldReceive('details')->once()->with('guid-install-test')->andReturn([ 'ready' => true, 'data' => [[ 'transaction_no' => 'INSTALL-TEST-001', 'product_id' => '10035070813217', 'product_name' => '测试商品', 'detail_requested_amount' => '53.59', 'detail_requested_quantity' => 1, ]], ]); $this->app->instance(InstallationDetailMirrorRepository::class, $mirror); $this->loginAs() ->get(route('business.installation-details.details', ['guid' => 'guid-install-test'])) ->assertOk() ->assertJsonPath('data.0.transaction_no', 'INSTALL-TEST-001') ->assertJsonPath('data.0.product_name', '测试商品'); } public function testInstallationChildEndpointRequiresTheSameSidebarPermission(): void { $this->withExceptionHandling(); $this->user->roles()->sync([\App\Models\Auth\Role::where('name', 'admin')->firstOrFail()->id]); setting()->set('system.sidebar_permissions', ['configured'=>['user_'.$this->user->id], 'subjects'=>['user_'.$this->user->id=>['store-management/basic-information']]]); $mirror=Mockery::mock(InstallationDetailMirrorRepository::class); $mirror->shouldNotReceive('details'); $this->app->instance(InstallationDetailMirrorRepository::class,$mirror); $this->loginAs()->getJson(route('business.installation-details.details',['guid'=>'guid-install-test']))->assertForbidden(); } public function testCompanyInformationUsesWorkbookHeadersAndReadOnlyUpstreamRows(): void { $this->mockUpstreamPage((object) [ 'id' => 1045, 'unified_social_credit_code' => '91320404MADJRTTA0U', 'company_name' => '测试上游公司', 'subscribed_capital' => '10.00', 'company_type' => '店铺-普通公司', 'establishment_date' => '2024-04-28', 'legal_representative' => '测试法人', 'registered_address' => '测试地址', 'business_scope' => '测试经营范围', 'basic_deposit_account_number' => 'J0001', 'company_status' => '正常', 'financial_officer' => '测试财务', 'supervisor' => '', 'taxpayer_category' => '小规模纳税人', 'shareholders' => null, ]); $this->loginAs() ->get(route('business.pages.show', [ 'section' => 'company-management', 'page' => 'basic-information', ])) ->assertOk() ->assertSeeText('公司基础信息') ->assertSeeText('认缴注册资本(万元)') ->assertSeeText('基本存款账户信息') ->assertSeeText('纳税人类型') ->assertSeeText('已配置') ->assertSeeText('测试上游公司') ->assertSeeText('既有只读上游') ->assertDontSeeText('导入') ->assertDontSeeText('新增'); } public function testStoreInformationKeepsTwelveHeadersAndShowsReadOnlyUpstreamRows(): void { $this->mockUpstreamPage((object) [ 'id' => 2047, 'opened_at' => '2026-07-18', 'erp_store_name' => '测试上游店铺', 'unified_social_credit_code' => '91320412MA216EYU49', 'company_name' => '测试关联公司', 'trademark_number' => '35774784', 'trademark_name' => null, 'platform' => '天猫', 'profit_center' => '运营中心A', 'store_manager' => '测试负责人', 'store_status' => '正常', 'store_type' => '旗舰店', 'channel_mode' => '直销', ]); $response = $this->loginAs()->get(route('business.pages.show', [ 'section' => 'store-management', 'page' => 'basic-information', ])); $response ->assertOk() ->assertSeeText('店铺名称') ->assertSeeText('店铺主体') ->assertSeeText('业务部门') ->assertSeeText('测试上游店铺') ->assertSeeText('测试关联公司') ->assertSeeText('既有只读上游') ->assertDontSeeText('导入') ->assertDontSeeText('新增'); preg_match_all('/