Implemented Get / IsMember for teams

Issue #331.
Added integration tests and a new attribute that requires a new environment variable with an organization to test.

Conflicts:
	Octokit.Tests.Integration/Octokit.Tests.Integration.csproj
This commit is contained in:
Daniel Cazzulino
2014-04-08 01:25:25 -03:00
parent 8806e6fed8
commit fb6adcb92b
7 changed files with 228 additions and 5 deletions
@@ -0,0 +1,123 @@
using System.Linq;
using System.Net;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Octokit;
using Octokit.Internal;
using Octokit.Tests.Helpers;
using Octokit.Tests.Integration;
using Xunit;
using System;
using System.Collections.Generic;
using Xunit.Sdk;
public class TeamsClientTests
{
public class TheCreateMethod
{
[OrganizationTest]
public async Task FailsWhenNotAuthenticated()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"));
var newTeam = new NewTeam("Test");
var e = await AssertEx.Throws<AuthorizationException>(async
() => await github.Organization.Team.CreateTeam(Helper.Organization, newTeam));
Assert.Equal(HttpStatusCode.Unauthorized, e.StatusCode);
}
[OrganizationTest]
public async Task FailsWhenAuthenticatedWithBadCredentials()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = new Credentials(Helper.Credentials.Login, "bad-password")
};
var newTeam = new NewTeam("Test");
var e = await AssertEx.Throws<AuthorizationException>(async
() => await github.Organization.Team.CreateTeam(Helper.Organization, newTeam));
Assert.Equal(HttpStatusCode.Unauthorized, e.StatusCode);
}
[OrganizationTest]
public async Task SucceedsWhenAuthenticated()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
var newTeam = new NewTeam(Guid.NewGuid().ToString());
var team = await github.Organization.Team.CreateTeam(Helper.Organization, newTeam);
Assert.Equal(newTeam.Name, team.Name);
}
}
public class TheIsMemberMethod
{
readonly Team team;
public TheIsMemberMethod()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests")) { Credentials = Helper.Credentials };
team = github.Organization.Team.GetAllTeams(Helper.Organization).Result.First();
}
//TODO: seems like a bug in Github: it's actually returning the membership information!
//Maybe because it's a public organization?
//[OrganizationTest]
public async Task FailsWhenNotAuthenticated()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"));
var e = await AssertEx.Throws<AuthorizationException>(async
() => await github.Organization.Team.IsMember(team.Id, Helper.UserName));
Assert.Equal(HttpStatusCode.Unauthorized, e.StatusCode);
}
[OrganizationTest]
public async Task FailsWhenAuthenticatedWithBadCredentials()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = new Credentials(Helper.Credentials.Login, "bad-password")
};
var e = await AssertEx.Throws<AuthorizationException>(async
() => await github.Organization.Team.IsMember(team.Id, Helper.UserName));
Assert.Equal(HttpStatusCode.Unauthorized, e.StatusCode);
}
[OrganizationTest]
public async Task GetsIsMemberWhenAuthenticated()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
var isMember = await github.Organization.Team.IsMember(team.Id, Helper.UserName);
Assert.True(isMember);
}
[OrganizationTest]
public async Task GetsIsMemberFalseForNonMemberWhenAuthenticated()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
var isMember = await github.Organization.Team.IsMember(team.Id, "foo");
Assert.False(isMember);
}
}
}
+11
View File
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Net.Http.Headers;
namespace Octokit.Tests.Integration
@@ -9,6 +10,7 @@ namespace Octokit.Tests.Integration
{
var githubUsername = Environment.GetEnvironmentVariable("OCTOKIT_GITHUBUSERNAME");
UserName = githubUsername;
Organization = Environment.GetEnvironmentVariable("OCTOKIT_GITHUBORGANIZATION");
var githubToken = Environment.GetEnvironmentVariable("OCTOKIT_OAUTHTOKEN");
@@ -23,7 +25,16 @@ namespace Octokit.Tests.Integration
return new Credentials(githubUsername, githubPassword);
});
static Helper()
{
// Force reading of environment variables.
// This wasn't happening if UserName/Organization were
// retrieved before Credentials.
Debug.WriteIf(Credentials == null, "No credentials specified.");
}
public static string UserName { get; private set; }
public static string Organization { get; private set; }
public static Credentials Credentials { get { return _credentialsThunk.Value; }}
@@ -78,9 +78,11 @@
<Compile Include="Clients\UserEmailsClientTests.cs" />
<Compile Include="Clients\FollowersClientTests.cs" />
<Compile Include="HttpClientAdapterTests.cs" />
<Compile Include="Clients\TeamsClientTests.cs" />
<Compile Include="IntegrationTestAttribute.cs" />
<Compile Include="Clients\IssuesClientTests.cs" />
<Compile Include="Clients\MiscellaneousClientTests.cs" />
<Compile Include="OrganizationTestAttribute.cs" />
<Compile Include="Reactive\ObservableIssuesClientTests.cs" />
<Compile Include="Reactive\ObservableMilestonesClientTests.cs" />
<Compile Include="Reactive\ObservableRepositoriesClientTests.cs" />
@@ -121,4 +123,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
@@ -0,0 +1,19 @@
using System.Collections.Generic;
using Xunit.Sdk;
namespace Octokit.Tests.Integration
{
public class OrganizationTestAttribute : IntegrationTestAttribute
{
protected override IEnumerable<ITestCommand> EnumerateTestCommands(IMethodInfo testMethod)
{
if (Helper.Organization == null)
return new[]
{
new SkipCommand(testMethod, MethodUtility.GetDisplayName(testMethod), "Automation settings not configured. Please set the OCTOKIT_GITHUBORGANIZATION environment variable to a GitHub organization owned by the test account specified in OCTOKIT_GITHUBUSERNAME.")
};
else
return base.EnumerateTestCommands(testMethod);
}
}
}
+21
View File
@@ -2,6 +2,7 @@
using System.Collections.Generic;
#endif
using System.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;
namespace Octokit
{
@@ -13,6 +14,18 @@ namespace Octokit
/// </remarks>
public interface ITeamsClient
{
/// <summary>
/// Gets a single <see cref="Team"/> by identifier.
/// </summary>
/// <remarks>
/// https://developer.github.com/v3/orgs/teams/#get-team
/// </remarks>
/// <param name="id">The team identifier.</param>
/// <returns>The <see cref="Team"/> with the given identifier.</returns>
[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get",
Justification = "Method makes a network request")]
Task<Team> Get(int id);
/// <summary>
/// Returns all <see cref="Team" />s for the current org.
/// </summary>
@@ -41,5 +54,13 @@ namespace Octokit
/// <returns></returns>
Task Delete(int id);
/// <summary>
/// Gets whether the user with the given <paramref name="login"/>
/// is a member of the team with the given <paramref name="id"/>.
/// </summary>
/// <param name="id">The team to check.</param>
/// <param name="login">The user to check.</param>
/// <returns><see langword="true"/> if the user is a member of the team; <see langword="false"/> otherwise.</returns>
Task<bool> IsMember(int id, string login);
}
}
+40 -2
View File
@@ -2,6 +2,7 @@
using System.Collections.Generic;
#endif
using System.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;
namespace Octokit
{
@@ -23,6 +24,21 @@ namespace Octokit
{
}
/// <summary>
/// Gets a single <see cref="Team"/> by identifier.
/// </summary>
/// <remarks>
/// https://developer.github.com/v3/orgs/teams/#get-team
/// </remarks>
/// <param name="id">The team identifier.</param>
/// <returns>The <see cref="Team"/> with the given identifier.</returns>
public Task<Team> Get(int id)
{
var endpoint = ApiUrls.Teams(id);
return ApiConnection.Get<Team>(endpoint);
}
/// <summary>
/// Returns all <see cref="Team" />s for the current org.
/// </summary>
@@ -60,7 +76,7 @@ namespace Octokit
{
Ensure.ArgumentNotNull(team, "team");
var endpoint = ApiUrls.TeamsUpdateOrDelete(id);
var endpoint = ApiUrls.Teams(id);
return ApiConnection.Patch<Team>(endpoint, team);
}
@@ -71,8 +87,30 @@ namespace Octokit
/// <returns></returns>
public Task Delete(int id)
{
var endpoint = ApiUrls.TeamsUpdateOrDelete(id);
var endpoint = ApiUrls.Teams(id);
return ApiConnection.Delete(endpoint);
}
/// <summary>
/// Gets whether the user with the given <paramref name="login"/>
/// is a member of the team with the given <paramref name="id"/>.
/// </summary>
/// <param name="id">The team to check.</param>
/// <param name="login">The user to check.</param>
/// <returns><see langword="true"/> if the user is a member of the team; <see langword="false"/> otherwise.</returns>
public async Task<bool> IsMember(int id, string login)
{
var endpoint = ApiUrls.TeamMember(id, login);
try
{
var response = await ApiConnection.Connection.GetAsync<string>(endpoint);
return response.StatusCode == System.Net.HttpStatusCode.NoContent;
}
catch (NotFoundException)
{
return false;
}
}
}
}
+11 -2
View File
@@ -937,15 +937,24 @@ namespace Octokit
/// <summary>
/// returns the <see cref="Uri"/> for teams
/// use for update or deleting a team
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public static Uri TeamsUpdateOrDelete(int id)
public static Uri Teams(int id)
{
return "teams/{0}".FormatUri(id);
}
/// <summary>
/// returns the <see cref="Uri"/> for team members
/// </summary>
/// <param name="id">The team id</param>
/// <param name="login">The user login.</param>
public static Uri TeamMember(int id, string login)
{
return "teams/{0}/members/{1}".FormatUri(id, login);
}
/// <summary>
/// returns the <see cref="Uri"/> for teams
/// use for update or deleting a team