Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of "Users.GetIncrementalUserExport" and "Users.GetIncrementalUserExportNextPage" (+Async versions) #347

Merged
merged 10 commits into from
Jun 23, 2018
33 changes: 33 additions & 0 deletions src/ZendeskApi_v2/Models/Users/GroupUserExportResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using ZendeskApi_v2.Models.Organizations;

namespace ZendeskApi_v2.Models.Users
{
public class GroupUserExportResponse
{
[JsonProperty("count")]
public long Count { get; set; }

[JsonProperty("end_time")]
[JsonConverter(typeof(UnixDateTimeConverter))]
public DateTimeOffset EndTime { get; set; }

[JsonProperty("next_page")]
public string NextPage { get; set; }

[JsonProperty("organizations")]
public IList<Organization> Organizations { get; set; }

[JsonProperty("identities")]
public IList<UserIdentity> Identities { get; set; }

[JsonProperty("groups")]
public IList<Groups.Group> Groups { get; set; }

[JsonProperty("users")]
public IList<User> Users { get; set; }
}
}
41 changes: 41 additions & 0 deletions src/ZendeskApi_v2/Requests/Users.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ public interface IUsers : ICore

IndividualUserResponse SetUserPhoto(long userId, ZenFile photo);

GroupUserExportResponse GetIncrementalUserExport(DateTimeOffset startTime, UserSideLoadOptions sideLoadOptions = UserSideLoadOptions.None);

GroupUserExportResponse GetIncrementalUserExportNextPage(string nextPage);
#endif

#if ASYNC
Expand Down Expand Up @@ -183,11 +186,17 @@ public interface IUsers : ICore

Task<IndividualUserResponse> SetUserPhotoAsync(long userId, ZenFile photo);

Task<GroupUserExportResponse> GetIncrementalUserExportAsync(DateTimeOffset startTime, UserSideLoadOptions sideLoadOptions = UserSideLoadOptions.None);

Task<GroupUserExportResponse> GetIncrementalUserExportNextPageAsync(string nextPage);

#endif
}

public class Users : Core, IUsers
{
private const string _incremental_export = "incremental/users.json?start_time=";

public Users(string yourZendeskUrl, string user, string password, string apiToken, string p_OAuthToken)
: base(yourZendeskUrl, user, password, apiToken, p_OAuthToken)
{
Expand Down Expand Up @@ -426,6 +435,22 @@ public IndividualUserResponse SetUserPhoto(long userId, ZenFile photo)
return GenericPut<IndividualUserResponse>($"users/{userId}.json", null, new Dictionary<string, object> { { "user[photo][uploaded_data]", photo } });
}

public GroupUserExportResponse GetIncrementalUserExport(DateTimeOffset startTime, UserSideLoadOptions sideLoadOptions = UserSideLoadOptions.None)
{
var resource =
GetResourceStringWithSideLoadOptionsParam(
_incremental_export + startTime.UtcDateTime.GetEpoch(),
sideLoadOptions);

return GenericGet<GroupUserExportResponse>(resource);
}

public GroupUserExportResponse GetIncrementalUserExportNextPage(string nextPage)
{
var resource = nextPage.Replace(ZendeskUrl, string.Empty);

return GenericGet<GroupUserExportResponse>(resource);
}
#endif

#if ASYNC
Expand Down Expand Up @@ -647,6 +672,22 @@ public Task<IndividualUserResponse> SetUserPhotoAsync(long userId, ZenFile photo
return GenericPutAsync<IndividualUserResponse>($"users/{userId}.json", null, new Dictionary<string, object> { { "user[photo][uploaded_data]", photo } });
}

public async Task<GroupUserExportResponse> GetIncrementalUserExportAsync(DateTimeOffset startTime, UserSideLoadOptions sideLoadOptions = UserSideLoadOptions.None)
{
var resource =
GetResourceStringWithSideLoadOptionsParam(
_incremental_export + startTime.UtcDateTime.GetEpoch(),
sideLoadOptions);

return await GenericGetAsync<GroupUserExportResponse>(resource);
}

public async Task<GroupUserExportResponse> GetIncrementalUserExportNextPageAsync(string nextPage)
{
var resource = nextPage.Replace(ZendeskUrl, string.Empty);

return await GenericGetAsync<GroupUserExportResponse>(resource);
}
#endif

private string GetResourceStringWithSideLoadOptionsParam(string resource, UserSideLoadOptions sideLoadOptions)
Expand Down
64 changes: 64 additions & 0 deletions test/ZendeskApi_v2.Test/UserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -497,5 +497,69 @@ public void CanBulkDeleteUsers()
Assert.AreEqual(JobStatusCompleted, jobResponse.JobStatus.Status.ToLower());
Assert.AreEqual(users.Count, jobResponse.JobStatus.Total);
}

