Skip to content

Commit 2aed53b

Browse files
committed
Update open ai provider test to include different test cases
1 parent 376c838 commit 2aed53b

File tree

10 files changed

+1057
-0
lines changed

10 files changed

+1057
-0
lines changed
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
<?php
2+
3+
use Joomla\AI\Exception\InvalidArgumentException;
4+
use Joomla\AI\Exception\ProviderException;
5+
use Joomla\AI\Exception\UnserializableResponseException;
6+
use Joomla\AI\Provider\OpenAIProvider;
7+
use Joomla\Http\Http;
8+
use Joomla\Http\HttpFactory;
9+
use Joomla\Http\Response as HttpResponse;
10+
use PHPUnit\Framework\TestCase;
11+
12+
class AudioTest extends TestCase
13+
{
14+
public function testSpeechGeneratesAudioSuccessfully()
15+
{
16+
echo "Test 1: Test speech method for successful completion\n";
17+
18+
$fakeAudioContent = "FAKEAUDIOCONTENT";
19+
20+
$moderationResponse = $this->createJsonResponse([
21+
'id' => 'modr-audio-test',
22+
'model' => 'omni-moderation-latest',
23+
'results' => [['flagged' => false]],
24+
]);
25+
26+
$speechResponse = new HttpResponse('php://memory', 200, ['Content-Type' => 'audio/mpeg']);
27+
$speechResponse->getBody()->write($fakeAudioContent);
28+
29+
$provider = $this->createProviderWithResponses($moderationResponse, $speechResponse);
30+
31+
$response = $provider->speech('Turn this text into speech.', [
32+
'model' => 'gpt-4o-mini-tts',
33+
'voice' => 'alloy',
34+
'response_format' => 'mp3',
35+
]);
36+
37+
$this->assertSame(200, $response->getStatusCode());
38+
$this->assertSame($fakeAudioContent, $response->getContent());
39+
40+
$metadata = $response->getMetadata();
41+
$this->assertSame('gpt-4o-mini-tts', $metadata['model']);
42+
$this->assertSame('alloy', $metadata['voice']);
43+
$this->assertSame('mp3', $metadata['format']);
44+
$this->assertSame('audio/mpeg', $metadata['content_type']);
45+
$this->assertSame('binary_audio', $metadata['data_type']);
46+
$this->assertSame(1.0, $metadata['speed']);
47+
$this->assertSame(strlen($fakeAudioContent), $metadata['size_bytes']);
48+
$this->assertArrayHasKey('created', $metadata);
49+
}
50+
51+
public function testSpeechThrowsInvalidVoiceException()
52+
{
53+
echo "Test 2: Test speech method raises InvalidArgumentException on invalid voice\n";
54+
55+
$moderationResponse = $this->createJsonResponse([
56+
'id' => 'modr-audio-invalid-voice',
57+
'model' => 'omni-moderation-latest',
58+
'results' => [['flagged' => false]],
59+
]);
60+
61+
$provider = $this->createProviderWithResponses($moderationResponse);
62+
63+
$this->expectException(InvalidArgumentException::class);
64+
$this->expectExceptionMessage("Voice 'robot'");
65+
66+
$provider->speech('Please speak with an unsupported voice.', [
67+
'voice' => 'robot',
68+
'response_format' => 'mp3',
69+
]);
70+
}
71+
72+
public function testTranscribeReturnsTextSuccessfully()
73+
{
74+
echo "Test 3: Test transcribe method for successful completion\n";
75+
76+
$audioFile = $this->createTempAudioFile();
77+
78+
try {
79+
$transcriptionResponse = $this->createJsonResponse([
80+
'text' => 'This is the transcribed text.',
81+
'language' => 'en',
82+
'duration' => 1.42,
83+
'usage' => ['prompt_tokens' => 12, 'total_tokens' => 18],
84+
]);
85+
86+
$provider = $this->createProviderWithResponses($transcriptionResponse);
87+
88+
$response = $provider->transcribe($audioFile, [
89+
'model' => 'gpt-4o-transcribe',
90+
'response_format' => 'json',
91+
]);
92+
93+
$this->assertSame(200, $response->getStatusCode());
94+
$this->assertSame('This is the transcribed text.', $response->getContent());
95+
96+
$metadata = $response->getMetadata();
97+
$this->assertSame('gpt-4o-transcribe', $metadata['model']);
98+
$this->assertSame('json', $metadata['response_format']);
99+
$this->assertSame('en', $metadata['language']);
100+
$this->assertSame(1.42, $metadata['duration']);
101+
$this->assertSame(['prompt_tokens' => 12, 'total_tokens' => 18], $metadata['usage']);
102+
$this->assertArrayHasKey('created', $metadata);
103+
} finally {
104+
@unlink($audioFile);
105+
}
106+
}
107+
108+
public function testTranscribeThrowsInvalidResponseFormat()
109+
{
110+
echo "Test 4: Test transcribe method raises InvalidArgumentException on invalid response format\n";
111+
112+
$audioFile = $this->createTempAudioFile();
113+
114+
try {
115+
$provider = $this->createProviderWithResponses();
116+
117+
$this->expectException(InvalidArgumentException::class);
118+
$this->expectExceptionMessage("only 'json' response format is supported");
119+
120+
$provider->transcribe($audioFile, [
121+
'model' => 'gpt-4o-transcribe',
122+
'response_format' => 'unsupported_format',
123+
]);
124+
} finally {
125+
@unlink($audioFile);
126+
}
127+
}
128+
129+
public function testTranslateReturnsTextSuccessfully()
130+
{
131+
echo "Test 5: Test translate method for successful completion\n";
132+
133+
$audioFile = $this->createTempAudioFile();
134+
135+
try {
136+
$translationResponse = $this->createJsonResponse([
137+
'text' => 'This is the translated text.',
138+
'usage' => ['prompt_tokens' => 10, 'total_tokens' => 15],
139+
]);
140+
141+
$provider = $this->createProviderWithResponses($translationResponse);
142+
143+
$response = $provider->translate($audioFile, [
144+
'model' => 'whisper-1',
145+
'response_format' => 'json',
146+
]);
147+
148+
$this->assertSame(200, $response->getStatusCode());
149+
$this->assertSame('This is the translated text.', $response->getContent());
150+
151+
$metadata = $response->getMetadata();
152+
$this->assertSame('whisper-1', $metadata['model']);
153+
$this->assertSame('json', $metadata['response_format']);
154+
$this->assertSame(['prompt_tokens' => 10, 'total_tokens' => 15], $metadata['usage']);
155+
$this->assertArrayHasKey('created', $metadata);
156+
} finally {
157+
@unlink($audioFile);
158+
}
159+
}
160+
161+
public function testTranslateRaisesProviderExceptionOnServerError()
162+
{
163+
echo "Test 6: Test translate method raises ProviderException on server error\n";
164+
165+
$audioFile = $this->createTempAudioFile();
166+
167+
try {
168+
$serverErrorResponse = $this->createJsonResponse([
169+
'error' => [
170+
'message' => 'Internal server error',
171+
'type' => 'server_error',
172+
],
173+
], 500);
174+
175+
$provider = $this->createProviderWithResponses($serverErrorResponse);
176+
177+
$this->expectException(ProviderException::class);
178+
$this->expectExceptionMessage('Internal server error');
179+
180+
$provider->translate($audioFile, [
181+
'model' => 'whisper-1',
182+
'response_format' => 'json',
183+
]);
184+
} finally {
185+
@unlink($audioFile);
186+
}
187+
}
188+
189+
public function testTranslateRaisesUnserializableResponseException()
190+
{
191+
echo "Test 7: Test translate method raises UnserializableResponseException on invalid JSON\n";
192+
193+
$audioFile = $this->createTempAudioFile();
194+
195+
try {
196+
$invalidResponse = new HttpResponse('php://memory', 200, ['Content-Type' => 'application/json']);
197+
$invalidResponse->getBody()->write('{ not valid json');
198+
199+
$provider = $this->createProviderWithResponses($invalidResponse);
200+
201+
$this->expectException(UnserializableResponseException::class);
202+
$this->expectExceptionMessage('Syntax error');
203+
204+
$provider->translate($audioFile, [
205+
'model' => 'whisper-1',
206+
'response_format' => 'json',
207+
]);
208+
} finally {
209+
@unlink($audioFile);
210+
}
211+
}
212+
213+
private function createProviderWithResponses(HttpResponse ...$responses): OpenAIProvider
214+
{
215+
$httpFactoryMock = $this->createMock(HttpFactory::class);
216+
$httpClientMock = $this->createMock(Http::class);
217+
218+
$httpFactoryMock->method('getHttp')->willReturn($httpClientMock);
219+
220+
if (!empty($responses)) {
221+
$httpClientMock->method('post')->willReturnOnConsecutiveCalls(...$responses);
222+
}
223+
224+
return new OpenAIProvider(['api_key' => 'test-api-key'], $httpFactoryMock);
225+
}
226+
227+
private function createTempAudioFile(): string
228+
{
229+
$audioFile = uniqid('audio-test-', true) . '.mp3';
230+
file_put_contents($audioFile, 'fake audio data');
231+
232+
return $audioFile;
233+
}
234+
235+
private function createJsonResponse(array $payload, int $status = 200): HttpResponse
236+
{
237+
$response = new HttpResponse('php://memory', $status, ['Content-Type' => 'application/json']);
238+
$response->getBody()->write(json_encode($payload));
239+
240+
return $response;
241+
}
242+
}

0 commit comments

Comments
 (0)