feat: add model to represent paged request
This commit is contained in:
@@ -0,0 +1,80 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace AnthropicClient.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a request to page through a collection of items.
|
||||||
|
/// </summary>
|
||||||
|
public class PagingRequest
|
||||||
|
{
|
||||||
|
private const int LimitMinimum = 1;
|
||||||
|
private const int LimitMaximum = 1000;
|
||||||
|
private const int DefaultLimit = 20;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ID of the item before which to start the page.
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("before_id")]
|
||||||
|
public string BeforeId { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ID of the item after which to start the page.
|
||||||
|
/// </summary>
|
||||||
|
[JsonPropertyName("after_id")]
|
||||||
|
public string AfterId { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum number of items to return in the page.
|
||||||
|
/// </summary>
|
||||||
|
public int Limit { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="PagingRequest"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="beforeId">The ID of the item before which to start the page.</param>
|
||||||
|
/// <param name="afterId">The ID of the item after which to start the page.</param>
|
||||||
|
/// <param name="limit">The maximum number of items to return in the page.</param>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="limit"/> is less than 1 or greater than 1000.</exception>
|
||||||
|
/// <returns>A new instance of the <see cref="PagingRequest"/> class.</returns>
|
||||||
|
public PagingRequest(
|
||||||
|
string beforeId = "",
|
||||||
|
string afterId = "",
|
||||||
|
int limit = DefaultLimit
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (limit is < LimitMinimum or > LimitMaximum)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(limit), $"{nameof(limit)} must be between {LimitMinimum} and {LimitMaximum}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
BeforeId = beforeId;
|
||||||
|
AfterId = afterId;
|
||||||
|
Limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the <see cref="PagingRequest"/> to a query string.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The query string representation of the <see cref="PagingRequest"/>.</returns>
|
||||||
|
public string ToQueryParameters()
|
||||||
|
{
|
||||||
|
var parameters = new List<string>();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(BeforeId) is false)
|
||||||
|
{
|
||||||
|
parameters.Add($"before_id={BeforeId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(AfterId) is false)
|
||||||
|
{
|
||||||
|
parameters.Add($"after_id={AfterId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Limit is not DefaultLimit)
|
||||||
|
{
|
||||||
|
parameters.Add($"limit={Limit}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Join("&", parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
namespace AnthropicClient.Tests.Unit.Models;
|
||||||
|
|
||||||
|
public class PagingRequestTests : SerializationTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Constructor_WhenLimitIsLessThanMinimum_ItShouldThrowArgumentOutOfRangeException()
|
||||||
|
{
|
||||||
|
var act = () => new PagingRequest(limit: 0);
|
||||||
|
|
||||||
|
act.Should().Throw<ArgumentOutOfRangeException>().WithMessage("limit must be between 1 and 1000. (Parameter 'limit')");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Constructor_WhenLimitIsGreaterThanMaximum_ItShouldThrowArgumentOutOfRangeException()
|
||||||
|
{
|
||||||
|
var act = () => new PagingRequest(limit: 1001);
|
||||||
|
|
||||||
|
act.Should().Throw<ArgumentOutOfRangeException>().WithMessage("limit must be between 1 and 1000. (Parameter 'limit')");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ToQueryParameters_WhenNoPropertiesSet_ItShouldReturnEmptyString()
|
||||||
|
{
|
||||||
|
var pagingRequest = new PagingRequest();
|
||||||
|
|
||||||
|
var result = pagingRequest.ToQueryParameters();
|
||||||
|
|
||||||
|
result.Should().BeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ToQueryParameters_WhenBeforeIdIsSet_ItShouldReturnBeforeId()
|
||||||
|
{
|
||||||
|
var pagingRequest = new PagingRequest(beforeId: "before-id");
|
||||||
|
|
||||||
|
var result = pagingRequest.ToQueryParameters();
|
||||||
|
|
||||||
|
result.Should().Be("before_id=before-id");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ToQueryParameters_WhenAfterIdIsSet_ItShouldReturnAfterId()
|
||||||
|
{
|
||||||
|
var pagingRequest = new PagingRequest(afterId: "after-id");
|
||||||
|
|
||||||
|
var result = pagingRequest.ToQueryParameters();
|
||||||
|
|
||||||
|
result.Should().Be("after_id=after-id");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ToQueryParameters_WhenLimitIsSetToNonDefaultValue_ItShouldReturnLimit()
|
||||||
|
{
|
||||||
|
var pagingRequest = new PagingRequest(limit: 10);
|
||||||
|
|
||||||
|
var result = pagingRequest.ToQueryParameters();
|
||||||
|
|
||||||
|
result.Should().Be("limit=10");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ToQueryParameters_WhenAllPropertiesAreSet_ItShouldReturnAllProperties()
|
||||||
|
{
|
||||||
|
var pagingRequest = new PagingRequest(beforeId: "before-id", afterId: "after-id", limit: 10);
|
||||||
|
|
||||||
|
var result = pagingRequest.ToQueryParameters();
|
||||||
|
|
||||||
|
result.Should().Be("before_id=before-id&after_id=after-id&limit=10");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user