Skip to content

Commit

Permalink
Add get/update/delete methods for organization memberships (#2014)
Browse files Browse the repository at this point in the history
  • Loading branch information
hnrkndrssn authored and shiftkey committed Oct 21, 2019
1 parent 9081295 commit 8b263cd
Show file tree
Hide file tree
Showing 11 changed files with 587 additions and 2 deletions.
44 changes: 44 additions & 0 deletions Octokit.Reactive/Clients/IObservableOrganizationMembersClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,50 @@ public interface IObservableOrganizationMembersClient
/// <param name="user">The login for the user</param>
/// <returns></returns>
IObservable<Unit> Conceal(string org, string user);

/// <summary>
/// Get a user's membership with an organization.
/// </summary>
/// <remarks>
/// This method requires authentication.
/// The authenticated user must be an organization member.
/// See the <a href="https://developer.github.com/v3/orgs/members/#get-organization-membership">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="user">The login for the user</param>
/// <returns></returns>
IObservable<OrganizationMembership> GetOrganizationMembership(string org, string user);

/// <summary>
/// Add a user to the organization or update the user's role withing the organization.
/// </summary>
/// <remarks>
/// This method requires authentication.
/// The authenticated user must be an organization owner.
/// See the <a href="https://developer.github.com/v3/orgs/members/#add-or-update-organization-membership">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="user">The login for the user</param>
/// <param name="addOrUpdateRequest">An <see cref="OrganizationMembershipUpdate"/> instance describing the
/// changes to make to the user's organization membership</param>
/// <returns></returns>
IObservable<OrganizationMembership> AddOrUpdateOrganizationMembership(string org, string user, OrganizationMembershipUpdate addOrUpdateRequest);

/// <summary>
/// Remove a user's membership with an organization.
/// </summary>
/// <remarks>
/// This method requires authentication.
/// The authenticated user must be an organization owner.
/// See the <a href="https://developer.github.com/v3/orgs/members/#remove-organization-membership">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="user">The login for the user</param>
/// <returns></returns>
IObservable<Unit> RemoveOrganizationMembership(string org, string user);

/// <summary>
/// List all pending invitations for the organization.
Expand Down
63 changes: 63 additions & 0 deletions Octokit.Reactive/Clients/ObservableOrganizationMembersClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,69 @@ public IObservable<Unit> Conceal(string org, string user)
return _client.Conceal(org, user).ToObservable();
}

/// <summary>
/// Get a user's membership with an organization.
/// </summary>
/// <remarks>
/// This method requires authentication.
/// The authenticated user must be an organization member.
/// See the <a href="https://developer.github.com/v3/orgs/members/#get-organization-membership">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="user">The login for the user</param>
/// <returns></returns>
public IObservable<OrganizationMembership> GetOrganizationMembership(string org, string user)
{
Ensure.ArgumentNotNullOrEmptyString(org, nameof(org));
Ensure.ArgumentNotNullOrEmptyString(user, nameof(user));

return _client.GetOrganizationMembership(org, user).ToObservable();
}

/// <summary>
/// Add a user to the organization or update the user's role withing the organization.
/// </summary>
/// <remarks>
/// This method requires authentication.
/// The authenticated user must be an organization owner.
/// See the <a href="https://developer.github.com/v3/orgs/members/#add-or-update-organization-membership">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="user">The login for the user</param>
/// <param name="addOrUpdateRequest">An <see cref="OrganizationMembershipUpdate"/> instance describing the
/// changes to make to the user's organization membership</param>
/// <returns></returns>
public IObservable<OrganizationMembership> AddOrUpdateOrganizationMembership(string org, string user, OrganizationMembershipUpdate addOrUpdateRequest)
{
Ensure.ArgumentNotNullOrEmptyString(org, nameof(org));
Ensure.ArgumentNotNullOrEmptyString(user, nameof(user));
Ensure.ArgumentNotNull(addOrUpdateRequest, nameof(addOrUpdateRequest));

return _client.AddOrUpdateOrganizationMembership(org, user, addOrUpdateRequest).ToObservable();
}

/// <summary>
/// Remove a user's membership with an organization.
/// </summary>
/// <remarks>
/// This method requires authentication.
/// The authenticated user must be an organization owner.
/// See the <a href="https://developer.github.com/v3/orgs/members/#remove-organization-membership">API documentation</a>
/// for more information.
/// </remarks>
/// <param name="org">The login for the organization</param>
/// <param name="user">The login for the user</param>
/// <returns></returns>
public IObservable<Unit> RemoveOrganizationMembership(string org, string user)
{
Ensure.ArgumentNotNullOrEmptyString(org, nameof(org));
Ensure.ArgumentNotNullOrEmptyString(user, nameof(user));

return _client.RemoveOrganizationMembership(org, user).ToObservable();
}

/// <summary>
/// List all pending invitations for the organization.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,75 @@ public async Task ReturnsMembersWthFilterAndRole()
}
}

