openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
joseharriaga/ReorganizeExamples

Branches

Tags

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

Clone

HTTPS

Download ZIP

tests/Files/FilesMockTests.cs

429lines · modecode

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