mirror of
https://github.com/zoriya/octokit.net.git
synced 2025-12-06 07:16:09 +00:00
Merge branch 'master' into release-0.6
Conflicts: Octokit.Tests.Integration/Clients/MiscellaneousClientTests.cs build.cmd build.fsx
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -69,4 +69,5 @@ nunit-*.xml
|
||||
*.userprefs
|
||||
packaging/
|
||||
tools/FAKE.Core
|
||||
tools/SourceLink.Fake
|
||||
*.ncrunch*
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Octokit;
|
||||
using Octokit.Tests.Helpers;
|
||||
using Octokit.Tests.Integration;
|
||||
using Xunit;
|
||||
|
||||
@@ -54,7 +55,7 @@ public class GistsClientTests
|
||||
Assert.NotNull(updatedGist);
|
||||
Assert.Equal(updatedGist.Description, gistUpdate.Description);
|
||||
|
||||
Assert.DoesNotThrow(async () => { await _fixture.Delete(createdGist.Id); });
|
||||
await _fixture.Delete(createdGist.Id);
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
@@ -103,15 +104,8 @@ public class GistsClientTests
|
||||
Assert.True(gists.Count > 0);
|
||||
|
||||
// Make sure we can successfully request gists for another user
|
||||
Assert.DoesNotThrow(async () => { await _fixture.GetAllForUser("FakeHaacked"); });
|
||||
Assert.DoesNotThrow(async () => { await _fixture.GetAllForUser("FakeHaacked", startTime); });
|
||||
|
||||
// Test public gists
|
||||
var publicGists = await _fixture.GetAllPublic();
|
||||
Assert.True(publicGists.Count > 1);
|
||||
|
||||
var publicGistsSinceStartTime = await _fixture.GetAllPublic(startTime);
|
||||
Assert.True(publicGistsSinceStartTime.Count > 0);
|
||||
await _fixture.GetAllForUser("FakeHaacked");
|
||||
await _fixture.GetAllForUser("FakeHaacked", startTime);
|
||||
|
||||
// Test starred gists
|
||||
await _fixture.Star(createdGist.Id);
|
||||
|
||||
@@ -31,9 +31,10 @@ public class MiscellaneousClientTests
|
||||
Credentials = Helper.Credentials
|
||||
};
|
||||
|
||||
var result = await github.Miscellaneous.RenderRawMarkdown("This is a **test**");
|
||||
var result = await github.Miscellaneous.RenderRawMarkdown("This is\r\n a **test**");
|
||||
|
||||
Assert.Equal("<p>This is a <strong>test</strong></p>\n", result);
|
||||
//Assert.Equal("<p>This is\n a <strong>test</strong></p>\n", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public class PullRequestReviewCommentsClientTests : IDisposable
|
||||
|
||||
var createdComment = await CreateComment(body, position, pullRequest.Sha, pullRequest.Number);
|
||||
|
||||
Assert.DoesNotThrow(async () => { await _client.Delete(Helper.UserName, _repository.Name, createdComment.Id); });
|
||||
await _client.Delete(Helper.UserName, _repository.Name, createdComment.Id);
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
|
||||
@@ -501,7 +501,7 @@ public class RepositoriesClientTests
|
||||
var repoName = Helper.MakeNameWithTimestamp("repo-to-delete");
|
||||
await github.Repository.Create(new NewRepository { Name = repoName });
|
||||
|
||||
Assert.DoesNotThrow(async () => { await github.Repository.Delete(Helper.UserName, repoName); });
|
||||
await github.Repository.Delete(Helper.UserName, repoName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reactive.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
using Octokit;
|
||||
@@ -33,6 +34,14 @@ public class RepositoryCommitsClientTests : IDisposable
|
||||
Assert.NotNull(commit);
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task CanGetCommitWithFiles()
|
||||
{
|
||||
var commit = await _fixture.Get("octokit", "octokit.net", "65a22f4d2cff94a286ac3e96440c810c5509196f");
|
||||
|
||||
Assert.True(commit.Files.Any(file => file.Filename.EndsWith("IConnection.cs")));
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task CanGetListOfCommits()
|
||||
{
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
<Compile Include="Reactive\ObservableRespositoryDeployKeysClientTests.cs" />
|
||||
<Compile Include="Reactive\ObservableUserEmailsClientTests.cs" />
|
||||
<Compile Include="Reactive\ObservableTeamsClientTests.cs" />
|
||||
<Compile Include="SelfTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Octokit.Reactive\Octokit.Reactive.csproj">
|
||||
|
||||
17
Octokit.Tests.Integration/SelfTests.cs
Normal file
17
Octokit.Tests.Integration/SelfTests.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Xunit;
|
||||
|
||||
namespace Octokit.Tests.Integration
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests to make sure our tests are ok.
|
||||
/// </summary>
|
||||
public class SelfTests
|
||||
{
|
||||
[Fact]
|
||||
public void NoTestsUseAsyncVoid()
|
||||
{
|
||||
var errors = typeof(SelfTests).Assembly.GetAsyncVoidMethodsList();
|
||||
Assert.Equal("", errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,14 +195,15 @@ namespace Octokit.Tests.Clients
|
||||
public class TheCommitsMethod
|
||||
{
|
||||
[Fact]
|
||||
public async void RequestsCorrectUrl()
|
||||
public async Task RequestsCorrectUrl()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new PullRequestsClient(connection);
|
||||
|
||||
client.Commits("fake", "repo", 42);
|
||||
await client.Commits("fake", "repo", 42);
|
||||
|
||||
connection.Received().GetAll<PullRequestCommit>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/pulls/42/commits"));
|
||||
connection.Received()
|
||||
.GetAll<PullRequestCommit>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/pulls/42/commits"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using NSubstitute;
|
||||
using Octokit.Tests.Helpers;
|
||||
using Xunit;
|
||||
using System.Collections.Generic;
|
||||
using NSubstitute;
|
||||
using Xunit;
|
||||
|
||||
namespace Octokit.Tests.Clients
|
||||
{
|
||||
@@ -336,7 +334,8 @@ namespace Octokit.Tests.Clients
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
client.SearchRepo(new SearchRepositoriesRequest("something"));
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Any<Dictionary<string, string>>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -351,13 +350,12 @@ namespace Octokit.Tests.Clients
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//check sizes for repos that are greater than 50 MB
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Size = Range.GreaterThan(50);
|
||||
|
||||
request.Size = Range.GreaterThan(1);
|
||||
client.SearchRepo(request);
|
||||
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
|
||||
connection.Received().Get<SearchRepositoryResult>(
|
||||
Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+size:>1"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -368,10 +366,38 @@ namespace Octokit.Tests.Clients
|
||||
//get repos whos stargazers are greater than 500
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Stars = Range.GreaterThan(500);
|
||||
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(
|
||||
Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+stars:>500"));
|
||||
}
|
||||
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
|
||||
[Fact]
|
||||
public void TestingTheStarsQualifier_LessThan()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//get repos whos stargazers are less than 500
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Stars = Range.LessThan(500);
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(
|
||||
Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+stars:<500"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestingTheStarsQualifier_LessThanOrEquals()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//get repos whos stargazers are less than 500 or equal to
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Stars = Range.LessThanOrEquals(500);
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(
|
||||
Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+stars:<=500"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -382,10 +408,9 @@ namespace Octokit.Tests.Clients
|
||||
//get repos which has forks that are greater than 50
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Forks = Range.GreaterThan(50);
|
||||
|
||||
client.SearchRepo(request);
|
||||
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+forks:>50"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -394,12 +419,11 @@ namespace Octokit.Tests.Clients
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//search repos that contains rails and forks are included in the search
|
||||
var request = new SearchRepositoriesRequest("rails");
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Fork = ForkQualifier.IncludeForks;
|
||||
|
||||
client.SearchRepo(request);
|
||||
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+fork:IncludeForks"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -410,10 +434,9 @@ namespace Octokit.Tests.Clients
|
||||
//get repos whos language is Ruby
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Language = Language.Ruby;
|
||||
|
||||
client.SearchRepo(request);
|
||||
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+language:Ruby"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -425,8 +448,47 @@ namespace Octokit.Tests.Clients
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.In = new[] { InQualifier.Description };
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+in:Description"));
|
||||
}
|
||||
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
|
||||
[Fact]
|
||||
public void TestingTheInQualifier_Name()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.In = new[] { InQualifier.Name };
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(
|
||||
Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+in:Name"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestingTheInQualifier_Readme()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.In = new[] { InQualifier.Readme };
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(
|
||||
Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+in:Readme"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestingTheInQualifier_Multiple()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.In = new[] { InQualifier.Readme, InQualifier.Description, InQualifier.Name };
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(
|
||||
Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+in:Readme,Description,Name"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -437,12 +499,52 @@ namespace Octokit.Tests.Clients
|
||||
//get repos where the search contains 'github' and has been created after year jan 1 2011
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Created = DateRange.GreaterThan(new DateTime(2011, 1, 1));
|
||||
|
||||
client.SearchRepo(request);
|
||||
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+created:>2011-01-01"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestingTheCreatedQualifier_GreaterThanOrEquals()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//get repos where the search contains 'github' and has been created after year jan 1 2011
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Created = DateRange.GreaterThanOrEquals(new DateTime(2011, 1, 1));
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+created:>=2011-01-01"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestingTheCreatedQualifier_LessThan()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//get repos where the search contains 'github' and has been created after year jan 1 2011
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Created = DateRange.LessThan(new DateTime(2011, 1, 1));
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+created:<2011-01-01"));
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void TestingTheCreatedQualifier_LessThanOrEquals()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//get repos where the search contains 'github' and has been created after year jan 1 2011
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Created = DateRange.LessThanOrEquals(new DateTime(2011, 1, 1));
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+created:<=2011-01-01"));
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void TestingTheUpdatedQualifier()
|
||||
{
|
||||
@@ -450,11 +552,49 @@ namespace Octokit.Tests.Clients
|
||||
var client = new SearchClient(connection);
|
||||
//get repos where the search contains 'github' and has been pushed before year jan 1 2013
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Updated = DateRange.LessThan(new DateTime(2013, 1, 1));
|
||||
|
||||
request.Updated = DateRange.GreaterThan(new DateTime(2013, 1, 1));
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+pushed:>2013-01-01"));
|
||||
}
|
||||
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
|
||||
[Fact]
|
||||
public void TestingTheUpdatedQualifier_GreaterThanOrEquals()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//get repos where the search contains 'github' and has been pushed before year jan 1 2013
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Updated = DateRange.GreaterThanOrEquals(new DateTime(2013, 1, 1));
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+pushed:>=2013-01-01"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestingTheUpdatedQualifier_LessThan()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//get repos where the search contains 'github' and has been pushed before year jan 1 2013
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Updated = DateRange.LessThan(new DateTime(2013, 1, 1));
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+pushed:<2013-01-01"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestingTheUpdatedQualifier_LessThanOrEquals()
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//get repos where the search contains 'github' and has been pushed before year jan 1 2013
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.Updated = DateRange.LessThanOrEquals(new DateTime(2013, 1, 1));
|
||||
client.SearchRepo(request);
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+pushed:<=2013-01-01"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -462,13 +602,12 @@ namespace Octokit.Tests.Clients
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//get repos where the Description contains rails and user/org is 'github'
|
||||
var request = new SearchRepositoriesRequest("rails");
|
||||
request.User = "github";
|
||||
|
||||
//get repos where search contains 'github' and user/org is 'github'
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.User = "rails";
|
||||
client.SearchRepo(request);
|
||||
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+user:rails"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -476,13 +615,16 @@ namespace Octokit.Tests.Clients
|
||||
{
|
||||
var connection = Substitute.For<IApiConnection>();
|
||||
var client = new SearchClient(connection);
|
||||
//get repos where the Description contains rails and user/org is 'github'
|
||||
var request = new SearchRepositoriesRequest("rails");
|
||||
request.Sort = RepoSearchSort.Forks;
|
||||
var request = new SearchRepositoriesRequest("github");
|
||||
request.SortField = RepoSearchSort.Stars;
|
||||
|
||||
client.SearchRepo(request);
|
||||
|
||||
connection.Received().Get<SearchRepositoryResult>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
|
||||
connection.Received().Get<SearchRepositoryResult>(
|
||||
Arg.Is<Uri>(u => u.ToString() == "search/repositories"),
|
||||
Arg.Is<Dictionary<string, string>>(d =>
|
||||
d["q"] == "github" &&
|
||||
d["sort"] == "stars"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
39
Octokit.Tests/Helpers/ReflectionExtensions.cs
Normal file
39
Octokit.Tests/Helpers/ReflectionExtensions.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
public static class ReflectionExtensions
|
||||
{
|
||||
public static string GetAsyncVoidMethodsList(this Assembly assembly)
|
||||
{
|
||||
return String.Join("\r\n",
|
||||
GetLoadableTypes(assembly)
|
||||
.SelectMany(type => type.GetMethods())
|
||||
.Where(HasAttribute<AsyncStateMachineAttribute>)
|
||||
.Where(method => method.ReturnType == typeof(void))
|
||||
.Select(method =>
|
||||
String.Format("Method '{0}' of '{1}' has an async void return type and that's bad",
|
||||
method.Name,
|
||||
method.DeclaringType.Name))
|
||||
.ToList());
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
|
||||
{
|
||||
try
|
||||
{
|
||||
return assembly.GetTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException e)
|
||||
{
|
||||
return e.Types.Where(t => t != null);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasAttribute<TAttribute>(this MethodInfo method) where TAttribute : Attribute
|
||||
{
|
||||
return method.GetCustomAttributes(typeof(TAttribute), false).Any();
|
||||
}
|
||||
}
|
||||
@@ -110,6 +110,7 @@
|
||||
<Compile Include="Exceptions\RateLimitExceededExceptionTests.cs" />
|
||||
<Compile Include="Exceptions\TwoFactorRequiredExceptionTests.cs" />
|
||||
<Compile Include="Helpers\NSubstituteExtensions.cs" />
|
||||
<Compile Include="Helpers\ReflectionExtensions.cs" />
|
||||
<Compile Include="Helpers\UriExtensionsTests.cs" />
|
||||
<Compile Include="Http\ApiConnectionTests.cs" />
|
||||
<Compile Include="Clients\AuthorizationsClientTests.cs" />
|
||||
@@ -170,6 +171,7 @@
|
||||
<Compile Include="Reactive\ObservableTreesClientTests.cs" />
|
||||
<Compile Include="Reactive\ObservableFollowersTest.cs" />
|
||||
<Compile Include="Reactive\ObservableUserEmailsClientTests.cs" />
|
||||
<Compile Include="SelfTests.cs" />
|
||||
<Compile Include="SimpleJsonSerializerTests.cs" />
|
||||
<Compile Include="Clients\UsersClientTests.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -275,16 +275,31 @@ namespace Octokit.Tests.Reactive
|
||||
public class TheCommitsMethod
|
||||
{
|
||||
[Fact]
|
||||
public async void FetchesAllCommitsForPullRequest()
|
||||
public async Task FetchesAllCommitsForPullRequest()
|
||||
{
|
||||
var commit = new PullRequestCommit();
|
||||
var expectedUrl = string.Format("repos/fake/repo/pulls/42/commits");
|
||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||
var connection = Substitute.For<IConnection>();
|
||||
IResponse<List<PullRequestCommit>> response = new ApiResponse<List<PullRequestCommit>>
|
||||
{
|
||||
ApiInfo = new ApiInfo(
|
||||
new Dictionary<string, Uri>(),
|
||||
new List<string>(),
|
||||
new List<string>(),
|
||||
"",
|
||||
new RateLimit(new Dictionary<string, string>())),
|
||||
BodyAsObject = new List<PullRequestCommit> { commit }
|
||||
};
|
||||
connection.Get<List<PullRequestCommit>>(Args.Uri, null, null)
|
||||
.Returns(Task.FromResult(response));
|
||||
gitHubClient.Connection.Returns(connection);
|
||||
var client = new ObservablePullRequestsClient(gitHubClient);
|
||||
|
||||
client.Commits("fake", "repo", 42);
|
||||
var commits = await client.Commits("fake", "repo", 42).ToList();
|
||||
|
||||
Assert.Equal(1, commits.Count);
|
||||
Assert.Same(commit, commits[0]);
|
||||
connection.Received().Get<List<PullRequestCommit>>(new Uri(expectedUrl, UriKind.Relative), null, null);
|
||||
}
|
||||
|
||||
|
||||
14
Octokit.Tests/SelfTests.cs
Normal file
14
Octokit.Tests/SelfTests.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Xunit;
|
||||
|
||||
/// <summary>
|
||||
/// Tests to make sure our tests are ok.
|
||||
/// </summary>
|
||||
public class SelfTests
|
||||
{
|
||||
[Fact]
|
||||
public void NoTestsUseAsyncVoid()
|
||||
{
|
||||
var errors = typeof(SelfTests).Assembly.GetAsyncVoidMethodsList();
|
||||
Assert.Equal("", errors);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
VisualStudioVersion = 12.0.30723.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Octokit", "Octokit\Octokit.csproj", "{08DD4305-7787-4823-A53F-4D0F725A07F3}"
|
||||
EndProject
|
||||
@@ -11,6 +11,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Octokit.Tests.Integration",
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{CEC9D451-6291-4EDF-971A-D398144FBF96}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
appveyor.yml = appveyor.yml
|
||||
build.cmd = build.cmd
|
||||
build.fsx = build.fsx
|
||||
script\cibuild.ps1 = script\cibuild.ps1
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Octokit
|
||||
RateLimit rateLimit)
|
||||
{
|
||||
Ensure.ArgumentNotNull(links, "links");
|
||||
Ensure.ArgumentNotNull(oauthScopes, "ouathScopes");
|
||||
Ensure.ArgumentNotNull(oauthScopes, "oauthScopes");
|
||||
|
||||
Links = new ReadOnlyDictionary<string, Uri>(links);
|
||||
OauthScopes = new ReadOnlyCollection<string>(oauthScopes);
|
||||
|
||||
@@ -2,19 +2,22 @@
|
||||
{
|
||||
public class ProductHeaderValue
|
||||
{
|
||||
ProductHeaderValue() { }
|
||||
readonly System.Net.Http.Headers.ProductHeaderValue _productHeaderValue;
|
||||
|
||||
public ProductHeaderValue(string name)
|
||||
: this(new System.Net.Http.Headers.ProductHeaderValue(name))
|
||||
{
|
||||
_productHeaderValue = new System.Net.Http.Headers.ProductHeaderValue(name);
|
||||
}
|
||||
|
||||
public ProductHeaderValue(string name, string value)
|
||||
: this(new System.Net.Http.Headers.ProductHeaderValue(name, value))
|
||||
{
|
||||
_productHeaderValue = new System.Net.Http.Headers.ProductHeaderValue(name, value);
|
||||
}
|
||||
|
||||
System.Net.Http.Headers.ProductHeaderValue _productHeaderValue;
|
||||
ProductHeaderValue(System.Net.Http.Headers.ProductHeaderValue productHeader)
|
||||
{
|
||||
_productHeaderValue = productHeader;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
@@ -43,7 +46,7 @@
|
||||
|
||||
public static ProductHeaderValue Parse(string input)
|
||||
{
|
||||
return new ProductHeaderValue { _productHeaderValue = System.Net.Http.Headers.ProductHeaderValue.Parse(input) };
|
||||
return new ProductHeaderValue(System.Net.Http.Headers.ProductHeaderValue.Parse(input));
|
||||
}
|
||||
|
||||
public static bool TryParse(string input,
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Octokit
|
||||
[SuppressMessage("Microsoft.Design", "CA1012:AbstractTypesShouldNotHaveConstructors")]
|
||||
public abstract class BaseSearchRequest
|
||||
{
|
||||
public BaseSearchRequest(string term)
|
||||
protected BaseSearchRequest(string term)
|
||||
{
|
||||
Ensure.ArgumentNotNullOrEmptyString(term, "term");
|
||||
Term = term;
|
||||
@@ -80,15 +80,17 @@ namespace Octokit
|
||||
{
|
||||
get
|
||||
{
|
||||
var d = new Dictionary<string, string>();
|
||||
d.Add("page", Page.ToString(CultureInfo.CurrentCulture));
|
||||
d.Add("per_page", PerPage.ToString(CultureInfo.CurrentCulture));
|
||||
var d = new Dictionary<string, string>
|
||||
{
|
||||
{ "page", Page.ToString(CultureInfo.CurrentCulture) }
|
||||
, { "per_page", PerPage.ToString(CultureInfo.CurrentCulture) }
|
||||
, { "order", SortOrder }
|
||||
, { "q", TermAndQualifiers }
|
||||
};
|
||||
if (!String.IsNullOrWhiteSpace(Sort))
|
||||
{
|
||||
d.Add("sort", Sort);
|
||||
}
|
||||
d.Add("order", SortOrder);
|
||||
d.Add("q", TermAndQualifiers);
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,17 +22,17 @@ namespace Octokit
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>s
|
||||
/// Optional. Gets or sets whether to the enable downloads for the new repository. The default is true.
|
||||
/// Optional. Gets or sets whether to enable downloads for the new repository. The default is true.
|
||||
/// </summary>
|
||||
public bool? HasDownloads { get; set; }
|
||||
|
||||
/// <summary>s
|
||||
/// Optional. Gets or sets whether to the enable issues for the new repository. The default is true.
|
||||
/// Optional. Gets or sets whether to enable issues for the new repository. The default is true.
|
||||
/// </summary>
|
||||
public bool? HasIssues { get; set; }
|
||||
|
||||
/// <summary>s
|
||||
/// Optional. Gets or sets whether to the enable the wiki for the new repository. The default is true.
|
||||
/// Optional. Gets or sets whether to enable the wiki for the new repository. The default is true.
|
||||
/// </summary>
|
||||
public bool? HasWiki { get; set; }
|
||||
|
||||
|
||||
@@ -13,43 +13,24 @@ namespace Octokit
|
||||
/// http://developer.github.com/v3/search/#search-repositories
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public class SearchRepositoriesRequest
|
||||
public class SearchRepositoriesRequest : BaseSearchRequest
|
||||
{
|
||||
public SearchRepositoriesRequest(string term)
|
||||
: base(term)
|
||||
{
|
||||
Term = term;
|
||||
Page = 1;
|
||||
PerPage = 100;
|
||||
Fork = ForkQualifier.ExcludeForks;
|
||||
Order = SortDirection.Descending;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The search terms. This can be any combination of the supported repository search parameters:
|
||||
/// http://developer.github.com/v3/search/#search-repositories
|
||||
/// </summary>
|
||||
public string Term { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// For https://help.github.com/articles/searching-repositories#sorting
|
||||
/// Optional Sort field. One of stars, forks, or updated. If not provided, results are sorted by best match.
|
||||
/// </summary>
|
||||
public RepoSearchSort? Sort { get; set; }
|
||||
public RepoSearchSort? SortField { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sort order one of asc or desc - the default is desc.
|
||||
/// </summary>
|
||||
public SortDirection Order { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Page of paginated results
|
||||
/// </summary>
|
||||
public int Page { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of items per page
|
||||
/// </summary>
|
||||
public int PerPage { get; set; }
|
||||
public override string Sort
|
||||
{
|
||||
get { return SortField.ToParameter(); }
|
||||
}
|
||||
|
||||
private IEnumerable<InQualifier> _inQualifier;
|
||||
|
||||
@@ -82,7 +63,7 @@ namespace Octokit
|
||||
/// Defaults to ExcludeForks
|
||||
/// https://help.github.com/articles/searching-repositories#forks
|
||||
/// </summary>
|
||||
public ForkQualifier Fork { get; set; }
|
||||
public ForkQualifier? Fork { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The size qualifier finds repository's that match a certain size (in kilobytes).
|
||||
@@ -120,7 +101,7 @@ namespace Octokit
|
||||
/// </summary>
|
||||
public DateRange Updated { get; set; }
|
||||
|
||||
public string MergeParameters()
|
||||
public override IReadOnlyCollection<string> MergedQualifiers()
|
||||
{
|
||||
var parameters = new List<string>();
|
||||
|
||||
@@ -139,7 +120,10 @@ namespace Octokit
|
||||
parameters.Add(String.Format(CultureInfo.InvariantCulture, "forks:{0}", Forks));
|
||||
}
|
||||
|
||||
if (Fork != null)
|
||||
{
|
||||
parameters.Add(String.Format(CultureInfo.InvariantCulture, "fork:{0}", Fork));
|
||||
}
|
||||
|
||||
if (Stars != null)
|
||||
{
|
||||
@@ -165,26 +149,7 @@ namespace Octokit
|
||||
{
|
||||
parameters.Add(String.Format(CultureInfo.InvariantCulture, "pushed:{0}", Updated));
|
||||
}
|
||||
|
||||
return String.Join("+", parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// get the params in the correct format...
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString")]
|
||||
public IDictionary<string, string> Parameters
|
||||
{
|
||||
get
|
||||
{
|
||||
var d = new System.Collections.Generic.Dictionary<string, string>();
|
||||
d.Add("page", Page.ToString());
|
||||
d.Add("per_page", PerPage.ToString());
|
||||
d.Add("sort", Sort.ToString());
|
||||
d.Add("q", Term + " " + MergeParameters()); //add qualifiers onto the search term
|
||||
return d;
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
internal string DebuggerDisplay
|
||||
@@ -222,7 +187,7 @@ namespace Octokit
|
||||
[SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString")]
|
||||
public Range(int size)
|
||||
{
|
||||
query = size.ToString();
|
||||
query = size.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -230,34 +195,30 @@ namespace Octokit
|
||||
/// </summary>
|
||||
/// <param name="minSize"></param>
|
||||
/// <param name="maxSize"></param>
|
||||
[SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object)"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString")]
|
||||
public Range(int minSize, int maxSize)
|
||||
{
|
||||
query = string.Format("{0}..{1}", minSize, maxSize);
|
||||
query = string.Format(CultureInfo.InvariantCulture, "{0}..{1}", minSize, maxSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Matches repositories with regards to the size <see cref="size"/>
|
||||
/// We will use the <see cref="op"/> to see what operator will be applied to the size qualifier
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)")]
|
||||
public Range(int size, SearchQualifierOperator op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case SearchQualifierOperator.GreaterThan:
|
||||
query = string.Format(">{0}", size.ToString());
|
||||
query = string.Format(CultureInfo.InvariantCulture, ">{0}", size);
|
||||
break;
|
||||
case SearchQualifierOperator.LessThan:
|
||||
query = string.Format("<{0}", size.ToString());
|
||||
query = string.Format(CultureInfo.InvariantCulture, "<{0}", size);
|
||||
break;
|
||||
case SearchQualifierOperator.LessThanOrEqualTo:
|
||||
query = string.Format("<={0}", size.ToString());
|
||||
query = string.Format(CultureInfo.InvariantCulture, "<={0}", size);
|
||||
break;
|
||||
case SearchQualifierOperator.GreaterThanOrEqualTo:
|
||||
query = string.Format(">={0}", size.ToString());
|
||||
break;
|
||||
default:
|
||||
query = string.Format(CultureInfo.InvariantCulture, ">={0}", size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -306,7 +267,7 @@ namespace Octokit
|
||||
/// </summary>
|
||||
public class DateRange
|
||||
{
|
||||
private string query = string.Empty;
|
||||
private readonly string query = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Matches repositories with regards to the date <see cref="date"/>
|
||||
@@ -314,24 +275,21 @@ namespace Octokit
|
||||
/// </summary>
|
||||
/// <param name="date">The date</param>
|
||||
/// <param name="op">And its search operator</param>
|
||||
[SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object[])"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.DateTime.ToString(System.String)"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object)")]
|
||||
public DateRange(DateTime date, SearchQualifierOperator op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case SearchQualifierOperator.GreaterThan:
|
||||
query = string.Format(">{0}", date.ToString("yyyy-MM-dd"));
|
||||
query = string.Format(CultureInfo.InvariantCulture, ">{0:yyyy-MM-dd}", date);
|
||||
break;
|
||||
case SearchQualifierOperator.LessThan:
|
||||
query = string.Format("<{0}", date.ToString("yyyy-MM-dd"));
|
||||
query = string.Format(CultureInfo.InvariantCulture, "<{0:yyyy-MM-dd}", date);
|
||||
break;
|
||||
case SearchQualifierOperator.LessThanOrEqualTo:
|
||||
query = string.Format("<={0}", date.ToString("yyyy-MM-dd"));
|
||||
query = string.Format(CultureInfo.InvariantCulture, "<={0:yyyy-MM-dd}", date);
|
||||
break;
|
||||
case SearchQualifierOperator.GreaterThanOrEqualTo:
|
||||
query = string.Format(">={0}", date.ToString("yyyy-MM-dd"));
|
||||
break;
|
||||
default:
|
||||
query = string.Format(CultureInfo.InvariantCulture, ">={0:yyyy-MM-dd}", date);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -754,14 +712,17 @@ namespace Octokit
|
||||
/// <summary>
|
||||
/// search by number of stars
|
||||
/// </summary>
|
||||
[Parameter(Value = "stars")]
|
||||
Stars,
|
||||
/// <summary>
|
||||
/// search by number of forks
|
||||
/// </summary>
|
||||
[Parameter(Value = "forks")]
|
||||
Forks,
|
||||
/// <summary>
|
||||
/// search by last updated
|
||||
/// </summary>
|
||||
[Parameter(Value = "updated")]
|
||||
Updated
|
||||
}
|
||||
|
||||
@@ -774,14 +735,12 @@ namespace Octokit
|
||||
/// <summary>
|
||||
/// only search for forked repos
|
||||
/// </summary>
|
||||
[Parameter(Value = "Only")]
|
||||
OnlyForks,
|
||||
/// <summary>
|
||||
/// include forked repos into the search
|
||||
/// </summary>
|
||||
IncludeForks,
|
||||
/// <summary>
|
||||
/// forks are not included in the search (default behaviour)
|
||||
/// </summary>
|
||||
ExcludeForks
|
||||
[Parameter(Value = "True")]
|
||||
IncludeForks
|
||||
}
|
||||
}
|
||||
@@ -15,5 +15,6 @@ namespace Octokit
|
||||
public Author Committer { get; set; }
|
||||
public string HtmlUrl { get; set; }
|
||||
public IReadOnlyList<GitReference> Parents { get; set; }
|
||||
public IReadOnlyList<GitHubCommitFile> Files { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
68
Octokit/Models/Response/GitHubCommitFile.cs
Normal file
68
Octokit/Models/Response/GitHubCommitFile.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Octokit
|
||||
{
|
||||
/// <summary>
|
||||
/// The affected files in a <see cref="GitHubCommit"/>.
|
||||
/// </summary>
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public class GitHubCommitFile
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the file
|
||||
/// </summary>
|
||||
[SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly")]
|
||||
public string Filename { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of additions performed on the file.
|
||||
/// </summary>
|
||||
public int Additions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of deletions performed on the file.
|
||||
/// </summary>
|
||||
public int Deletions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of changes performed on the file.
|
||||
/// </summary>
|
||||
public int Changes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// File status, like modified, added, deleted.
|
||||
/// </summary>
|
||||
public string Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The url to the file blob.
|
||||
/// </summary>
|
||||
public string BlobUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The url to file contents API.
|
||||
/// </summary>
|
||||
public string ContentsUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The raw url to download the file.
|
||||
/// </summary>
|
||||
public string RawUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The SHA of the file.
|
||||
/// </summary>
|
||||
public string Sha { get; set; }
|
||||
|
||||
internal string DebuggerDisplay
|
||||
{
|
||||
get
|
||||
{
|
||||
return String.Format(CultureInfo.InvariantCulture, "Filename: {0} ({1})", Filename, Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,6 +130,7 @@
|
||||
<Compile Include="Models\Response\GistFile.cs" />
|
||||
<Compile Include="Models\Response\GistFork.cs" />
|
||||
<Compile Include="Models\Response\GistHistory.cs" />
|
||||
<Compile Include="Models\Response\GitHubCommitFile.cs" />
|
||||
<Compile Include="Models\Response\GitReference.cs" />
|
||||
<Compile Include="Models\Response\GitTag.cs" />
|
||||
<Compile Include="Models\Response\Issue.cs" />
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
<Compile Include="Models\Response\Blob.cs" />
|
||||
<Compile Include="Models\Response\CommitStatus.cs" />
|
||||
<Compile Include="Models\Response\EventInfo.cs" />
|
||||
<Compile Include="Models\Response\GitHubCommitFile.cs" />
|
||||
<Compile Include="Models\Response\GitReference.cs" />
|
||||
<Compile Include="Models\Response\GitTag.cs" />
|
||||
<Compile Include="Models\Response\Issue.cs" />
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
<Compile Include="Models\Response\Blob.cs" />
|
||||
<Compile Include="Models\Response\CommitStatus.cs" />
|
||||
<Compile Include="Models\Response\EventInfo.cs" />
|
||||
<Compile Include="Models\Response\GitHubCommitFile.cs" />
|
||||
<Compile Include="Models\Response\GitReference.cs" />
|
||||
<Compile Include="Models\Response\GitTag.cs" />
|
||||
<Compile Include="Models\Response\Issue.cs" />
|
||||
@@ -350,5 +351,5 @@
|
||||
<Compile Include="Models\Request\MarkAsReadRequest.cs" />
|
||||
<Compile Include="Models\Request\NewThreadSubscription.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.MonoTouch.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -222,6 +222,7 @@
|
||||
<Compile Include="Models\Response\GistFile.cs" />
|
||||
<Compile Include="Models\Response\GistFork.cs" />
|
||||
<Compile Include="Models\Response\GistHistory.cs" />
|
||||
<Compile Include="Models\Response\GitHubCommitFile.cs" />
|
||||
<Compile Include="Models\Response\GitReference.cs" />
|
||||
<Compile Include="Models\Response\GitTag.cs" />
|
||||
<Compile Include="Models\Response\EventInfo.cs" />
|
||||
|
||||
@@ -229,6 +229,7 @@
|
||||
<Compile Include="Models\Response\GistFile.cs" />
|
||||
<Compile Include="Models\Response\GistFork.cs" />
|
||||
<Compile Include="Models\Response\GistHistory.cs" />
|
||||
<Compile Include="Models\Response\GitHubCommitFile.cs" />
|
||||
<Compile Include="Models\Response\GitReference.cs" />
|
||||
<Compile Include="Models\Response\GitTag.cs" />
|
||||
<Compile Include="Models\Response\EventInfo.cs" />
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
<Compile Include="Models\Request\NotificationsRequest.cs" />
|
||||
<Compile Include="Models\Request\PublicKey.cs" />
|
||||
<Compile Include="Models\Request\CommitRequest.cs" />
|
||||
<Compile Include="Models\Response\GitHubCommitFile.cs" />
|
||||
<Compile Include="Models\Response\RepositoryPermissions.cs" />
|
||||
<Compile Include="Models\Request\NewThreadSubscription.cs" />
|
||||
<Compile Include="Models\Response\DeployKey.cs" />
|
||||
|
||||
13
appveyor.yml
Normal file
13
appveyor.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
build_script:
|
||||
- cmd: build.cmd BuildApp
|
||||
- cmd: build.cmd UnitTests
|
||||
- cmd: build.cmd IntegrationTests -ev OCTOKIT_GITHUBUSERNAME "%OCTOKIT_GITHUBUSERNAME%" -ev OCTOKIT_GITHUBPASSWORD "%OCTOKIT_GITHUBPASSWORD%"
|
||||
- cmd: build.cmd SourceLink
|
||||
#- cmd: build.cmd CreatePackages
|
||||
- cmd: build.cmd CreateOctokitPackage
|
||||
- cmd: build.cmd CreateOctokitReactivePackage
|
||||
test: off
|
||||
artifacts:
|
||||
- path: packaging\*.nupkg
|
||||
@@ -1,6 +1,7 @@
|
||||
@echo off
|
||||
|
||||
"tools\nuget\nuget.exe" "install" "FAKE.Core" "-OutputDirectory" "tools" "-ExcludeVersion" "-version" "3.5.8"
|
||||
"tools\nuget\nuget.exe" "install" "SourceLink.Fake" "-OutputDirectory" "tools" "-ExcludeVersion" "-version" "0.4.2"
|
||||
|
||||
:Build
|
||||
cls
|
||||
|
||||
25
build.fsx
25
build.fsx
@@ -1,6 +1,8 @@
|
||||
#r @"tools\FAKE.Core\tools\FakeLib.dll"
|
||||
#load "tools/SourceLink.Fake/tools/SourceLink.fsx"
|
||||
open Fake
|
||||
open System
|
||||
open SourceLink
|
||||
|
||||
let authors = ["GitHub"]
|
||||
|
||||
@@ -27,6 +29,8 @@ let releaseNotes =
|
||||
|
||||
let buildMode = getBuildParamOrDefault "buildMode" "Release"
|
||||
|
||||
MSBuildDefaults <- { MSBuildDefaults with Verbosity = Some MSBuildVerbosity.Minimal }
|
||||
|
||||
Target "Clean" (fun _ ->
|
||||
CleanDirs [buildDir; reactiveBuildDir; testResultsDir; packagingRoot; packagingDir; reactivePackagingDir]
|
||||
)
|
||||
@@ -94,6 +98,23 @@ Target "IntegrationTests" (fun _ ->
|
||||
|> traceImportant
|
||||
)
|
||||
|
||||
Target "SourceLink" (fun _ ->
|
||||
use repo = new GitRepo(__SOURCE_DIRECTORY__)
|
||||
[ "Octokit/Octokit.csproj"
|
||||
"Octokit/Octokit-netcore45.csproj"
|
||||
"Octokit/Octokit-Portable.csproj"
|
||||
"Octokit.Reactive/Octokit.Reactive.csproj" ]
|
||||
|> Seq.iter (fun pf ->
|
||||
let proj = VsProj.LoadRelease pf
|
||||
logfn "source linking %s" proj.OutputFilePdb
|
||||
let files = (proj.Compiles -- "SolutionInfo.cs").SetBaseDirectory __SOURCE_DIRECTORY__
|
||||
repo.VerifyChecksums files
|
||||
proj.VerifyPdbChecksums files
|
||||
proj.CreateSrcSrv "https://raw.githubusercontent.com/octokit/octokit.net/{0}/%var2%" repo.Revision (repo.Paths files)
|
||||
Pdbstr.exec proj.OutputFilePdb proj.OutputFilePdbSrcSrv
|
||||
)
|
||||
)
|
||||
|
||||
Target "CreateOctokitPackage" (fun _ ->
|
||||
let net45Dir = packagingDir @@ "lib/net45/"
|
||||
let netcore45Dir = packagingDir @@ "lib/netcore45/"
|
||||
@@ -102,10 +123,13 @@ Target "CreateOctokitPackage" (fun _ ->
|
||||
|
||||
CopyFile net45Dir (buildDir @@ "Release/Net45/Octokit.dll")
|
||||
CopyFile net45Dir (buildDir @@ "Release/Net45/Octokit.XML")
|
||||
CopyFile net45Dir (buildDir @@ "Release/Net45/Octokit.pdb")
|
||||
CopyFile netcore45Dir (buildDir @@ "Release/NetCore45/Octokit.dll")
|
||||
CopyFile netcore45Dir (buildDir @@ "Release/NetCore45/Octokit.XML")
|
||||
CopyFile netcore45Dir (buildDir @@ "Release/NetCore45/Octokit.pdb")
|
||||
CopyFile portableDir (buildDir @@ "Release/Portable/Octokit.dll")
|
||||
CopyFile portableDir (buildDir @@ "Release/Portable/Octokit.XML")
|
||||
CopyFile portableDir (buildDir @@ "Release/Portable/Octokit.pdb")
|
||||
CopyFiles packagingDir ["LICENSE.txt"; "README.md"; "ReleaseNotes.md"]
|
||||
|
||||
NuGet (fun p ->
|
||||
@@ -128,6 +152,7 @@ Target "CreateOctokitReactivePackage" (fun _ ->
|
||||
|
||||
CopyFile net45Dir (reactiveBuildDir @@ "Release/Net45/Octokit.Reactive.dll")
|
||||
CopyFile net45Dir (reactiveBuildDir @@ "Release/Net45/Octokit.Reactive.XML")
|
||||
CopyFile net45Dir (reactiveBuildDir @@ "Release/Net45/Octokit.Reactive.pdb")
|
||||
CopyFiles reactivePackagingDir ["LICENSE.txt"; "README.md"; "ReleaseNotes.md"]
|
||||
|
||||
NuGet (fun p ->
|
||||
|
||||
63
docs/getting-started.md
Normal file
63
docs/getting-started.md
Normal file
@@ -0,0 +1,63 @@
|
||||
## Getting Started
|
||||
|
||||
The easiest way to get started with Octokit is to use a plain `GitHubClient`:
|
||||
|
||||
```
|
||||
var client = new GitHubClient(new ProductHeaderValue("my-cool-app"));
|
||||
```
|
||||
|
||||
This will let you access unauthenticated GitHub APIs, but you will be subject to rate limiting (you can read more about this [here](https://developer.github.com/v3/#rate-limiting)).
|
||||
|
||||
But why do you need this `ProductHeaderValue` value?
|
||||
|
||||
The API will reject you if you don't provide a `User-Agent` header (more details [here](https://developer.github.com/v3/#user-agent-required)). This is also to identify applications that are accessing the API and enable GitHub to contact the application author if there are problems. So pick a name that stands out!
|
||||
|
||||
### Authenticated Access
|
||||
|
||||
If you want to access private repositories or perform actions on behalf of a user, you need to pass credentials to the client.
|
||||
|
||||
There are two options supported by the API - basic and OAuth authentication.
|
||||
|
||||
```
|
||||
var basicAuth = new Credentials("username", "password"); // NOTE: not real credentials
|
||||
client.Credentials = basicAuth;
|
||||
```
|
||||
|
||||
```
|
||||
var tokenAuth = new Credentials("token"); // NOTE: not real token
|
||||
client.Credentials = tokenAuth;
|
||||
```
|
||||
|
||||
It is **strongly recommended** to use the [OAuth Flow](https://github.com/octokit/octokit.net/blob/master/docs/oauth-flow.md) for interactions on behalf of a user, as this gives two significant benefits:
|
||||
|
||||
- the application owner never needs to store a user's password
|
||||
- the token can be revoked by the user at a later date
|
||||
|
||||
When authenticated, you have 5000 requests per hour available. So this is the recommended approach for interacting with the API.
|
||||
|
||||
### Connecting to GitHub Enterprise
|
||||
|
||||
Octokit also supports connecting to GitHub Enterprise environments - just provide the URL to your GitHub Enterprise server when creating the client.
|
||||
|
||||
```
|
||||
var ghe = new Uri("https://github.myenterprise.com/");
|
||||
var client = new GitHubClient(new ProductHeaderValue("my-cool-app"), ghe);
|
||||
```
|
||||
|
||||
### Get exploring
|
||||
|
||||
Once you've got that setup, the simplest thing to experiment with is fetching details about a specific user:
|
||||
|
||||
```
|
||||
var user = await client.User.Get("shiftkey");
|
||||
Console.WriteLine("{0} has {1} public repositories - go check out their profile at {1}",
|
||||
user.Name,
|
||||
user.PublicRepos,
|
||||
user.Url);
|
||||
```
|
||||
|
||||
If you've authenticated as a given user, you can query their details directly:
|
||||
|
||||
```
|
||||
var user = await client.User.Current();
|
||||
```
|
||||
@@ -2,12 +2,16 @@
|
||||
|
||||
This is a place for putting together some introductory documentation about how to use Octokit.net.
|
||||
|
||||
- [Getting Started](https://github.com/octokit/octokit.net/blob/master/docs/getting-started.md)
|
||||
- [OAuth Flow](https://github.com/octokit/octokit.net/blob/master/docs/oauth-flow.md)
|
||||
- [Releases API](https://github.com/octokit/octokit.net/blob/master/docs/releases.md)
|
||||
- [Git Database API](https://github.com/octokit/octokit.net/blob/master/docs/releases.md)
|
||||
|
||||
|
||||
Possible topics to cover:
|
||||
|
||||
- Authentication
|
||||
- Working with Repositories
|
||||
- Working with User data
|
||||
- Working with Git data
|
||||
- Searching Repositories
|
||||
- ...
|
||||
|
||||
@@ -16,4 +20,5 @@ If you're not sure where to start, there's a suite of
|
||||
which can help you to get familiar with how things currently work.
|
||||
|
||||
Love and Octocats,
|
||||
|
||||
The Octokit.net Team
|
||||
|
||||
100
docs/oauth-flow.md
Normal file
100
docs/oauth-flow.md
Normal file
@@ -0,0 +1,100 @@
|
||||
## OAuth Flow
|
||||
|
||||
If you have a service which needs to interact with the GitHub API on behalf of a user, you should use the OAuth flow. [Phil Haack](https://haacked.com) has written a great [blog post](http://haacked.com/archive/2014/04/24/octokit-oauth/) on using Octokit in ASP.NET, and even has a [demo project](https://github.com/Haacked/octokit-oauth-demo) you can try out, so this will just go over the specific APIs in more detail.
|
||||
|
||||
### Setup
|
||||
|
||||
First, you need to register your application on GitHub (or GitHub Enterprise). While logged in, go to your account settings and click the Applications tab. Then click "Register new application".
|
||||
|
||||
Or just navigate to [https://github.com/settings/applications/new](https://github.com/settings/applications/new) if you're lazy.
|
||||
|
||||
Fill in some details about your application:
|
||||
|
||||

|
||||
|
||||
Then click "Register application", and you'll get your client id and client secret.
|
||||
|
||||

|
||||
|
||||
### Starting the OAuth Flow
|
||||
|
||||
We'll use these in a few places, so define these as private fields:
|
||||
|
||||
```
|
||||
var clientId = "some-id-here";
|
||||
var clientSecret = "some-id-here";
|
||||
var client = new GitHubClient(new ProductHeaderValue("my-cool-app"));
|
||||
```
|
||||
|
||||
To start the authentication flow, you need to craft a URL indicating your application needs to authenticate on behalf of the current user.
|
||||
|
||||
```
|
||||
// NOTE: this is not required, but highly recommended!
|
||||
// ask the ASP.NET Membership provider to generate a random value
|
||||
// and store it in the current user's session
|
||||
string csrf = Membership.GeneratePassword(24, 1);
|
||||
Session["CSRF:State"] = csrf;
|
||||
|
||||
var request = new OauthLoginRequest(clientId)
|
||||
{
|
||||
Scopes = {"user", "notifications"},
|
||||
State = csrf
|
||||
};
|
||||
|
||||
// NOTE: user must be navigated to this URL
|
||||
var oauthLoginUrl = client.Oauth.GetGitHubLoginUrl(request);
|
||||
```
|
||||
|
||||
Scopes are keys which specify the permissions the application needs. If you don't specify a `Scopes` value, your application will only have read access to the user's public data (repository, user info, etc). There's lots of different scopes available for different interactions with user data, so have a look at the [documentation](https://developer.github.com/v3/oauth/#scopes) for more information.
|
||||
|
||||
### Generating the token
|
||||
|
||||
Once the user has been navigated to the URL above and clicked "Authorize Application", you will receive a callback at the default Callback URL for your application. If you require a more flexible URL, you can override this by specifying a different URL when creating the request.
|
||||
|
||||
```
|
||||
var request = new OauthLoginRequest(clientId)
|
||||
{
|
||||
// other parameters
|
||||
RedirectUri = new Url("https://mycoolsite.com/some/uri")
|
||||
};
|
||||
```
|
||||
|
||||
The callback will have two parameters, the code generated by the GitHub API and some additional state - this is specifically to prevent CSRF (Cross-Site Request Forgery) attacks and is highly recommended.
|
||||
|
||||
With this code you can then request an access token by providing your client secret. This doesn't require any user interaction, so it can be done in the background.
|
||||
|
||||
```
|
||||
public async Task<ActionResult> Authorize(string code, string state)
|
||||
{
|
||||
if (String.IsNullOrEmpty(code))
|
||||
return RedirectToAction("Index");
|
||||
|
||||
var expectedState = Session["CSRF:State"] as string;
|
||||
if (state != expectedState) throw new InvalidOperationException("SECURITY FAIL!");
|
||||
Session["CSRF:State"] = null;
|
||||
|
||||
var request = new OauthTokenRequest(clientId, clientSecret, code);
|
||||
var token = await client.Oauth.CreateAccessToken(request);
|
||||
Session["OAuthToken"] = token.AccessToken;
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
```
|
||||
|
||||
And now you have an access token, you can set up your credentials to use this token:
|
||||
|
||||
```
|
||||
// repositories which include public and private repositories.
|
||||
public async Task<ActionResult> Index()
|
||||
{
|
||||
var accessToken = Session["OAuthToken"] as string;
|
||||
if (accessToken != null)
|
||||
{
|
||||
client.Credentials = new Credentials(accessToken);
|
||||
|
||||
var repositories = await client.Repository.GetAllForCurrent();
|
||||
}
|
||||
|
||||
/* TODO: all the rest of the webapp */
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user