From 437bf911173b3da202b1687ae18e89ba9a4bb29d Mon Sep 17 00:00:00 2001 From: Alexander Efremov Date: Wed, 1 Jun 2016 21:16:55 +0700 Subject: [PATCH] Add ApiOptions overloads to methods on I(Observable)OrganizationMembersClient (#1332) --- .../IObservableOrganizationMembersClient.cs | 105 ++++++++++++ .../ObservableOrganizationMembersClient.cs | 145 ++++++++++++++++- .../Clients/OrganizationMembersClientTests.cs | 60 ++++++- .../Clients/OrganizationMembersClientTests.cs | 153 +++++++++++++++--- ...bservableOrganizationMembersClientTests.cs | 126 ++++++++++++++- Octokit/Clients/IOrganizationMembersClient.cs | 108 ++++++++++++- Octokit/Clients/OrganizationMembersClient.cs | 148 ++++++++++++++++- 7 files changed, 802 insertions(+), 43 deletions(-) diff --git a/Octokit.Reactive/Clients/IObservableOrganizationMembersClient.cs b/Octokit.Reactive/Clients/IObservableOrganizationMembersClient.cs index 5d15d246..8d77cad6 100644 --- a/Octokit.Reactive/Clients/IObservableOrganizationMembersClient.cs +++ b/Octokit.Reactive/Clients/IObservableOrganizationMembersClient.cs @@ -27,6 +27,29 @@ namespace Octokit.Reactive /// IObservable GetAll(string org); + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// Options for changing the API response + /// + IObservable GetAll(string org, ApiOptions options); + /// /// /// List all users who are members of an organization. A member is a user that @@ -50,6 +73,30 @@ namespace Octokit.Reactive /// IObservable GetAll(string org, OrganizationMembersFilter filter); + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The members filter, + /// Options for changing the API response + /// + IObservable GetAll(string org, OrganizationMembersFilter filter, ApiOptions options); + /// /// /// List all users who are members of an organization. A member is a user that @@ -73,6 +120,30 @@ namespace Octokit.Reactive /// IObservable GetAll(string org, OrganizationMembersRole role); + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The role filter to use when getting the users, + /// Options for changing the API response + /// + IObservable GetAll(string org, OrganizationMembersRole role, ApiOptions options); + /// /// /// List all users who are members of an organization. A member is a user that @@ -97,6 +168,31 @@ namespace Octokit.Reactive /// IObservable GetAll(string org, OrganizationMembersFilter filter, OrganizationMembersRole role); + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The members filter, + /// The role filter to use when getting the users, + /// Options for changing the API response + /// + IObservable GetAll(string org, OrganizationMembersFilter filter, OrganizationMembersRole role, ApiOptions options); + /// /// List all users who have publicized their membership of the organization. /// @@ -105,6 +201,15 @@ namespace Octokit.Reactive /// IObservable GetAllPublic(string org); + /// + /// List all users who have publicized their membership of the organization. + /// + /// http://developer.github.com/v3/orgs/members/#public-members-list + /// The login for the organization + /// Options for changing the API response + /// + IObservable GetAllPublic(string org, ApiOptions options); + /// /// Check if a user is, publicly or privately, a member of the organization. /// diff --git a/Octokit.Reactive/Clients/ObservableOrganizationMembersClient.cs b/Octokit.Reactive/Clients/ObservableOrganizationMembersClient.cs index 0bb84d35..56bde28b 100644 --- a/Octokit.Reactive/Clients/ObservableOrganizationMembersClient.cs +++ b/Octokit.Reactive/Clients/ObservableOrganizationMembersClient.cs @@ -46,7 +46,36 @@ namespace Octokit.Reactive { Ensure.ArgumentNotNullOrEmptyString(org, "org"); - return _connection.GetAndFlattenAllPages(ApiUrls.Members(org)); + return GetAll(org, ApiOptions.None); + } + + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// Options for changing the API response + /// + public IObservable GetAll(string org, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(org, "org"); + Ensure.ArgumentNotNull(options, "options"); + + return _connection.GetAndFlattenAllPages(ApiUrls.Members(org), options); } /// @@ -74,7 +103,37 @@ namespace Octokit.Reactive { Ensure.ArgumentNotNullOrEmptyString(org, "org"); - return _connection.GetAndFlattenAllPages(ApiUrls.Members(org, filter)); + return GetAll(org, filter, ApiOptions.None); + } + + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The members filter, + /// Options for changing the API response + /// + public IObservable GetAll(string org, OrganizationMembersFilter filter, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(org, "org"); + Ensure.ArgumentNotNull(options, "options"); + + return _connection.GetAndFlattenAllPages(ApiUrls.Members(org, filter), options); } /// @@ -102,7 +161,37 @@ namespace Octokit.Reactive { Ensure.ArgumentNotNullOrEmptyString(org, "org"); - return _connection.GetAndFlattenAllPages(ApiUrls.Members(org, role)); + return GetAll(org, role, ApiOptions.None); + } + + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The role filter to use when getting the users, + /// Options for changing the API response + /// + public IObservable GetAll(string org, OrganizationMembersRole role, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(org, "org"); + Ensure.ArgumentNotNull(options, "options"); + + return _connection.GetAndFlattenAllPages(ApiUrls.Members(org, role), options); } /// @@ -131,7 +220,38 @@ namespace Octokit.Reactive { Ensure.ArgumentNotNullOrEmptyString(org, "org"); - return _connection.GetAndFlattenAllPages(ApiUrls.Members(org, filter, role)); + return GetAll(org, filter, role, ApiOptions.None); + } + + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The members filter, + /// The role filter to use when getting the users, + /// Options for changing the API response + /// + public IObservable GetAll(string org, OrganizationMembersFilter filter, OrganizationMembersRole role, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(org, "org"); + Ensure.ArgumentNotNull(options, "options"); + + return _connection.GetAndFlattenAllPages(ApiUrls.Members(org, filter, role), options); } /// @@ -144,7 +264,22 @@ namespace Octokit.Reactive { Ensure.ArgumentNotNullOrEmptyString(org, "org"); - return _connection.GetAndFlattenAllPages(ApiUrls.PublicMembers(org)); + return GetAllPublic(org, ApiOptions.None); + } + + /// + /// List all users who have publicized their membership of the organization. + /// + /// http://developer.github.com/v3/orgs/members/#public-members-list + /// The login for the organization + /// Options for changing the API response + /// + public IObservable GetAllPublic(string org, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(org, "org"); + Ensure.ArgumentNotNull(options, "options"); + + return _connection.GetAndFlattenAllPages(ApiUrls.PublicMembers(org), options); } /// diff --git a/Octokit.Tests.Integration/Clients/OrganizationMembersClientTests.cs b/Octokit.Tests.Integration/Clients/OrganizationMembersClientTests.cs index d0cb22b9..5e3d4c56 100644 --- a/Octokit.Tests.Integration/Clients/OrganizationMembersClientTests.cs +++ b/Octokit.Tests.Integration/Clients/OrganizationMembersClientTests.cs @@ -20,8 +20,64 @@ namespace Octokit.Tests.Integration.Clients [IntegrationTest] public async Task ReturnsMembers() { - var members = _gitHub.Organization.Member.GetAll(_organizationFixture); - Assert.NotNull(members); + var members = await + _gitHub.Organization.Member.GetAll(_organizationFixture); + Assert.NotEmpty(members); + } + + [IntegrationTest] + public async Task ReturnsCorrectCountOfMembersWithoutStart() + { + var options = new ApiOptions + { + PageCount = 1, + PageSize = 1 + }; + + var members = await _gitHub.Organization.Member.GetAll(_organizationFixture, options); + + Assert.Equal(1, members.Count); + } + + [IntegrationTest] + public async Task ReturnsCorrectCountOfMembersWithStart() + { + var options = new ApiOptions + { + PageCount = 1, + PageSize = 1, + StartPage = 1 + }; + + var members = await _gitHub.Organization.Member.GetAll(_organizationFixture, options); + + Assert.Equal(1, members.Count); + } + + [IntegrationTest] + public async Task ReturnsDistinctMembersBasedOnStartPage() + { + var startOptions = new ApiOptions + { + PageCount = 1, + PageSize = 1, + StartPage = 1 + }; + + var firstPage = await _gitHub.Organization.Member.GetAll(_organizationFixture, startOptions); + + var skipStartOptions = new ApiOptions + { + PageSize = 1, + PageCount = 1, + StartPage = 2 + }; + + var secondPage = await _gitHub.Organization.Member.GetAll(_organizationFixture, skipStartOptions); + + Assert.Equal(1, firstPage.Count); + Assert.Equal(1, secondPage.Count); + Assert.NotEqual(firstPage.First().Id, secondPage.First().Id); } [IntegrationTest(Skip = "TwoFactor filter can't be used unless the requester is an organization owner")] diff --git a/Octokit.Tests/Clients/OrganizationMembersClientTests.cs b/Octokit.Tests/Clients/OrganizationMembersClientTests.cs index 4bf1b353..bcd2ec4f 100644 --- a/Octokit.Tests/Clients/OrganizationMembersClientTests.cs +++ b/Octokit.Tests/Clients/OrganizationMembersClientTests.cs @@ -33,16 +33,51 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org"); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members"), Args.ApiOptions); + } + + [Fact] + public void RequestsTheCorrectUrlWithApiOptions() + { + var client = Substitute.For(); + var orgMembersClient = new OrganizationMembersClient(client); + + var options = new ApiOptions + { + PageCount = 1, + StartPage = 1, + PageSize = 1 + }; + + orgMembersClient.GetAll("org", options); + + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members"), options); } [Fact] public async Task EnsureNonNullArguments() { - var orgMembers = new OrganizationMembersClient(Substitute.For()); + var client = new OrganizationMembersClient(Substitute.For()); - await Assert.ThrowsAsync(() => orgMembers.GetAll(null)); - await Assert.ThrowsAsync(() => orgMembers.GetAll("")); + await Assert.ThrowsAsync(() => client.GetAll(null)); + + await Assert.ThrowsAsync(() => client.GetAll(null, ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAll("org", null)); + + await Assert.ThrowsAsync(() => client.GetAll(null, OrganizationMembersFilter.All)); + await Assert.ThrowsAsync(() => client.GetAll(null, OrganizationMembersFilter.All, ApiOptions.None)); + + await Assert.ThrowsAsync(() => client.GetAll("org", OrganizationMembersFilter.All, null)); + await Assert.ThrowsAsync(() => client.GetAll(null, OrganizationMembersFilter.All, OrganizationMembersRole.Admin)); + + await Assert.ThrowsAsync(() => client.GetAll(null, OrganizationMembersFilter.All, OrganizationMembersRole.Admin, ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAll("org", OrganizationMembersFilter.All, OrganizationMembersRole.Admin, null)); + + await Assert.ThrowsAsync(() => client.GetAll("")); + await Assert.ThrowsAsync(() => client.GetAll("", ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAll("", OrganizationMembersFilter.All)); + await Assert.ThrowsAsync(() => client.GetAll("", OrganizationMembersFilter.All, OrganizationMembersRole.Admin)); + await Assert.ThrowsAsync(() => client.GetAll("", OrganizationMembersFilter.All, OrganizationMembersRole.Admin, ApiOptions.None)); } [Fact] @@ -53,7 +88,7 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org", OrganizationMembersFilter.All); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=all")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=all"), Args.ApiOptions); } [Fact] @@ -64,7 +99,25 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=2fa_disabled")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=2fa_disabled"), Args.ApiOptions); + } + + [Fact] + public void TwoFactorFilterRequestTheCorrectUrlWithApiOptions() + { + var client = Substitute.For(); + var orgMembersClient = new OrganizationMembersClient(client); + + var options = new ApiOptions + { + PageCount = 1, + StartPage = 1, + PageSize = 1 + }; + + orgMembersClient.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled, options); + + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=2fa_disabled"), options); } [Fact] @@ -75,7 +128,7 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org", OrganizationMembersRole.All); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?role=all")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?role=all"), Args.ApiOptions); } [Fact] @@ -86,7 +139,7 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org", OrganizationMembersRole.Admin); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?role=admin")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?role=admin"), Args.ApiOptions); } [Fact] @@ -97,7 +150,25 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org", OrganizationMembersRole.Member); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?role=member")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?role=member"), Args.ApiOptions); + } + + [Fact] + public void MemberRoleFilterRequestTheCorrectUrlWithApiOptions() + { + var client = Substitute.For(); + var orgMembersClient = new OrganizationMembersClient(client); + + var options = new ApiOptions + { + PageCount = 1, + StartPage = 1, + PageSize = 1 + }; + + orgMembersClient.GetAll("org", OrganizationMembersRole.Member, options); + + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?role=member"), options); } [Fact] @@ -108,7 +179,7 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org", OrganizationMembersFilter.All, OrganizationMembersRole.All); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=all&role=all")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=all&role=all"), Args.ApiOptions); } [Fact] @@ -119,7 +190,7 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org", OrganizationMembersFilter.All, OrganizationMembersRole.Admin); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=all&role=admin")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=all&role=admin"), Args.ApiOptions); } [Fact] @@ -130,7 +201,7 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org", OrganizationMembersFilter.All, OrganizationMembersRole.Member); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=all&role=member")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=all&role=member"), Args.ApiOptions); } [Fact] @@ -141,7 +212,7 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled, OrganizationMembersRole.All); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=2fa_disabled&role=all")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=2fa_disabled&role=all"), Args.ApiOptions); } [Fact] @@ -152,7 +223,7 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled, OrganizationMembersRole.Admin); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=2fa_disabled&role=admin")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=2fa_disabled&role=admin"), Args.ApiOptions); } [Fact] @@ -163,30 +234,70 @@ namespace Octokit.Tests.Clients orgMembersClient.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled, OrganizationMembersRole.Member); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=2fa_disabled&role=member")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=2fa_disabled&role=member"), Args.ApiOptions); + } + + [Fact] + public void TwoFactorFilterPlusMemberRoleRequestTheCorrectUrlWithApiOptions() + { + var client = Substitute.For(); + var orgMembersClient = new OrganizationMembersClient(client); + + var options = new ApiOptions + { + PageCount = 1, + StartPage = 1, + PageSize = 1 + }; + + orgMembersClient.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled, OrganizationMembersRole.Member, options); + + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/members?filter=2fa_disabled&role=member"), options); } } public class TheGetPublicMethod { [Fact] - public void RequestsTheCorrectUrl() + public async Task RequestsTheCorrectUrl() { var client = Substitute.For(); var orgMembers = new OrganizationMembersClient(client); - orgMembers.GetAllPublic("org"); + await orgMembers.GetAllPublic("org"); - client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/public_members")); + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/public_members"), Args.ApiOptions); + } + + [Fact] + public async Task RequestsTheCorrectUrlWithApiOptions() + { + var client = Substitute.For(); + var orgMembers = new OrganizationMembersClient(client); + + var options = new ApiOptions + { + PageCount = 1, + StartPage = 1, + PageSize = 1 + }; + + await orgMembers.GetAllPublic("org", options); + + client.Received().GetAll(Arg.Is(u => u.ToString() == "orgs/org/public_members"), options); } [Fact] public async Task EnsureNonNullArguments() { - var orgMembers = new OrganizationMembersClient(Substitute.For()); + var client = new OrganizationMembersClient(Substitute.For()); - await Assert.ThrowsAsync(() => orgMembers.GetAllPublic(null)); - await Assert.ThrowsAsync(() => orgMembers.GetAllPublic("")); + await Assert.ThrowsAsync(() => client.GetAllPublic(null)); + await Assert.ThrowsAsync(() => client.GetAllPublic(null, ApiOptions.None)); + await Assert.ThrowsAsync(() => client.GetAllPublic("org", null)); + + await Assert.ThrowsAsync(() => client.GetAllPublic("")); + await Assert.ThrowsAsync(() => client.GetAllPublic("", ApiOptions.None)); } } diff --git a/Octokit.Tests/Reactive/ObservableOrganizationMembersClientTests.cs b/Octokit.Tests/Reactive/ObservableOrganizationMembersClientTests.cs index 92941de0..6f4dc49c 100644 --- a/Octokit.Tests/Reactive/ObservableOrganizationMembersClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableOrganizationMembersClientTests.cs @@ -31,7 +31,26 @@ namespace Octokit.Tests.Reactive client.GetAll("org"); gitHubClient.Connection.Received(1).Get>( - new Uri("orgs/org/members", UriKind.Relative), null, null); + new Uri("orgs/org/members", UriKind.Relative), Args.EmptyDictionary, null); + } + + [Fact] + public void RequestsCorrectUrlWithApiOptions() + { + var gitHubClient = Substitute.For(); + var client = new ObservableOrganizationMembersClient(gitHubClient); + + var options = new ApiOptions + { + PageCount = 1, + StartPage = 1, + PageSize = 1 + }; + + client.GetAll("org", options); + + gitHubClient.Connection.Received(1).Get>( + new Uri("orgs/org/members", UriKind.Relative), Arg.Is>(d => d.Count == 2), null); } [Fact] @@ -39,8 +58,80 @@ namespace Octokit.Tests.Reactive { var client = new ObservableOrganizationMembersClient(Substitute.For()); - await Assert.ThrowsAsync(() => client.GetAll(null).ToTask()); - await Assert.ThrowsAsync(() => client.GetAll("").ToTask()); + Assert.Throws(() => client.GetAll(null)); + + Assert.Throws(() => client.GetAll(null, ApiOptions.None)); + Assert.Throws(() => client.GetAll("org", null)); + + Assert.Throws(() => client.GetAll(null, OrganizationMembersFilter.All)); + Assert.Throws(() => client.GetAll(null, OrganizationMembersFilter.All, ApiOptions.None)); + + Assert.Throws(() => client.GetAll("org", OrganizationMembersFilter.All, null)); + Assert.Throws(() => client.GetAll(null, OrganizationMembersFilter.All, OrganizationMembersRole.Admin)); + + Assert.Throws(() => client.GetAll(null, OrganizationMembersFilter.All, OrganizationMembersRole.Admin, ApiOptions.None)); + Assert.Throws(() => client.GetAll("org", OrganizationMembersFilter.All, OrganizationMembersRole.Admin, null)); + + Assert.Throws(() => client.GetAll("")); + Assert.Throws(() => client.GetAll("", ApiOptions.None)); + Assert.Throws(() => client.GetAll("", OrganizationMembersFilter.All)); + Assert.Throws(() => client.GetAll("", OrganizationMembersFilter.All, OrganizationMembersRole.Admin)); + Assert.Throws(() => client.GetAll("", OrganizationMembersFilter.All, OrganizationMembersRole.Admin, ApiOptions.None)); + } + + [Fact] + public void TwoFactorFilterRequestTheCorrectUrlWithApiOptions() + { + var client = Substitute.For(); + var orgMembersClient = new ObservableOrganizationMembersClient(client); + + var options = new ApiOptions + { + PageCount = 1, + StartPage = 1, + PageSize = 1 + }; + + orgMembersClient.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled, options); + + client.Connection.Received(1).Get>( + new Uri("orgs/org/members?filter=2fa_disabled", UriKind.Relative), Arg.Is>(d => d.Count == 2), null); + } + + [Fact] + public void MemberRoleFilterRequestTheCorrectUrlWithApiOptions() + { + var client = Substitute.For(); + var orgMembersClient = new ObservableOrganizationMembersClient(client); + + var options = new ApiOptions + { + PageCount = 1, + StartPage = 1, + PageSize = 1 + }; + + orgMembersClient.GetAll("org", OrganizationMembersRole.Member, options); + + client.Connection.Received().Get>(Arg.Is(u => u.ToString() == "orgs/org/members?role=member"), Arg.Is>(d => d.Count == 2), null); + } + + [Fact] + public void TwoFactorFilterPlusMemberRoleRequestTheCorrectUrlWithApiOptions() + { + var client = Substitute.For(); + var orgMembersClient = new ObservableOrganizationMembersClient(client); + + var options = new ApiOptions + { + PageCount = 1, + StartPage = 1, + PageSize = 1 + }; + + orgMembersClient.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled, OrganizationMembersRole.Member, options); + + client.Connection.Received().Get>(Arg.Is(u => u.ToString() == "orgs/org/members?filter=2fa_disabled&role=member"), Arg.Is>(d => d.Count == 2), null); } } @@ -55,7 +146,26 @@ namespace Octokit.Tests.Reactive client.GetAllPublic("org"); gitHubClient.Connection.Received(1).Get>( - new Uri("orgs/org/public_members", UriKind.Relative), null, null); + new Uri("orgs/org/public_members", UriKind.Relative), Args.EmptyDictionary, null); + } + + [Fact] + public void RequestsTheCorrectUrlWithApiOptions() + { + var gitHubClient = Substitute.For(); + var client = new ObservableOrganizationMembersClient(gitHubClient); + + var options = new ApiOptions + { + PageCount = 1, + StartPage = 1, + PageSize = 1 + }; + + client.GetAllPublic("org", options); + + gitHubClient.Connection.Received(1).Get>( + new Uri("orgs/org/public_members", UriKind.Relative), Arg.Is>(d => d.Count == 2), null); } [Fact] @@ -63,8 +173,12 @@ namespace Octokit.Tests.Reactive { var client = new ObservableOrganizationMembersClient(Substitute.For()); - await Assert.ThrowsAsync(() => client.GetAllPublic(null).ToTask()); - await Assert.ThrowsAsync(() => client.GetAllPublic("").ToTask()); + Assert.Throws(() => client.GetAllPublic(null)); + Assert.Throws(() => client.GetAllPublic(null, ApiOptions.None)); + Assert.Throws(() => client.GetAllPublic("org", null)); + + Assert.Throws(() => client.GetAllPublic("")); + Assert.Throws(() => client.GetAllPublic("", ApiOptions.None)); } } diff --git a/Octokit/Clients/IOrganizationMembersClient.cs b/Octokit/Clients/IOrganizationMembersClient.cs index 61c7144b..c72f5bba 100644 --- a/Octokit/Clients/IOrganizationMembersClient.cs +++ b/Octokit/Clients/IOrganizationMembersClient.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading.Tasks; namespace Octokit @@ -34,6 +33,29 @@ namespace Octokit /// The users Task> GetAll(string org); + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// Options for changing the API response + /// The users + Task> GetAll(string org, ApiOptions options); + /// /// /// List all users who are members of an organization. A member is a user that @@ -57,6 +79,30 @@ namespace Octokit /// The users Task> GetAll(string org, OrganizationMembersFilter filter); + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The filter to use when getting the users, + /// Options for changing the API response + /// The users + Task> GetAll(string org, OrganizationMembersFilter filter, ApiOptions options); + /// /// /// List all users who are members of an organization. A member is a user that @@ -80,6 +126,30 @@ namespace Octokit /// The users Task> GetAll(string org, OrganizationMembersRole role); + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The role filter to use when getting the users, + /// Options for changing the API response + /// The users + Task> GetAll(string org, OrganizationMembersRole role, ApiOptions options); + /// /// /// List all users who are members of an organization. A member is a user that @@ -104,6 +174,31 @@ namespace Octokit /// The users Task> GetAll(string org, OrganizationMembersFilter filter, OrganizationMembersRole role); + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The filter to use when getting the users, + /// The role filter to use when getting the users, + /// Options for changing the API response + /// The users + Task> GetAll(string org, OrganizationMembersFilter filter, OrganizationMembersRole role, ApiOptions options); + /// /// List all users who have publicized their membership of the organization. /// @@ -112,6 +207,15 @@ namespace Octokit /// Task> GetAllPublic(string org); + /// + /// List all users who have publicized their membership of the organization. + /// + /// http://developer.github.com/v3/orgs/members/#public-members-list + /// The login for the organization + /// Options for changing the API response + /// + Task> GetAllPublic(string org, ApiOptions options); + /// /// Check if a user is, publicly or privately, a member of the organization. /// diff --git a/Octokit/Clients/OrganizationMembersClient.cs b/Octokit/Clients/OrganizationMembersClient.cs index ed6cadc5..5462c0a9 100644 --- a/Octokit/Clients/OrganizationMembersClient.cs +++ b/Octokit/Clients/OrganizationMembersClient.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Net; using System.Threading.Tasks; using Octokit.Internal; @@ -78,7 +77,36 @@ namespace Octokit { Ensure.ArgumentNotNullOrEmptyString(org, "org"); - return ApiConnection.GetAll(ApiUrls.Members(org)); + return GetAll(org, ApiOptions.None); + } + + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// Options for changing the API response + /// The users + public Task> GetAll(string org, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(org, "org"); + Ensure.ArgumentNotNull(options, "options"); + + return ApiConnection.GetAll(ApiUrls.Members(org), options); } /// @@ -106,7 +134,37 @@ namespace Octokit { Ensure.ArgumentNotNullOrEmptyString(org, "org"); - return ApiConnection.GetAll(ApiUrls.Members(org, filter)); + return GetAll(org, filter, ApiOptions.None); + } + + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The filter to use when getting the users, + /// Options for changing the API response + /// The users + public Task> GetAll(string org, OrganizationMembersFilter filter, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(org, "org"); + Ensure.ArgumentNotNull(options, "options"); + + return ApiConnection.GetAll(ApiUrls.Members(org, filter), options); } /// @@ -134,7 +192,37 @@ namespace Octokit { Ensure.ArgumentNotNullOrEmptyString(org, "org"); - return ApiConnection.GetAll(ApiUrls.Members(org, role)); + return GetAll(org, role, ApiOptions.None); + } + + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The role filter to use when getting the users, + /// Options for changing the API response + /// The users + public Task> GetAll(string org, OrganizationMembersRole role, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(org, "org"); + Ensure.ArgumentNotNull(options, "options"); + + return ApiConnection.GetAll(ApiUrls.Members(org, role), options); } /// @@ -163,7 +251,38 @@ namespace Octokit { Ensure.ArgumentNotNullOrEmptyString(org, "org"); - return ApiConnection.GetAll(ApiUrls.Members(org, filter, role)); + return GetAll(org, filter, role, ApiOptions.None); + } + + /// + /// + /// List all users who are members of an organization. A member is a user that + /// belongs to at least 1 team in the organization. + /// + /// + /// If the authenticated user is also an owner of this organization then both + /// concealed and public member will be returned. + /// + /// + /// If the requester is not an owner of the organization the query will be redirected + /// to the public members list. + /// + /// + /// + /// See the API documentation + /// for more information. + /// + /// The login for the organization + /// The filter to use when getting the users, + /// The role filter to use when getting the users, + /// Options for changing the API response + /// The users + public Task> GetAll(string org, OrganizationMembersFilter filter, OrganizationMembersRole role, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(org, "org"); + Ensure.ArgumentNotNull(options, "options"); + + return ApiConnection.GetAll(ApiUrls.Members(org, filter, role), options); } /// @@ -176,7 +295,22 @@ namespace Octokit { Ensure.ArgumentNotNullOrEmptyString(org, "org"); - return ApiConnection.GetAll(ApiUrls.PublicMembers(org)); + return GetAllPublic(org, ApiOptions.None); + } + + /// + /// List all users who have publicized their membership of the organization. + /// + /// http://developer.github.com/v3/orgs/members/#public-members-list + /// The login for the organization + /// Options for changing the API response + /// + public Task> GetAllPublic(string org, ApiOptions options) + { + Ensure.ArgumentNotNullOrEmptyString(org, "org"); + Ensure.ArgumentNotNull(options, "options"); + + return ApiConnection.GetAll(ApiUrls.PublicMembers(org), options); } ///