Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 121 additions & 22 deletions Google.GenAI.E2E.Tests/Files/FilesDownloadTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

Expand All @@ -32,6 +33,7 @@ public class FilesDownloadTest
private static TestServerProcess? _server;
private Client vertexClient;
private Client geminiClient;
private string fileUri;
public TestContext TestContext { get; set; }

[ClassInitialize]
Expand Down Expand Up @@ -76,52 +78,149 @@ public void TestInit()
geminiClient =
new Client(apiKey: apiKey, vertexAI: false, httpOptions: geminiClientHttpOptions);

// Specific setup for this test class
// Note that replay mode does not return any bytes when downloading a file.
fileUri = "https://generativelanguage.googleapis.com/v1beta/files/p1crkz5nfru4:download?alt=media";

}

[TestMethod]
public async Task DownloadFileNameVertexTest()
{
var ex = await Assert.ThrowsExceptionAsync<NotSupportedException>(async () =>
{
await vertexClient.Files.DownloadAsync(fileName: "fileName");
});
var ex = await Assert.ThrowsExceptionAsync<NotSupportedException>(async () =>
{
await vertexClient.Files.DownloadAsync(fileName: "fileName");
});

StringAssert.Contains(ex.Message, "This method is only supported in the Gemini Developer API client");
StringAssert.Contains(ex.Message, "This method is only supported in the Gemini Developer API client");
}

[TestMethod]
public async Task DownloadFileNameGeminiTest()
{
var stream = await geminiClient.Files.DownloadAsync(
fileName: fileUri
);
using (MemoryStream memoryStream = new MemoryStream()) {
await stream.CopyToAsync(memoryStream);
memoryStream.Position = 0;
byte[] bytes = memoryStream.ToArray();
// Replay mode does not return any bytes when downloading a file.
if (!TestServer.IsReplayMode) {
Assert.IsTrue(bytes.Length > 0);
}
}
}

[TestMethod]
public async Task DownloadToFileFileNameVertexTest()
{
var ex = await Assert.ThrowsExceptionAsync<NotSupportedException>(async () =>
{
await vertexClient.Files.DownloadToFileAsync(fileName: "fileName", outputPath: "outputPath");
});
var ex = await Assert.ThrowsExceptionAsync<NotSupportedException>(async () =>
{
await vertexClient.Files.DownloadToFileAsync(fileName: "fileName", outputPath: "outputPath");
});

StringAssert.Contains(ex.Message, "This method is only supported in the Gemini Developer API client");
}

StringAssert.Contains(ex.Message, "This method is only supported in the Gemini Developer API client");
[TestMethod]
public async Task DownloadToFileFileNameGeminiTest()
{
await geminiClient.Files.DownloadToFileAsync(
fileName: fileUri,
outputPath: "output.mp4"
);
}

[TestMethod]
public async Task DownloadFileVertexTest()
{
var file = new Google.GenAI.Types.File { Name = "Name"};
var ex = await Assert.ThrowsExceptionAsync<NotSupportedException>(async () =>
{
await vertexClient.Files.DownloadAsync(file: file);
});
var file = new Google.GenAI.Types.File { Name = "Name"};
var ex = await Assert.ThrowsExceptionAsync<NotSupportedException>(async () =>
{
await vertexClient.Files.DownloadAsync(file: file);
});

StringAssert.Contains(ex.Message, "This method is only supported in the Gemini Developer API client");
}

StringAssert.Contains(ex.Message, "This method is only supported in the Gemini Developer API client");
[TestMethod]
public async Task DownloadFileGeminiTest()
{
var file = new Google.GenAI.Types.File {
Name = fileUri
};
await geminiClient.Files.DownloadAsync(file: file);
}

[TestMethod]
public async Task DownloadToFileFileVertexTest()
{
var file = new Google.GenAI.Types.File { Name = "Name"};
var ex = await Assert.ThrowsExceptionAsync<NotSupportedException>(async () =>
{
await vertexClient.Files.DownloadToFileAsync(file: file, outputPath: "outputPath");
});
var file = new Google.GenAI.Types.File { Name = "Name"};
var ex = await Assert.ThrowsExceptionAsync<NotSupportedException>(async () =>
{
await vertexClient.Files.DownloadToFileAsync(file: file, outputPath: "outputPath");
});

StringAssert.Contains(ex.Message, "This method is only supported in the Gemini Developer API client");
StringAssert.Contains(ex.Message, "This method is only supported in the Gemini Developer API client");
}

