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
1 change: 1 addition & 0 deletions Src/Notion.Client/Api/ApiEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ public static class FileUploadsApiUrls
public static string Send(string fileUploadId) => $"/v1/file_uploads/{fileUploadId}/send";
public static string Complete(string fileUploadId) => $"/v1/file_uploads/{fileUploadId}/complete";
public static string List => "/v1/file_uploads";
public static string Retrieve(IRetrieveFileUploadPathParameters pathParameters) => $"/v1/file_uploads/{pathParameters.FileUploadId}";
}
}
}
11 changes: 11 additions & 0 deletions Src/Notion.Client/Api/FileUploads/IFileUploadsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,16 @@ Task<ListFileUploadsResponse> ListAsync(
ListFileUploadsRequest request,
CancellationToken cancellationToken = default
);

/// <summary>
/// Retrieve a specific File Upload by its ID.
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<RetrieveFileUploadResponse> RetrieveAsync(
RetrieveFileUploadRequest request,
CancellationToken cancellationToken = default
);
}
}
28 changes: 28 additions & 0 deletions Src/Notion.Client/Api/FileUploads/Retrieve/FileUploadsClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Notion.Client
{
public sealed partial class FileUploadsClient
{
public async Task<RetrieveFileUploadResponse> RetrieveAsync(
RetrieveFileUploadRequest request,
CancellationToken cancellationToken = default)
{
IRetrieveFileUploadPathParameters pathParameters = request;

if (pathParameters == null || string.IsNullOrEmpty(pathParameters.FileUploadId))
{
throw new ArgumentNullException(nameof(pathParameters.FileUploadId), "FileUploadId cannot be null or empty.");
}

var endpoint = ApiEndpoints.FileUploadsApiUrls.Retrieve(pathParameters);

return await _restClient.GetAsync<RetrieveFileUploadResponse>(
endpoint,
cancellationToken: cancellationToken
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Notion.Client
{
public interface IRetrieveFileUploadPathParameters
{
/// <summary>
/// The ID of the File Upload to retrieve.
/// </summary>
string FileUploadId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Notion.Client
{
public class RetrieveFileUploadRequest : IRetrieveFileUploadPathParameters
{
public string FileUploadId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Notion.Client
{
public class RetrieveFileUploadResponse : FileObjectResponse
{
}
}
38 changes: 37 additions & 1 deletion Test/Notion.IntegrationTests/FileUploadsClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,41 @@ public async Task ListAsync()
Assert.NotNull(response.Results);
Assert.True(response.Results.Count <= 5);
}

[Fact]
public async Task RetrieveAsync()
{
// Arrange
var createRequest = new CreateFileUploadRequest
{
Mode = FileUploadMode.ExternalUrl,
ExternalUrl = "https://unsplash.com/photos/hOhlYhAiizc/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNzYwMTkxNzc3fA&force=true",
FileName = "sample-image.jpg",
};

var createResponse = await Client.FileUploads.CreateAsync(createRequest);

Assert.NotNull(createResponse);
Assert.NotNull(createResponse.Id);
Assert.Equal("sample-image.jpg", createResponse.FileName);
Assert.Equal("image/jpeg", createResponse.ContentType);
Assert.Equal("pending", createResponse.Status);

// Act
var retrieveRequest = new RetrieveFileUploadRequest
{
FileUploadId = createResponse.Id
};

var retrieveResponse = await Client.FileUploads.RetrieveAsync(retrieveRequest);

// Assert
Assert.NotNull(retrieveResponse);
Assert.Equal(createResponse.Id, retrieveResponse.Id);
Assert.Equal("sample-image.jpg", retrieveResponse.FileName);
Assert.Equal("image/jpeg", retrieveResponse.ContentType);
// The status might have changed from "pending" to "uploaded" depending on Notion's processing time
Assert.Contains(retrieveResponse.Status, new[] { "pending", "uploaded" });
}
}
}
}
57 changes: 57 additions & 0 deletions Test/Notion.UnitTests/FileUploadsClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,61 @@ public async Task ListAsync_CallsRestClientGetAsync_WithCorrectParameters()
}

#endregion ListAsync Tests

#region RetrieveAsync Tests

// Add tests for RetrieveAsync method
[Fact]
public async Task RetrieveAsync_ThrowsArgumentNullException_WhenFileUploadIdIsNullOrEmpty()
{
// Arrange
var request = new RetrieveFileUploadRequest
{
FileUploadId = null
};

// Act & Assert
var exception = await Assert.ThrowsAsync<ArgumentNullException>(() => _fileUploadClient.RetrieveAsync(request));
Assert.Equal("FileUploadId", exception.ParamName);
Assert.Equal("FileUploadId cannot be null or empty. (Parameter 'FileUploadId')", exception.Message);
}

[Fact]
public async Task RetrieveAsync_CallsRestClientGetAsync_WithCorrectParameters()
{
// Arrange
var fileUploadId = Guid.NewGuid().ToString();
var request = new RetrieveFileUploadRequest
{
FileUploadId = fileUploadId
};

var expectedResponse = new RetrieveFileUploadResponse
{
Id = fileUploadId,
FileName = "testfile.txt",
Status = "completed"
};

_restClientMock
.Setup(client => client.GetAsync<RetrieveFileUploadResponse>(
It.Is<string>(url => url == ApiEndpoints.FileUploadsApiUrls.Retrieve(request)),
It.IsAny<IDictionary<string, string>>(),
null,
null,
It.IsAny<CancellationToken>()
))
.ReturnsAsync(expectedResponse);

// Act
var response = await _fileUploadClient.RetrieveAsync(request);

// Assert
Assert.Equal(expectedResponse.Id, response.Id);
Assert.Equal(expectedResponse.FileName, response.FileName);
Assert.Equal(expectedResponse.Status, response.Status);
_restClientMock.VerifyAll();
}

#endregion RetrieveAsync Tests
}
Loading