Skip to main content
Glama

CTX: Context as Code (CaC) tool

by context-hub
MIT License
235
  • Apple
  • Linux
UrlSourceTest.php10.2 kB
<?php declare(strict_types=1); namespace Tests\Feature\Console\GenerateCommand; use Butschster\ContextGenerator\Lib\HttpClient\HttpClientInterface; use Butschster\ContextGenerator\Lib\HttpClient\HttpResponse; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use Tests\Feature\Console\ConsoleTestCase; final class UrlSourceTest extends ConsoleTestCase { private string $outputDir; private MockHttpClient $mockHttpClient; public static function commandsProvider(): \Generator { yield 'generate' => ['generate']; yield 'build' => ['build']; yield 'compile' => ['compile']; } #[Test] #[DataProvider('commandsProvider')] public function basic_url_source_should_be_rendered(string $command): void { // Setup mock response $this->mockHttpClient->addResponse( 'https://example.com/api', new HttpResponse( statusCode: 200, body: '<html><body><h1>Example API</h1><p>This is example content</p></body></html>', headers: ['Content-Type' => 'text/html'], ), ); $this ->buildContext( workDir: $this->outputDir, configPath: $this->getFixturesDir('Console/GenerateCommand/UrlSource/basic.yaml'), command: $command, ) ->assertDocumentsCompiled() ->assertContext( document: 'url-source.md', contains: [ '# Basic URL Source Test', 'URL: https://example.com/api', 'Example API', 'This is example content', ], ); } #[Test] #[DataProvider('commandsProvider')] public function source_with_missed_urls_parameter(string $command): void { $this ->buildContext( workDir: $this->outputDir, configPath: $this->getFixturesDir('Console/GenerateCommand/UrlSource/invalid.yaml'), command: $command, ) ->assertDocumentError( document: 'url-source.md', contains: [ 'URL source must have a "urls" array property', ], ); } #[Test] #[DataProvider('commandsProvider')] public function url_source_with_selector_should_extract_content(): void { // Setup mock response with content that has elements to select $this->mockHttpClient->addResponse( 'https://example.com/docs', new HttpResponse( statusCode: 200, body: '<html><body><div class="header">Header</div><div class="content"><h2>Documentation</h2><p>Selected content</p></div><div class="footer">Footer</div></body></html>', headers: ['Content-Type' => 'text/html'], ), ); $this ->buildContext( workDir: $this->outputDir, configPath: $this->getFixturesDir('Console/GenerateCommand/UrlSource/with-selector.yaml'), ) ->assertDocumentsCompiled() ->assertContext( document: 'selector-test.md', contains: [ '# URL Source with Selector', 'URL: https://example.com/docs (selector: .content)', 'Documentation', 'Selected content', ], notContains: [ 'Header', 'Footer', ], ); } #[Test] #[DataProvider('commandsProvider')] public function url_source_with_headers_should_send_headers(): void { // Setup mock response $this->mockHttpClient->addResponse( 'https://api.example.com/data', new HttpResponse( statusCode: 200, body: '{"message": "Authentication successful", "data": {"name": "Test User", "email": "test@example.com"}}', headers: ['Content-Type' => 'application/json'], ), ); $this ->buildContext( workDir: $this->outputDir, configPath: $this->getFixturesDir('Console/GenerateCommand/UrlSource/with-headers.yaml'), ) ->assertDocumentsCompiled() ->assertContext( document: 'headers-test.md', contains: [ '# URL Source with Headers', 'URL: https://api.example.com/data', 'Authentication successful', 'Test User', ], ); // Verify the headers were sent $sentHeaders = $this->mockHttpClient->getRequestHeaders('https://api.example.com/data'); $this->assertArrayHasKey('Authorization', $sentHeaders); $this->assertEquals('Bearer test-token', $sentHeaders['Authorization']); $this->assertArrayHasKey('Accept', $sentHeaders); $this->assertEquals('application/json', $sentHeaders['Accept']); } #[Test] #[DataProvider('commandsProvider')] public function url_source_with_multiple_urls_should_fetch_all(): void { // Setup mock responses for multiple URLs $this->mockHttpClient->addResponse( 'https://example.com/page1', new HttpResponse( statusCode: 200, body: '<html><body><h1>Page 1</h1><p>Content from page 1</p></body></html>', headers: ['Content-Type' => 'text/html'], ), ); $this->mockHttpClient->addResponse( 'https://example.com/page2', new HttpResponse( statusCode: 200, body: '<html><body><h1>Page 2</h1><p>Content from page 2</p></body></html>', headers: ['Content-Type' => 'text/html'], ), ); $this ->buildContext( workDir: $this->outputDir, configPath: $this->getFixturesDir('Console/GenerateCommand/UrlSource/multiple-urls.yaml'), ) ->assertDocumentsCompiled() ->assertContext( document: 'multiple-urls.md', contains: [ '# Multiple URLs Test', 'URL: https://example.com/page1', 'Page 1', 'Content from page 1', 'URL: https://example.com/page2', 'Page 2', 'Content from page 2', ], ); } #[Test] #[DataProvider('commandsProvider')] public function url_source_with_failed_request_should_show_error(): void { // Setup mock response with error $this->mockHttpClient->addResponse( 'https://example.com/not-found', new HttpResponse( statusCode: 404, body: 'Not Found', headers: [], ), ); $this ->buildContext( workDir: $this->outputDir, configPath: $this->getFixturesDir('Console/GenerateCommand/UrlSource/failed-request.yaml'), ) ->assertDocumentsCompiled() ->assertContext( document: 'failed-request.md', contains: [ '# Failed Request Test', 'URL: https://example.com/not-found', 'Error: HTTP status code 404', ], ); } #[Test] #[DataProvider('commandsProvider')] public function url_source_with_variables_should_resolve_variables(): void { // Setup mock response $this->mockHttpClient->addResponse( 'https://api.production.example.com/data', new HttpResponse( statusCode: 200, body: '<html><body><h1>Production API</h1><p>This is production data</p></body></html>', headers: ['Content-Type' => 'text/html'], ), ); // Create env file with variables $envFile = $this->createTempFile( "ENV_NAME=production\nAPI_TOKEN=prod-token\n", '.env', ); $this ->buildContext( workDir: $this->outputDir, configPath: $this->getFixturesDir('Console/GenerateCommand/UrlSource/with-variables.yaml'), envFile: $envFile, ) ->assertDocumentsCompiled() ->assertContext( document: 'variables-test.md', contains: [ '# URL Source with Variables', 'URL: https://api.production.example.com/data', 'Production API', 'This is production data', ], ); // Verify the headers were sent with resolved variables $sentHeaders = $this->mockHttpClient->getRequestHeaders('https://api.production.example.com/data'); $this->assertArrayHasKey('Authorization', $sentHeaders); $this->assertEquals('Bearer prod-token', $sentHeaders['Authorization']); } #[\Override] protected function setUp(): void { parent::setUp(); $this->outputDir = $this->createTempDir(); // Create mock HTTP client $this->mockHttpClient = new MockHttpClient(); // Register mock HTTP client in the container $this->getContainer()->bindSingleton(HttpClientInterface::class, $this->mockHttpClient); } protected function buildContext( string $workDir, ?string $configPath = null, ?string $inlineJson = null, ?string $envFile = null, string $command = 'generate', bool $asJson = true, ): CompilingResult { return (new ContextBuilder($this->getConsole()))->build( workDir: $workDir, configPath: $configPath, inlineJson: $inlineJson, envFile: $envFile, command: $command, asJson: $asJson, ); } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/context-hub/generator'

If you have feedback or need assistance with the MCP directory API, please join our Discord server