Skip to content

Commit f7e72fa

Browse files
committed
minor #126 [Platform] Add tests for model clients (OskarStark)
This PR was squashed before being merged into the main branch. Discussion ---------- [Platform] Add tests for model clients | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | Docs? | no | Issues | -- | License | MIT Commits ------- 17bfbf6 [Platform] Add tests for model clients
2 parents 09c5c3a + 17bfbf6 commit f7e72fa

File tree

4 files changed

+296
-0
lines changed

4 files changed

+296
-0
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\AI\Platform\Tests\Bridge\Azure\OpenAI;
13+
14+
use PHPUnit\Framework\Attributes\CoversClass;
15+
use PHPUnit\Framework\Attributes\Small;
16+
use PHPUnit\Framework\Attributes\Test;
17+
use PHPUnit\Framework\Attributes\TestWith;
18+
use PHPUnit\Framework\Attributes\UsesClass;
19+
use PHPUnit\Framework\TestCase;
20+
use Symfony\AI\Platform\Bridge\Azure\OpenAI\EmbeddingsModelClient;
21+
use Symfony\AI\Platform\Bridge\OpenAI\Embeddings;
22+
use Symfony\Component\HttpClient\MockHttpClient;
23+
use Symfony\Component\HttpClient\Response\MockResponse;
24+
use Webmozart\Assert\InvalidArgumentException;
25+
26+
#[CoversClass(EmbeddingsModelClient::class)]
27+
#[UsesClass(Embeddings::class)]
28+
#[Small]
29+
/**
30+
* @author Oskar Stark <[email protected]>
31+
*/
32+
final class EmbeddingsModelClientTest extends TestCase
33+
{
34+
#[Test]
35+
#[TestWith(['http://test.azure.com', 'The base URL must not contain the protocol.'])]
36+
#[TestWith(['https://test.azure.com', 'The base URL must not contain the protocol.'])]
37+
#[TestWith(['http://test.azure.com/path', 'The base URL must not contain the protocol.'])]
38+
#[TestWith(['https://test.azure.com:443', 'The base URL must not contain the protocol.'])]
39+
public function itThrowsExceptionWhenBaseUrlContainsProtocol(string $invalidUrl, string $expectedMessage): void
40+
{
41+
$this->expectException(InvalidArgumentException::class);
42+
$this->expectExceptionMessage($expectedMessage);
43+
44+
new EmbeddingsModelClient(new MockHttpClient(), $invalidUrl, 'deployment', 'api-version', 'api-key');
45+
}
46+
47+
#[Test]
48+
public function itThrowsExceptionWhenDeploymentIsEmpty(): void
49+
{
50+
$this->expectException(InvalidArgumentException::class);
51+
$this->expectExceptionMessage('The deployment must not be empty.');
52+
53+
new EmbeddingsModelClient(new MockHttpClient(), 'test.azure.com', '', 'api-version', 'api-key');
54+
}
55+
56+
#[Test]
57+
public function itThrowsExceptionWhenApiVersionIsEmpty(): void
58+
{
59+
$this->expectException(InvalidArgumentException::class);
60+
$this->expectExceptionMessage('The API version must not be empty.');
61+
62+
new EmbeddingsModelClient(new MockHttpClient(), 'test.azure.com', 'deployment', '', 'api-key');
63+
}
64+
65+
#[Test]
66+
public function itThrowsExceptionWhenApiKeyIsEmpty(): void
67+
{
68+
$this->expectException(InvalidArgumentException::class);
69+
$this->expectExceptionMessage('The API key must not be empty.');
70+
71+
new EmbeddingsModelClient(new MockHttpClient(), 'test.azure.com', 'deployment', 'api-version', '');
72+
}
73+
74+
#[Test]
75+
public function itAcceptsValidParameters(): void
76+
{
77+
$client = new EmbeddingsModelClient(new MockHttpClient(), 'test.azure.com', 'text-embedding-ada-002', '2023-12-01-preview', 'valid-api-key');
78+
79+
$this->assertInstanceOf(EmbeddingsModelClient::class, $client);
80+
}
81+
82+
#[Test]
83+
public function itIsSupportingTheCorrectModel(): void
84+
{
85+
$client = new EmbeddingsModelClient(new MockHttpClient(), 'test.azure.com', 'deployment', '2023-12-01', 'api-key');
86+
87+
self::assertTrue($client->supports(new Embeddings()));
88+
}
89+
90+
#[Test]
91+
public function itIsExecutingTheCorrectRequest(): void
92+
{
93+
$responseCallback = static function (string $method, string $url, array $options): MockResponse {
94+
self::assertSame('POST', $method);
95+
self::assertSame('https://test.azure.com/openai/deployments/embeddings-deployment/embeddings?api-version=2023-12-01', $url);
96+
self::assertSame(['api-key: test-api-key'], $options['normalized_headers']['api-key']);
97+
self::assertSame('{"model":"text-embedding-3-small","input":"Hello, world!"}', $options['body']);
98+
99+
return new MockResponse();
100+
};
101+
102+
$httpClient = new MockHttpClient([$responseCallback]);
103+
$client = new EmbeddingsModelClient($httpClient, 'test.azure.com', 'embeddings-deployment', '2023-12-01', 'test-api-key');
104+
$client->request(new Embeddings(), 'Hello, world!');
105+
}
106+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\AI\Platform\Tests\Bridge\Azure\OpenAI;
13+
14+
use PHPUnit\Framework\Attributes\CoversClass;
15+
use PHPUnit\Framework\Attributes\Small;
16+
use PHPUnit\Framework\Attributes\Test;
17+
use PHPUnit\Framework\Attributes\TestWith;
18+
use PHPUnit\Framework\Attributes\UsesClass;
19+
use PHPUnit\Framework\TestCase;
20+
use Symfony\AI\Platform\Bridge\Azure\OpenAI\GPTModelClient;
21+
use Symfony\AI\Platform\Bridge\OpenAI\GPT;
22+
use Symfony\Component\HttpClient\MockHttpClient;
23+
use Symfony\Component\HttpClient\Response\MockResponse;
24+
use Webmozart\Assert\InvalidArgumentException;
25+
26+
#[CoversClass(GPTModelClient::class)]
27+
#[UsesClass(GPT::class)]
28+
#[Small]
29+
/**
30+
* @author Oskar Stark <[email protected]>
31+
*/
32+
final class GPTModelClientTest extends TestCase
33+
{
34+
#[Test]
35+
#[TestWith(['http://test.azure.com', 'The base URL must not contain the protocol.'])]
36+
#[TestWith(['https://test.azure.com', 'The base URL must not contain the protocol.'])]
37+
#[TestWith(['http://test.azure.com/openai', 'The base URL must not contain the protocol.'])]
38+
#[TestWith(['https://test.azure.com:443', 'The base URL must not contain the protocol.'])]
39+
public function itThrowsExceptionWhenBaseUrlContainsProtocol(string $invalidUrl, string $expectedMessage): void
40+
{
41+
$this->expectException(InvalidArgumentException::class);
42+
$this->expectExceptionMessage($expectedMessage);
43+
44+
new GPTModelClient(new MockHttpClient(), $invalidUrl, 'deployment', 'api-version', 'api-key');
45+
}
46+
47+
#[Test]
48+
public function itThrowsExceptionWhenDeploymentIsEmpty(): void
49+
{
50+
$this->expectException(InvalidArgumentException::class);
51+
$this->expectExceptionMessage('The deployment must not be empty.');
52+
53+
new GPTModelClient(new MockHttpClient(), 'test.azure.com', '', 'api-version', 'api-key');
54+
}
55+
56+
#[Test]
57+
public function itThrowsExceptionWhenApiVersionIsEmpty(): void
58+
{
59+
$this->expectException(InvalidArgumentException::class);
60+
$this->expectExceptionMessage('The API version must not be empty.');
61+
62+
new GPTModelClient(new MockHttpClient(), 'test.azure.com', 'deployment', '', 'api-key');
63+
}
64+
65+
#[Test]
66+
public function itThrowsExceptionWhenApiKeyIsEmpty(): void
67+
{
68+
$this->expectException(InvalidArgumentException::class);
69+
$this->expectExceptionMessage('The API key must not be empty.');
70+
71+
new GPTModelClient(new MockHttpClient(), 'test.azure.com', 'deployment', 'api-version', '');
72+
}
73+
74+
#[Test]
75+
public function itAcceptsValidParameters(): void
76+
{
77+
$client = new GPTModelClient(new MockHttpClient(), 'test.azure.com', 'gpt-35-turbo', '2023-12-01-preview', 'valid-api-key');
78+
79+
$this->assertInstanceOf(GPTModelClient::class, $client);
80+
}
81+
82+
#[Test]
83+
public function itIsSupportingTheCorrectModel(): void
84+
{
85+
$client = new GPTModelClient(new MockHttpClient(), 'test.azure.com', 'deployment', '2023-12-01', 'api-key');
86+
87+
self::assertTrue($client->supports(new GPT()));
88+
}
89+
90+
#[Test]
91+
public function itIsExecutingTheCorrectRequest(): void
92+
{
93+
$responseCallback = static function (string $method, string $url, array $options): MockResponse {
94+
self::assertSame('POST', $method);
95+
self::assertSame('https://test.azure.com/openai/deployments/gpt-deployment/chat/completions?api-version=2023-12-01', $url);
96+
self::assertSame(['api-key: test-api-key'], $options['normalized_headers']['api-key']);
97+
self::assertSame('{"messages":[{"role":"user","content":"Hello"}]}', $options['body']);
98+
99+
return new MockResponse();
100+
};
101+
102+
$httpClient = new MockHttpClient([$responseCallback]);
103+
$client = new GPTModelClient($httpClient, 'test.azure.com', 'gpt-deployment', '2023-12-01', 'test-api-key');
104+
$client->request(new GPT(), ['messages' => [['role' => 'user', 'content' => 'Hello']]]);
105+
}
106+
}

src/platform/tests/Bridge/Azure/OpenAI/WhisperModelClientTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,67 @@
1414
use PHPUnit\Framework\Attributes\CoversClass;
1515
use PHPUnit\Framework\Attributes\Small;
1616
use PHPUnit\Framework\Attributes\Test;
17+
use PHPUnit\Framework\Attributes\TestWith;
1718
use PHPUnit\Framework\TestCase;
1819
use Symfony\AI\Platform\Bridge\Azure\OpenAI\WhisperModelClient;
1920
use Symfony\AI\Platform\Bridge\OpenAI\Whisper;
2021
use Symfony\AI\Platform\Bridge\OpenAI\Whisper\Task;
2122
use Symfony\Component\HttpClient\MockHttpClient;
2223
use Symfony\Component\HttpClient\Response\MockResponse;
24+
use Webmozart\Assert\InvalidArgumentException;
2325

2426
#[CoversClass(WhisperModelClient::class)]
2527
#[Small]
2628
final class WhisperModelClientTest extends TestCase
2729
{
30+
#[Test]
31+
#[TestWith(['http://test.azure.com', 'The base URL must not contain the protocol.'])]
32+
#[TestWith(['https://test.azure.com', 'The base URL must not contain the protocol.'])]
33+
#[TestWith(['http://test.azure.com:8080', 'The base URL must not contain the protocol.'])]
34+
#[TestWith(['https://test.azure.com:443', 'The base URL must not contain the protocol.'])]
35+
public function itThrowsExceptionWhenBaseUrlContainsProtocol(string $invalidUrl, string $expectedMessage): void
36+
{
37+
$this->expectException(InvalidArgumentException::class);
38+
$this->expectExceptionMessage($expectedMessage);
39+
40+
new WhisperModelClient(new MockHttpClient(), $invalidUrl, 'deployment', 'api-version', 'api-key');
41+
}
42+
43+
#[Test]
44+
public function itThrowsExceptionWhenDeploymentIsEmpty(): void
45+
{
46+
$this->expectException(InvalidArgumentException::class);
47+
$this->expectExceptionMessage('The deployment must not be empty.');
48+
49+
new WhisperModelClient(new MockHttpClient(), 'test.azure.com', '', 'api-version', 'api-key');
50+
}
51+
52+
#[Test]
53+
public function itThrowsExceptionWhenApiVersionIsEmpty(): void
54+
{
55+
$this->expectException(InvalidArgumentException::class);
56+
$this->expectExceptionMessage('The API version must not be empty.');
57+
58+
new WhisperModelClient(new MockHttpClient(), 'test.azure.com', 'deployment', '', 'api-key');
59+
}
60+
61+
#[Test]
62+
public function itThrowsExceptionWhenApiKeyIsEmpty(): void
63+
{
64+
$this->expectException(InvalidArgumentException::class);
65+
$this->expectExceptionMessage('The API key must not be empty.');
66+
67+
new WhisperModelClient(new MockHttpClient(), 'test.azure.com', 'deployment', 'api-version', '');
68+
}
69+
70+
#[Test]
71+
public function itAcceptsValidParameters(): void
72+
{
73+
$client = new WhisperModelClient(new MockHttpClient(), 'test.azure.com', 'valid-deployment', '2023-12-01', 'valid-api-key');
74+
75+
$this->assertInstanceOf(WhisperModelClient::class, $client);
76+
}
77+
2878
#[Test]
2979
public function itSupportsWhisperModel(): void
3080
{

src/platform/tests/Bridge/OpenAI/DallE/ModelClientTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\Attributes\CoversClass;
1515
use PHPUnit\Framework\Attributes\Small;
1616
use PHPUnit\Framework\Attributes\Test;
17+
use PHPUnit\Framework\Attributes\TestWith;
1718
use PHPUnit\Framework\Attributes\UsesClass;
1819
use PHPUnit\Framework\TestCase;
1920
use Symfony\AI\Platform\Bridge\OpenAI\DallE;
@@ -24,6 +25,7 @@
2425
use Symfony\Component\HttpClient\MockHttpClient;
2526
use Symfony\Component\HttpClient\Response\MockResponse;
2627
use Symfony\Contracts\HttpClient\ResponseInterface as HttpResponse;
28+
use Webmozart\Assert\InvalidArgumentException;
2729

2830
#[CoversClass(ModelClient::class)]
2931
#[UsesClass(DallE::class)]
@@ -33,6 +35,38 @@
3335
#[Small]
3436
final class ModelClientTest extends TestCase
3537
{
38+
#[Test]
39+
public function itThrowsExceptionWhenApiKeyIsEmpty(): void
40+
{
41+
$this->expectException(InvalidArgumentException::class);
42+
$this->expectExceptionMessage('The API key must not be empty.');
43+
44+
new ModelClient(new MockHttpClient(), '');
45+
}
46+
47+
#[Test]
48+
#[TestWith(['api-key-without-prefix'])]
49+
#[TestWith(['pk-api-key'])]
50+
#[TestWith(['SK-api-key'])]
51+
#[TestWith(['skapikey'])]
52+
#[TestWith(['sk api-key'])]
53+
#[TestWith(['sk'])]
54+
public function itThrowsExceptionWhenApiKeyDoesNotStartWithSk(string $invalidApiKey): void
55+
{
56+
$this->expectException(InvalidArgumentException::class);
57+
$this->expectExceptionMessage('The API key must start with "sk-".');
58+
59+
new ModelClient(new MockHttpClient(), $invalidApiKey);
60+
}
61+
62+
#[Test]
63+
public function itAcceptsValidApiKey(): void
64+
{
65+
$modelClient = new ModelClient(new MockHttpClient(), 'sk-valid-api-key');
66+
67+
$this->assertInstanceOf(ModelClient::class, $modelClient);
68+
}
69+
3670
#[Test]
3771
public function itIsSupportingTheCorrectModel(): void
3872
{

0 commit comments

Comments
 (0)