shouldReceive('forSource')->once()->with('js_data_middle_platform')->andReturn($query); $query->shouldReceive('select')->once()->ordered()->with( Mockery::on(static fn (string $sql): bool => str_contains($sql, 'SELECT TOP 5000') && str_contains($sql, 'jd_jzt_finance_records')), ['2026-08'], )->andReturn([['shop_name' => '测试店铺', 'amount' => 100]]); $query->shouldReceive('select')->once()->ordered()->with( Mockery::on(static fn (string $sql): bool => str_contains($sql, 'SUM(CASE WHEN in_out_type') && str_contains($sql, 'jd_jzt_finance_records')), ['2026-08'], )->andReturn([['income' => 100, 'expense' => 0, 'record_count' => 1]]); $result = (new PlatformPromotionAccountRepository($factory))->dashboard([ 'month' => '2026-08', 'shop_name' => '', 'account' => '', ], 5000, 'jd'); $this->assertCount(1, $result['jd']); $this->assertSame(1, $result['jdSummary']['record_count']); $this->assertSame([], $result['dy']); $this->assertSame([], $result['dw']); $this->assertSame([], $result['vipSales']); } public function test_dashboard_rejects_an_unknown_platform_before_connecting(): void { $factory = Mockery::mock(UpstreamReadOnlyQueryFactory::class); $this->expectException(InvalidArgumentException::class); (new PlatformPromotionAccountRepository($factory))->dashboard([ 'month' => '2026-08', ], 200, 'unknown'); } public function test_vip_dashboard_queries_marketing_month_summary_and_daily_details(): void { $factory = Mockery::mock(UpstreamReadOnlyQueryFactory::class); $query = Mockery::mock(UpstreamReadOnlyQuery::class); $factory->shouldReceive('forSource')->once()->with('js_data_middle_platform')->andReturn($query); $query->shouldReceive('select')->once()->with( Mockery::on(static fn (string $sql): bool => str_contains($sql, 'vip_marketingMonthlySummary') && str_contains($sql, 'SELECT TOP 5000') && ! str_contains($sql, 'vip_taxDeclarationDetail') && ! str_contains($sql, 'vip_marketingDailyReport')), ['2026-08'], )->andReturn([ [ 'account' => 'vip-account-01', 'totalCostYuan' => 123.45, 'totalImpressionCount' => 6789, 'recordCount' => 1, ], ]); $query->shouldReceive('select')->once()->with( Mockery::on(static fn (string $sql): bool => str_contains($sql, 'vip_marketingDailyReport') && str_contains($sql, 'SELECT TOP 5000') && ! str_contains($sql, 'vip_taxDeclarationDetail') && ! str_contains($sql, 'vip_monthlySaleProgress')), ['2026-08'], )->andReturn([ [ 'account' => 'vip-account-01', 'costYuan' => 123.45, 'impressionCount' => 6789, ], ]); $result = (new PlatformPromotionAccountRepository($factory))->dashboard([ 'month' => '2026-08', 'shop_name' => '', 'account' => '', 'advertiser_id' => '', ], 5000, 'vip'); $this->assertCount(1, $result['vipMarketingDaily']); $this->assertSame([], $result['vipSales']); $this->assertSame([], $result['vipTax']); $this->assertCount(1, $result['vipMarketing']); $this->assertSame(123.45, $result['vipSummary']['cost']); $this->assertSame(6789.0, $result['vipSummary']['impressions']); $this->assertSame(1, $result['vipSummary']['account_count']); $this->assertSame(1, $result['vipSummary']['daily_record_count']); } }