[Test]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I am a fan fo the Assert.That() method of unit it test assertions.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rate Limit
Do you run all tests that often? In my daily work, we have used the incremental Ticket Export and we are yet to hit the limit in actual use.
So gut feeling is wait and see if it becomes a problem and if so it could be built in that it have a "LastExecuted.txt" file in %temp% and if run too often.
But given that the test CanGetIncrementalTicketExportWithGroupsSideLoadPaged have not given an issue I guess this will not either (have same rate limit)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding Assert.That

I can change my unit-tests to that (I normally use MS-Test and not nUnit and they do not have the Assert.That so not used to that)...

Practical how do I make this change to the PR? (Is it a new PR?) [Sorry: still very noob on this Git and PR thing]

Copy link
Author

@rwjdk rwjdk Jun 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this style OK (Assert.That feels clunky for null/not Null checks)?

        [Test]
        public void CanGetIncrementalUserExport()
        {
            var incrementalUserExport = api.Users.GetIncrementalUserExport(DateTimeOffset.MinValue);
            Assert.That(incrementalUserExport.Users.Count, Is.GreaterThan(0));
            Assert.IsNull(incrementalUserExport.Organizations);
            Assert.IsNull(incrementalUserExport.Identities);
            Assert.IsNull(incrementalUserExport.Groups);

            var incrementalUserExportNextPage = api.Users.GetIncrementalUserExportNextPage(incrementalUserExport.NextPage);
            Assert.That(incrementalUserExportNextPage.Users.Count, Is.GreaterThan(0));
            Assert.IsNull(incrementalUserExportNextPage.Organizations);
            Assert.IsNull(incrementalUserExportNextPage.Identities);
            Assert.IsNull(incrementalUserExportNextPage.Groups);
        }

Copy link
Member

@mozts2005 mozts2005 Jun 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rwjdk for updating the PR just update the branch on your fork and it will auto update the PR

As for the test cases I like the

        [Test]
        public void CanGetIncrementalUserExport()
        {
            var incrementalUserExport = api.Users.GetIncrementalUserExport(DateTimeOffset.MinValue);
            Assert.That(incrementalUserExport.Users.Count, Is.GreaterThan(0));
            Assert.That(incrementalUserExport.Organizations, Is.Null);
            Assert.That(incrementalUserExport.Identities, Is.Null);
            Assert.That(incrementalUserExport.Groups,  Is.Null);

            var incrementalUserExportNextPage = api.Users.GetIncrementalUserExportNextPage(incrementalUserExport.NextPage);
            Assert.That(incrementalUserExportNextPage.Users.Count, Is.GreaterThan(0));
            Assert.That(incrementalUserExportNextPage.Organizations, Is.Null);
            Assert.That(incrementalUserExportNextPage.Identities, Is.Null);
            Assert.That(incrementalUserExportNextPage.Groups, Is.Null);
        }

The "That" format reads as English which helps new people to coding and is the format recommended by the NUnit team.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point :-) - Change made to the tests now

