Skip to content

Commit

Permalink
Merge branch 'release/0.65.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Jericho committed Jul 13, 2023
2 parents 72cb9cc + c19d34d commit a0e48c7
Show file tree
Hide file tree
Showing 4 changed files with 277 additions and 4 deletions.
165 changes: 165 additions & 0 deletions Source/ZoomNet.UnitTests/Extensions/InternalTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
using Shouldly;
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
using ZoomNet.Models;

namespace ZoomNet.UnitTests.Extensions
{
public class InternalTests
{
public class AsPaginatedResponse
{
[Fact]
public async Task ThrowsExceptionWhenExpectedRecordsAreMissing()
{
// Arrange
var responseContent = @"{
""next_page_token"": """",
""page_number"": 1,
""page_size"": 100,
""total_records"": 5
}";
var message = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(responseContent)
};
var response = new MockFluentHttpResponse(message, null, CancellationToken.None);

// Act
await Should.ThrowAsync<ArgumentException>(() => response.AsPaginatedResponse<UserCallLog>("call_logs")).ConfigureAwait(false);
}

[Fact]
public async Task DoesNotThrowExceptionWhenRecordsAreMissingAndTotalRecordsIsZero()
{
// Arrange
var responseContent = @"{
""next_page_token"": """",
""page_size"": 100,
""total_records"": 0
}";
var message = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(responseContent)
};
var response = new MockFluentHttpResponse(message, null, CancellationToken.None);

// Act
var paginatedResponse = await response.AsPaginatedResponse<UserCallLog>("call_logs").ConfigureAwait(false);

// Assert
paginatedResponse.PageCount.ShouldBe(0);
paginatedResponse.PageNumber.ShouldBe(0);
paginatedResponse.PageSize.ShouldBe(100);
paginatedResponse.Records.ShouldBeEmpty();
paginatedResponse.TotalRecords.ShouldBe(0);
}
}

public class AsPaginatedResponseWithToken
{
[Fact]
public async Task ThrowsExceptionWhenExpectedRecordsAreMissing()
{
// Arrange
var responseContent = @"{
""next_page_token"": """",
""page_number"": 1,
""page_size"": 100,
""total_records"": 5,
""from"": ""2023-07-05"",
""to"": ""2023-07-12""
}";
var message = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(responseContent)
};
var response = new MockFluentHttpResponse(message, null, CancellationToken.None);

// Act
await Should.ThrowAsync<ArgumentException>(() => response.AsPaginatedResponseWithToken<UserCallLog>("call_logs")).ConfigureAwait(false);
}

[Fact]
public async Task DoesNotThrowExceptionWhenRecordsAreMissingAndTotalRecordsIsZero()
{
// Arrange
var responseContent = @"{
""next_page_token"": """",
""page_size"": 100,
""total_records"": 0,
""from"": ""2023-07-05"",
""to"": ""2023-07-12""
}";
var message = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(responseContent)
};
var response = new MockFluentHttpResponse(message, null, CancellationToken.None);

// Act
var paginatedResponse = await response.AsPaginatedResponseWithToken<UserCallLog>("call_logs").ConfigureAwait(false);

// Assert
paginatedResponse.PageSize.ShouldBe(100);
paginatedResponse.Records.ShouldBeEmpty();
paginatedResponse.TotalRecords.ShouldBe(0);
}
}

public class AsPaginatedResponseWithTokenAndDateRange
{
[Fact]
public async Task ThrowsExceptionWhenExpectedRecordsAreMissing()
{
// Arrange
var responseContent = @"{
""next_page_token"": """",
""page_number"": 1,
""page_size"": 100,
""total_records"": 5,
""from"": ""2023-07-05"",
""to"": ""2023-07-12""
}";
var message = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(responseContent)
};
var response = new MockFluentHttpResponse(message, null, CancellationToken.None);

// Act
await Should.ThrowAsync<ArgumentException>(() => response.AsPaginatedResponseWithTokenAndDateRange<UserCallLog>("call_logs")).ConfigureAwait(false);
}

[Fact]
public async Task DoesNotThrowExceptionWhenRecordsAreMissingAndTotalRecordsIsZero()
{
// Arrange
var responseContent = @"{
""next_page_token"": """",
""page_size"": 100,
""total_records"": 0,
""from"": ""2023-07-05"",
""to"": ""2023-07-12""
}";
var message = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(responseContent)
};
var response = new MockFluentHttpResponse(message, null, CancellationToken.None);

// Act
var paginatedResponse = await response.AsPaginatedResponseWithTokenAndDateRange<UserCallLog>("call_logs").ConfigureAwait(false);

