diff --git a/Octokit.Reactive/Clients/IObservableTeamsClient.cs b/Octokit.Reactive/Clients/IObservableTeamsClient.cs
index a5555c60..d6f4f6b1 100644
--- a/Octokit.Reactive/Clients/IObservableTeamsClient.cs
+++ b/Octokit.Reactive/Clients/IObservableTeamsClient.cs
@@ -65,8 +65,6 @@ namespace Octokit.Reactive
/// https://developer.github.com/v3/orgs/teams/#list-team-members
///
/// The team identifier
- /// Thrown when a general API error occurs.
- /// A list of the team's member s.
IObservable GetAllMembers(int id);
///
@@ -77,10 +75,29 @@ namespace Octokit.Reactive
///
/// The team identifier
/// Options to change API behaviour.
- /// Thrown when a general API error occurs.
- /// A list of the team's member s.
IObservable GetAllMembers(int id, ApiOptions options);
+ ///
+ /// Returns all members with the specified role in the given team of the given role.
+ ///
+ ///
+ /// https://developer.github.com/v3/orgs/teams/#list-team-members
+ ///
+ /// The team identifier
+ /// The request filter
+ IObservable GetAllMembers(int id, TeamMembersRequest request);
+
+ ///
+ /// Returns all members with the specified role in the given team of the given role.
+ ///
+ ///
+ /// https://developer.github.com/v3/orgs/teams/#list-team-members
+ ///
+ /// The team identifier
+ /// The request filter
+ /// Options to change API behaviour.
+ IObservable GetAllMembers(int id, TeamMembersRequest request, ApiOptions options);
+
///
/// Returns newly created for the current org.
///
@@ -106,14 +123,24 @@ namespace Octokit.Reactive
/// Adds a to a .
///
///
- /// See the API documentation for more information.
+ /// See the API documentation for more information.
///
/// The team identifier.
/// The user to add to the team.
- /// Thrown if you attempt to add an organization to a team.
- /// A result indicating the membership status
+ [Obsolete("Please use AddOrEditMembership instead")]
IObservable AddMembership(int id, string login);
+ ///
+ /// Adds a to a .
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The team identifier.
+ /// The user to add to the team.
+ /// Additional parameters for the request
+ IObservable AddOrEditMembership(int id, string login, UpdateTeamMembership request);
+
///
/// Removes a from a .
///
@@ -131,9 +158,21 @@ namespace Octokit.Reactive
///
/// The team to check.
/// The user to check.
- /// A result indicating the membership status
+ [Obsolete("Please use GetMembershipDetails instead")]
IObservable GetMembership(int id, string login);
+ ///
+ /// Gets whether the user with the given
+ /// is a member of the team with the given .
+ /// A is thrown if the user is not a member.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The team to check.
+ /// The user to check.
+ IObservable GetMembershipDetails(int id, string login);
+
///
/// Returns all team's repositories.
///
diff --git a/Octokit.Reactive/Clients/ObservableTeamsClient.cs b/Octokit.Reactive/Clients/ObservableTeamsClient.cs
index e6297e28..e023549c 100644
--- a/Octokit.Reactive/Clients/ObservableTeamsClient.cs
+++ b/Octokit.Reactive/Clients/ObservableTeamsClient.cs
@@ -121,6 +121,38 @@ namespace Octokit.Reactive
return _connection.GetAndFlattenAllPages(ApiUrls.TeamMembers(id), options);
}
+ ///
+ /// Returns all members with the specified role in the given team of the given role.
+ ///
+ ///
+ /// https://developer.github.com/v3/orgs/teams/#list-team-members
+ ///
+ /// The team identifier
+ /// The request filter
+ public IObservable GetAllMembers(int id, TeamMembersRequest request)
+ {
+ Ensure.ArgumentNotNull(request, nameof(request));
+
+ return GetAllMembers(id, request, ApiOptions.None);
+ }
+
+ ///
+ /// Returns all members with the specified role in the given team of the given role.
+ ///
+ ///
+ /// https://developer.github.com/v3/orgs/teams/#list-team-members
+ ///
+ /// The team identifier
+ /// The request filter
+ /// Options to change API behaviour.
+ public IObservable GetAllMembers(int id, TeamMembersRequest request, ApiOptions options)
+ {
+ Ensure.ArgumentNotNull(request, nameof(request));
+ Ensure.ArgumentNotNull(options, nameof(options));
+
+ return _connection.GetAndFlattenAllPages(ApiUrls.TeamMembers(id), request.ToParametersDictionary(), options);
+ }
+
///
/// Returns newly created for the current org.
///
@@ -160,12 +192,11 @@ namespace Octokit.Reactive
/// Adds a to a .
///
///
- /// See the API documentation for more information.
+ /// See the API documentation for more information.
///
/// The team identifier.
/// The user to add to the team.
- /// Thrown if you attempt to add an organization to a team.
- /// A result indicating the membership status
+ [Obsolete("Please use AddOrEditMembership instead")]
public IObservable AddMembership(int id, string login)
{
Ensure.ArgumentNotNullOrEmptyString(login, "login");
@@ -173,6 +204,23 @@ namespace Octokit.Reactive
return _client.AddMembership(id, login).ToObservable();
}
+ ///
+ /// Adds a to a .
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The team identifier.
+ /// The user to add to the team.
+ /// Additional parameters for the request
+ public IObservable AddOrEditMembership(int id, string login, UpdateTeamMembership request)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(login, nameof(login));
+ Ensure.ArgumentNotNull(request, nameof(request));
+
+ return _client.AddOrEditMembership(id, login, request).ToObservable();
+ }
+
///
/// Removes a from a .
///
@@ -195,7 +243,7 @@ namespace Octokit.Reactive
///
/// The team to check.
/// The user to check.
- /// A result indicating the membership status
+ [Obsolete("Please use GetMembershipDetails instead")]
public IObservable GetMembership(int id, string login)
{
Ensure.ArgumentNotNullOrEmptyString(login, "login");
@@ -203,6 +251,23 @@ namespace Octokit.Reactive
return _client.GetMembership(id, login).ToObservable();
}
+ ///
+ /// Gets whether the user with the given
+ /// is a member of the team with the given .
+ /// A is thrown if the user is not a member.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The team to check.
+ /// The user to check.
+ public IObservable GetMembershipDetails(int id, string login)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(login, "login");
+
+ return _client.GetMembershipDetails(id, login).ToObservable();
+ }
+
///
/// Returns all team's repositories.
///
diff --git a/Octokit.Tests.Integration/Clients/TeamsClientTests.cs b/Octokit.Tests.Integration/Clients/TeamsClientTests.cs
index 1af5833f..db8f9c37 100644
--- a/Octokit.Tests.Integration/Clients/TeamsClientTests.cs
+++ b/Octokit.Tests.Integration/Clients/TeamsClientTests.cs
@@ -52,6 +52,56 @@ public class TeamsClientTests
}
}
+ public class TheAddOrEditMembershipMethod : IDisposable
+ {
+ private readonly IGitHubClient _github;
+ private readonly TeamContext _teamContext;
+
+ public TheAddOrEditMembershipMethod()
+ {
+ _github = Helper.GetAuthenticatedClient();
+
+ var newTeam = new NewTeam(Helper.MakeNameWithTimestamp("team-fixture"));
+ newTeam.Maintainers.Add(Helper.UserName);
+
+ _teamContext = _github.CreateTeamContext(Helper.Organization, newTeam).Result;
+ }
+
+ [OrganizationTest]
+ public async Task AddsMembership()
+ {
+ var login = "octokitnet-test1";
+
+ var membership = await _github.Organization.Team.AddOrEditMembership(_teamContext.TeamId, login, new UpdateTeamMembership(TeamRole.Member));
+
+ Assert.Equal(TeamRole.Member, membership.Role);
+ Assert.Equal(MembershipState.Pending, membership.State);
+ }
+
+ [OrganizationTest]
+ public async Task EditsMembership()
+ {
+ var login = "octokitnet-test1";
+
+ // Add as member
+ await _github.Organization.Team.AddOrEditMembership(_teamContext.TeamId, login, new UpdateTeamMembership(TeamRole.Member));
+
+ // Update to maintainer
+ var membership = await _github.Organization.Team.AddOrEditMembership(_teamContext.TeamId, login, new UpdateTeamMembership(TeamRole.Maintainer));
+
+ Assert.Equal(TeamRole.Maintainer, membership.Role);
+ Assert.Equal(MembershipState.Pending, membership.State);
+ }
+
+ public void Dispose()
+ {
+ if (_teamContext != null)
+ {
+ _teamContext.Dispose();
+ }
+ }
+ }
+
public class TheGetMembershipMethod
{
readonly Team team;
@@ -94,26 +144,83 @@ public class TeamsClientTests
}
}
- public class TheGetAllMembersMethod
+ public class TheGetMembershipDetailsMethod : IDisposable
{
- readonly Team team;
+ private readonly IGitHubClient _github;
+ private readonly TeamContext _teamContext;
- public TheGetAllMembersMethod()
+ public TheGetMembershipDetailsMethod()
{
- var github = Helper.GetAuthenticatedClient();
+ _github = Helper.GetAuthenticatedClient();
- team = github.Organization.Team.GetAll(Helper.Organization).Result.First();
+ var newTeam = new NewTeam(Helper.MakeNameWithTimestamp("team-fixture"));
+ newTeam.Maintainers.Add(Helper.UserName);
+
+ _teamContext = _github.CreateTeamContext(Helper.Organization, newTeam).Result;
}
[OrganizationTest]
- public async Task GetsAllMembersWhenAuthenticated()
+ public async Task GetsMembershipDetails()
{
- var github = Helper.GetAuthenticatedClient();
+ var membership = await _github.Organization.Team.GetMembershipDetails(_teamContext.TeamId, Helper.UserName);
- var members = await github.Organization.Team.GetAllMembers(team.Id);
+ Assert.Equal(TeamRole.Maintainer, membership.Role);
+ Assert.Equal(MembershipState.Active, membership.State);
+ }
+
+ [OrganizationTest]
+ public async Task ThrowsWhenNotAMember()
+ {
+ await Assert.ThrowsAsync(() => _github.Organization.Team.GetMembershipDetails(_teamContext.TeamId, "foo"));
+ }
+
+ public void Dispose()
+ {
+ if (_teamContext != null)
+ {
+ _teamContext.Dispose();
+ }
+ }
+ }
+
+ public class TheGetAllMembersMethod : IDisposable
+ {
+ private readonly IGitHubClient _github;
+ private readonly TeamContext _teamContext;
+
+ public TheGetAllMembersMethod()
+ {
+ _github = Helper.GetAuthenticatedClient();
+
+ var newTeam = new NewTeam(Helper.MakeNameWithTimestamp("team-fixture"));
+ newTeam.Maintainers.Add(Helper.UserName);
+
+ _teamContext = _github.CreateTeamContext(Helper.Organization, newTeam).Result;
+ }
+
+ [OrganizationTest]
+ public async Task GetsAllMembers()
+ {
+ var members = await _github.Organization.Team.GetAllMembers(_teamContext.TeamId);
Assert.Contains(Helper.UserName, members.Select(u => u.Login));
}
+
+ [OrganizationTest]
+ public async Task GetsAllMembersWithRoleFilter()
+ {
+ var members = await _github.Organization.Team.GetAllMembers(_teamContext.TeamId, new TeamMembersRequest(TeamRoleFilter.Member));
+
+ Assert.Empty(members);
+ }
+
+ public void Dispose()
+ {
+ if (_teamContext != null)
+ {
+ _teamContext.Dispose();
+ }
+ }
}
public class TheGetAllRepositoriesMethod
diff --git a/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs b/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs
index 90d8e435..bd8900ba 100644
--- a/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs
+++ b/Octokit.Tests.Integration/Helpers/ObservableGithubClientExtensions.cs
@@ -28,7 +28,7 @@ namespace Octokit.Tests.Integration.Helpers
return new RepositoryContext(client.Connection, repo);
}
- internal static async Task CreateEnterpriseTeamContext(this IObservableGitHubClient client, string organization, NewTeam newTeam)
+ internal static async Task CreateTeamContext(this IObservableGitHubClient client, string organization, NewTeam newTeam)
{
var team = await client.Organization.Team.Create(organization, newTeam);
diff --git a/Octokit.Tests.Integration/Reactive/Enterprise/ObservableEnterpriseLdapClientTests.cs b/Octokit.Tests.Integration/Reactive/Enterprise/ObservableEnterpriseLdapClientTests.cs
index 01441e96..f09b45ee 100644
--- a/Octokit.Tests.Integration/Reactive/Enterprise/ObservableEnterpriseLdapClientTests.cs
+++ b/Octokit.Tests.Integration/Reactive/Enterprise/ObservableEnterpriseLdapClientTests.cs
@@ -23,7 +23,7 @@ namespace Octokit.Tests.Integration
_github = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient());
NewTeam newTeam = new NewTeam(Helper.MakeNameWithTimestamp("test-team")) { Description = "Test Team" };
- _context = _github.CreateEnterpriseTeamContext(EnterpriseHelper.Organization, newTeam).Result;
+ _context = _github.CreateTeamContext(EnterpriseHelper.Organization, newTeam).Result;
}
[GitHubEnterpriseTest]
diff --git a/Octokit.Tests.Integration/Reactive/ObservableTeamsClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableTeamsClientTests.cs
index 6c02f885..77773dad 100644
--- a/Octokit.Tests.Integration/Reactive/ObservableTeamsClientTests.cs
+++ b/Octokit.Tests.Integration/Reactive/ObservableTeamsClientTests.cs
@@ -1,4 +1,5 @@
-using System.Linq;
+using System;
+using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Octokit;
@@ -9,28 +10,132 @@ using Xunit;
public class ObservableTeamsClientTests
{
- public class TheGetAllMembersMethod
+ public class TheAddOrEditMembershipMethod : IDisposable
{
- readonly Team _team;
+ private readonly IObservableGitHubClient _github;
+ private readonly TeamContext _teamContext;
- public TheGetAllMembersMethod()
+ public TheAddOrEditMembershipMethod()
{
- var github = Helper.GetAuthenticatedClient();
+ _github = new ObservableGitHubClient(Helper.GetAuthenticatedClient());
- _team = github.Organization.Team.GetAll(Helper.Organization).Result.First();
+ var newTeam = new NewTeam(Helper.MakeNameWithTimestamp("team-fixture"));
+ newTeam.Maintainers.Add(Helper.UserName);
+
+ _teamContext = _github.CreateTeamContext(Helper.Organization, newTeam).Result;
}
[OrganizationTest]
- public async Task GetsAllMembersWhenAuthenticated()
+ public async Task AddsMembership()
{
- var github = Helper.GetAuthenticatedClient();
- var client = new ObservableTeamsClient(github);
+ var login = "octokitnet-test1";
- var observable = client.GetAllMembers(_team.Id, ApiOptions.None);
- var members = await observable.ToList();
+ var membership = await _github.Organization.Team.AddOrEditMembership(_teamContext.TeamId, login, new UpdateTeamMembership(TeamRole.Member));
- Assert.True(members.Count > 0);
- Assert.True(members.Any(x => x.Login == Helper.UserName));
+ Assert.Equal(TeamRole.Member, membership.Role);
+ Assert.Equal(MembershipState.Pending, membership.State);
+ }
+
+ [OrganizationTest]
+ public async Task EditsMembership()
+ {
+ var login = "octokitnet-test1";
+
+ // Add as member
+ await _github.Organization.Team.AddOrEditMembership(_teamContext.TeamId, login, new UpdateTeamMembership(TeamRole.Member));
+
+ // Update to maintainer
+ var membership = await _github.Organization.Team.AddOrEditMembership(_teamContext.TeamId, login, new UpdateTeamMembership(TeamRole.Maintainer));
+
+ Assert.Equal(TeamRole.Maintainer, membership.Role);
+ Assert.Equal(MembershipState.Pending, membership.State);
+ }
+
+ public void Dispose()
+ {
+ if (_teamContext != null)
+ {
+ _teamContext.Dispose();
+ }
+ }
+ }
+
+ public class TheGetMembershipDetailsMethod : IDisposable
+ {
+ private readonly IObservableGitHubClient _github;
+ private readonly TeamContext _teamContext;
+
+ public TheGetMembershipDetailsMethod()
+ {
+ _github = new ObservableGitHubClient(Helper.GetAuthenticatedClient());
+
+ var newTeam = new NewTeam(Helper.MakeNameWithTimestamp("team-fixture"));
+ newTeam.Maintainers.Add(Helper.UserName);
+
+ _teamContext = _github.CreateTeamContext(Helper.Organization, newTeam).Result;
+ }
+
+ [OrganizationTest]
+ public async Task GetsMembershipDetails()
+ {
+ var membership = await _github.Organization.Team.GetMembershipDetails(_teamContext.TeamId, Helper.UserName);
+
+ Assert.Equal(TeamRole.Maintainer, membership.Role);
+ Assert.Equal(MembershipState.Active, membership.State);
+ }
+
+ [OrganizationTest]
+ public async Task ThrowsWhenNotAMember()
+ {
+ Assert.ThrowsAsync(async () => await _github.Organization.Team.GetMembershipDetails(_teamContext.TeamId, "foo"));
+ }
+
+ public void Dispose()
+ {
+ if (_teamContext != null)
+ {
+ _teamContext.Dispose();
+ }
+ }
+ }
+
+ public class TheGetAllMembersMethod : IDisposable
+ {
+ private readonly IObservableGitHubClient _github;
+ private readonly TeamContext _teamContext;
+
+ public TheGetAllMembersMethod()
+ {
+ _github = new ObservableGitHubClient(Helper.GetAuthenticatedClient());
+
+ var newTeam = new NewTeam(Helper.MakeNameWithTimestamp("team-fixture"));
+ newTeam.Maintainers.Add(Helper.UserName);
+
+ _teamContext = _github.CreateTeamContext(Helper.Organization, newTeam).Result;
+ }
+
+ [OrganizationTest]
+ public async Task GetsAllMembers()
+ {
+ var members = await _github.Organization.Team.GetAllMembers(_teamContext.TeamId).ToList();
+
+ Assert.Contains(Helper.UserName, members.Select(u => u.Login));
+ }
+
+ [OrganizationTest]
+ public async Task GetsAllMembersWithRequest()
+ {
+ var members = await _github.Organization.Team.GetAllMembers(_teamContext.TeamId, new TeamMembersRequest(TeamRoleFilter.Member)).ToList();
+
+ Assert.Empty(members);
+ }
+
+ public void Dispose()
+ {
+ if (_teamContext != null)
+ {
+ _teamContext.Dispose();
+ }
}
}
diff --git a/Octokit.Tests/Clients/TeamsClientTests.cs b/Octokit.Tests/Clients/TeamsClientTests.cs
index f769987f..0cafb140 100644
--- a/Octokit.Tests/Clients/TeamsClientTests.cs
+++ b/Octokit.Tests/Clients/TeamsClientTests.cs
@@ -61,7 +61,7 @@ namespace Octokit.Tests.Clients
}
}
- public class TheGetMembersMethod
+ public class TheGetAllMembersMethod
{
[Fact]
public void RequestsTheCorrectUrl()
@@ -75,6 +75,34 @@ namespace Octokit.Tests.Clients
Arg.Is(u => u.ToString() == "teams/1/members"),
Args.ApiOptions);
}
+
+ [Fact]
+ public void RequestsTheCorrectUrlWithRequest()
+ {
+ var connection = Substitute.For();
+ var client = new TeamsClient(connection);
+
+ client.GetAllMembers(1, new TeamMembersRequest(TeamRoleFilter.Maintainer));
+
+ connection.Received().GetAll(
+ Arg.Is(u => u.ToString() == "teams/1/members"),
+ Arg.Is>(d => d["role"] == "maintainer"),
+ Args.ApiOptions);
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var connection = Substitute.For();
+ var client = new TeamsClient(connection);
+
+ await Assert.ThrowsAsync(() => client.GetAllMembers(1, (TeamMembersRequest)null));
+
+ await Assert.ThrowsAsync(() => client.GetAllMembers(1, (ApiOptions)null));
+
+ await Assert.ThrowsAsync(() => client.GetAllMembers(1, null, ApiOptions.None));
+ await Assert.ThrowsAsync(() => client.GetAllMembers(1, new TeamMembersRequest(TeamRoleFilter.All), null));
+ }
}
public class TheCreateMethod
@@ -184,6 +212,36 @@ namespace Octokit.Tests.Clients
}
}
+ public class TheAddOrEditMembershipMethod
+ {
+ [Fact]
+ public async Task RequestsTheCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new TeamsClient(connection);
+ var request = new UpdateTeamMembership(TeamRole.Maintainer);
+
+ await client.AddOrEditMembership(1, "user", request);
+
+ connection.Received().Put(
+ Arg.Is(u => u.ToString() == "teams/1/memberships/user"),
+ Arg.Is(x => x.Role == TeamRole.Maintainer));
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullOrEmptyArguments()
+ {
+ var connection = Substitute.For();
+ var client = new TeamsClient(connection);
+ var request = new UpdateTeamMembership(TeamRole.Maintainer);
+
+ await Assert.ThrowsAsync(() => client.AddOrEditMembership(1, null, request));
+ await Assert.ThrowsAsync(() => client.AddOrEditMembership(1, "user", null));
+
+ await Assert.ThrowsAsync(() => client.AddOrEditMembership(1, "", request));
+ }
+ }
+
public class TheGetAllForCurrentMethod
{
[Fact]
@@ -221,6 +279,30 @@ namespace Octokit.Tests.Clients
}
}
+ public class TheGetMembershipDetailsMethod
+ {
+ [Fact]
+ public async Task RequestsTheCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new TeamsClient(connection);
+ await client.GetMembershipDetails(1, "user");
+
+ connection.Received().Get(Arg.Is(u => u.ToString() == "teams/1/memberships/user"));
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullOrEmptyArguments()
+ {
+ var connection = Substitute.For();
+ var client = new TeamsClient(connection);
+
+ await Assert.ThrowsAsync(() => client.GetMembershipDetails(1, null));
+
+ await Assert.ThrowsAsync(() => client.GetMembershipDetails(1, ""));
+ }
+ }
+
public class TheRemoveMembershipMethod
{
[Fact]
diff --git a/Octokit.Tests/Reactive/ObservableTeamsClientTests.cs b/Octokit.Tests/Reactive/ObservableTeamsClientTests.cs
index eee914fc..fa5a4a95 100644
--- a/Octokit.Tests/Reactive/ObservableTeamsClientTests.cs
+++ b/Octokit.Tests/Reactive/ObservableTeamsClientTests.cs
@@ -11,6 +11,15 @@ namespace Octokit.Tests.Reactive
{
public class ObservableTeamsClientTests
{
+ public class TheCtor
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ Assert.Throws(() => new ObservableTeamsClient(null));
+ }
+ }
+
public class TheCreateMethod
{
[Fact]
@@ -37,12 +46,101 @@ namespace Octokit.Tests.Reactive
}
}
- public class TheCtor
+ public class TheGetMembershipDetailsMethod
{
+ [Fact]
+ public void RequestsTheCorrectUrl()
+ {
+ var github = Substitute.For();
+ var client = new ObservableTeamsClient(github);
+
+ client.GetMembershipDetails(1, "user");
+
+ github.Organization.Team.Received().GetMembershipDetails(1, "user");
+ }
+
[Fact]
public void EnsuresNonNullArguments()
{
- Assert.Throws(() => new ObservableTeamsClient(null));
+ var github = Substitute.For();
+ var client = new ObservableTeamsClient(github);
+
+ Assert.Throws(() => client.GetMembershipDetails(1, null));
+
+ Assert.Throws(() => client.GetMembershipDetails(1, ""));
+ }
+ }
+
+ public class TheGetAllMembersMethod
+ {
+ [Fact]
+ public void RequestsTheCorrectUrl()
+ {
+ var github = Substitute.For();
+ var client = new ObservableTeamsClient(github);
+
+ client.GetAllMembers(1);
+
+ github.Connection.Received().Get>(
+ Arg.Is(u => u.ToString() == "teams/1/members"),
+ Args.EmptyDictionary,
+ null);
+ }
+
+ [Fact]
+ public void RequestsTheCorrectUrlWithRequest()
+ {
+ var github = Substitute.For();
+ var client = new ObservableTeamsClient(github);
+
+ client.GetAllMembers(1, new TeamMembersRequest(TeamRoleFilter.Maintainer));
+
+ github.Connection.Received().Get>(
+ Arg.Is(u => u.ToString() == "teams/1/members"),
+ Arg.Is>(d => d["role"] == "maintainer"),
+ null);
+ }
+
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ var github = Substitute.For();
+ var client = new ObservableTeamsClient(github);
+
+ Assert.Throws(() => client.GetAllMembers(1, (TeamMembersRequest)null));
+
+ Assert.Throws(() => client.GetAllMembers(1, (ApiOptions)null));
+
+ Assert.Throws(() => client.GetAllMembers(1, null, ApiOptions.None));
+ Assert.Throws(() => client.GetAllMembers(1, new TeamMembersRequest(TeamRoleFilter.All), null));
+ }
+ }
+
+ public class TheAddOrEditMembershipMethod
+ {
+ [Fact]
+ public async Task RequestsTheCorrectUrl()
+ {
+ var github = Substitute.For();
+ var client = new ObservableTeamsClient(github);
+ var request = new UpdateTeamMembership(TeamRole.Maintainer);
+
+ client.AddOrEditMembership(1, "user", request);
+
+ github.Organization.Team.Received().AddOrEditMembership(1, "user", request);
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullOrEmptyArguments()
+ {
+ var github = Substitute.For();
+ var client = new ObservableTeamsClient(github);
+ var request = new UpdateTeamMembership(TeamRole.Maintainer);
+
+ Assert.Throws(() => client.AddOrEditMembership(1, null, request));
+ Assert.Throws(() => client.AddOrEditMembership(1, "user", null));
+
+ Assert.Throws(() => client.AddOrEditMembership(1, "", request));
}
}
diff --git a/Octokit/Clients/ITeamsClient.cs b/Octokit/Clients/ITeamsClient.cs
index 7a42619c..f67fb1a2 100644
--- a/Octokit/Clients/ITeamsClient.cs
+++ b/Octokit/Clients/ITeamsClient.cs
@@ -62,24 +62,43 @@ namespace Octokit
///
/// Returns all members of the given team.
///
- /// The team identifier
///
/// https://developer.github.com/v3/orgs/teams/#list-team-members
///
- /// A list of the team's member s.
+ /// The team identifier
Task> GetAllMembers(int id);
///
/// Returns all members of the given team.
///
- /// The team identifier
- /// Options to change API behaviour.
///
/// https://developer.github.com/v3/orgs/teams/#list-team-members
///
- /// A list of the team's member s.
+ /// The team identifier
+ /// Options to change API behaviour.
Task> GetAllMembers(int id, ApiOptions options);
+ ///
+ /// Returns all members with the specified role in the given team of the given role.
+ ///
+ ///
+ /// https://developer.github.com/v3/orgs/teams/#list-team-members
+ ///
+ /// The team identifier
+ /// The request filter
+ Task> GetAllMembers(int id, TeamMembersRequest request);
+
+ ///
+ /// Returns all members with the specified role in the given team of the given role.
+ ///
+ ///
+ /// https://developer.github.com/v3/orgs/teams/#list-team-members
+ ///
+ /// The team identifier
+ /// The request filter
+ /// Options to change API behaviour.
+ Task> GetAllMembers(int id, TeamMembersRequest request, ApiOptions options);
+
///
/// Returns newly created for the current org.
///
@@ -105,14 +124,24 @@ namespace Octokit
/// Adds a to a .
///
///
- /// See the API documentation for more information.
+ /// See the API documentation for more information.
///
/// The team identifier.
/// The user to add to the team.
- /// Thrown if you attempt to add an organization to a team.
- /// A result indicating the membership status
+ [Obsolete("Please use AddOrEditMembership instead")]
Task AddMembership(int id, string login);
+ ///
+ /// Adds a to a .
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The team identifier.
+ /// The user to add to the team.
+ /// Additional parameters for the request
+ Task AddOrEditMembership(int id, string login, UpdateTeamMembership request);
+
///
/// Removes a from a .
///
@@ -130,9 +159,21 @@ namespace Octokit
///
/// The team to check.
/// The user to check.
- /// A result indicating the membership status
+ [Obsolete("Please use GetMembershipDetails instead")]
Task GetMembership(int id, string login);
+ ///
+ /// Gets whether the user with the given
+ /// is a member of the team with the given .
+ /// A is thrown if the user is not a member.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The team to check.
+ /// The user to check.
+ Task GetMembershipDetails(int id, string login);
+
///
/// Returns all team's repositories.
///
diff --git a/Octokit/Clients/TeamsClient.cs b/Octokit/Clients/TeamsClient.cs
index fd2ac393..8da6b769 100644
--- a/Octokit/Clients/TeamsClient.cs
+++ b/Octokit/Clients/TeamsClient.cs
@@ -92,11 +92,10 @@ namespace Octokit
///
/// Returns all members of the given team.
///
- /// The team identifier
///
/// https://developer.github.com/v3/orgs/teams/#list-team-members
///
- /// A list of the team's member s.
+ /// The team identifier
public Task> GetAllMembers(int id)
{
return GetAllMembers(id, ApiOptions.None);
@@ -110,7 +109,6 @@ namespace Octokit
///
/// The team identifier
/// Options to change API behaviour.
- /// A list of the team's member s.
public Task> GetAllMembers(int id, ApiOptions options)
{
Ensure.ArgumentNotNull(options, "options");
@@ -120,13 +118,47 @@ namespace Octokit
return ApiConnection.GetAll(endpoint, options);
}
+ ///
+ /// Returns all members with the specified role in the given team of the given role.
+ ///
+ ///
+ /// https://developer.github.com/v3/orgs/teams/#list-team-members
+ ///
+ /// The team identifier
+ /// The request filter
+ public Task> GetAllMembers(int id, TeamMembersRequest request)
+ {
+ Ensure.ArgumentNotNull(request, nameof(request));
+
+ return GetAllMembers(id, request, ApiOptions.None);
+ }
+
+ ///
+ /// Returns all members with the specified role in the given team of the given role.
+ ///
+ ///
+ /// https://developer.github.com/v3/orgs/teams/#list-team-members
+ ///
+ /// The team identifier
+ /// The request filter
+ /// Options to change API behaviour.
+ public Task> GetAllMembers(int id, TeamMembersRequest request, ApiOptions options)
+ {
+ Ensure.ArgumentNotNull(request, nameof(request));
+ Ensure.ArgumentNotNull(options, nameof(options));
+
+ var endpoint = ApiUrls.TeamMembers(id);
+
+ return ApiConnection.GetAll(endpoint, request.ToParametersDictionary(), options);
+ }
+
///
/// Gets whether the user with the given
/// is a member of the team with the given .
///
/// The team to check.
/// The user to check.
- /// A result indicating the membership status
+ [Obsolete("Please use GetMembershipDetails instead")]
public async Task GetMembership(int id, string login)
{
Ensure.ArgumentNotNullOrEmptyString(login, "login");
@@ -149,6 +181,25 @@ namespace Octokit
: TeamMembership.Pending;
}
+ ///
+ /// Gets whether the user with the given
+ /// is a member of the team with the given .
+ /// A is thrown if the user is not a member.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The team to check.
+ /// The user to check.
+ public Task GetMembershipDetails(int id, string login)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(login, nameof(login));
+
+ var endpoint = ApiUrls.TeamMember(id, login);
+
+ return ApiConnection.Get(endpoint);
+ }
+
///
/// Returns newly created for the current org.
///
@@ -192,12 +243,11 @@ namespace Octokit
/// Adds a to a .
///
///
- /// See the API documentation for more information.
+ /// See the API documentation for more information.
///
/// The team identifier.
/// The user to add to the team.
- /// Thrown if you attempt to add an organization to a team.
- /// A result indicating the membership status
+ [Obsolete("Please use AddOrEditMembership instead")]
public async Task AddMembership(int id, string login)
{
Ensure.ArgumentNotNullOrEmptyString(login, "login");
@@ -225,6 +275,25 @@ namespace Octokit
: TeamMembership.Pending;
}
+ ///
+ /// Adds a to a .
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The team identifier.
+ /// The user to add to the team.
+ /// Additional parameters for the request
+ public Task AddOrEditMembership(int id, string login, UpdateTeamMembership request)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(login, nameof(login));
+ Ensure.ArgumentNotNull(request, nameof(request));
+
+ var endpoint = ApiUrls.TeamMember(id, login);
+
+ return ApiConnection.Put(endpoint, request);
+ }
+
///
/// Removes a from a .
///
diff --git a/Octokit/Models/Request/TeamMembersRequest.cs b/Octokit/Models/Request/TeamMembersRequest.cs
new file mode 100644
index 00000000..babc18d4
--- /dev/null
+++ b/Octokit/Models/Request/TeamMembersRequest.cs
@@ -0,0 +1,55 @@
+using System.Diagnostics;
+using System.Globalization;
+using Octokit.Internal;
+
+namespace Octokit
+{
+ ///
+ /// Used to filter requests for team members
+ ///
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class TeamMembersRequest : RequestParameters
+ {
+ public TeamMembersRequest(TeamRoleFilter role)
+ {
+ Role = role;
+ }
+
+ ///
+ /// Which membership roles to get
+ ///
+ public TeamRoleFilter Role { get; private set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Role {0} ", Role);
+ }
+ }
+ }
+
+ ///
+ /// Filtering by Roles within a Team
+ ///
+ public enum TeamRoleFilter
+ {
+ ///
+ /// Regular Team Member
+ ///
+ [Parameter(Value = "member")]
+ Member,
+
+ ///
+ /// Team Maintainer
+ ///
+ [Parameter(Value = "maintainer")]
+ Maintainer,
+
+ ///
+ /// All Roles
+ ///
+ [Parameter(Value = "all")]
+ All
+ }
+}
diff --git a/Octokit/Models/Request/UpdateTeamMembership.cs b/Octokit/Models/Request/UpdateTeamMembership.cs
new file mode 100644
index 00000000..369537ba
--- /dev/null
+++ b/Octokit/Models/Request/UpdateTeamMembership.cs
@@ -0,0 +1,31 @@
+using System.Diagnostics;
+using System.Globalization;
+using Octokit.Internal;
+
+namespace Octokit
+{
+ ///
+ /// Used to filter requests for team members
+ ///
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class UpdateTeamMembership
+ {
+ public UpdateTeamMembership(TeamRole role)
+ {
+ Role = role;
+ }
+
+ ///
+ /// Which membership roles to get
+ ///
+ public TeamRole Role { get; private set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Role {0}", Role);
+ }
+ }
+ }
+}
diff --git a/Octokit/Models/Response/MembershipState.cs b/Octokit/Models/Response/MembershipState.cs
new file mode 100644
index 00000000..697d8799
--- /dev/null
+++ b/Octokit/Models/Response/MembershipState.cs
@@ -0,0 +1,23 @@
+using System;
+using Octokit.Internal;
+
+namespace Octokit
+{
+ ///
+ /// States of a Team/Organization Membership
+ ///
+ public enum MembershipState
+ {
+ ///
+ /// The membership is pending
+ ///
+ [Parameter(Value = "pending")]
+ Pending,
+
+ ///
+ /// The membership is active
+ ///
+ [Parameter(Value = "active")]
+ Active
+ }
+}
diff --git a/Octokit/Models/Response/TeamMembership.cs b/Octokit/Models/Response/TeamMembership.cs
index 2dba0d8b..fc865c97 100644
--- a/Octokit/Models/Response/TeamMembership.cs
+++ b/Octokit/Models/Response/TeamMembership.cs
@@ -1,5 +1,8 @@
-namespace Octokit
+using System;
+
+namespace Octokit
{
+ [Obsolete("Please use TeamMembershipDetails response class instead")]
public enum TeamMembership
{
NotFound = 0,
diff --git a/Octokit/Models/Response/TeamMembershipDetails.cs b/Octokit/Models/Response/TeamMembershipDetails.cs
new file mode 100644
index 00000000..53abf76b
--- /dev/null
+++ b/Octokit/Models/Response/TeamMembershipDetails.cs
@@ -0,0 +1,40 @@
+using System.Diagnostics;
+using System.Globalization;
+using Octokit.Internal;
+
+namespace Octokit
+{
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class TeamMembershipDetails
+ {
+ public StringEnum Role { get; protected set; }
+
+ public StringEnum State { get; protected set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ return string.Format(CultureInfo.InvariantCulture, "Role: {0} State: {1}", Role, State);
+ }
+ }
+ }
+
+ ///
+ /// Roles within a Team
+ ///
+ public enum TeamRole
+ {
+ ///
+ /// Regular Team Member
+ ///
+ [Parameter(Value = "member")]
+ Member,
+
+ ///
+ /// Team Maintainer
+ ///
+ [Parameter(Value = "maintainer")]
+ Maintainer
+ }
+}