openai/openai-dotnet

Public

mirrored from https://github.com/openai/openai-dotnetAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.3.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

tests/Files/FilesMockTests.cs

501lines · modecode

1using NUnit.Framework;
2using OpenAI.Files;
3using OpenAI.Tests.Utility;
4using System;
5using System.ClientModel;
6using System.IO;
7using System.Linq;
8using System.Threading;
9using System.Threading.Tasks;
10
11namespace OpenAI.Tests.Files;
12
13[TestFixture(true)]
14[TestFixture(false)]
15[Parallelizable(ParallelScope.All)]
16[Category("Files")]
17[Category("Smoke")]
18public class FilesMockTests : SyncAsyncTestBase
19{
20 private static readonly ApiKeyCredential s_fakeCredential = new ApiKeyCredential("key");
21
22 public FilesMockTests(bool isAsync)
23 : base(isAsync)
24 {
25 }
26
27 public enum FileSourceKind
28 {
29 UsingStream,
30 UsingFilePath,
31 UsingBinaryData
32 }
33
34 private static Array s_fileSourceKindSource = Enum.GetValues(typeof(FileSourceKind));
35
36 private static object[] s_purposeSource =
37 {
38 ("assistants", FilePurpose.Assistants),
39 ("assistants_output", FilePurpose.AssistantsOutput),
40 ("batch", FilePurpose.Batch),
41 ("batch_output", FilePurpose.BatchOutput),
42 ("fine-tune", FilePurpose.FineTune),
43 ("fine-tune-results", FilePurpose.FineTuneResults),
44 ("vision", FilePurpose.Vision)
45 };
46
47#pragma warning disable CS0618
48 private static object[] s_statusSource =
49 {
50 ("uploaded", FileStatus.Uploaded),
51 ("processed", FileStatus.Processed),
52 ("error", FileStatus.Error)
53 };
54#pragma warning restore CS0618
55
56 [Test]
57 public async Task GetFileDeserializesId()
58 {
59 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """
60 {
61 "id": "returned_file_id"
62 }
63 """);
64 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential, clientOptions);
65
66 OpenAIFile fileInfo = IsAsync
67 ? await client.GetFileAsync("file_id")
68 : client.GetFile("file_id");
69
70 Assert.That(fileInfo.Id, Is.EqualTo("returned_file_id"));
71 }
72
73 [Test]
74 public async Task GetFileDeserializesCreatedAt()
75 {
76 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """
77 {
78 "created_at": 1704096000
79 }
80 """);
81 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential, clientOptions);
82
83 OpenAIFile fileInfo = IsAsync
84 ? await client.GetFileAsync("file_id")
85 : client.GetFile("file_id");
86
87 Assert.That(fileInfo.CreatedAt.ToUnixTimeSeconds(), Is.EqualTo(1704096000));
88 }
89
90 [Test]
91 [TestCaseSource(nameof(s_purposeSource))]
92 public async Task GetFileDeserializesPurpose((string stringValue, FilePurpose expectedValue) purpose)
93 {
94 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, $$"""
95 {
96 "purpose": "{{purpose.stringValue}}"
97 }
98 """);
99 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential, clientOptions);
100
101 OpenAIFile fileInfo = IsAsync
102 ? await client.GetFileAsync("file_id")
103 : client.GetFile("file_id");
104
105 Assert.That(fileInfo.Purpose, Is.EqualTo(purpose.expectedValue));
106 }
107
108
109#pragma warning disable CS0618
110 [Test]
111 [TestCaseSource(nameof(s_statusSource))]
112 public async Task GetFileDeserializesStatus((string stringValue, FileStatus expectedValue) status)
113 {
114 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, $$"""
115 {
116 "status": "{{status.stringValue}}"
117 }
118 """);
119 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential, clientOptions);
120
121 OpenAIFile fileInfo = IsAsync
122 ? await client.GetFileAsync("file_id")
123 : client.GetFile("file_id");
124
125 Assert.That(fileInfo.Status, Is.EqualTo(status.expectedValue));
126 }
127#pragma warning restore CS0618
128
129#pragma warning disable CS0618
130 [Test]
131 public async Task GetFileDeserializesStatusDetails()
132 {
133 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """
134 {
135 "status_details": "This is definitely an error."
136 }
137 """);
138 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential, clientOptions);
139
140 OpenAIFile fileInfo = IsAsync
141 ? await client.GetFileAsync("file_id")
142 : client.GetFile("file_id");
143
144 Assert.That(fileInfo.StatusDetails, Is.EqualTo("This is definitely an error."));
145 }
146#pragma warning restore CS0618
147
148 [Test]
149 public void GetFileRespectsTheCancellationToken()
150 {
151 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential);
152 using CancellationTokenSource cancellationSource = new();
153 cancellationSource.Cancel();
154
155 if (IsAsync)
156 {
157 Assert.That(async () => await client.GetFileAsync("fileId", cancellationSource.Token),
158 Throws.InstanceOf<OperationCanceledException>());
159 }
160 else
161 {
162 Assert.That(() => client.GetFile("fileId", cancellationSource.Token),
163 Throws.InstanceOf<OperationCanceledException>());
164 }
165 }
166
167 [Test]
168 [TestCaseSource(nameof(s_fileSourceKindSource))]
169 public async Task UploadFileDeserializesId(FileSourceKind fileSourceKind)
170 {
171 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """
172 {
173 "id": "returned_file_id"
174 }
175 """);
176 OpenAIFile fileInfo = await InvokeUploadFileSyncOrAsync(clientOptions, fileSourceKind);
177
178 Assert.That(fileInfo.Id, Is.EqualTo("returned_file_id"));
179 }
180
181 [Test]
182 [TestCaseSource(nameof(s_fileSourceKindSource))]
183 public async Task UploadFileDeserializesCreatedAt(FileSourceKind fileSourceKind)
184 {
185 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """
186 {
187 "created_at": 1704096000
188 }
189 """);
190 OpenAIFile fileInfo = await InvokeUploadFileSyncOrAsync(clientOptions, fileSourceKind);
191
192 Assert.That(fileInfo.CreatedAt.ToUnixTimeSeconds(), Is.EqualTo(1704096000));
193 }
194
195 [Test]
196 public async Task UploadFileDeserializesPurpose(
197 [ValueSource(nameof(s_fileSourceKindSource))] FileSourceKind fileSourceKind,
198 [ValueSource(nameof(s_purposeSource))] (string stringValue, FilePurpose expectedValue) purpose)
199 {
200 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, $$"""
201 {
202 "purpose": "{{purpose.stringValue}}"
203 }
204 """);
205 OpenAIFile fileInfo = await InvokeUploadFileSyncOrAsync(clientOptions, fileSourceKind);
206
207 Assert.That(fileInfo.Purpose, Is.EqualTo(purpose.expectedValue));
208 }
209
210#pragma warning disable CS0618
211 [Test]
212 public async Task UploadFileDeserializesStatus(
213 [ValueSource(nameof(s_fileSourceKindSource))] FileSourceKind fileSourceKind,
214 [ValueSource(nameof(s_statusSource))] (string stringValue, FileStatus expectedValue) status)
215 {
216 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, $$"""
217 {
218 "status": "{{status.stringValue}}"
219 }
220 """);
221 OpenAIFile fileInfo = await InvokeUploadFileSyncOrAsync(clientOptions, fileSourceKind);
222
223 Assert.That(fileInfo.Status, Is.EqualTo(status.expectedValue));
224 }
225#pragma warning restore CS0618
226
227#pragma warning disable CS0618
228 [Test]
229 [TestCaseSource(nameof(s_fileSourceKindSource))]
230 public async Task UploadFileDeserializesStatusDetails(FileSourceKind fileSourceKind)
231 {
232 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """
233 {
234 "status_details": "This is definitely an error."
235 }
236 """);
237 OpenAIFile fileInfo = await InvokeUploadFileSyncOrAsync(clientOptions, fileSourceKind);
238
239 Assert.That(fileInfo.StatusDetails, Is.EqualTo("This is definitely an error."));
240 }
241#pragma warning restore CS0618
242
243 [Test]
244 public async Task UploadFileDeserializesBigSizes()
245 {
246 long bigSize = (long)int.MaxValue + (long)int.MaxValue / 2;
247
248 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, $$"""
249 {
250 "bytes": {{bigSize}}
251 }
252 """);
253 OpenAIFile fileInfo = await InvokeUploadFileSyncOrAsync(clientOptions, FileSourceKind.UsingFilePath);
254
255 Assert.That(fileInfo.SizeInBytesLong, Is.EqualTo(bigSize));
256 Assert.Throws<OverflowException>(() => _ = fileInfo.SizeInBytes);
257 }
258
259 [Test]
260 public void UploadFileRespectsTheCancellationToken()
261 {
262 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential);
263 using var stream = new MemoryStream(Array.Empty<byte>());
264 using CancellationTokenSource cancellationSource = new();
265 cancellationSource.Cancel();
266
267 if (IsAsync)
268 {
269 Assert.That(async () => await client.UploadFileAsync(stream, "filename.txt", FileUploadPurpose.Assistants, cancellationSource.Token),
270 Throws.InstanceOf<OperationCanceledException>());
271 }
272 else
273 {
274 Assert.That(() => client.UploadFile(stream, "filename.txt", FileUploadPurpose.Assistants, cancellationSource.Token),
275 Throws.InstanceOf<OperationCanceledException>());
276 }
277 }
278
279 [Test]
280 public async Task GetFilesDeserializesId()
281 {
282 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """
283 {
284 "object": "list",
285 "data": [
286 {
287 "id": "returned_file_id"
288 }
289 ]
290 }
291 """);
292 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential, clientOptions);
293
294 OpenAIFileCollection fileInfoCollection = IsAsync
295 ? await client.GetFilesAsync(FilePurpose.Assistants)
296 : client.GetFiles(FilePurpose.Assistants);
297 OpenAIFile fileInfo = fileInfoCollection.Single();
298
299 Assert.That(fileInfo.Id, Is.EqualTo("returned_file_id"));
300 }
301
302 [Test]
303 public async Task GetFilesDeserializesCreatedAt()
304 {
305 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """
306 {
307 "object": "list",
308 "data": [
309 {
310 "created_at": 1704096000
311 }
312 ]
313 }
314 """);
315 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential, clientOptions);
316
317 OpenAIFileCollection fileInfoCollection = IsAsync
318 ? await client.GetFilesAsync(FilePurpose.Assistants)
319 : client.GetFiles(FilePurpose.Assistants);
320 OpenAIFile fileInfo = fileInfoCollection.Single();
321
322 Assert.That(fileInfo.CreatedAt.ToUnixTimeSeconds(), Is.EqualTo(1704096000));
323 }
324
325 [Test]
326 [TestCaseSource(nameof(s_purposeSource))]
327 public async Task GetFilesDeserializesPurpose((string stringValue, FilePurpose expectedValue) purpose)
328 {
329 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, $$"""
330 {
331 "object": "list",
332 "data": [
333 {
334 "purpose": "{{purpose.stringValue}}"
335 }
336 ]
337 }
338 """);
339 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential, clientOptions);
340
341 OpenAIFileCollection fileInfoCollection = IsAsync
342 ? await client.GetFilesAsync(FilePurpose.Assistants)
343 : client.GetFiles(FilePurpose.Assistants);
344 OpenAIFile fileInfo = fileInfoCollection.Single();
345
346 Assert.That(fileInfo.Purpose, Is.EqualTo(purpose.expectedValue));
347 }
348
349#pragma warning disable CS0618
350 [Test]
351 [TestCaseSource(nameof(s_statusSource))]
352 public async Task GetFilesDeserializesStatus((string stringValue, FileStatus expectedValue) status)
353 {
354 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, $$"""
355 {
356 "object": "list",
357 "data": [
358 {
359 "status": "{{status.stringValue}}"
360 }
361 ]
362 }
363 """);
364 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential, clientOptions);
365
366 OpenAIFileCollection fileInfoCollection = IsAsync
367 ? await client.GetFilesAsync(FilePurpose.Assistants)
368 : client.GetFiles(FilePurpose.Assistants);
369 OpenAIFile fileInfo = fileInfoCollection.Single();
370
371 Assert.That(fileInfo.Status, Is.EqualTo(status.expectedValue));
372 }
373#pragma warning restore CS0618
374
375#pragma warning disable CS0618
376 [Test]
377 public async Task GetFilesDeserializesStatusDetails()
378 {
379 OpenAIClientOptions clientOptions = GetClientOptionsWithMockResponse(200, """
380 {
381 "object": "list",
382 "data": [
383 {
384 "status_details": "This is definitely an error."
385 }
386 ]
387 }
388 """);
389 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential, clientOptions);
390
391 OpenAIFileCollection fileInfoCollection = IsAsync
392 ? await client.GetFilesAsync(FilePurpose.Assistants)
393 : client.GetFiles(FilePurpose.Assistants);
394 OpenAIFile fileInfo = fileInfoCollection.Single();
395
396 Assert.That(fileInfo.StatusDetails, Is.EqualTo("This is definitely an error."));
397 }
398#pragma warning restore CS0618
399
400 [Test]
401 public void GetFilesRespectsTheCancellationToken()
402 {
403 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential);
404 using CancellationTokenSource cancellationSource = new();
405 cancellationSource.Cancel();
406
407 if (IsAsync)
408 {
409 Assert.That(async () => await client.GetFilesAsync(FilePurpose.Assistants, cancellationSource.Token),
410 Throws.InstanceOf<OperationCanceledException>());
411 }
412 else
413 {
414 Assert.That(() => client.GetFiles(FilePurpose.Assistants, cancellationSource.Token),
415 Throws.InstanceOf<OperationCanceledException>());
416 }
417 }
418
419 [Test]
420 public void DownloadFileRespectsTheCancellationToken()
421 {
422 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential);
423 using CancellationTokenSource cancellationSource = new();
424 cancellationSource.Cancel();
425
426 if (IsAsync)
427 {
428 Assert.That(async () => await client.DownloadFileAsync("fileId", cancellationSource.Token),
429 Throws.InstanceOf<OperationCanceledException>());
430 }
431 else
432 {
433 Assert.That(() => client.DownloadFile("fileId", cancellationSource.Token),
434 Throws.InstanceOf<OperationCanceledException>());
435 }
436 }
437
438 [Test]
439 public void DeleteFileRespectsTheCancellationToken()
440 {
441 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential);
442 using CancellationTokenSource cancellationSource = new();
443 cancellationSource.Cancel();
444
445 if (IsAsync)
446 {
447 Assert.That(async () => await client.DeleteFileAsync("fileId", cancellationSource.Token),
448 Throws.InstanceOf<OperationCanceledException>());
449 }
450 else
451 {
452 Assert.That(() => client.DeleteFile("fileId", cancellationSource.Token),
453 Throws.InstanceOf<OperationCanceledException>());
454 }
455 }
456
457 private OpenAIClientOptions GetClientOptionsWithMockResponse(int status, string content)
458 {
459 MockPipelineResponse response = new MockPipelineResponse(status);
460 response.SetContent(content);
461
462 return new OpenAIClientOptions()
463 {
464 Transport = new MockPipelineTransport(response)
465 };
466 }
467
468 private async ValueTask<OpenAIFile> InvokeUploadFileSyncOrAsync(OpenAIClientOptions clientOptions, FileSourceKind fileSourceKind)
469 {
470 OpenAIFileClient client = new OpenAIFileClient(s_fakeCredential, clientOptions);
471 string filename = "images_dog_and_cat.png";
472 string path = Path.Combine("Assets", filename);
473
474 if (fileSourceKind == FileSourceKind.UsingStream)
475 {
476 using FileStream file = File.OpenRead(path);
477
478 return IsAsync
479 ? await client.UploadFileAsync(file, filename, purpose: FileUploadPurpose.Assistants)
480 : client.UploadFile(file, filename, purpose: FileUploadPurpose.Assistants);
481 }
482 else if (fileSourceKind == FileSourceKind.UsingFilePath)
483 {
484 return IsAsync
485 ? await client.UploadFileAsync(path, purpose: FileUploadPurpose.Assistants)
486 : client.UploadFile(path, purpose: FileUploadPurpose.Assistants);
487 }
488 else if (fileSourceKind == FileSourceKind.UsingBinaryData)
489 {
490 using FileStream file = File.OpenRead(path);
491 BinaryData content = BinaryData.FromStream(file);
492
493 return IsAsync
494 ? await client.UploadFileAsync(content, filename, purpose: FileUploadPurpose.Assistants)
495 : client.UploadFile(content, filename, purpose: FileUploadPurpose.Assistants);
496 }
497
498 Assert.Fail("Invalid source kind.");
499 return null;
500 }
501}
502