instance('config', new Repository(['third_game' => [ 'api_url' => 'https://supplier.test', 'sn' => 'test-merchant', 'key' => 'test-secret', 'currency' => 'CNY', ]])); $app->instance('cache', new CacheRepository(new ArrayStore())); $app->instance(Factory::class, new Factory()); $app->instance('log', new \Psr\Log\NullLogger()); Facade::setFacadeApplication($app); Carbon::setTestNow(Carbon::parse('2026-11-04 12:00:00', 'Asia/Shanghai')); Http::preventStrayRequests(); } protected function tearDown(): void { Carbon::setTestNow(); Facade::clearResolvedInstances(); parent::tearDown(); } public function test_documented_platform_spelling_zero_rates_and_daily_refresh(): void { Http::fake(['https://supplier.test/api/server/quota' => Http::sequence() ->push(['code' => 10000, 'data' => ['ratios' => [ ['platfrom' => ' AG ', 'ratio' => 0.09], ['platfrom' => 'pg', 'ratio' => '0'], ]]]) ->push(['code' => 10000, 'data' => ['ratios' => [['platfrom' => 'ag', 'ratio' => '0.10']]]])]); $service = new ThirdGameCommissionService(); $first = $service->rates(); $this->assertSame(['ag' => '0.0900000000', 'pg' => '0.0000000000'], $first['ratios']); $this->assertSame($first, (new ThirdGameCommissionService())->rates()); Http::assertSentCount(1); Http::assertSent(fn ($request) => $request->method() === 'POST' && $request['currency'] === 'CNY' && $request->hasHeader('sn', 'test-merchant') && $request->hasHeader('sign')); Carbon::setTestNow(Carbon::parse('2026-11-05 00:00:01', 'Asia/Shanghai')); $this->assertSame('0.1000000000', $service->rates()['ratios']['ag']); Http::assertSentCount(2); } public function test_provider_failure_is_cached_for_the_day_and_does_not_turn_into_a_zero_rate(): void { Http::fake(['*' => Http::response(['code' => 10404, 'data' => null])]); $service = new ThirdGameCommissionService(); $this->assertFalse($service->rates()['available']); $this->assertSame([], $service->rates()['ratios']); Http::assertSentCount(1); } public function test_malformed_and_conflicting_rates_are_not_accepted_and_merchant_caches_are_isolated(): void { Http::fake(['*' => Http::response(['code' => 10000, 'data' => ['ratios' => [ ['platfrom' => 'negative', 'ratio' => '-0.1'], ['platfrom' => 'large', 'ratio' => '1.01'], ['platfrom' => 'bad', 'ratio' => 'NaN'], ['platfrom' => 'ag', 'ratio' => '.09'], ['platfrom' => 'pg', 'ratio' => '0.1'], ['platfrom' => 'PG', 'ratio' => '0.2'], ['platform' => 'pp', 'ratio' => '0.1234567891'], ]]])]); $service = new ThirdGameCommissionService(); $this->assertSame(['pp' => '0.1234567891'], $service->rates()['ratios']); config(['third_game.sn' => 'another-merchant']); $service->rates(); Http::assertSentCount(2); config(['third_game.currency' => 'USD']); $service->rates(); Http::assertSentCount(3); } }