Skip to content

Commit

Permalink
Merge branch 'release/0.30.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Jericho committed Jun 1, 2021
2 parents 6f02dca + 6ca0328 commit 2f3160f
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 39 deletions.
2 changes: 1 addition & 1 deletion Source/ZoomNet.IntegrationTests/Tests/Users.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public async Task RunAsync(string userId, IZoomClient client, TextWriter log, Ca
//await Task.Delay(500, cancellationToken).ConfigureAwait(false);

// CREATE NEW USER (commenting out this integration test because I currently do not have permission to create users)
//var newUser = await client.Users.CreateAsync("[email protected]", "ZoomNet", "Integration Testing", UserType.Basic, UserCreateType.Normal, cancellationToken).ConfigureAwait(false);
//var newUser = await client.Users.CreateAsync("[email protected]", "ZoomNet", "Integration Testing", null, UserType.Basic, UserCreateType.Normal, cancellationToken).ConfigureAwait(false);
//await log.WriteLineAsync($"New user created: {newUser.Id}").ConfigureAwait(false);
//await Task.Delay(500, cancellationToken).ConfigureAwait(false);

Expand Down
2 changes: 1 addition & 1 deletion Source/ZoomNet.IntegrationTests/TestsRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public async Task<int> RunAsync()
};

// Ensure the Console is tall enough and centered on the screen
Console.WindowHeight = Math.Min(60, Console.LargestWindowHeight);
if (OperatingSystem.IsWindows()) Console.WindowHeight = Math.Min(60, Console.LargestWindowHeight);
ConsoleUtils.CenterConsole();

// These are the integration tests that we will execute
Expand Down
134 changes: 134 additions & 0 deletions Source/ZoomNet.UnitTests/Extensions/Internal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using Newtonsoft.Json.Linq;
using Shouldly;
using System;
using Xunit;