public void CanGetIncrementalUserExport()
{
var incrementalUserExport = api.Users.GetIncrementalUserExport(DateTimeOffset.MinValue);
Assert.That(incrementalUserExport.Users.Count, Is.GreaterThan(0));
Assert.That(incrementalUserExport.Organizations, Is.Null);
Assert.That(incrementalUserExport.Identities, Is.Null);
Assert.That(incrementalUserExport.Groups, Is.Null);

var incrementalUserExportNextPage = api.Users.GetIncrementalUserExportNextPage(incrementalUserExport.NextPage);
Assert.That(incrementalUserExportNextPage.Users.Count, Is.GreaterThan(0));
Assert.That(incrementalUserExportNextPage.Organizations, Is.Null);
Assert.That(incrementalUserExportNextPage.Identities, Is.Null);
Assert.That(incrementalUserExportNextPage.Groups, Is.Null);
}

[Test]
public void CanGetIncrementalUserExportWithSideLoadOptions()
{
var incrementalUserExport = api.Users.GetIncrementalUserExport(DateTimeOffset.MinValue, UserSideLoadOptions.Organizations | UserSideLoadOptions.Groups | UserSideLoadOptions.Identities);
Assert.That(incrementalUserExport.Users.Count, Is.GreaterThan(0));
Assert.That(incrementalUserExport.Organizations, Is.Not.Null);
Assert.That(incrementalUserExport.Identities, Is.Not.Null);
Assert.That(incrementalUserExport.Groups, Is.Not.Null);

var incrementalUserExportNextPage = api.Users.GetIncrementalUserExportNextPage(incrementalUserExport.NextPage);
Assert.That(incrementalUserExportNextPage.Users.Count, Is.GreaterThan(0));
Assert.That(incrementalUserExportNextPage.Organizations, Is.Not.Null);
Assert.That(incrementalUserExportNextPage.Identities, Is.Not.Null);
Assert.That(incrementalUserExportNextPage.Groups, Is.Not.Null);
}

[Test]
public async Task CanGetIncrementalUserExportAsync()
{
var incrementalUserExport = await api.Users.GetIncrementalUserExportAsync(DateTimeOffset.MinValue);
Assert.That(incrementalUserExport.Users.Count, Is.GreaterThan(0));
Assert.That(incrementalUserExport.Organizations, Is.Null);
Assert.That(incrementalUserExport.Identities, Is.Null);
Assert.That(incrementalUserExport.Groups, Is.Null);

var incrementalUserExportNextPage = await api.Users.GetIncrementalUserExportNextPageAsync(incrementalUserExport.NextPage);
Assert.That(incrementalUserExportNextPage.Users.Count, Is.GreaterThan(0));
Assert.That(incrementalUserExportNextPage.Organizations, Is.Null);
Assert.That(incrementalUserExportNextPage.Identities, Is.Null);
Assert.That(incrementalUserExportNextPage.Groups, Is.Null);
}

[Test]
public async Task CanGetIncrementalUserExportAsyncWithSideLoadOptions()
{
var incrementalUserExport = await api.Users.GetIncrementalUserExportAsync(DateTimeOffset.MinValue, UserSideLoadOptions.Organizations | UserSideLoadOptions.Groups | UserSideLoadOptions.Identities);
Assert.That(incrementalUserExport.Users.Count > 0);
Assert.That(incrementalUserExport.Organizations, Is.Not.Null);
Assert.That(incrementalUserExport.Identities, Is.Not.Null);
Assert.That(incrementalUserExport.Groups, Is.Not.Null);

var incrementalUserExportNextPage = await api.Users.GetIncrementalUserExportNextPageAsync(incrementalUserExport.NextPage);
Assert.That(incrementalUserExportNextPage.Users.Count > 0);
Assert.That(incrementalUserExportNextPage.Organizations, Is.Not.Null);
Assert.That(incrementalUserExportNextPage.Identities, Is.Not.Null);
Assert.That(incrementalUserExportNextPage.Groups, Is.Not.Null);
}
}
}