Skip to content

Commit

Permalink
Merge pull request #1072 from TattsGroup/add-member-role-filter
Browse files Browse the repository at this point in the history
Add member role filter to OrganizationMembersClient.GetAll() functions
  • Loading branch information
shiftkey committed Jan 31, 2016
2 parents 59df91d + d760124 commit 829677c
Show file tree
Hide file tree
Showing 8 changed files with 415 additions and 0 deletions.
47 changes: 47 additions & 0 deletions Octokit.Reactive/Clients/IObservableOrganizationMembersClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,53 @@ public interface IObservableOrganizationMembersClient
[Obsolete("No longer supported, use GetAll(string, OrganizationMembersFilter) instead")]
IObservable<User> GetAll(string org, string filter);

/// <summary>
/// <para>
/// List all users who are members of an organization. A member is a user that
/// belongs to at least 1 team in the organization.
/// </para>
/// <para>
/// If the authenticated user is also an owner of this organization then both
/// concealed and public member will be returned.
/// </para>
/// <para>
/// If the requester is not an owner of the organization the query will be redirected
/// to the public members list.
/// </para>
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/orgs/members/#members-list">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="role">The role filter to use when getting the users, <see cref="OrganizationMembersRole"/></param>
/// <returns></returns>
IObservable<User> GetAll(string org, OrganizationMembersRole role);

/// <summary>
/// <para>
/// List all users who are members of an organization. A member is a user that
/// belongs to at least 1 team in the organization.
/// </para>
/// <para>
/// If the authenticated user is also an owner of this organization then both
/// concealed and public member will be returned.
/// </para>
/// <para>
/// If the requester is not an owner of the organization the query will be redirected
/// to the public members list.
/// </para>
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/orgs/members/#members-list">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="filter">The members filter, <see cref="OrganizationMembersFilter"/> </param>
/// <param name="role">The role filter to use when getting the users, <see cref="OrganizationMembersRole"/></param>
/// <returns></returns>
IObservable<User> GetAll(string org, OrganizationMembersFilter filter, OrganizationMembersRole role);

/// <summary>
/// List all users who have publicized their membership of the organization.
/// </summary>
Expand Down
57 changes: 57 additions & 0 deletions Octokit.Reactive/Clients/ObservableOrganizationMembersClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,63 @@ public IObservable<User> GetAll(string org, string filter)
return _connection.GetAndFlattenAllPages<User>(ApiUrls.Members(org, filter));
}

/// <summary>
/// <para>
/// List all users who are members of an organization. A member is a user that
/// belongs to at least 1 team in the organization.
/// </para>
/// <para>
/// If the authenticated user is also an owner of this organization then both
/// concealed and public member will be returned.
/// </para>
/// <para>
/// If the requester is not an owner of the organization the query will be redirected
/// to the public members list.
/// </para>
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/orgs/members/#members-list">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="role">The role filter to use when getting the users, <see cref="OrganizationMembersRole"/></param>
/// <returns></returns>
public IObservable<User> GetAll(string org, OrganizationMembersRole role)
{
Ensure.ArgumentNotNullOrEmptyString(org, "org");

return _connection.GetAndFlattenAllPages<User>(ApiUrls.Members(org, role));
}

/// <summary>
/// <para>
/// List all users who are members of an organization. A member is a user that
/// belongs to at least 1 team in the organization.
/// </para>
/// <para>
/// If the authenticated user is also an owner of this organization then both
/// concealed and public member will be returned.
/// </para>
/// <para>
/// If the requester is not an owner of the organization the query will be redirected
/// to the public members list.
/// </para>
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/orgs/members/#members-list">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="filter">The members filter, <see cref="OrganizationMembersFilter"/> </param>
/// <param name="role">The role filter to use when getting the users, <see cref="OrganizationMembersRole"/></param>
/// <returns></returns>
public IObservable<User> GetAll(string org, OrganizationMembersFilter filter, OrganizationMembersRole role)
{
Ensure.ArgumentNotNullOrEmptyString(org, "org");

return _connection.GetAndFlattenAllPages<User>(ApiUrls.Members(org, filter, role));
}

/// <summary>
/// List all users who have publicized their membership of the organization.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Octokit;
using Octokit.Tests.Integration;
using Octokit.Tests.Integration.Helpers;
using Xunit;