// Assert
paginatedResponse.PageSize.ShouldBe(100);
paginatedResponse.Records.ShouldBeEmpty();
paginatedResponse.TotalRecords.ShouldBe(0);
}
}
}
}
102 changes: 102 additions & 0 deletions Source/ZoomNet.UnitTests/MockFluentHttpResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using Newtonsoft.Json.Linq;
using Pathoschild.Http.Client;
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Threading;
using System.Threading.Tasks;

namespace ZoomNet.UnitTests
{
internal class MockFluentHttpResponse : IResponse
{
public MockFluentHttpResponse(HttpResponseMessage message, MediaTypeFormatterCollection formatters = null, CancellationToken cancellationToken = default)
{
Message = message;
Formatters = formatters;
CancellationToken = cancellationToken;
}

public bool IsSuccessStatusCode => Message.IsSuccessStatusCode;

public HttpStatusCode Status => Message.StatusCode;

public HttpResponseMessage Message { get; private set; }

public MediaTypeFormatterCollection Formatters { get; private set; }

public CancellationToken CancellationToken { get; private set; }

public IResponse WithCancellationToken(CancellationToken cancellationToken)
{
CancellationToken = cancellationToken;
return this;
}

public Task<T> As<T>()
{
return Message.Content.ReadAsAsync<T>(Formatters, CancellationToken);
}

public Task<T[]> AsArray<T>()
{
return As<T[]>();
}

public Task<byte[]> AsByteArray()
{
return this.AssertContent().ReadAsByteArrayAsync(
#if NET5_0_OR_GREATER
this.CancellationToken
#endif
);
}

public Task<string> AsString()
{
return this.AssertContent().ReadAsStringAsync(
#if NET5_0_OR_GREATER
this.CancellationToken
#endif
);
}

public async Task<Stream> AsStream()
{
Stream stream = await this.AssertContent()
.ReadAsStreamAsync(
#if NET5_0_OR_GREATER
this.CancellationToken
#endif
)
.ConfigureAwait(false);
stream.Position = 0;
return stream;
}

public async Task<JToken> AsRawJson()
{
string content = await this.AsString().ConfigureAwait(false);
return JToken.Parse(content);
}

public async Task<JObject> AsRawJsonObject()
{
string content = await this.AsString().ConfigureAwait(false);
return JObject.Parse(content);
}

public async Task<JArray> AsRawJsonArray()
{
string content = await this.AsString().ConfigureAwait(false);
return JArray.Parse(content);
}

private HttpContent AssertContent()
{
return this.Message?.Content ?? throw new NullReferenceException("The response has no body to read.");
}
}
}
6 changes: 3 additions & 3 deletions Source/ZoomNet/Extensions/Internal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -971,7 +971,7 @@ private static async Task<PaginatedResponse<T>> AsPaginatedResponse<T>(this Http
var jsonProperty = rootElement.GetProperty(propertyName, false);

// Make sure the desired property is present. It's ok if the property is missing when there are no records.
if (!jsonProperty.HasValue && pageSize > 0)
if (!jsonProperty.HasValue && totalRecords is > 0)
{
throw new ArgumentException($"The response does not contain a field called '{propertyName}'", nameof(propertyName));
}
Expand Down Expand Up @@ -1011,7 +1011,7 @@ private static async Task<PaginatedResponseWithToken<T>> AsPaginatedResponseWith
var jsonProperty = rootElement.GetProperty(propertyName, false);

// Make sure the desired property is present. It's ok if the property is missing when there are no records.
if (!jsonProperty.HasValue && pageSize > 0)
if (!jsonProperty.HasValue && totalRecords is > 0)
{
throw new ArgumentException($"The response does not contain a field called '{propertyName}'", nameof(propertyName));
}
Expand Down Expand Up @@ -1052,7 +1052,7 @@ private static async Task<PaginatedResponseWithTokenAndDateRange<T>> AsPaginated
var jsonProperty = rootElement.GetProperty(propertyName, false);

// Make sure the desired property is present. It's ok if the property is missing when there are no records.
if (!jsonProperty.HasValue && pageSize > 0)
if (!jsonProperty.HasValue && totalRecords is > 0)
{
throw new ArgumentException($"The response does not contain a field called '{propertyName}'", nameof(propertyName));
}
Expand Down
8 changes: 7 additions & 1 deletion Source/ZoomNet/Models/CallLogTransferInfoExtensionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ public enum CallLogTransferInfoExtensionType
/// sharedLineGroup.
/// </summary>
[EnumMember(Value = "sharedLineGroup")]
SharedLineGroup
SharedLineGroup,

/// <summary>
/// pstn.
/// </summary>
[EnumMember(Value = "pstn")]
Pstn
}
}

0 comments on commit a0e48c7

Please sign in to comment.