From 3aaa588daf3d8128f8e6dad178408a8c8a50c8cd Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 4 Sep 2025 14:57:54 +0200 Subject: [PATCH] refactor: use MockHttpClient callback for URL assertions Replace reflection-based testing with MockClient and MockResponses to test URL generation and payload creation. Use callback-based assertions in MockHttpClient for cleaner and more direct URL validation at request time. --- .../Bridge/HuggingFace/ModelClientTest.php | 69 +++++++++++++------ 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/src/platform/tests/Bridge/HuggingFace/ModelClientTest.php b/src/platform/tests/Bridge/HuggingFace/ModelClientTest.php index c124702a4..1268c533e 100644 --- a/src/platform/tests/Bridge/HuggingFace/ModelClientTest.php +++ b/src/platform/tests/Bridge/HuggingFace/ModelClientTest.php @@ -26,6 +26,7 @@ use Symfony\AI\Platform\Message\UserMessage; use Symfony\AI\Platform\Model; use Symfony\Component\HttpClient\MockHttpClient; +use Symfony\Component\HttpClient\Response\MockResponse; #[CoversClass(ModelClient::class)] #[Small] @@ -35,16 +36,23 @@ final class ModelClientTest extends TestCase #[DataProvider('urlTestCases')] public function testGetUrlForDifferentInputsAndTasks(?string $task, string $expectedUrl) { - $reflection = new \ReflectionClass(ModelClient::class); - $getUrlMethod = $reflection->getMethod('getUrl'); + $response = new MockResponse('{"result": "test"}', [ + 'http_code' => 200, + ]); + + $httpClient = new MockHttpClient(function (string $method, string $url) use ($expectedUrl, $response): MockResponse { + $this->assertSame('POST', $method); + $this->assertSame($expectedUrl, $url); + + return $response; + }); $model = new Model('test-model'); - $httpClient = new MockHttpClient(); $modelClient = new ModelClient($httpClient, 'test-provider', 'test-api-key'); - $actualUrl = $getUrlMethod->invoke($modelClient, $model, $task); - - $this->assertEquals($expectedUrl, $actualUrl); + // Make a request to trigger URL generation + $options = $task ? ['task' => $task] : []; + $modelClient->request($model, 'test input', $options); } public static function urlTestCases(): \Iterator @@ -76,37 +84,56 @@ public static function urlTestCases(): \Iterator #[DataProvider('payloadTestCases')] public function testGetPayloadForDifferentInputsAndTasks(object|array|string $input, array $options, array $expectedKeys, array $expectedValues = []) { + $response = new MockResponse('{"result": "test"}'); + $httpClient = new MockHttpClient($response); + + $model = new Model('test-model'); + $modelClient = new ModelClient($httpClient, 'test-provider', 'test-api-key'); + // Contract handling first $contract = Contract::create( new FileNormalizer(), new MessageBagNormalizer() ); - $payload = $contract->createRequestPayload(new Model('test-model'), $input); - - $reflection = new \ReflectionClass(ModelClient::class); - $getPayloadMethod = $reflection->getMethod('getPayload'); + $payload = $contract->createRequestPayload($model, $input); - $httpClient = new MockHttpClient(); - $modelClient = new ModelClient($httpClient, 'test-provider', 'test-api-key'); + // Make a request to trigger payload generation + $modelClient->request($model, $payload, $options); - $actual = $getPayloadMethod->invoke($modelClient, $payload, $options); + // Get the request options that were sent + $requestOptions = $response->getRequestOptions(); - // Check that expected keys exist + // Check that expected keys exist in the transformed structure foreach ($expectedKeys as $key) { - $this->assertArrayHasKey($key, $actual); + if ('json' === $key) { + // JSON gets transformed to body in HTTP client + $this->assertArrayHasKey('body', $requestOptions); + } elseif ('headers' === $key) { + $this->assertArrayHasKey('headers', $requestOptions); + } } // Check expected values if specified foreach ($expectedValues as $path => $value) { $keys = explode('.', $path); - $current = $actual; - foreach ($keys as $key) { - $this->assertArrayHasKey($key, $current); - $current = $current[$key]; - } - $this->assertEquals($value, $current); + if ('headers' === $keys[0] && 'Content-Type' === $keys[1]) { + // Check Content-Type header in the normalized structure + $this->assertContains('Content-Type: application/json', $requestOptions['headers']); + } elseif ('json' === $keys[0]) { + // JSON content is in the body, need to decode + $body = json_decode($requestOptions['body'], true); + $current = $body; + + // Navigate through the remaining keys + for ($i = 1; $i < \count($keys); ++$i) { + $this->assertArrayHasKey($keys[$i], $current); + $current = $current[$keys[$i]]; + } + + $this->assertEquals($value, $current); + } } }