[TestMethod]
public async Task DownloadToFileFileGeminiTest()
{
var file = new Google.GenAI.Types.File {
Name = fileUri
};
await geminiClient.Files.DownloadToFileAsync(file: file, outputPath: "output.mp4");
}

[TestMethod]
public async Task DownloadToFileVideoVertexTest()
{
var video = new Google.GenAI.Types.Video {
Uri = fileUri
};
var ex = await Assert.ThrowsExceptionAsync<NotSupportedException>(async () =>
{
await vertexClient.Files.DownloadToFileAsync(video: video, outputPath: "outputPath");
});

StringAssert.Contains(ex.Message, "This method is only supported in the Gemini Developer API client");
}

[TestMethod]
public async Task DownloadToFileVideoGeminiTest()
{
var video = new Google.GenAI.Types.Video {
Uri = fileUri
};
await geminiClient.Files.DownloadToFileAsync(video: video, outputPath: "output.mp4");
}


[TestMethod]
public async Task DownloadToFileGeneratedVideoVertexTest()
{
var video = new Google.GenAI.Types.Video {
Uri = fileUri
};
var generatedVideo = new Google.GenAI.Types.GeneratedVideo { Video = video };
var ex = await Assert.ThrowsExceptionAsync<NotSupportedException>(async () =>
{
await vertexClient.Files.DownloadToFileAsync(generatedVideo: generatedVideo, outputPath: "outputPath");
});

StringAssert.Contains(ex.Message, "This method is only supported in the Gemini Developer API client");
}

