tmpDir = sys_get_temp_dir() . '/bf-bundled-' . bin2hex(random_bytes(4)); mkdir($this->tmpDir, 0700, true); } protected function tearDown(): void { if (is_dir($this->tmpDir)) { foreach (glob($this->tmpDir . '/*') ?: [] as $file) { unlink($file); } rmdir($this->tmpDir); } } public function testReturnsBundledScenariosFromTheConfiguredDirectory(): void { $this->writeManifest([ 'skirmish' => ['name' => 'Skirmish', 'summary' => 'Open ground.'], 'hold-the-line' => ['name' => 'Hold the Line', 'summary' => 'Defend.'], ]); $this->writeFixture('skirmish', '{}'); $this->writeFixture('hold-the-line', '{}'); $handler = new GetBundledScenarios($this->tmpDir); $response = $handler->handle(new Request([], [], [], [], [], '', 'GET', '/scenarios/bundled', null, ''), []); self::assertSame(200, $response->status); $body = json_decode($response->body, true); self::assertSame( [ ['id' => 'hold-the-line', 'name' => 'Hold the Line', 'summary' => 'Defend.'], ['id' => 'skirmish', 'name' => 'Skirmish', 'summary' => 'Open ground.'], ], $body, ); } public function testFiltersOutFixturesWithoutAManifestEntry(): void { $this->writeManifest(['skirmish' => ['name' => 'Skirmish', 'summary' => 'Open ground.']]); $this->writeFixture('skirmish', '{}'); $this->writeFixture('rogue', '{}'); $handler = new GetBundledScenarios($this->tmpDir); $response = $handler->handle(new Request([], [], [], [], [], '', 'GET', '/scenarios/bundled', null, ''), []); $body = json_decode($response->body, true); self::assertCount(1, $body); self::assertSame('skirmish', $body[0]['id']); } public function testIgnoresFilesWithDisallowedFilenames(): void { $this->writeManifest(['skirmish' => ['name' => 'Skirmish', 'summary' => 'Open ground.']]); $this->writeFixture('skirmish', '{}'); $this->writeFixture('bad..json', '{}'); $this->writeFixture('README', 'plain text'); $handler = new GetBundledScenarios($this->tmpDir); $response = $handler->handle(new Request([], [], [], [], [], '', 'GET', '/scenarios/bundled', null, ''), []); $body = json_decode($response->body, true); self::assertCount(1, $body); self::assertSame('skirmish', $body[0]['id']); } public function testReturnsEmptyArrayWhenManifestIsMissing(): void { $handler = new GetBundledScenarios($this->tmpDir); $response = $handler->handle(new Request([], [], [], [], [], '', 'GET', '/scenarios/bundled', null, ''), []); self::assertSame(200, $response->status); self::assertSame([], json_decode($response->body, true)); } /** @param array $entries */ private function writeManifest(array $entries): void { file_put_contents($this->tmpDir . '/manifest.json', json_encode($entries, JSON_THROW_ON_ERROR)); } private function writeFixture(string $name, string $body): void { file_put_contents($this->tmpDir . '/' . $name . '.json', $body); } }