public class TheGetOrganizationMembershipMethod
{
readonly IGitHubClient _gitHub;

public TheGetOrganizationMembershipMethod()
{
_gitHub = Helper.GetAuthenticatedClient();
}

[OrganizationTest]
public async Task ReturnsUsersMembershipOrganizationMembership()
{
using (var teamContext = await _gitHub.CreateTeamContext(Helper.Organization, new NewTeam(Helper.MakeNameWithTimestamp("team"))))
{
teamContext.InviteMember("alfhenrik-test-2");

var organizationMemberhip = await _gitHub.Organization.Member.GetOrganizationMembership(Helper.Organization, "alfhenrik-test-2");
Assert.Equal(MembershipState.Pending, organizationMemberhip.State);
Assert.Equal(MembershipRole.Member, organizationMemberhip.Role);
}
}
}

public class TheAddOrUpdateOrganizationMembershipMethod
{
readonly IGitHubClient _gitHub;

public TheAddOrUpdateOrganizationMembershipMethod()
{
_gitHub = Helper.GetAuthenticatedClient();
}

[OrganizationTest]
public async Task ReturnsUsersPendingMemberOrganizationMembership()
{
var organizationMembership = await _gitHub.Organization.Member.AddOrUpdateOrganizationMembership(Helper.Organization, "alfhenrik-test-2", new OrganizationMembershipUpdate());
Assert.Equal(MembershipState.Pending, organizationMembership.State);
Assert.Equal(MembershipRole.Member, organizationMembership.Role);
await _gitHub.Organization.Member.RemoveOrganizationMembership(Helper.Organization, "alfhenrik-test-2");
}

[OrganizationTest]
public async Task ReturnsUsersPendingAdminOrganizationMembership()
{
var organizationMembership = await _gitHub.Organization.Member.AddOrUpdateOrganizationMembership(Helper.Organization, "alfhenrik-test-2", new OrganizationMembershipUpdate { Role = MembershipRole.Admin});
Assert.Equal(MembershipState.Pending, organizationMembership.State);
Assert.Equal(MembershipRole.Admin, organizationMembership.Role);
await _gitHub.Organization.Member.RemoveOrganizationMembership(Helper.Organization, "alfhenrik-test-2");
}
}

public class TheRemoveOrganizationMembershipMethod
{
readonly IGitHubClient _gitHub;

public TheRemoveOrganizationMembershipMethod()
{
_gitHub = Helper.GetAuthenticatedClient();
}

[OrganizationTest]
public async Task RemovesOrganizationMembership()
{
await _gitHub.Organization.Member.AddOrUpdateOrganizationMembership(Helper.Organization, "alfhenrik-test-2", new OrganizationMembershipUpdate());
await _gitHub.Organization.Member.RemoveOrganizationMembership(Helper.Organization, "alfhenrik-test-2");
await Assert.ThrowsAsync<NotFoundException>(() => _gitHub.Organization.Member.GetOrganizationMembership(Helper.Organization, "alfhenrik-test-2"));
}
}