namespace ZoomNet.UnitTests.Utilities
{
public class InternalTests
{
[Fact]
public void GetProperty_when_property_is_present_and_throwIfMissing_is_true()
{
// Arrange
var item = new JObject()
{
{ "aaa", "123" }
};

// Act
var property = item.GetProperty("aaa", true);

// Assert
property.ShouldNotBeNull();
property.Value<string>().ShouldBe("123");
}

[Fact]
public void GetProperty_when_property_is_present_and_throwIfMissing_is_false()
{
// Arrange
var item = new JObject()
{
{ "aaa", "123" }
};

// Act
var property = item.GetProperty("aaa", false);

// Assert
property.ShouldNotBeNull();
property.Value<string>().ShouldBe("123");
}

[Fact]
public void GetProperty_returns_null_when_property_is_missing_and_throwIfMissing_is_false()
{
// Arrange
var item = new JObject()
{
{ "aaa", "123" }
};

// Act
var property = item.GetProperty("zzz", false);

// Assert
property.ShouldBeNull();
}

[Fact]
public void GetProperty_throws_when_property_is_missing_and_throwIfMissing_is_true()
{
// Arrange
var item = new JObject()
{
{ "aaa", "123" }
};

// Act
Should.Throw<ArgumentException>(() => item.GetProperty("zzz", true));
}

[Fact]
public void GetPropertyValue_when_property_is_present_and_default_value_is_provided()
{
// Arrange
var item = new JObject()
{
{ "aaa", "123" }
};

// Act
var property = item.GetPropertyValue("aaa", "Default value");

// Assert
property.ShouldBe("123");
}

[Fact]
public void GetPropertyValue_when_property_is_present_and_default_value_is_omitted()
{
// Arrange
var item = new JObject()
{
{ "aaa", "123" }
};

// Act
var property = item.GetPropertyValue<string>("aaa");

// Assert
property.ShouldBe("123");
}

[Fact]
public void GetPropertyValue_returns_default_value_when_property_is_missing()
{
// Arrange
var item = new JObject()
{
{ "aaa", "123" }
};

// Act
var property = item.GetPropertyValue("zzz", "Default value");

// Assert
property.ShouldBe("Default value");
}

[Fact]
public void GetPropertyValue_throws_when_property_is_missing()
{
// Arrange
var item = new JObject()
{
{ "aaa", "123" }
};

// Act
Should.Throw<ArgumentException>(() => item.GetPropertyValue<string>("zzz"));
}
}
}
28 changes: 17 additions & 11 deletions Source/ZoomNet/Extensions/Internal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -489,29 +489,35 @@ internal static JToken GetProperty(this JToken item, string name, bool throwIfMi
{
var parts = name.Split('/');
var property = item[parts[0]];
if (property == null && throwIfMissing) throw new ArgumentException($"Unable to find '{name}'", nameof(name));
if (property == null)
{
if (throwIfMissing) throw new ArgumentException($"Unable to find '{name}'", nameof(name));
else return null;
}

foreach (var part in parts.Skip(1))
{
property = property[part];
if (property == null && throwIfMissing) throw new ArgumentException($"Unable to find '{part}'", nameof(name));
if (property == null)
{
if (throwIfMissing) throw new ArgumentException($"Unable to find '{name}'", nameof(name));
else return null;
}
}

return property;
}

internal static T GetPropertyValue<T>(this JToken item, string name, T defaultValue = default)
internal static T GetPropertyValue<T>(this JToken item, string name, T defaultValue)
{
var property = item.GetProperty(name);
var property = item.GetProperty(name, false);
if (property == null) return defaultValue;
return property.Value<T>();
}

internal static T GetPropertyValue<T>(this JToken item, string name, bool throwIfMissing = true)
internal static T GetPropertyValue<T>(this JToken item, string name)
{
var property = item.GetProperty(name);
if (property == null && throwIfMissing) throw new ArgumentException($"Unable to find '{name}'", nameof(name));
if (property == null) return default;
var property = item.GetProperty(name, true);
return property.Value<T>();
}

Expand Down Expand Up @@ -662,7 +668,7 @@ internal static void CheckForZoomErrors(this IResponse response)
{
var jObject = JObject.Parse(responseContent);

errorCode = jObject.GetPropertyValue<int?>("code", false);
errorCode = jObject.GetPropertyValue<int?>("code", null);
errorMessage = jObject.GetPropertyValue<string>("message", errorCode.HasValue ? $"Error code: {errorCode}" : null);

isError = errorCode.HasValue || !string.IsNullOrEmpty(errorMessage);
Expand Down Expand Up @@ -878,8 +884,8 @@ private static async Task<PaginatedResponseWithTokenAndDateRange<T>> AsPaginated
var serializer = new JsonSerializer();
if (jsonConverter != null) serializer.Converters.Add(jsonConverter);

var from = DateTime.ParseExact(jObject.GetPropertyValue<string>("from", true), "yyyy-MM-dd", CultureInfo.InvariantCulture);
var to = DateTime.ParseExact(jObject.GetPropertyValue<string>("to", true), "yyyy-MM-dd", CultureInfo.InvariantCulture);
var from = DateTime.ParseExact(jObject.GetPropertyValue<string>("from"), "yyyy-MM-dd", CultureInfo.InvariantCulture);
var to = DateTime.ParseExact(jObject.GetPropertyValue<string>("to"), "yyyy-MM-dd", CultureInfo.InvariantCulture);
var nextPageToken = jObject.GetPropertyValue<string>("next_page_token", string.Empty);
var pageSize = jObject.GetPropertyValue<int>("page_size", 0);
var totalRecords = jObject.GetPropertyValue<int?>("total_records", null);
Expand Down
3 changes: 2 additions & 1 deletion Source/ZoomNet/Resources/IUsers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,14 @@ public interface IUsers
/// <param name="email">The email address.</param>
/// <param name="firstName">First name.</param>
/// <param name="lastName">Last name.</param>
/// <param name="password">User password. Only used when createType is <see cref="UserCreateType.Auto"/>.</param>
/// <param name="type">The type of user.</param>
/// <param name="createType">Specify how to create the user.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// The new user.
/// </returns>
Task<User> CreateAsync(string email, string firstName = null, string lastName = null, UserType type = UserType.Basic, UserCreateType createType = UserCreateType.Normal, CancellationToken cancellationToken = default);
Task<User> CreateAsync(string email, string firstName = null, string lastName = null, string password = null, UserType type = UserType.Basic, UserCreateType createType = UserCreateType.Normal, CancellationToken cancellationToken = default);

/// <summary>
/// Retrieve the information of a specific user on a Zoom account.
Expand Down
4 changes: 3 additions & 1 deletion Source/ZoomNet/Resources/Users.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,14 @@ public Task<PaginatedResponseWithToken<User>> GetAllAsync(UserStatus status = Us
/// <param name="email">The email address.</param>
/// <param name="firstName">First name.</param>
/// <param name="lastName">Last name.</param>
/// <param name="password">User password. Only used when createType is <see cref="UserCreateType.Auto"/>.</param>
/// <param name="type">The type of user.</param>
/// <param name="createType">Specify how to create the user.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// The new user.
/// </returns>
public Task<User> CreateAsync(string email, string firstName = null, string lastName = null, UserType type = UserType.Basic, UserCreateType createType = UserCreateType.Normal, CancellationToken cancellationToken = default)
public Task<User> CreateAsync(string email, string firstName = null, string lastName = null, string password = null, UserType type = UserType.Basic, UserCreateType createType = UserCreateType.Normal, CancellationToken cancellationToken = default)
{
var data = new JObject()
{
Expand All @@ -111,6 +112,7 @@ public Task<User> CreateAsync(string email, string firstName = null, string last
data.AddPropertyIfEnumValue("user_info/type", type);
data.AddPropertyIfValue("user_info/first_name", firstName);
data.AddPropertyIfValue("user_info/last_name", lastName);
data.AddPropertyIfValue("user_info/password", password);

return _client
.PostAsync("users")
Expand Down
6 changes: 3 additions & 3 deletions Source/ZoomNet/Utilities/OAuthTokenHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,12 @@ public string RefreshTokenIfNecessary(bool forceRefresh)
throw new ZoomException(jObject.GetPropertyValue("reason", "The Zoom API did not provide a reason"), response, "No diagnostic available", null);
}

_connectionInfo.RefreshToken = jObject.GetPropertyValue<string>("refresh_token", true);
_connectionInfo.AccessToken = jObject.GetPropertyValue<string>("access_token", true);
_connectionInfo.RefreshToken = jObject.GetPropertyValue<string>("refresh_token");
_connectionInfo.AccessToken = jObject.GetPropertyValue<string>("access_token");
_connectionInfo.GrantType = OAuthGrantType.RefreshToken;
_connectionInfo.TokenExpiration = requestTime.AddSeconds(jObject.GetPropertyValue<int>("expires_in", 60 * 60));
_connectionInfo.TokenScope = new ReadOnlyDictionary<string, string[]>(
jObject.GetPropertyValue<string>("scope", true)
jObject.GetPropertyValue<string>("scope")
.Split(' ')
.Select(x => x.Split(new[] { ':' }, 2))
.Select(x => new KeyValuePair<string, string[]>(x[0], x.Skip(1).ToArray()))
Expand Down
32 changes: 16 additions & 16 deletions Source/ZoomNet/Utilities/WebhookEventConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
break;
case EventType.MeetingServiceIssue:
var meetingServiceIssueEvent = payloadJsonProperty.ToObject<MeetingServiceIssueEvent>(serializer);
meetingServiceIssueEvent.Issues = payloadJsonProperty.GetPropertyValue<string>("object/issues", true);
meetingServiceIssueEvent.Issues = payloadJsonProperty.GetPropertyValue<string>("object/issues");
webHookEvent = meetingServiceIssueEvent;
break;
case EventType.MeetingCreated:
Expand Down Expand Up @@ -173,53 +173,53 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
break;
case EventType.MeetingParticipantJoinedWaitingRoom:
var meetingParticipantJoinedWaitingRoomEvent = payloadJsonProperty.ToObject<MeetingParticipantJoinedWaitingRoomEvent>(serializer);
meetingParticipantJoinedWaitingRoomEvent.JoinedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time", true);
meetingParticipantJoinedWaitingRoomEvent.JoinedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time");
meetingParticipantJoinedWaitingRoomEvent.Participant = payloadJsonProperty.GetProperty("object/participant", true).ToObject<WebhookParticipant>();
webHookEvent = meetingParticipantJoinedWaitingRoomEvent;
break;
case EventType.MeetingParticipantLeftWaitingRoom:
var meetingParticipantLeftWaitingRoomEvent = payloadJsonProperty.ToObject<MeetingParticipantLeftWaitingRoomEvent>(serializer);
meetingParticipantLeftWaitingRoomEvent.LeftOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time", true);
meetingParticipantLeftWaitingRoomEvent.LeftOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time");
meetingParticipantLeftWaitingRoomEvent.Participant = payloadJsonProperty.GetProperty("object/participant", true).ToObject<WebhookParticipant>();
webHookEvent = meetingParticipantLeftWaitingRoomEvent;
break;
case EventType.MeetingParticipantAdmitted:
var meetingParticipantAdmittedEvent = payloadJsonProperty.ToObject<MeetingParticipantAdmittedEvent>(serializer);
meetingParticipantAdmittedEvent.AdmittedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time", true);
meetingParticipantAdmittedEvent.AdmittedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time");
meetingParticipantAdmittedEvent.Participant = payloadJsonProperty.GetProperty("object/participant", true).ToObject<WebhookParticipant>();
webHookEvent = meetingParticipantAdmittedEvent;
break;
case EventType.MeetingParticipantJoined:
var meetingParticipantJoinedEvent = payloadJsonProperty.ToObject<MeetingParticipantJoinedEvent>(serializer);
meetingParticipantJoinedEvent.JoinedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time", true);
meetingParticipantJoinedEvent.JoinedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time");
meetingParticipantJoinedEvent.Participant = payloadJsonProperty.GetProperty("object/participant", true).ToObject<WebhookParticipant>();
webHookEvent = meetingParticipantJoinedEvent;
break;
case EventType.MeetingParticipantSentToWaitingRoom:
var meetingParticipantSentToWaitingRoomEvent = payloadJsonProperty.ToObject<MeetingParticipantSentToWaitingRoomEvent>(serializer);
meetingParticipantSentToWaitingRoomEvent.SentToWaitingRoomOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time", true);
meetingParticipantSentToWaitingRoomEvent.SentToWaitingRoomOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time");
meetingParticipantSentToWaitingRoomEvent.Participant = payloadJsonProperty.GetProperty("object/participant", true).ToObject<WebhookParticipant>();
webHookEvent = meetingParticipantSentToWaitingRoomEvent;
break;
case EventType.MeetingParticipantLeft:
var meetingParticipantLeftEvent = payloadJsonProperty.ToObject<MeetingParticipantLeftEvent>(serializer);
meetingParticipantLeftEvent.LeftOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/leave_time", true);
meetingParticipantLeftEvent.LeftOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/leave_time");
meetingParticipantLeftEvent.Participant = payloadJsonProperty.GetProperty("object/participant", true).ToObject<WebhookParticipant>();
webHookEvent = meetingParticipantLeftEvent;
break;
case EventType.MeetingLiveStreamStarted:
var meetingLiveStreamStartedEvent = payloadJsonProperty.ToObject<MeetingLiveStreamStartedEvent>(serializer);
meetingLiveStreamStartedEvent.StartedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/date_time", true);
meetingLiveStreamStartedEvent.Operator = payloadJsonProperty.GetPropertyValue<string>("object/operator", true);
meetingLiveStreamStartedEvent.OperatorId = payloadJsonProperty.GetPropertyValue<string>("object/operator_id", true);
meetingLiveStreamStartedEvent.StartedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/date_time");
meetingLiveStreamStartedEvent.Operator = payloadJsonProperty.GetPropertyValue<string>("object/operator");
meetingLiveStreamStartedEvent.OperatorId = payloadJsonProperty.GetPropertyValue<string>("object/operator_id");
meetingLiveStreamStartedEvent.StreamingInfo = payloadJsonProperty.GetProperty("object/live_streaming", true).ToObject<LiveStreamingInfo>();
webHookEvent = meetingLiveStreamStartedEvent;
break;
case EventType.MeetingLiveStreamStopped:
var meetingLiveStreamStoppedEvent = payloadJsonProperty.ToObject<MeetingLiveStreamStoppedEvent>(serializer);
meetingLiveStreamStoppedEvent.StoppedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/date_time", true);
meetingLiveStreamStoppedEvent.Operator = payloadJsonProperty.GetPropertyValue<string>("object/operator", true);
meetingLiveStreamStoppedEvent.OperatorId = payloadJsonProperty.GetPropertyValue<string>("object/operator_id", true);
meetingLiveStreamStoppedEvent.StoppedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/date_time");
meetingLiveStreamStoppedEvent.Operator = payloadJsonProperty.GetPropertyValue<string>("object/operator");
meetingLiveStreamStoppedEvent.OperatorId = payloadJsonProperty.GetPropertyValue<string>("object/operator_id");
meetingLiveStreamStoppedEvent.StreamingInfo = payloadJsonProperty.GetProperty("object/live_streaming", true).ToObject<LiveStreamingInfo>();
webHookEvent = meetingLiveStreamStoppedEvent;
break;
Expand Down Expand Up @@ -253,7 +253,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
break;
case EventType.WebinarServiceIssue:
var webinarServiceIssueEvent = payloadJsonProperty.ToObject<WebinarServiceIssueEvent>(serializer);
webinarServiceIssueEvent.Issues = payloadJsonProperty.GetPropertyValue<string>("object/issues", true);
webinarServiceIssueEvent.Issues = payloadJsonProperty.GetPropertyValue<string>("object/issues");
webHookEvent = webinarServiceIssueEvent;
break;
case EventType.WebinarRegistrationCreated:
Expand Down Expand Up @@ -290,13 +290,13 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
break;
case EventType.WebinarParticipantJoined:
var webinarParticipantJoinedEvent = payloadJsonProperty.ToObject<WebinarParticipantJoinedEvent>(serializer);
webinarParticipantJoinedEvent.JoinedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time", true);
webinarParticipantJoinedEvent.JoinedOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time");
webinarParticipantJoinedEvent.Participant = payloadJsonProperty.GetProperty("object/participant", true).ToObject<WebhookParticipant>();
webHookEvent = webinarParticipantJoinedEvent;
break;
case EventType.WebinarParticipantLeft:
var webinarParticipantLeftEvent = payloadJsonProperty.ToObject<WebinarParticipantLeftEvent>(serializer);
webinarParticipantLeftEvent.LeftOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time", true);
webinarParticipantLeftEvent.LeftOn = payloadJsonProperty.GetPropertyValue<DateTime>("object/participant/date_time");
webinarParticipantLeftEvent.Participant = payloadJsonProperty.GetProperty("object/participant", true).ToObject<WebhookParticipant>();
webHookEvent = webinarParticipantLeftEvent;
break;
Expand Down
Loading

0 comments on commit 2f3160f

Please sign in to comment.