namespace Octokit.Tests.Integration.Clients
{
public class OrganizationMembersClientTests
{
public class TheGetAllMethod
{
private IGitHubClient _gitHub;
private string _organizationFixture;

public TheGetAllMethod()
{
_gitHub = Helper.GetAuthenticatedClient();
_organizationFixture = "octokit";
}

[IntegrationTest]
public async Task ReturnsMembers()
{
var members = _gitHub.Organization.Member.GetAll(_organizationFixture);
Assert.NotNull(members);
}

[IntegrationTest(Skip = "TwoFactor filter can't be used unless the requester is an organization owner")]
public async Task ReturnsMembersWithFilter()
{
var no2FAMembers = await _gitHub.Organization.Member.GetAll(_organizationFixture, OrganizationMembersFilter.TwoFactorAuthenticationDisabled);
Assert.NotNull(no2FAMembers);
}

[IntegrationTest(Skip = "Admin/Member filter doesn't work unless the requester is an organization member")]
public async Task ReturnsMembersWithRole()
{
var adminMembers = await _gitHub.Organization.Member.GetAll(_organizationFixture, OrganizationMembersRole.Admin);
Assert.NotNull(adminMembers);

var normalMembers = await _gitHub.Organization.Member.GetAll(_organizationFixture, OrganizationMembersRole.Member);
Assert.NotNull(normalMembers);

// There shouldnt be any members that are in both groups if the role filter works correctly
var membersInBoth = adminMembers.Select(a => a.Id).Intersect(normalMembers.Select(n => n.Id));
Assert.True(membersInBoth.Count() == 0);
}

[IntegrationTest(Skip = "TwoFactor filter can't be used unless the requester is an organization owner")]
public async Task ReturnsMembersWthFilterAndRole()
{
// Get count of admin/normal members
var adminCount = (await _gitHub.Organization.Member.GetAll(_organizationFixture, OrganizationMembersRole.Admin)).Count;
var memberCount = (await _gitHub.Organization.Member.GetAll(_organizationFixture, OrganizationMembersRole.Member)).Count;

// Ensure that there are less admins with no 2 factor, than there are total admins
var adminsWithNo2FA = await _gitHub.Organization.Member.GetAll(_organizationFixture, OrganizationMembersFilter.TwoFactorAuthenticationDisabled, OrganizationMembersRole.Admin);
Assert.NotNull(adminsWithNo2FA);
Assert.True(adminsWithNo2FA.Count <= adminCount);

// Ensure that there are less members with no 2 factor, than there are total admins
var membersWithNo2FA = await _gitHub.Organization.Member.GetAll(_organizationFixture, OrganizationMembersFilter.TwoFactorAuthenticationDisabled, OrganizationMembersRole.Member);
Assert.NotNull(membersWithNo2FA);
Assert.True(membersWithNo2FA.Count <= memberCount);
}
}
}
}
1 change: 1 addition & 0 deletions Octokit.Tests.Integration/Octokit.Tests.Integration.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
<Compile Include="Clients\GistsClientTests.cs" />
<Compile Include="Clients\IssuesEventsClientTests.cs" />
<Compile Include="Clients\MilestonesClientTests.cs" />
<Compile Include="Clients\OrganizationMembersClientTests.cs" />
<Compile Include="Clients\PullRequestsClientTests.cs" />
<Compile Include="Clients\ReferencesClientTests.cs" />
<Compile Include="Clients\RepositoryCommitsClientTests.cs" />
Expand Down
99 changes: 99 additions & 0 deletions Octokit.Tests/Clients/OrganizationMembersClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,105 @@ public void TwoFactorFilterRequestTheCorrectUrl()

client.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/members?filter=2fa_disabled"));
}

[Fact]
public void AllRoleFilterRequestTheCorrectUrl()
{
var client = Substitute.For<IApiConnection>();
var orgMembersClient = new OrganizationMembersClient(client);

orgMembersClient.GetAll("org", OrganizationMembersRole.All);

client.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/members?role=all"));
}

[Fact]
public void AdminRoleFilterRequestTheCorrectUrl()
{
var client = Substitute.For<IApiConnection>();
var orgMembersClient = new OrganizationMembersClient(client);

orgMembersClient.GetAll("org", OrganizationMembersRole.Admin);

client.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/members?role=admin"));
}

