Skip to content

Commit 82e6c8f

Browse files
committed
test: adds unit tests
1 parent 62b8776 commit 82e6c8f

19 files changed

+4178
-14
lines changed

src/Files/DTO/File.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ private function detectAndProcessFile(string $file, ?string $providedMimeType):
8484
return;
8585
}
8686

87+
// Check if it's a local file path (before base64 check)
88+
if (file_exists($file) && is_file($file)) {
89+
$this->fileType = FileTypeEnum::inline();
90+
$this->base64Data = $this->convertFileToBase64($file);
91+
$this->mimeType = $this->determineMimeType($providedMimeType, null, $file);
92+
return;
93+
}
94+
8795
// Check if it's plain base64
8896
if (preg_match('/^[A-Za-z0-9+\/]*={0,2}$/', $file)) {
8997
if ($providedMimeType === null) {
@@ -97,14 +105,6 @@ private function detectAndProcessFile(string $file, ?string $providedMimeType):
97105
return;
98106
}
99107

100-
// If none of the above, assume it's a local file path
101-
if (file_exists($file)) {
102-
$this->fileType = FileTypeEnum::inline();
103-
$this->base64Data = $this->convertFileToBase64($file);
104-
$this->mimeType = $this->determineMimeType($providedMimeType, null, $file);
105-
return;
106-
}
107-
108108
throw new \InvalidArgumentException(
109109
'Invalid file provided. Expected URL, base64 data, or valid local file path.'
110110
);

src/Results/DTO/GenerativeAiResult.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,10 @@ public function toFiles(): array
300300
*/
301301
public function toImageFiles(): array
302302
{
303-
return array_filter(
303+
return array_values(array_filter(
304304
$this->toFiles(),
305305
fn(File $file) => $file->isImage()
306-
);
306+
));
307307
}
308308

309309
/**
@@ -315,10 +315,10 @@ public function toImageFiles(): array
315315
*/
316316
public function toAudioFiles(): array
317317
{
318-
return array_filter(
318+
return array_values(array_filter(
319319
$this->toFiles(),
320320
fn(File $file) => $file->isAudio()
321-
);
321+
));
322322
}
323323

324324
/**
@@ -330,10 +330,10 @@ public function toAudioFiles(): array
330330
*/
331331
public function toVideoFiles(): array
332332
{
333-
return array_filter(
333+
return array_values(array_filter(
334334
$this->toFiles(),
335335
fn(File $file) => $file->isVideo()
336-
);
336+
));
337337
}
338338

339339
/**

tests/unit/Files/DTO/FileTest.php

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WordPress\AiClient\Tests\unit\Files\DTO;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use WordPress\AiClient\Files\DTO\File;
9+
use WordPress\AiClient\Files\Enums\FileTypeEnum;
10+
11+
/**
12+
* @covers \WordPress\AiClient\Files\DTO\File
13+
*/
14+
class FileTest extends TestCase
15+
{
16+
/**
17+
* Tests creating a File from a URL.
18+
*
19+
* @return void
20+
*/
21+
public function testCreateFromUrl(): void
22+
{
23+
$url = 'https://example.com/image.jpg';
24+
$mimeType = 'image/jpeg';
25+
26+
$file = new File($url, $mimeType);
27+
28+
$this->assertEquals(FileTypeEnum::remote(), $file->getFileType());
29+
$this->assertEquals($url, $file->getUrl());
30+
$this->assertNull($file->getBase64Data());
31+
$this->assertNull($file->getDataUri());
32+
$this->assertEquals($mimeType, $file->getMimeType());
33+
$this->assertTrue($file->isImage());
34+
}
35+
36+
/**
37+
* Tests creating a File from a URL with inferred MIME type.
38+
*
39+
* @return void
40+
*/
41+
public function testCreateFromUrlWithInferredMimeType(): void
42+
{
43+
$url = 'https://example.com/document.pdf';
44+
45+
$file = new File($url);
46+
47+
$this->assertEquals(FileTypeEnum::remote(), $file->getFileType());
48+
$this->assertEquals($url, $file->getUrl());
49+
$this->assertEquals('application/pdf', $file->getMimeType());
50+
$this->assertFalse($file->isText());
51+
}
52+
53+
/**
54+
* Tests creating a File from a data URI.
55+
*
56+
* @return void
57+
*/
58+
public function testCreateFromDataUri(): void
59+
{
60+
$base64Data = 'SGVsbG8gV29ybGQ=';
61+
$dataUri = 'data:text/plain;base64,' . $base64Data;
62+
63+
$file = new File($dataUri);
64+
65+
$this->assertEquals(FileTypeEnum::inline(), $file->getFileType());
66+
$this->assertNull($file->getUrl());
67+
$this->assertEquals($base64Data, $file->getBase64Data());
68+
$this->assertEquals($dataUri, $file->getDataUri());
69+
$this->assertEquals('text/plain', $file->getMimeType());
70+
$this->assertTrue($file->isText());
71+
}
72+
73+
/**
74+
* Tests creating a File from a data URI with provided MIME type override.
75+
*
76+
* @return void
77+
*/
78+
public function testCreateFromDataUriWithMimeTypeOverride(): void
79+
{
80+
$base64Data = 'SGVsbG8gV29ybGQ=';
81+
$dataUri = 'data:text/plain;base64,' . $base64Data;
82+
$overrideMimeType = 'text/html';
83+
84+
$file = new File($dataUri, $overrideMimeType);
85+
86+
$this->assertEquals(FileTypeEnum::inline(), $file->getFileType());
87+
$this->assertEquals($base64Data, $file->getBase64Data());
88+
$this->assertEquals($overrideMimeType, $file->getMimeType());
89+
$this->assertEquals('data:text/html;base64,' . $base64Data, $file->getDataUri());
90+
}
91+
92+
/**
93+
* Tests creating a File from plain base64 data.
94+
*
95+
* @return void
96+
*/
97+
public function testCreateFromPlainBase64(): void
98+
{
99+
$base64Data = 'SGVsbG8gV29ybGQ=';
100+
$mimeType = 'text/plain';
101+
102+
$file = new File($base64Data, $mimeType);
103+
104+
$this->assertEquals(FileTypeEnum::inline(), $file->getFileType());
105+
$this->assertNull($file->getUrl());
106+
$this->assertEquals($base64Data, $file->getBase64Data());
107+
$this->assertEquals('data:text/plain;base64,' . $base64Data, $file->getDataUri());
108+
$this->assertEquals($mimeType, $file->getMimeType());
109+
}
110+
111+
/**
112+
* Tests that plain base64 without MIME type throws exception.
113+
*
114+
* @return void
115+
*/
116+
public function testPlainBase64WithoutMimeTypeThrowsException(): void
117+
{
118+
$this->expectException(\InvalidArgumentException::class);
119+
$this->expectExceptionMessage('MIME type is required when providing plain base64 data without data URI format.');
120+
121+
new File('SGVsbG8gV29ybGQ=');
122+
}
123+
124+
/**
125+
* Tests creating a File from a local file path.
126+
*
127+
* @return void
128+
*/
129+
public function testCreateFromLocalFile(): void
130+
{
131+
// Create a temporary file
132+
$tempFile = tempnam(sys_get_temp_dir(), 'test');
133+
file_put_contents($tempFile, 'Hello World');
134+
135+
try {
136+
$file = new File($tempFile, 'text/plain');
137+
138+
$this->assertEquals(FileTypeEnum::inline(), $file->getFileType());
139+
$this->assertNull($file->getUrl());
140+
$this->assertEquals(base64_encode('Hello World'), $file->getBase64Data());
141+
$this->assertEquals('text/plain', $file->getMimeType());
142+
} finally {
143+
unlink($tempFile);
144+
}
145+
}
146+
147+
/**
148+
* Tests that invalid file format throws exception.
149+
*
150+
* @return void
151+
*/
152+
public function testInvalidFileFormatThrowsException(): void
153+
{
154+
$this->expectException(\InvalidArgumentException::class);
155+
$this->expectExceptionMessage('Invalid file provided. Expected URL, base64 data, or valid local file path.');
156+
157+
new File('not-a-valid-file-or-url', 'text/plain');
158+
}
159+
160+
/**
161+
* Tests that non-existent local file throws exception.
162+
*
163+
* @return void
164+
*/
165+
public function testNonExistentLocalFileThrowsException(): void
166+
{
167+
$this->expectException(\InvalidArgumentException::class);
168+
$this->expectExceptionMessage('Invalid file provided. Expected URL, base64 data, or valid local file path.');
169+
170+
new File('/path/to/non/existent/file.txt', 'text/plain');
171+
}
172+
173+
/**
174+
* Tests that passing a directory throws exception.
175+
*
176+
* @return void
177+
*/
178+
public function testDirectoryThrowsException(): void
179+
{
180+
// Create a directory instead of a file
181+
$tempDir = sys_get_temp_dir() . '/test_dir_' . uniqid();
182+
mkdir($tempDir);
183+
184+
try {
185+
$this->expectException(\InvalidArgumentException::class);
186+
$this->expectExceptionMessage('Invalid file provided. Expected URL, base64 data, or valid local file path.');
187+
188+
new File($tempDir, 'text/plain');
189+
} finally {
190+
rmdir($tempDir);
191+
}
192+
}
193+
194+
/**
195+
* Tests MIME type methods.
196+
*
197+
* @return void
198+
*/
199+
public function testMimeTypeMethods(): void
200+
{
201+
$file = new File('https://example.com/video.mp4');
202+
203+
$this->assertEquals('video/mp4', $file->getMimeType());
204+
$this->assertInstanceOf(\WordPress\AiClient\Files\ValueObjects\MimeType::class, $file->getMimeTypeObject());
205+
$this->assertTrue($file->isVideo());
206+
$this->assertFalse($file->isImage());
207+
$this->assertFalse($file->isAudio());
208+
$this->assertFalse($file->isText());
209+
}
210+
211+
/**
212+
* Tests JSON schema.
213+
*
214+
* @return void
215+
*/
216+
public function testJsonSchema(): void
217+
{
218+
$schema = File::getJsonSchema();
219+
220+
$this->assertIsArray($schema);
221+
$this->assertEquals('object', $schema['type']);
222+
$this->assertArrayHasKey('oneOf', $schema);
223+
$this->assertCount(2, $schema['oneOf']);
224+
225+
// Check remote file schema
226+
$remoteSchema = $schema['oneOf'][0];
227+
$this->assertArrayHasKey('properties', $remoteSchema);
228+
$this->assertArrayHasKey('fileType', $remoteSchema['properties']);
229+
$this->assertArrayHasKey('mimeType', $remoteSchema['properties']);
230+
$this->assertArrayHasKey('url', $remoteSchema['properties']);
231+
$this->assertEquals(['fileType', 'mimeType', 'url'], $remoteSchema['required']);
232+
233+
// Check inline file schema
234+
$inlineSchema = $schema['oneOf'][1];
235+
$this->assertArrayHasKey('properties', $inlineSchema);
236+
$this->assertArrayHasKey('fileType', $inlineSchema['properties']);
237+
$this->assertArrayHasKey('mimeType', $inlineSchema['properties']);
238+
$this->assertArrayHasKey('base64Data', $inlineSchema['properties']);
239+
$this->assertEquals(['fileType', 'mimeType', 'base64Data'], $inlineSchema['required']);
240+
}
241+
242+
/**
243+
* Tests data URI without MIME type defaults correctly.
244+
*
245+
* @return void
246+
*/
247+
public function testDataUriWithoutMimeType(): void
248+
{
249+
$base64Data = 'SGVsbG8gV29ybGQ=';
250+
$dataUri = 'data:;base64,' . $base64Data;
251+
252+
$this->expectException(\InvalidArgumentException::class);
253+
$this->expectExceptionMessage('Unable to determine MIME type. Please provide it explicitly.');
254+
255+
new File($dataUri);
256+
}
257+
258+
/**
259+
* Tests URL with unknown extension.
260+
*
261+
* @return void
262+
*/
263+
public function testUrlWithUnknownExtension(): void
264+
{
265+
$this->expectException(\InvalidArgumentException::class);
266+
$this->expectExceptionMessage('Unable to determine MIME type. Please provide it explicitly.');
267+
268+
new File('https://example.com/file.unknown');
269+
}
270+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WordPress\AiClient\Tests\unit\Files\Enums;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use WordPress\AiClient\Files\Enums\FileTypeEnum;
9+
use WordPress\AiClient\Tests\unit\EnumTestTrait;
10+
11+
/**
12+
* @covers \WordPress\AiClient\Files\Enums\FileTypeEnum
13+
*/
14+
class FileTypeEnumTest extends TestCase
15+
{
16+
use EnumTestTrait;
17+
18+
/**
19+
* Gets the enum class to test.
20+
*
21+
* @return string
22+
*/
23+
protected function getEnumClass(): string
24+
{
25+
return FileTypeEnum::class;
26+
}
27+
28+
/**
29+
* Gets the expected enum values.
30+
*
31+
* @return array
32+
*/
33+
protected function getExpectedValues(): array
34+
{
35+
return [
36+
'INLINE' => 'inline',
37+
'REMOTE' => 'remote',
38+
];
39+
}
40+
41+
/**
42+
* Tests the specific enum methods.
43+
*
44+
* @return void
45+
*/
46+
public function testSpecificEnumMethods(): void
47+
{
48+
$inline = FileTypeEnum::inline();
49+
$this->assertTrue($inline->isInline());
50+
$this->assertFalse($inline->isRemote());
51+
52+
$remote = FileTypeEnum::remote();
53+
$this->assertTrue($remote->isRemote());
54+
$this->assertFalse($remote->isInline());
55+
}
56+
}

0 commit comments

Comments
 (0)