guides = new GuideRepository(dirname(__DIR__, 2) . '/Fixtures/guides'); } public function testListsTopicsSortedWithoutExtension(): void { self::assertSame(['divi-shortform', 'overview'], $this->guides->topics()); } public function testReturnsMarkdownOfKnownTopic(): void { self::assertStringContainsString('Testinhalt Kurzform', (string) $this->guides->get('divi-shortform')); } /** * @dataProvider maliciousTopics */ public function testRejectsAnythingThatIsNotAPlainTopicName(string $topic): void { self::assertNull($this->guides->get($topic)); } /** @return array */ public static function maliciousTopics(): array { return [ 'traversal' => ['../../wp-config'], 'with extension' => ['overview.md'], 'empty' => [''], 'absolute' => ['/etc/passwd'], 'unknown' => ['does-not-exist'], 'uppercase' => ['OVERVIEW'], ]; } public function testFilesAreTheDefaultWhenNoFilterIsRegistered(): void { Filters\expectApplied('lit_mcp_guides')->once()->with([])->andReturn([]); self::assertSame(['divi-shortform', 'overview'], $this->guides->topics()); self::assertStringContainsString('Testinhalt Kurzform', (string) $this->guides->get('divi-shortform')); } public function testTheFilterAddsAndOverridesTopicsAndIgnoresInvalidNames(): void { Filters\expectApplied('lit_mcp_guides')->andReturn([ 'site-rules' => "# Regeln\nas-is", 'overview' => 'Eigene Übersicht', '../../wp-config' => 'nope', 'Upper' => 'nope', 'not-string' => ['nope'], 7 => 'nope', ]); self::assertSame(['divi-shortform', 'overview', 'site-rules'], $this->guides->topics()); self::assertSame("# Regeln\nas-is", $this->guides->get('site-rules')); self::assertSame('Eigene Übersicht', $this->guides->get('overview')); self::assertNull($this->guides->get('../../wp-config')); self::assertNull($this->guides->get('Upper')); self::assertNull($this->guides->get('not-string')); } public function testANonArrayFilterResultIsIgnored(): void { Filters\expectApplied('lit_mcp_guides')->andReturn('kaputt'); self::assertSame(['divi-shortform', 'overview'], $this->guides->topics()); } public function testMissingDirectoryYieldsNoTopics(): void { self::assertSame([], (new GuideRepository('/nonexistent/dir'))->topics()); } }