| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- <?php
- namespace Tests\Unit;
- use App\Services\SportClientService;
- use Illuminate\Container\Container;
- use Illuminate\Filesystem\Filesystem;
- use Illuminate\Foundation\Application;
- use Illuminate\Foundation\Bootstrap\LoadConfiguration;
- use Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables;
- use Illuminate\Http\Client\Factory;
- use Illuminate\Http\Client\Request;
- use Illuminate\Support\Env;
- use Illuminate\Support\Facades\Facade;
- use Illuminate\Support\Facades\Http;
- use PHPUnit\Framework\Attributes\DataProvider;
- use PHPUnit\Framework\Attributes\PreserveGlobalState;
- use PHPUnit\Framework\Attributes\RunInSeparateProcess;
- use PHPUnit\Framework\TestCase;
- class RuntimeConfigurationCacheTest extends TestCase
- {
- private string $temporaryRoot;
- private const ENVIRONMENT = [
- 'APP_ENV' => 'local',
- 'APP_URL' => 'https://app.example.test',
- 'FOOTBALL_APP_URL' => 'https://football-app.example.test',
- 'API_FOOTBALL_HOST' => 'https://football.example.test',
- 'API_FOOTBALL_KEY' => 'football-test-key',
- 'API_BASKETBALL_HOST' => 'https://basketball.example.test',
- 'API_BASKETBALL_KEY' => 'basketball-test-key',
- 'SEND_TELEGRAM' => 'true',
- 'unique_identification' => 'custom-test-salt',
- ];
- protected function tearDown(): void
- {
- Facade::clearResolvedInstances();
- Facade::setFacadeApplication(null);
- Container::setInstance(null);
- if (isset($this->temporaryRoot)) {
- (new Filesystem())->deleteDirectory($this->temporaryRoot);
- }
- parent::tearDown();
- }
- public static function configurationModes(): array
- {
- return [
- 'uncached, telegram enabled' => [false, true],
- 'cached, telegram enabled' => [true, true],
- 'cached, telegram disabled' => [true, false],
- ];
- }
- #[DataProvider('configurationModes')]
- #[RunInSeparateProcess]
- #[PreserveGlobalState(false)]
- public function test_runtime_configuration_survives_caching(bool $cached, bool $sendTelegram): void
- {
- // Bootstrap only configuration in a temporary application, without project providers or .env.
- $this->temporaryRoot = sys_get_temp_dir() . '/runtime-config-test-' . bin2hex(random_bytes(8));
- mkdir($this->temporaryRoot . '/config', 0700, true);
- mkdir($this->temporaryRoot . '/bootstrap/cache', 0700, true);
- foreach (['app', 'services'] as $file) {
- copy(dirname(__DIR__, 2) . '/config/' . $file . '.php', $this->temporaryRoot . '/config/' . $file . '.php');
- }
- $environment = array_replace(self::ENVIRONMENT, ['SEND_TELEGRAM' => $sendTelegram ? 'true' : 'false']);
- $contents = '';
- foreach ($environment as $key => $value) {
- $contents .= $key . '=' . $value . PHP_EOL;
- }
- file_put_contents($this->temporaryRoot . '/.env', $contents);
- $this->clearEnvironment();
- $app = $this->bootConfiguration();
- if ($cached) {
- // Use the same serialized config format as config:cache, then start with a fresh environment.
- file_put_contents($app->getCachedConfigPath(), '<?php return ' . var_export($app['config']->all(), true) . ';');
- $this->clearEnvironment();
- $app = $this->bootConfiguration();
- foreach (array_keys(self::ENVIRONMENT) as $key) {
- $this->assertNull(env($key), 'Cached bootstrap must skip loading ' . $key . ' from .env');
- }
- }
- $this->assertSame($cached, $app['config_loaded_from_cache']);
- $this->assertSame('local', config('app.env'));
- $this->assertSame('https://app.example.test', config('app.url'));
- $this->assertSame('https://football-app.example.test', config('app.football_url'));
- $this->assertSame('custom-test-salt', config('app.unique_identification'));
- $this->assertSame($sendTelegram, config('services.telegram.send_enabled'));
- $app->instance(Factory::class, new Factory());
- Facade::clearResolvedInstances();
- Facade::setFacadeApplication($app);
- Http::preventStrayRequests();
- Http::fake(['*' => Http::response(['response' => []])]);
- foreach ([1 => 'football', 2 => 'basketball'] as $type => $sport) {
- $endpoint = $type === 1 ? 'fixtures' : 'games';
- foreach (['get', 'post'] as $method) {
- $params = ['live' => 'all'];
- $this->assertSame(['response' => []], SportClientService::$method($type, $endpoint, $params));
- Http::assertSent(fn (Request $request) =>
- $request->method() === strtoupper($method)
- && strtok($request->url(), '?') === 'https://' . $sport . '.example.test/' . $endpoint
- && $request->hasHeader('x-apisports-key', $sport . '-test-key')
- && $request->data() === $params
- );
- }
- }
- Http::assertSentCount(4);
- }
- private function bootConfiguration(): Application
- {
- $app = new Application($this->temporaryRoot);
- (new LoadEnvironmentVariables())->bootstrap($app);
- (new LoadConfiguration())->bootstrap($app);
- return $app;
- }
- private function clearEnvironment(): void
- {
- foreach (array_merge(array_keys(self::ENVIRONMENT), ['APP_CONFIG_CACHE']) as $key) {
- unset($_ENV[$key], $_SERVER[$key]);
- putenv($key);
- }
- Env::enablePutenv();
- }
- }
|