mirror of
https://github.com/zoriya/octokit.net.git
synced 2025-12-20 14:15:12 +00:00
Make Issue readonly and fix a bug
Found a bug in which we were using Name when we should be using Login.
This commit is contained in:
267
Octokit.Tests/Models/IssueTest.cs
Normal file
267
Octokit.Tests/Models/IssueTest.cs
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Octokit;
|
||||||
|
using Octokit.Internal;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
public class IssueTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void CanBeDeserialized()
|
||||||
|
{
|
||||||
|
const string json = @"{
|
||||||
|
""id"": 1,
|
||||||
|
""url"": ""https://api.github.com/repos/octocat/Hello-World/issues/1347"",
|
||||||
|
""html_url"": ""https://github.com/octocat/Hello-World/issues/1347"",
|
||||||
|
""number"": 1347,
|
||||||
|
""state"": ""open"",
|
||||||
|
""title"": ""Found a bug"",
|
||||||
|
""body"": ""I'm having a problem with this."",
|
||||||
|
""user"": {
|
||||||
|
""login"": ""octocat"",
|
||||||
|
""id"": 1,
|
||||||
|
""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"",
|
||||||
|
""gravatar_id"": """",
|
||||||
|
""url"": ""https://api.github.com/users/octocat"",
|
||||||
|
""html_url"": ""https://github.com/octocat"",
|
||||||
|
""followers_url"": ""https://api.github.com/users/octocat/followers"",
|
||||||
|
""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"",
|
||||||
|
""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"",
|
||||||
|
""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"",
|
||||||
|
""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"",
|
||||||
|
""organizations_url"": ""https://api.github.com/users/octocat/orgs"",
|
||||||
|
""repos_url"": ""https://api.github.com/users/octocat/repos"",
|
||||||
|
""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"",
|
||||||
|
""received_events_url"": ""https://api.github.com/users/octocat/received_events"",
|
||||||
|
""type"": ""User"",
|
||||||
|
""site_admin"": false
|
||||||
|
},
|
||||||
|
""labels"": [
|
||||||
|
{
|
||||||
|
""url"": ""https://api.github.com/repos/octocat/Hello-World/labels/bug"",
|
||||||
|
""name"": ""bug"",
|
||||||
|
""color"": ""f29513""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
""assignee"": {
|
||||||
|
""login"": ""octocat"",
|
||||||
|
""id"": 1,
|
||||||
|
""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"",
|
||||||
|
""gravatar_id"": """",
|
||||||
|
""url"": ""https://api.github.com/users/octocat"",
|
||||||
|
""html_url"": ""https://github.com/octocat"",
|
||||||
|
""followers_url"": ""https://api.github.com/users/octocat/followers"",
|
||||||
|
""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"",
|
||||||
|
""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"",
|
||||||
|
""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"",
|
||||||
|
""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"",
|
||||||
|
""organizations_url"": ""https://api.github.com/users/octocat/orgs"",
|
||||||
|
""repos_url"": ""https://api.github.com/users/octocat/repos"",
|
||||||
|
""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"",
|
||||||
|
""received_events_url"": ""https://api.github.com/users/octocat/received_events"",
|
||||||
|
""type"": ""User"",
|
||||||
|
""site_admin"": false
|
||||||
|
},
|
||||||
|
""milestone"": {
|
||||||
|
""url"": ""https://api.github.com/repos/octocat/Hello-World/milestones/1"",
|
||||||
|
""number"": 1,
|
||||||
|
""state"": ""open"",
|
||||||
|
""title"": ""v1.0"",
|
||||||
|
""description"": """",
|
||||||
|
""creator"": {
|
||||||
|
""login"": ""octocat"",
|
||||||
|
""id"": 1,
|
||||||
|
""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"",
|
||||||
|
""gravatar_id"": """",
|
||||||
|
""url"": ""https://api.github.com/users/octocat"",
|
||||||
|
""html_url"": ""https://github.com/octocat"",
|
||||||
|
""followers_url"": ""https://api.github.com/users/octocat/followers"",
|
||||||
|
""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"",
|
||||||
|
""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"",
|
||||||
|
""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"",
|
||||||
|
""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"",
|
||||||
|
""organizations_url"": ""https://api.github.com/users/octocat/orgs"",
|
||||||
|
""repos_url"": ""https://api.github.com/users/octocat/repos"",
|
||||||
|
""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"",
|
||||||
|
""received_events_url"": ""https://api.github.com/users/octocat/received_events"",
|
||||||
|
""type"": ""User"",
|
||||||
|
""site_admin"": false
|
||||||
|
},
|
||||||
|
""open_issues"": 4,
|
||||||
|
""closed_issues"": 8,
|
||||||
|
""created_at"": ""2011-04-10T20:09:31Z"",
|
||||||
|
""updated_at"": ""2014-03-03T18:58:10Z"",
|
||||||
|
""closed_at"": ""2013-02-12T13:22:01Z"",
|
||||||
|
""due_on"": null
|
||||||
|
},
|
||||||
|
""comments"": 0,
|
||||||
|
""pull_request"": {
|
||||||
|
""url"": ""https://api.github.com/repos/octocat/Hello-World/pulls/1347"",
|
||||||
|
""html_url"": ""https://github.com/octocat/Hello-World/pull/1347"",
|
||||||
|
""diff_url"": ""https://github.com/octocat/Hello-World/pull/1347.diff"",
|
||||||
|
""patch_url"": ""https://github.com/octocat/Hello-World/pull/1347.patch""
|
||||||
|
},
|
||||||
|
""closed_at"": null,
|
||||||
|
""created_at"": ""2011-04-22T13:33:48Z"",
|
||||||
|
""updated_at"": ""2011-04-22T13:33:48Z"",
|
||||||
|
""closed_by"": {
|
||||||
|
""login"": ""octocat"",
|
||||||
|
""id"": 1,
|
||||||
|
""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"",
|
||||||
|
""gravatar_id"": """",
|
||||||
|
""url"": ""https://api.github.com/users/octocat"",
|
||||||
|
""html_url"": ""https://github.com/octocat"",
|
||||||
|
""followers_url"": ""https://api.github.com/users/octocat/followers"",
|
||||||
|
""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"",
|
||||||
|
""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"",
|
||||||
|
""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"",
|
||||||
|
""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"",
|
||||||
|
""organizations_url"": ""https://api.github.com/users/octocat/orgs"",
|
||||||
|
""repos_url"": ""https://api.github.com/users/octocat/repos"",
|
||||||
|
""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"",
|
||||||
|
""received_events_url"": ""https://api.github.com/users/octocat/received_events"",
|
||||||
|
""type"": ""User"",
|
||||||
|
""site_admin"": false
|
||||||
|
}
|
||||||
|
}";
|
||||||
|
var serializer = new SimpleJsonSerializer();
|
||||||
|
|
||||||
|
var issue = serializer.Deserialize<Issue>(json);
|
||||||
|
|
||||||
|
Assert.Equal(1347, issue.Number);
|
||||||
|
Assert.Equal("octocat", issue.User.Login);
|
||||||
|
Assert.Equal("bug", issue.Labels.First().Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TheToUpdateMethod
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void CreatesAnIssueUpdateRequestObject()
|
||||||
|
{
|
||||||
|
const string json = @"{
|
||||||
|
""id"": 1,
|
||||||
|
""url"": ""https://api.github.com/repos/octocat/Hello-World/issues/1347"",
|
||||||
|
""html_url"": ""https://github.com/octocat/Hello-World/issues/1347"",
|
||||||
|
""number"": 1347,
|
||||||
|
""state"": ""open"",
|
||||||
|
""title"": ""Found a bug"",
|
||||||
|
""body"": ""I'm having a problem with this."",
|
||||||
|
""user"": {
|
||||||
|
""login"": ""octocat"",
|
||||||
|
""id"": 1,
|
||||||
|
""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"",
|
||||||
|
""gravatar_id"": """",
|
||||||
|
""url"": ""https://api.github.com/users/octocat"",
|
||||||
|
""html_url"": ""https://github.com/octocat"",
|
||||||
|
""followers_url"": ""https://api.github.com/users/octocat/followers"",
|
||||||
|
""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"",
|
||||||
|
""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"",
|
||||||
|
""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"",
|
||||||
|
""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"",
|
||||||
|
""organizations_url"": ""https://api.github.com/users/octocat/orgs"",
|
||||||
|
""repos_url"": ""https://api.github.com/users/octocat/repos"",
|
||||||
|
""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"",
|
||||||
|
""received_events_url"": ""https://api.github.com/users/octocat/received_events"",
|
||||||
|
""type"": ""User"",
|
||||||
|
""site_admin"": false
|
||||||
|
},
|
||||||
|
""labels"": [
|
||||||
|
{
|
||||||
|
""url"": ""https://api.github.com/repos/octocat/Hello-World/labels/bug"",
|
||||||
|
""name"": ""bug"",
|
||||||
|
""color"": ""f29513""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
""assignee"": {
|
||||||
|
""login"": ""octocat"",
|
||||||
|
""id"": 1,
|
||||||
|
""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"",
|
||||||
|
""gravatar_id"": """",
|
||||||
|
""url"": ""https://api.github.com/users/octocat"",
|
||||||
|
""html_url"": ""https://github.com/octocat"",
|
||||||
|
""followers_url"": ""https://api.github.com/users/octocat/followers"",
|
||||||
|
""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"",
|
||||||
|
""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"",
|
||||||
|
""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"",
|
||||||
|
""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"",
|
||||||
|
""organizations_url"": ""https://api.github.com/users/octocat/orgs"",
|
||||||
|
""repos_url"": ""https://api.github.com/users/octocat/repos"",
|
||||||
|
""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"",
|
||||||
|
""received_events_url"": ""https://api.github.com/users/octocat/received_events"",
|
||||||
|
""type"": ""User"",
|
||||||
|
""site_admin"": false
|
||||||
|
},
|
||||||
|
""milestone"": {
|
||||||
|
""url"": ""https://api.github.com/repos/octocat/Hello-World/milestones/1"",
|
||||||
|
""number"": 1,
|
||||||
|
""state"": ""open"",
|
||||||
|
""title"": ""v1.0"",
|
||||||
|
""description"": """",
|
||||||
|
""creator"": {
|
||||||
|
""login"": ""octocat"",
|
||||||
|
""id"": 1,
|
||||||
|
""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"",
|
||||||
|
""gravatar_id"": """",
|
||||||
|
""url"": ""https://api.github.com/users/octocat"",
|
||||||
|
""html_url"": ""https://github.com/octocat"",
|
||||||
|
""followers_url"": ""https://api.github.com/users/octocat/followers"",
|
||||||
|
""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"",
|
||||||
|
""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"",
|
||||||
|
""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"",
|
||||||
|
""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"",
|
||||||
|
""organizations_url"": ""https://api.github.com/users/octocat/orgs"",
|
||||||
|
""repos_url"": ""https://api.github.com/users/octocat/repos"",
|
||||||
|
""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"",
|
||||||
|
""received_events_url"": ""https://api.github.com/users/octocat/received_events"",
|
||||||
|
""type"": ""User"",
|
||||||
|
""site_admin"": false
|
||||||
|
},
|
||||||
|
""open_issues"": 4,
|
||||||
|
""closed_issues"": 8,
|
||||||
|
""created_at"": ""2011-04-10T20:09:31Z"",
|
||||||
|
""updated_at"": ""2014-03-03T18:58:10Z"",
|
||||||
|
""closed_at"": ""2013-02-12T13:22:01Z"",
|
||||||
|
""due_on"": null
|
||||||
|
},
|
||||||
|
""comments"": 0,
|
||||||
|
""pull_request"": {
|
||||||
|
""url"": ""https://api.github.com/repos/octocat/Hello-World/pulls/1347"",
|
||||||
|
""html_url"": ""https://github.com/octocat/Hello-World/pull/1347"",
|
||||||
|
""diff_url"": ""https://github.com/octocat/Hello-World/pull/1347.diff"",
|
||||||
|
""patch_url"": ""https://github.com/octocat/Hello-World/pull/1347.patch""
|
||||||
|
},
|
||||||
|
""closed_at"": null,
|
||||||
|
""created_at"": ""2011-04-22T13:33:48Z"",
|
||||||
|
""updated_at"": ""2011-04-22T13:33:48Z"",
|
||||||
|
""closed_by"": {
|
||||||
|
""login"": ""octocat"",
|
||||||
|
""id"": 1,
|
||||||
|
""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"",
|
||||||
|
""gravatar_id"": """",
|
||||||
|
""url"": ""https://api.github.com/users/octocat"",
|
||||||
|
""html_url"": ""https://github.com/octocat"",
|
||||||
|
""followers_url"": ""https://api.github.com/users/octocat/followers"",
|
||||||
|
""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"",
|
||||||
|
""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"",
|
||||||
|
""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"",
|
||||||
|
""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"",
|
||||||
|
""organizations_url"": ""https://api.github.com/users/octocat/orgs"",
|
||||||
|
""repos_url"": ""https://api.github.com/users/octocat/repos"",
|
||||||
|
""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"",
|
||||||
|
""received_events_url"": ""https://api.github.com/users/octocat/received_events"",
|
||||||
|
""type"": ""User"",
|
||||||
|
""site_admin"": false
|
||||||
|
}
|
||||||
|
}";
|
||||||
|
var serializer = new SimpleJsonSerializer();
|
||||||
|
var issue = serializer.Deserialize<Issue>(json);
|
||||||
|
|
||||||
|
var update = issue.ToUpdate();
|
||||||
|
|
||||||
|
Assert.Equal("bug", update.Labels.Single());
|
||||||
|
Assert.Equal(1, update.Milestone.GetValueOrDefault());
|
||||||
|
Assert.Equal("octocat", update.Assignee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -126,6 +126,7 @@
|
|||||||
<Compile Include="Models\DeploymentStatusTests.cs" />
|
<Compile Include="Models\DeploymentStatusTests.cs" />
|
||||||
<Compile Include="Models\DeploymentTests.cs" />
|
<Compile Include="Models\DeploymentTests.cs" />
|
||||||
<Compile Include="Models\IssueRequestTests.cs" />
|
<Compile Include="Models\IssueRequestTests.cs" />
|
||||||
|
<Compile Include="Models\IssueTest.cs" />
|
||||||
<Compile Include="Models\MilestoneRequestTests.cs" />
|
<Compile Include="Models\MilestoneRequestTests.cs" />
|
||||||
<Compile Include="Models\ModelExtensionsTests.cs" />
|
<Compile Include="Models\ModelExtensionsTests.cs" />
|
||||||
<Compile Include="Models\NewReferenceTests.cs" />
|
<Compile Include="Models\NewReferenceTests.cs" />
|
||||||
|
|||||||
@@ -126,6 +126,7 @@
|
|||||||
<Compile Include="Models\DeploymentStatusTests.cs" />
|
<Compile Include="Models\DeploymentStatusTests.cs" />
|
||||||
<Compile Include="Models\DeploymentTests.cs" />
|
<Compile Include="Models\DeploymentTests.cs" />
|
||||||
<Compile Include="Models\IssueRequestTests.cs" />
|
<Compile Include="Models\IssueRequestTests.cs" />
|
||||||
|
<Compile Include="Models\IssueTest.cs" />
|
||||||
<Compile Include="Models\MilestoneRequestTests.cs" />
|
<Compile Include="Models\MilestoneRequestTests.cs" />
|
||||||
<Compile Include="Models\ModelExtensionsTests.cs" />
|
<Compile Include="Models\ModelExtensionsTests.cs" />
|
||||||
<Compile Include="Models\NewReferenceTests.cs" />
|
<Compile Include="Models\NewReferenceTests.cs" />
|
||||||
|
|||||||
@@ -140,6 +140,7 @@
|
|||||||
<Compile Include="Http\RequestTests.cs" />
|
<Compile Include="Http\RequestTests.cs" />
|
||||||
<Compile Include="Models\DeploymentStatusTests.cs" />
|
<Compile Include="Models\DeploymentStatusTests.cs" />
|
||||||
<Compile Include="Models\DeploymentTests.cs" />
|
<Compile Include="Models\DeploymentTests.cs" />
|
||||||
|
<Compile Include="Models\IssueTest.cs" />
|
||||||
<Compile Include="Models\NewReferenceTests.cs" />
|
<Compile Include="Models\NewReferenceTests.cs" />
|
||||||
<Compile Include="Models\MilestoneRequestTests.cs" />
|
<Compile Include="Models\MilestoneRequestTests.cs" />
|
||||||
<Compile Include="Models\IssueRequestTests.cs" />
|
<Compile Include="Models\IssueRequestTests.cs" />
|
||||||
|
|||||||
@@ -9,344 +9,349 @@ using System.Reactive.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
public class ObservableIssuesClientTests
|
public class ObservableIssuesClientTests
|
||||||
|
{
|
||||||
|
public class TheGetMethod
|
||||||
{
|
{
|
||||||
public class TheGetMethod
|
[Fact]
|
||||||
|
public void GetsFromClientIssueIssue()
|
||||||
{
|
{
|
||||||
[Fact]
|
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||||
public void GetsFromClientIssueIssue()
|
var client = new ObservableIssuesClient(gitHubClient);
|
||||||
{
|
|
||||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
|
||||||
var client = new ObservableIssuesClient(gitHubClient);
|
|
||||||
|
|
||||||
client.Get("fake", "repo", 42);
|
client.Get("fake", "repo", 42);
|
||||||
|
|
||||||
gitHubClient.Issue.Received().Get("fake", "repo", 42);
|
gitHubClient.Issue.Received().Get("fake", "repo", 42);
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EnsuresNonNullArguments()
|
|
||||||
{
|
|
||||||
var client = new ObservableIssuesClient(Substitute.For<IGitHubClient>());
|
|
||||||
|
|
||||||
await AssertEx.Throws<ArgumentNullException>(async () => await client.Get(null, "name", 1));
|
|
||||||
await AssertEx.Throws<ArgumentNullException>(async () => await client.Get("owner", null, 1));
|
|
||||||
await AssertEx.Throws<ArgumentException>(async () => await client.Get(null, "", 1));
|
|
||||||
await AssertEx.Throws<ArgumentException>(async () => await client.Get("", null, 1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TheGetForRepositoryMethod
|
[Fact]
|
||||||
|
public async Task EnsuresNonNullArguments()
|
||||||
{
|
{
|
||||||
[Fact]
|
var client = new ObservableIssuesClient(Substitute.For<IGitHubClient>());
|
||||||
public async Task ReturnsEveryPageOfIssues()
|
|
||||||
{
|
|
||||||
var firstPageUrl = new Uri("repos/fake/repo/issues", UriKind.Relative);
|
|
||||||
var secondPageUrl = new Uri("https://example.com/page/2");
|
|
||||||
var firstPageLinks = new Dictionary<string, Uri> { { "next", secondPageUrl } };
|
|
||||||
var firstPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 1},
|
|
||||||
new Issue {Number = 2},
|
|
||||||
new Issue {Number = 3},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(firstPageLinks)
|
|
||||||
};
|
|
||||||
var thirdPageUrl = new Uri("https://example.com/page/3");
|
|
||||||
var secondPageLinks = new Dictionary<string, Uri> { { "next", thirdPageUrl } };
|
|
||||||
var secondPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 4},
|
|
||||||
new Issue {Number = 5},
|
|
||||||
new Issue {Number = 6},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(secondPageLinks)
|
|
||||||
};
|
|
||||||
var lastPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 7},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(new Dictionary<string, Uri>())
|
|
||||||
};
|
|
||||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(Arg.Is(firstPageUrl),
|
|
||||||
Arg.Is<Dictionary<string, string>>(d => d.Count == 4
|
|
||||||
&& d["direction"] == "desc"
|
|
||||||
&& d["state"] == "open"
|
|
||||||
&& d["sort"] == "created"
|
|
||||||
&& d["filter"] == "assigned"), Arg.Any<string>())
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => firstPageResponse));
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(secondPageUrl, null, null)
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => secondPageResponse));
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(thirdPageUrl, null, null)
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => lastPageResponse));
|
|
||||||
var client = new ObservableIssuesClient(gitHubClient);
|
|
||||||
|
|
||||||
var results = await client.GetForRepository("fake", "repo").ToArray();
|
await AssertEx.Throws<ArgumentNullException>(async () => await client.Get(null, "name", 1));
|
||||||
|
await AssertEx.Throws<ArgumentNullException>(async () => await client.Get("owner", null, 1));
|
||||||
Assert.Equal(7, results.Length);
|
await AssertEx.Throws<ArgumentException>(async () => await client.Get(null, "", 1));
|
||||||
Assert.Equal(firstPageResponse.BodyAsObject[0].Number, results[0].Number);
|
await AssertEx.Throws<ArgumentException>(async () => await client.Get("", null, 1));
|
||||||
Assert.Equal(secondPageResponse.BodyAsObject[1].Number, results[4].Number);
|
|
||||||
Assert.Equal(lastPageResponse.BodyAsObject[0].Number, results[6].Number);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TheGetAllForOwnedAndMemberRepositoriesMethod
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public async Task ReturnsEveryPageOfIssues()
|
|
||||||
{
|
|
||||||
var firstPageUrl = new Uri("user/issues", UriKind.Relative);
|
|
||||||
var secondPageUrl = new Uri("https://example.com/page/2");
|
|
||||||
var firstPageLinks = new Dictionary<string, Uri> { { "next", secondPageUrl } };
|
|
||||||
var firstPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 1},
|
|
||||||
new Issue {Number = 2},
|
|
||||||
new Issue {Number = 3},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(firstPageLinks)
|
|
||||||
};
|
|
||||||
var thirdPageUrl = new Uri("https://example.com/page/3");
|
|
||||||
var secondPageLinks = new Dictionary<string, Uri> { { "next", thirdPageUrl } };
|
|
||||||
var secondPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 4},
|
|
||||||
new Issue {Number = 5},
|
|
||||||
new Issue {Number = 6},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(secondPageLinks)
|
|
||||||
};
|
|
||||||
var lastPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 7},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(new Dictionary<string, Uri>())
|
|
||||||
};
|
|
||||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(Arg.Is(firstPageUrl),
|
|
||||||
Arg.Is<Dictionary<string, string>>(d => d.Count == 4
|
|
||||||
&& d["direction"] == "desc"
|
|
||||||
&& d["state"] == "open"
|
|
||||||
&& d["sort"] == "created"
|
|
||||||
&& d["filter"] == "assigned"), Arg.Any<string>())
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => firstPageResponse));
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(secondPageUrl, null, null)
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => secondPageResponse));
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(thirdPageUrl, null, null)
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => lastPageResponse));
|
|
||||||
var client = new ObservableIssuesClient(gitHubClient);
|
|
||||||
|
|
||||||
var results = await client.GetAllForOwnedAndMemberRepositories().ToArray();
|
|
||||||
|
|
||||||
Assert.Equal(7, results.Length);
|
|
||||||
Assert.Equal(firstPageResponse.BodyAsObject[0].Number, results[0].Number);
|
|
||||||
Assert.Equal(secondPageResponse.BodyAsObject[1].Number, results[4].Number);
|
|
||||||
Assert.Equal(lastPageResponse.BodyAsObject[0].Number, results[6].Number);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TheGetAllForOrganizationMethod
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public async Task ReturnsEveryPageOfIssues()
|
|
||||||
{
|
|
||||||
var firstPageUrl = new Uri("orgs/test/issues", UriKind.Relative);
|
|
||||||
var secondPageUrl = new Uri("https://example.com/page/2");
|
|
||||||
var firstPageLinks = new Dictionary<string, Uri> { { "next", secondPageUrl } };
|
|
||||||
var firstPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 1},
|
|
||||||
new Issue {Number = 2},
|
|
||||||
new Issue {Number = 3},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(firstPageLinks)
|
|
||||||
};
|
|
||||||
var thirdPageUrl = new Uri("https://example.com/page/3");
|
|
||||||
var secondPageLinks = new Dictionary<string, Uri> { { "next", thirdPageUrl } };
|
|
||||||
var secondPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 4},
|
|
||||||
new Issue {Number = 5},
|
|
||||||
new Issue {Number = 6},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(secondPageLinks)
|
|
||||||
};
|
|
||||||
var lastPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 7},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(new Dictionary<string, Uri>())
|
|
||||||
};
|
|
||||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(Arg.Is(firstPageUrl),
|
|
||||||
Arg.Is<Dictionary<string, string>>(d => d.Count == 4
|
|
||||||
&& d["direction"] == "desc"
|
|
||||||
&& d["state"] == "open"
|
|
||||||
&& d["sort"] == "created"
|
|
||||||
&& d["filter"] == "assigned"), Arg.Any<string>())
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => firstPageResponse));
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(secondPageUrl, null, null)
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => secondPageResponse));
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(thirdPageUrl, null, null)
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => lastPageResponse));
|
|
||||||
var client = new ObservableIssuesClient(gitHubClient);
|
|
||||||
|
|
||||||
var results = await client.GetAllForOrganization("test").ToArray();
|
|
||||||
|
|
||||||
Assert.Equal(7, results.Length);
|
|
||||||
Assert.Equal(firstPageResponse.BodyAsObject[0].Number, results[0].Number);
|
|
||||||
Assert.Equal(secondPageResponse.BodyAsObject[1].Number, results[4].Number);
|
|
||||||
Assert.Equal(lastPageResponse.BodyAsObject[0].Number, results[6].Number);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TheGetAllForCurrentMethod
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public async Task ReturnsEveryPageOfIssues()
|
|
||||||
{
|
|
||||||
var firstPageUrl = new Uri("issues", UriKind.Relative);
|
|
||||||
var secondPageUrl = new Uri("https://example.com/page/2");
|
|
||||||
var firstPageLinks = new Dictionary<string, Uri> { { "next", secondPageUrl } };
|
|
||||||
var firstPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 1},
|
|
||||||
new Issue {Number = 2},
|
|
||||||
new Issue {Number = 3},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(firstPageLinks)
|
|
||||||
};
|
|
||||||
var thirdPageUrl = new Uri("https://example.com/page/3");
|
|
||||||
var secondPageLinks = new Dictionary<string, Uri> { { "next", thirdPageUrl } };
|
|
||||||
var secondPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 4},
|
|
||||||
new Issue {Number = 5},
|
|
||||||
new Issue {Number = 6},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(secondPageLinks)
|
|
||||||
};
|
|
||||||
var lastPageResponse = new ApiResponse<List<Issue>>
|
|
||||||
{
|
|
||||||
BodyAsObject = new List<Issue>
|
|
||||||
{
|
|
||||||
new Issue {Number = 7},
|
|
||||||
},
|
|
||||||
ApiInfo = CreateApiInfo(new Dictionary<string, Uri>())
|
|
||||||
};
|
|
||||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(Arg.Is(firstPageUrl),
|
|
||||||
Arg.Is<Dictionary<string, string>>(d => d.Count == 4
|
|
||||||
&& d["direction"] == "desc"
|
|
||||||
&& d["state"] == "open"
|
|
||||||
&& d["sort"] == "created"
|
|
||||||
&& d["filter"] == "assigned"), Arg.Any<string>())
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => firstPageResponse));
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(secondPageUrl, null, null)
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => secondPageResponse));
|
|
||||||
gitHubClient.Connection.Get<List<Issue>>(thirdPageUrl, null, null)
|
|
||||||
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => lastPageResponse));
|
|
||||||
var client = new ObservableIssuesClient(gitHubClient);
|
|
||||||
|
|
||||||
var results = await client.GetAllForCurrent().ToArray();
|
|
||||||
|
|
||||||
Assert.Equal(7, results.Length);
|
|
||||||
Assert.Equal(firstPageResponse.BodyAsObject[0].Number, results[0].Number);
|
|
||||||
Assert.Equal(secondPageResponse.BodyAsObject[1].Number, results[4].Number);
|
|
||||||
Assert.Equal(lastPageResponse.BodyAsObject[0].Number, results[6].Number);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TheCreateMethod
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void CreatesFromClientIssueIssue()
|
|
||||||
{
|
|
||||||
var newIssue = new NewIssue("some title");
|
|
||||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
|
||||||
var client = new ObservableIssuesClient(gitHubClient);
|
|
||||||
|
|
||||||
client.Create("fake", "repo", newIssue);
|
|
||||||
|
|
||||||
gitHubClient.Issue.Received().Create("fake", "repo", newIssue);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void EnsuresArgumentsNotNull()
|
|
||||||
{
|
|
||||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
|
||||||
var client = new ObservableIssuesClient(gitHubClient);
|
|
||||||
|
|
||||||
Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewIssue("title")));
|
|
||||||
Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewIssue("x")));
|
|
||||||
Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewIssue("x")));
|
|
||||||
Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewIssue("x")));
|
|
||||||
Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TheUpdateMethod
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void UpdatesClientIssueIssue()
|
|
||||||
{
|
|
||||||
var issueUpdate = new IssueUpdate();
|
|
||||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
|
||||||
var client = new ObservableIssuesClient(gitHubClient);
|
|
||||||
|
|
||||||
client.Update("fake", "repo", 42, issueUpdate);
|
|
||||||
|
|
||||||
gitHubClient.Issue.Received().Update("fake", "repo", 42, issueUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void EnsuresArgumentsNotNull()
|
|
||||||
{
|
|
||||||
var gitHubClient = Substitute.For<IGitHubClient>();
|
|
||||||
var client = new ObservableIssuesClient(gitHubClient);
|
|
||||||
|
|
||||||
Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewIssue("title")));
|
|
||||||
Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewIssue("x")));
|
|
||||||
Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewIssue("x")));
|
|
||||||
Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewIssue("x")));
|
|
||||||
Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TheCtor
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void EnsuresArgument()
|
|
||||||
{
|
|
||||||
Assert.Throws<ArgumentNullException>(() => new IssuesClient(null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ApiInfo CreateApiInfo(IDictionary<string, Uri> links)
|
|
||||||
{
|
|
||||||
return new ApiInfo(links, new List<string>(), new List<string>(), "etag", new RateLimit(new Dictionary<string, string>()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TheGetForRepositoryMethod
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task ReturnsEveryPageOfIssues()
|
||||||
|
{
|
||||||
|
var firstPageUrl = new Uri("repos/fake/repo/issues", UriKind.Relative);
|
||||||
|
var secondPageUrl = new Uri("https://example.com/page/2");
|
||||||
|
var firstPageLinks = new Dictionary<string, Uri> { { "next", secondPageUrl } };
|
||||||
|
var firstPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(1),
|
||||||
|
CreateIssue(2),
|
||||||
|
CreateIssue(3)
|
||||||
|
},
|
||||||
|
ApiInfo = CreateApiInfo(firstPageLinks)
|
||||||
|
};
|
||||||
|
var thirdPageUrl = new Uri("https://example.com/page/3");
|
||||||
|
var secondPageLinks = new Dictionary<string, Uri> { { "next", thirdPageUrl } };
|
||||||
|
var secondPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(4),
|
||||||
|
CreateIssue(5),
|
||||||
|
CreateIssue(6)
|
||||||
|
},
|
||||||
|
ApiInfo = CreateApiInfo(secondPageLinks)
|
||||||
|
};
|
||||||
|
var lastPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(7),
|
||||||
|
},
|
||||||
|
ApiInfo = CreateApiInfo(new Dictionary<string, Uri>())
|
||||||
|
};
|
||||||
|
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(Arg.Is(firstPageUrl),
|
||||||
|
Arg.Is<Dictionary<string, string>>(d => d.Count == 4
|
||||||
|
&& d["direction"] == "desc"
|
||||||
|
&& d["state"] == "open"
|
||||||
|
&& d["sort"] == "created"
|
||||||
|
&& d["filter"] == "assigned"), Arg.Any<string>())
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => firstPageResponse));
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(secondPageUrl, null, null)
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => secondPageResponse));
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(thirdPageUrl, null, null)
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => lastPageResponse));
|
||||||
|
var client = new ObservableIssuesClient(gitHubClient);
|
||||||
|
|
||||||
|
var results = await client.GetForRepository("fake", "repo").ToArray();
|
||||||
|
|
||||||
|
Assert.Equal(7, results.Length);
|
||||||
|
Assert.Equal(firstPageResponse.BodyAsObject[0].Number, results[0].Number);
|
||||||
|
Assert.Equal(secondPageResponse.BodyAsObject[1].Number, results[4].Number);
|
||||||
|
Assert.Equal(lastPageResponse.BodyAsObject[0].Number, results[6].Number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TheGetAllForOwnedAndMemberRepositoriesMethod
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task ReturnsEveryPageOfIssues()
|
||||||
|
{
|
||||||
|
var firstPageUrl = new Uri("user/issues", UriKind.Relative);
|
||||||
|
var secondPageUrl = new Uri("https://example.com/page/2");
|
||||||
|
var firstPageLinks = new Dictionary<string, Uri> { { "next", secondPageUrl } };
|
||||||
|
var firstPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(1),
|
||||||
|
CreateIssue(2),
|
||||||
|
CreateIssue(3) },
|
||||||
|
ApiInfo = CreateApiInfo(firstPageLinks)
|
||||||
|
};
|
||||||
|
var thirdPageUrl = new Uri("https://example.com/page/3");
|
||||||
|
var secondPageLinks = new Dictionary<string, Uri> { { "next", thirdPageUrl } };
|
||||||
|
var secondPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(4),
|
||||||
|
CreateIssue(5),
|
||||||
|
CreateIssue(6)
|
||||||
|
},
|
||||||
|
ApiInfo = CreateApiInfo(secondPageLinks)
|
||||||
|
};
|
||||||
|
var lastPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(7)
|
||||||
|
},
|
||||||
|
ApiInfo = CreateApiInfo(new Dictionary<string, Uri>())
|
||||||
|
};
|
||||||
|
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(Arg.Is(firstPageUrl),
|
||||||
|
Arg.Is<Dictionary<string, string>>(d => d.Count == 4
|
||||||
|
&& d["direction"] == "desc"
|
||||||
|
&& d["state"] == "open"
|
||||||
|
&& d["sort"] == "created"
|
||||||
|
&& d["filter"] == "assigned"), Arg.Any<string>())
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => firstPageResponse));
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(secondPageUrl, null, null)
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => secondPageResponse));
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(thirdPageUrl, null, null)
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => lastPageResponse));
|
||||||
|
var client = new ObservableIssuesClient(gitHubClient);
|
||||||
|
|
||||||
|
var results = await client.GetAllForOwnedAndMemberRepositories().ToArray();
|
||||||
|
|
||||||
|
Assert.Equal(7, results.Length);
|
||||||
|
Assert.Equal(firstPageResponse.BodyAsObject[0].Number, results[0].Number);
|
||||||
|
Assert.Equal(secondPageResponse.BodyAsObject[1].Number, results[4].Number);
|
||||||
|
Assert.Equal(lastPageResponse.BodyAsObject[0].Number, results[6].Number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TheGetAllForOrganizationMethod
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task ReturnsEveryPageOfIssues()
|
||||||
|
{
|
||||||
|
var firstPageUrl = new Uri("orgs/test/issues", UriKind.Relative);
|
||||||
|
var secondPageUrl = new Uri("https://example.com/page/2");
|
||||||
|
var firstPageLinks = new Dictionary<string, Uri> { { "next", secondPageUrl } };
|
||||||
|
var firstPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(1),
|
||||||
|
CreateIssue(2),
|
||||||
|
CreateIssue(3)
|
||||||
|
},
|
||||||
|
ApiInfo = CreateApiInfo(firstPageLinks)
|
||||||
|
};
|
||||||
|
var thirdPageUrl = new Uri("https://example.com/page/3");
|
||||||
|
var secondPageLinks = new Dictionary<string, Uri> { { "next", thirdPageUrl } };
|
||||||
|
var secondPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(4),
|
||||||
|
CreateIssue(5),
|
||||||
|
CreateIssue(6)
|
||||||
|
},
|
||||||
|
ApiInfo = CreateApiInfo(secondPageLinks)
|
||||||
|
};
|
||||||
|
var lastPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(7)
|
||||||
|
},
|
||||||
|
ApiInfo = CreateApiInfo(new Dictionary<string, Uri>())
|
||||||
|
};
|
||||||
|
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(Arg.Is(firstPageUrl),
|
||||||
|
Arg.Is<Dictionary<string, string>>(d => d.Count == 4
|
||||||
|
&& d["direction"] == "desc"
|
||||||
|
&& d["state"] == "open"
|
||||||
|
&& d["sort"] == "created"
|
||||||
|
&& d["filter"] == "assigned"), Arg.Any<string>())
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => firstPageResponse));
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(secondPageUrl, null, null)
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => secondPageResponse));
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(thirdPageUrl, null, null)
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => lastPageResponse));
|
||||||
|
var client = new ObservableIssuesClient(gitHubClient);
|
||||||
|
|
||||||
|
var results = await client.GetAllForOrganization("test").ToArray();
|
||||||
|
|
||||||
|
Assert.Equal(7, results.Length);
|
||||||
|
Assert.Equal(firstPageResponse.BodyAsObject[0].Number, results[0].Number);
|
||||||
|
Assert.Equal(secondPageResponse.BodyAsObject[1].Number, results[4].Number);
|
||||||
|
Assert.Equal(lastPageResponse.BodyAsObject[0].Number, results[6].Number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TheGetAllForCurrentMethod
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task ReturnsEveryPageOfIssues()
|
||||||
|
{
|
||||||
|
var firstPageUrl = new Uri("issues", UriKind.Relative);
|
||||||
|
var secondPageUrl = new Uri("https://example.com/page/2");
|
||||||
|
var firstPageLinks = new Dictionary<string, Uri> { { "next", secondPageUrl } };
|
||||||
|
var firstPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(1),
|
||||||
|
CreateIssue(2),
|
||||||
|
CreateIssue(3)
|
||||||
|
},
|
||||||
|
ApiInfo = CreateApiInfo(firstPageLinks)
|
||||||
|
};
|
||||||
|
var thirdPageUrl = new Uri("https://example.com/page/3");
|
||||||
|
var secondPageLinks = new Dictionary<string, Uri> { { "next", thirdPageUrl } };
|
||||||
|
var secondPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(4),
|
||||||
|
CreateIssue(5),
|
||||||
|
CreateIssue(6)
|
||||||
|
},
|
||||||
|
ApiInfo = CreateApiInfo(secondPageLinks)
|
||||||
|
};
|
||||||
|
var lastPageResponse = new ApiResponse<List<Issue>>
|
||||||
|
{
|
||||||
|
BodyAsObject = new List<Issue>
|
||||||
|
{
|
||||||
|
CreateIssue(7)
|
||||||
|
},
|
||||||
|
ApiInfo = CreateApiInfo(new Dictionary<string, Uri>())
|
||||||
|
};
|
||||||
|
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(Arg.Is(firstPageUrl),
|
||||||
|
Arg.Is<Dictionary<string, string>>(d => d.Count == 4
|
||||||
|
&& d["direction"] == "desc"
|
||||||
|
&& d["state"] == "open"
|
||||||
|
&& d["sort"] == "created"
|
||||||
|
&& d["filter"] == "assigned"), Arg.Any<string>())
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => firstPageResponse));
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(secondPageUrl, null, null)
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => secondPageResponse));
|
||||||
|
gitHubClient.Connection.Get<List<Issue>>(thirdPageUrl, null, null)
|
||||||
|
.Returns(Task.Factory.StartNew<IResponse<List<Issue>>>(() => lastPageResponse));
|
||||||
|
var client = new ObservableIssuesClient(gitHubClient);
|
||||||
|
|
||||||
|
var results = await client.GetAllForCurrent().ToArray();
|
||||||
|
|
||||||
|
Assert.Equal(7, results.Length);
|
||||||
|
Assert.Equal(firstPageResponse.BodyAsObject[0].Number, results[0].Number);
|
||||||
|
Assert.Equal(secondPageResponse.BodyAsObject[1].Number, results[4].Number);
|
||||||
|
Assert.Equal(lastPageResponse.BodyAsObject[0].Number, results[6].Number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TheCreateMethod
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void CreatesFromClientIssueIssue()
|
||||||
|
{
|
||||||
|
var newIssue = new NewIssue("some title");
|
||||||
|
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||||
|
var client = new ObservableIssuesClient(gitHubClient);
|
||||||
|
|
||||||
|
client.Create("fake", "repo", newIssue);
|
||||||
|
|
||||||
|
gitHubClient.Issue.Received().Create("fake", "repo", newIssue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnsuresArgumentsNotNull()
|
||||||
|
{
|
||||||
|
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||||
|
var client = new ObservableIssuesClient(gitHubClient);
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewIssue("title")));
|
||||||
|
Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewIssue("x")));
|
||||||
|
Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewIssue("x")));
|
||||||
|
Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewIssue("x")));
|
||||||
|
Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TheUpdateMethod
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void UpdatesClientIssueIssue()
|
||||||
|
{
|
||||||
|
var issueUpdate = new IssueUpdate();
|
||||||
|
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||||
|
var client = new ObservableIssuesClient(gitHubClient);
|
||||||
|
|
||||||
|
client.Update("fake", "repo", 42, issueUpdate);
|
||||||
|
|
||||||
|
gitHubClient.Issue.Received().Update("fake", "repo", 42, issueUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EnsuresArgumentsNotNull()
|
||||||
|
{
|
||||||
|
var gitHubClient = Substitute.For<IGitHubClient>();
|
||||||
|
var client = new ObservableIssuesClient(gitHubClient);
|
||||||
|
|
||||||
|
Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewIssue("title")));
|
||||||
|
Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewIssue("x")));
|
||||||
|
Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewIssue("x")));
|
||||||
|
Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewIssue("x")));
|
||||||
|
Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TheCtor
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void EnsuresArgument()
|
||||||
|
{
|
||||||
|
Assert.Throws<ArgumentNullException>(() => new IssuesClient(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ApiInfo CreateApiInfo(IDictionary<string, Uri> links)
|
||||||
|
{
|
||||||
|
return new ApiInfo(links, new List<string>(), new List<string>(), "etag", new RateLimit(new Dictionary<string, string>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Issue CreateIssue(int issueNumber)
|
||||||
|
{
|
||||||
|
var serializer = new SimpleJsonSerializer();
|
||||||
|
return serializer.Deserialize<Issue>(@"{""number"": """ + issueNumber + @"""}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Octokit.Internal;
|
using Octokit.Internal;
|
||||||
@@ -10,6 +9,11 @@ namespace Octokit
|
|||||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||||
public class IssueUpdate
|
public class IssueUpdate
|
||||||
{
|
{
|
||||||
|
public IssueUpdate()
|
||||||
|
{
|
||||||
|
Labels = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Title of the milestone (required)
|
/// Title of the milestone (required)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -45,8 +49,7 @@ namespace Octokit
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Only users with push access can set labels for new issues. Labels are silently dropped otherwise.
|
/// Only users with push access can set labels for new issues. Labels are silently dropped otherwise.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
public ICollection<string> Labels { get; private set; }
|
||||||
public ICollection<string> Labels { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the issue is open or closed.
|
/// Whether the issue is open or closed.
|
||||||
@@ -63,12 +66,6 @@ namespace Octokit
|
|||||||
|
|
||||||
public void AddLabel(string name)
|
public void AddLabel(string name)
|
||||||
{
|
{
|
||||||
// lazily create the label array
|
|
||||||
if (Labels == null)
|
|
||||||
{
|
|
||||||
Labels = new List<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
Labels.Add(name);
|
Labels.Add(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,71 +13,71 @@ namespace Octokit
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The URL for this milestone.
|
/// The URL for this milestone.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Uri Url { get; set; }
|
public Uri Url { get; protected set; }
|
||||||
public Uri HtmlUrl { get; set; }
|
|
||||||
|
public Uri HtmlUrl { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The issue number.
|
/// The issue number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Number { get; set; }
|
public int Number { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the issue is open or closed.
|
/// Whether the issue is open or closed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ItemState State { get; set; }
|
public ItemState State { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Title of the issue
|
/// Title of the issue
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Title { get; set; }
|
public string Title { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Details about the issue.
|
/// Details about the issue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Body { get; set; }
|
public string Body { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user that created the issue.
|
/// The user that created the issue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public User User { get; set; }
|
public User User { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The set of labels applied to the issue
|
/// The set of labels applied to the issue
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
|
public IReadOnlyCollection<Label> Labels { get; protected set; }
|
||||||
public ICollection<Label> Labels { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user this issue is assigned to.
|
/// The user this issue is assigned to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public User Assignee { get; set; }
|
public User Assignee { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The milestone, if any, that this issue is assigned to.
|
/// The milestone, if any, that this issue is assigned to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Milestone Milestone { get; set; }
|
public Milestone Milestone { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of comments on the issue.
|
/// The number of comments on the issue.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Comments { get; set; }
|
public int Comments { get; protected set; }
|
||||||
|
|
||||||
public PullRequest PullRequest { get; set; }
|
public PullRequest PullRequest { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date the issue was closed if closed.
|
/// The date the issue was closed if closed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset? ClosedAt { get; set; }
|
public DateTimeOffset? ClosedAt { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date the issue was created.
|
/// The date the issue was created.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset CreatedAt { get; set; }
|
public DateTimeOffset CreatedAt { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date the issue was last updated.
|
/// The date the issue was last updated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset? UpdatedAt { get; set; }
|
public DateTimeOffset? UpdatedAt { get; protected set; }
|
||||||
|
|
||||||
internal string DebuggerDisplay
|
internal string DebuggerDisplay
|
||||||
{
|
{
|
||||||
@@ -95,7 +95,7 @@ namespace Octokit
|
|||||||
|
|
||||||
var assignee = Assignee == null
|
var assignee = Assignee == null
|
||||||
? null
|
? null
|
||||||
: Assignee.Name;
|
: Assignee.Login;
|
||||||
|
|
||||||
var issueUpdate = new IssueUpdate
|
var issueUpdate = new IssueUpdate
|
||||||
{
|
{
|
||||||
@@ -106,9 +106,9 @@ namespace Octokit
|
|||||||
Title = Title
|
Title = Title
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Labels.Any())
|
foreach (var label in Labels.Select(l => l.Name))
|
||||||
{
|
{
|
||||||
issueUpdate.Labels = new List<string>(Labels.Select(l => l.Name));
|
issueUpdate.Labels.Add(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
return issueUpdate;
|
return issueUpdate;
|
||||||
|
|||||||
Reference in New Issue
Block a user