[TestMethod]
public async Task DownloadToFileGeneratedVideoGeminiTest()
{
var video = new Google.GenAI.Types.Video {
Uri = fileUri
};
var generatedVideo = new Google.GenAI.Types.GeneratedVideo { Video = video };
await geminiClient.Files.DownloadToFileAsync(generatedVideo: generatedVideo, outputPath: "output.mp4");
}

}
8 changes: 8 additions & 0 deletions Google.GenAI.E2E.Tests/GenerateVideos/GenerateVideosTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,14 @@ public async Task GenerateVideosSourceGeneratedVideoExtensionGeminiTest() {
Assert.IsTrue(operation1.Response.GeneratedVideos.Count > 0);
Assert.IsNotNull(operation1.Response.GeneratedVideos.First().Video.Uri);

// Download generated video
await geminiClient.Files.DownloadToFileAsync(
generatedVideo: operation1.Response.GeneratedVideos.First(),
outputPath: "generatedVideo.mp4"
);
// Downloaded video is a file. Bytes do not get written to the Video object.
Assert.IsNull(operation1.Response.GeneratedVideos.First().Video.VideoBytes);


var source2 = new GenerateVideosSource {
Prompt = "Driving through a tunnel.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"recordID": "FilesDownloadTest.DownloadFileGeminiTest",
"interactions": [
{
"request": {
"method": "GET",
"url": "/v1beta/files/p1crkz5nfru4:download?alt=media",
"request": "GET /v1beta/files/p1crkz5nfru4:download?alt=media HTTP/1.1",
"headers": {
"Test-Name": "FilesDownloadTest.DownloadFileGeminiTest"
},
"bodySegments": [
null
],
"previousRequest": "b4d6e60a9b97e7b98c63df9308728c5c88c0b40c398046772c63447b94608b4d",
"serverAddress": "generativelanguage.googleapis.com",
"port": 443,
"protocol": "https"
},
"shaSum": "08bb6900db8c1081bd4fba2165729edcb5ef19d480cc9720f44afb2051b2fa64",
"response": {
"statusCode": 200,
"headers": {
"Cache-Control": "private, max-age=0",
"Content-Disposition": "attachment",
"Content-Length": "9864924",
"Content-Type": "video/mp4",
"Date": "Fri, 05 Dec 2025 00:28:41 GMT",
"Expires": "Fri, 05 Dec 2025 00:28:41 GMT",
"Server": "UploadServer",
"Vary": "Origin, X-Origin, Referer",
"X-Goog-Hash": "crc32c=gJcFCw==",
"X-Guploader-Uploadid": "AHVrFxNByvn8lmmbTbI9uaG057t8JlUFnsfGOucrJjeoKE8nKxTTw4WU4B4duLoXA55ENK5L"
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"recordID": "FilesDownloadTest.DownloadFileNameGeminiTest",
"interactions": [
{
"request": {
"method": "GET",
"url": "/v1beta/files/p1crkz5nfru4:download?alt=media",
"request": "GET /v1beta/files/p1crkz5nfru4:download?alt=media HTTP/1.1",
"headers": {
"Test-Name": "FilesDownloadTest.DownloadFileNameGeminiTest"
},
"bodySegments": [
null
],
"previousRequest": "b4d6e60a9b97e7b98c63df9308728c5c88c0b40c398046772c63447b94608b4d",
"serverAddress": "generativelanguage.googleapis.com",
"port": 443,
"protocol": "https"
},
"shaSum": "18bbcea5cd8767590ff9faa8ccacafea676641cb903f9f5c4387961aff0178b7",
"response": {
"statusCode": 200,
"headers": {
"Cache-Control": "private, max-age=0",
"Content-Disposition": "attachment",
"Content-Length": "9864924",
"Content-Type": "video/mp4",
"Date": "Fri, 05 Dec 2025 00:28:41 GMT",
"Expires": "Fri, 05 Dec 2025 00:28:41 GMT",
"Server": "UploadServer",
"Vary": "Origin, X-Origin, Referer",
"X-Goog-Hash": "crc32c=gJcFCw==",
"X-Guploader-Uploadid": "AOCedOGMI8lsVHl-DTBMudTwo8x7jESnNE_MCTq-ftZcNtTncchOwSn48BO8J9rA8mnuWnKe"
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"recordID": "FilesDownloadTest.DownloadToFileFileGeminiTest",
"interactions": [
{
"request": {
"method": "GET",
"url": "/v1beta/files/p1crkz5nfru4:download?alt=media",
"request": "GET /v1beta/files/p1crkz5nfru4:download?alt=media HTTP/1.1",
"headers": {
"Test-Name": "FilesDownloadTest.DownloadToFileFileGeminiTest"
},
"bodySegments": [
null
],
"previousRequest": "b4d6e60a9b97e7b98c63df9308728c5c88c0b40c398046772c63447b94608b4d",
"serverAddress": "generativelanguage.googleapis.com",
"port": 443,
"protocol": "https"
},
"shaSum": "ccaef8722bcdb8adda81f07cfa81d11207a9733097e78cc3a7d8fb77c15a9784",
"response": {
"statusCode": 200,
"headers": {
"Cache-Control": "private, max-age=0",
"Content-Disposition": "attachment",
"Content-Length": "9864924",
"Content-Type": "video/mp4",
"Date": "Fri, 05 Dec 2025 00:28:41 GMT",
"Expires": "Fri, 05 Dec 2025 00:28:41 GMT",
"Server": "UploadServer",
"Vary": "Origin, X-Origin, Referer",
"X-Goog-Hash": "crc32c=gJcFCw==",
"X-Guploader-Uploadid": "AOCedOGKSBhUtiM7zN7ZwzzSik4a6nr_jXIjsnLdZPc6Og91PRIUwK9yLdz6owLI2A01c_JT"
}
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"recordID": "FilesDownloadTest.DownloadToFileFileNameGeminiTest",
"interactions": [
{
"request": {
"method": "GET",
"url": "/v1beta/files/p1crkz5nfru4:download?alt=media",
"request": "GET /v1beta/files/p1crkz5nfru4:download?alt=media HTTP/1.1",
"headers": {
"Test-Name": "FilesDownloadTest.DownloadToFileFileNameGeminiTest"
},
"bodySegments": [
null
],
"previousRequest": "b4d6e60a9b97e7b98c63df9308728c5c88c0b40c398046772c63447b94608b4d",
"serverAddress": "generativelanguage.googleapis.com",
"port": 443,
"protocol": "https"
},
"shaSum": "d2db4a49d811b14b0e90fd20d54a74dc94ab86bda393ab232032246bd9d643f2",
"response": {
"statusCode": 200,
"headers": {
"Cache-Control": "private, max-age=0",
"Content-Disposition": "attachment",
"Content-Length": "9864924",
"Content-Type": "video/mp4",
"Date": "Fri, 05 Dec 2025 00:28:41 GMT",
"Expires": "Fri, 05 Dec 2025 00:28:41 GMT",
"Server": "UploadServer",
"Vary": "Origin, X-Origin, Referer",
"X-Goog-Hash": "crc32c=gJcFCw==",
"X-Guploader-Uploadid": "AOCedOFaLQvh80wJ-fvOmETYMnJe4RQA-koiijz7DaTUX7EI-v-sxtnjam9Zq7RlzhNKjfJbsroMF1A"
}
}
}
]
}
Loading
Loading