public class TheGetAllPendingInvitationsMethod
{
readonly IGitHubClient _gitHub;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
using System.Threading.Tasks;
using Octokit.Reactive;
using Octokit.Tests.Integration.Helpers;
Expand All @@ -8,6 +9,78 @@ namespace Octokit.Tests.Integration.Reactive
{
public class ObservableOrganizationMembersClientTests
{
public class TheGetOrganizationMembershipMethod
{
readonly IGitHubClient _gitHub;
readonly ObservableOrganizationMembersClient _client;

public TheGetOrganizationMembershipMethod()
{
_gitHub = Helper.GetAuthenticatedClient();
_client = new ObservableOrganizationMembersClient(_gitHub);
}

[OrganizationTest]
public async Task ReturnsUsersMembershipOrganizationMembership()
{
using (var teamContext = await _gitHub.CreateTeamContext(Helper.Organization, new NewTeam(Helper.MakeNameWithTimestamp("team"))))
{
teamContext.InviteMember("alfhenrik-test-2");

var organizationMemberhip = await _client.GetOrganizationMembership(Helper.Organization, "alfhenrik-test-2");
Assert.Equal(MembershipState.Pending, organizationMemberhip.State);
Assert.Equal(MembershipRole.Member, organizationMemberhip.Role);
await _client.RemoveOrganizationMembership(Helper.Organization, "alfhenrik-test-2");
}
}
}

public class TheAddOrUpdateOrganizationMembershipMethod
{
readonly ObservableOrganizationMembersClient _client;

public TheAddOrUpdateOrganizationMembershipMethod()
{
_client = new ObservableOrganizationMembersClient(Helper.GetAuthenticatedClient());
}

[OrganizationTest]
public async Task ReturnsUsersPendingMemberOrganizationMembership()
{
var organizationMembership = await _client.AddOrUpdateOrganizationMembership(Helper.Organization, "alfhenrik-test-2", new OrganizationMembershipUpdate());
Assert.Equal(MembershipState.Pending, organizationMembership.State);
Assert.Equal(MembershipRole.Member, organizationMembership.Role);
await _client.RemoveOrganizationMembership(Helper.Organization, "alfhenrik-test-2");
}

[OrganizationTest]
public async Task ReturnsUsersPendingAdminOrganizationMembership()
{
var organizationMembership = await _client.AddOrUpdateOrganizationMembership(Helper.Organization, "alfhenrik-test-2", new OrganizationMembershipUpdate { Role = MembershipRole.Admin});
Assert.Equal(MembershipState.Pending, organizationMembership.State);
Assert.Equal(MembershipRole.Admin, organizationMembership.Role);
await _client.RemoveOrganizationMembership(Helper.Organization, "alfhenrik-test-2");
}
}

public class TheRemoveOrganizationMembershipMethod
{
readonly ObservableOrganizationMembersClient _client;

public TheRemoveOrganizationMembershipMethod()
{
_client = new ObservableOrganizationMembersClient(Helper.GetAuthenticatedClient());
}

[OrganizationTest]
public async Task RemovesOrganizationMembership()
{
await _client.AddOrUpdateOrganizationMembership(Helper.Organization, "alfhenrik-test-2", new OrganizationMembershipUpdate());
await _client.RemoveOrganizationMembership(Helper.Organization, "alfhenrik-test-2");
await Assert.ThrowsAsync<NotFoundException>(() => _client.GetOrganizationMembership(Helper.Organization, "alfhenrik-test-2").ToTask());
}
}

public class TheGetAllPendingInvitationsMethod
{
readonly IGitHubClient _gitHub;
Expand Down
79 changes: 79 additions & 0 deletions Octokit.Tests/Clients/OrganizationMembersClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,85 @@ public async Task EnsureNonNullArguments()
}
}

public class TheGetOrganizationMembershipMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new OrganizationMembersClient(connection);

client.GetOrganizationMembership("org", "username");

connection.Received().Get<OrganizationMembership>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/memberships/username"));
}

[Fact]
public async Task EnsureNonNullArguments()
{
var client = new OrganizationMembersClient(Substitute.For<IApiConnection>());

await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetOrganizationMembership(null, "username"));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetOrganizationMembership("", "username"));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetOrganizationMembership("org", null));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetOrganizationMembership("org", ""));
}
}

public class TheAddOrUpdateOrganizationMembershipMethod
{
[Fact]
public void PostsToTheCorrectUrl()
{
var orgMembershipUpdate = new OrganizationMembershipUpdate();

var connection = Substitute.For<IApiConnection>();
var client = new OrganizationMembersClient(connection);

client.AddOrUpdateOrganizationMembership("org", "username", orgMembershipUpdate);

connection.Received().Put<OrganizationMembership>(Arg.Is<Uri>(u => u.ToString() == "orgs/org/memberships/username"), Arg.Any<object>());
}

[Fact]
public async Task EnsureNonNullArguments()
{
var client = new OrganizationMembersClient(Substitute.For<IApiConnection>());
var orgMembershipUpdate = new OrganizationMembershipUpdate();

await Assert.ThrowsAsync<ArgumentNullException>(() => client.AddOrUpdateOrganizationMembership(null, "username", orgMembershipUpdate));
await Assert.ThrowsAsync<ArgumentException>(() => client.AddOrUpdateOrganizationMembership("", "username", orgMembershipUpdate));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.AddOrUpdateOrganizationMembership("org", null, orgMembershipUpdate));
await Assert.ThrowsAsync<ArgumentException>(() => client.AddOrUpdateOrganizationMembership("org", "", orgMembershipUpdate));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.AddOrUpdateOrganizationMembership("org", "username", null));
}
}

public class TheDeleteOrganizationMembershipMethod
{
[Fact]
public void PostsToTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new OrganizationMembersClient(connection);

client.RemoveOrganizationMembership("org", "username");

connection.Received().Delete(Arg.Is<Uri>(u => u.ToString() == "orgs/org/memberships/username"));
}

[Fact]
public async Task EnsureNonNullArguments()
{
var client = new OrganizationMembersClient(Substitute.For<IApiConnection>());

await Assert.ThrowsAsync<ArgumentNullException>(() => client.RemoveOrganizationMembership(null, "username"));
await Assert.ThrowsAsync<ArgumentException>(() => client.RemoveOrganizationMembership("", "username"));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.RemoveOrganizationMembership("org", null));
await Assert.ThrowsAsync<ArgumentException>(() => client.RemoveOrganizationMembership("org", ""));
}
}

public class TheGetAllPendingInvitationsMethod
{
[Fact]
Expand Down
Loading

0 comments on commit 8b263cd

Please sign in to comment.