[Fact]
public void MemberRoleFilterRequestTheCorrectUrl()
{
var client = Substitute.For<IApiConnection>();
var orgMembersClient = new OrganizationMembersClient(client);

orgMembersClient.GetAll("org", OrganizationMembersRole.Member);

client.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/members?role=member"));
}

[Fact]
public void AllFilterPlusAllRoleFilterRequestTheCorrectUrl()
{
var client = Substitute.For<IApiConnection>();
var orgMembersClient = new OrganizationMembersClient(client);

orgMembersClient.GetAll("org", OrganizationMembersFilter.All, OrganizationMembersRole.All);

client.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/members?filter=all&role=all"));
}

[Fact]
public void AllFilterPlusAdminRoleFilterRequestTheCorrectUrl()
{
var client = Substitute.For<IApiConnection>();
var orgMembersClient = new OrganizationMembersClient(client);

orgMembersClient.GetAll("org", OrganizationMembersFilter.All, OrganizationMembersRole.Admin);

client.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/members?filter=all&role=admin"));
}

[Fact]
public void AllFilterPlusMemberRoleFilterRequestTheCorrectUrl()
{
var client = Substitute.For<IApiConnection>();
var orgMembersClient = new OrganizationMembersClient(client);

orgMembersClient.GetAll("org", OrganizationMembersFilter.All, OrganizationMembersRole.Member);

client.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/members?filter=all&role=member"));
}

[Fact]
public void TwoFactorFilterPlusAllRoleRequestTheCorrectUrl()
{
var client = Substitute.For<IApiConnection>();
var orgMembersClient = new OrganizationMembersClient(client);

orgMembersClient.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled, OrganizationMembersRole.All);

client.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/members?filter=2fa_disabled&role=all"));
}

[Fact]
public void TwoFactorFilterPlusAdminRoleRequestTheCorrectUrl()
{
var client = Substitute.For<IApiConnection>();
var orgMembersClient = new OrganizationMembersClient(client);

orgMembersClient.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled, OrganizationMembersRole.Admin);

client.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/members?filter=2fa_disabled&role=admin"));
}

[Fact]
public void TwoFactorFilterPlusMemberRoleRequestTheCorrectUrl()
{
var client = Substitute.For<IApiConnection>();
var orgMembersClient = new OrganizationMembersClient(client);

orgMembersClient.GetAll("org", OrganizationMembersFilter.TwoFactorAuthenticationDisabled, OrganizationMembersRole.Member);

client.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/members?filter=2fa_disabled&role=member"));
}
}

public class TheGetPublicMethod
Expand Down
47 changes: 47 additions & 0 deletions Octokit/Clients/IOrganizationMembersClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,53 @@ public interface IOrganizationMembersClient
[Obsolete("No longer supported, use GetAll(string, OrganizationMembersFilter) instead")]
Task<IReadOnlyList<User>> GetAll(string org, string filter);

/// <summary>
/// <para>
/// List all users who are members of an organization. A member is a user that
/// belongs to at least 1 team in the organization.
/// </para>
/// <para>
/// If the authenticated user is also an owner of this organization then both
/// concealed and public member will be returned.
/// </para>
/// <para>
/// If the requester is not an owner of the organization the query will be redirected
/// to the public members list.
/// </para>
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/orgs/members/#members-list">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="role">The role filter to use when getting the users, <see cref="OrganizationMembersRole"/></param>
/// <returns>The users</returns>
Task<IReadOnlyList<User>> GetAll(string org, OrganizationMembersRole role);

/// <summary>
/// <para>
/// List all users who are members of an organization. A member is a user that
/// belongs to at least 1 team in the organization.
/// </para>
/// <para>
/// If the authenticated user is also an owner of this organization then both
/// concealed and public member will be returned.
/// </para>
/// <para>
/// If the requester is not an owner of the organization the query will be redirected
/// to the public members list.
/// </para>
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/orgs/members/#members-list">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="filter">The filter to use when getting the users, <see cref="OrganizationMembersFilter"/></param>
/// <param name="role">The role filter to use when getting the users, <see cref="OrganizationMembersRole"/></param>
/// <returns>The users</returns>
Task<IReadOnlyList<User>> GetAll(string org, OrganizationMembersFilter filter, OrganizationMembersRole role);

/// <summary>
/// List all users who have publicized their membership of the organization.
/// </summary>
Expand Down
Loading

0 comments on commit 829677c

Please sign in to comment.