diff --git a/Octokit.Tests.Integration/IssuesEventsClientTests.cs b/Octokit.Tests.Integration/IssuesEventsClientTests.cs index 8e2a644f74..e6916cb379 100644 --- a/Octokit.Tests.Integration/IssuesEventsClientTests.cs +++ b/Octokit.Tests.Integration/IssuesEventsClientTests.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Net.Http.Headers; +using System.Threading; using System.Threading.Tasks; using Octokit; using Octokit.Tests.Integration; @@ -9,8 +10,11 @@ public class IssuesEventsClientTests { readonly IGitHubClient _gitHubClient; + readonly IIssuesEventsClient _issuesEventsClientClient; + readonly IIssuesClient _issuesClient; readonly Repository _repository; - readonly string _owner; + readonly string _repositoryOwner; + readonly string _repositoryName; public IssuesEventsClientTests() { @@ -18,29 +22,80 @@ public IssuesEventsClientTests() { Credentials = Helper.Credentials }; + _issuesEventsClientClient = _gitHubClient.Issue.Events; + _issuesClient = _gitHubClient.Issue; var repoName = Helper.MakeNameWithTimestamp("public-repo"); _repository = _gitHubClient.Repository.Create(new NewRepository { Name = repoName }).Result; - _owner = _repository.Owner.Login; + _repositoryOwner = _repository.Owner.Login; + _repositoryName = _repository.Name; } - //[IntegrationTest] - //public async Task CanListEventsForAnIssue() - //{ - // throw new NotImplementedException(); - //} - - //[IntegrationTest] - //public async Task CanListEventsForARepository() - //{ - // throw new NotImplementedException(); - //} - - //[IntegrationTest] - //public async Task CanRetrieveOneEvent() - //{ - // throw new NotImplementedException(); - //} + [IntegrationTest] + public async Task CanListEventInfoForAnIssue() + { + var newIssue = new NewIssue("a test issue") { Body = "A new unassigned issue" }; + var issue = await _issuesClient.Create(_repositoryOwner, _repositoryName, newIssue); + + var issueEventInfo = await _issuesEventsClientClient.GetForIssue(_repositoryOwner, _repositoryName, issue.Number); + Assert.Empty(issueEventInfo); + + var closed = _issuesClient.Update(_repositoryOwner, _repository.Name, issue.Number, new IssueUpdate { State = ItemState.Closed }) + .Result; + Assert.NotNull(closed); + issueEventInfo = await _issuesEventsClientClient.GetForIssue(_repositoryOwner, _repositoryName, issue.Number); + + Assert.Equal(1, issueEventInfo.Count); + Assert.Equal(EventInfoState.Closed, issueEventInfo[0].InfoState); + } + + [IntegrationTest] + public async Task CanListIssueEventsForARepository() + { + // create 2 new issues + var newIssue1 = new NewIssue("A test issue1") { Body = "Everything's coming up Millhouse" }; + var newIssue2 = new NewIssue("A test issue2") { Body = "A new unassigned issue" }; + + var issue1 = await _issuesClient.Create(_repositoryOwner, _repository.Name, newIssue1); + Thread.Sleep(1000); + var issue2 = await _issuesClient.Create(_repositoryOwner, _repository.Name, newIssue2); + Thread.Sleep(1000); + + // close and open issue1 + var closed1 = _issuesClient.Update(_repositoryOwner, _repository.Name, issue1.Number,new IssueUpdate { State = ItemState.Closed }) + .Result; + Assert.NotNull(closed1); + var reopened1 = _issuesClient.Update(_repositoryOwner, _repository.Name, issue1.Number, new IssueUpdate { State = ItemState.Open }) + .Result; + Assert.NotNull(reopened1); + + // close issue2 + var closed2 = _issuesClient.Update(_repositoryOwner, _repository.Name, issue2.Number, new IssueUpdate { State = ItemState.Closed }) + .Result; + Assert.NotNull(closed2); + + var issueEvents = await _issuesEventsClientClient.GetForRepository(_repositoryOwner, _repositoryName); + + Assert.Equal(3, issueEvents.Count); + Assert.Equal(2, issueEvents.Count(issueEvent => issueEvent.Issue.Body == "Everything's coming up Millhouse")); + } + + [IntegrationTest] + public async Task CanRetrieveIssueEventById() + { + var newIssue = new NewIssue("a test issue") { Body = "A new unassigned issue" }; + var issue = await _issuesClient.Create(_repositoryOwner, _repositoryName, newIssue); + var closed = _issuesClient.Update(_repositoryOwner, _repository.Name, issue.Number, new IssueUpdate { State = ItemState.Closed }) + .Result; + Assert.NotNull(closed); + var issueEvents = await _issuesEventsClientClient.GetForRepository(_repositoryOwner, _repositoryName); + int issueEventId = issueEvents[0].Id; + + var issueEventLookupById = await _issuesEventsClientClient.Get(_repositoryOwner, _repositoryName, issueEventId); + + Assert.Equal(issueEventId, issueEventLookupById.Id); + Assert.Equal(issueEvents[0].InfoState, issueEventLookupById.InfoState); + } public void Dispose() { diff --git a/Octokit/Clients/IIssuesClient.cs b/Octokit/Clients/IIssuesClient.cs index b47b4c368c..297a77a4ac 100644 --- a/Octokit/Clients/IIssuesClient.cs +++ b/Octokit/Clients/IIssuesClient.cs @@ -8,6 +8,13 @@ public interface IIssuesClient { IAssigneesClient Assignee { get; } + /// + /// Client for reading various event information associated with issues/pull requests. + /// This is useful both for display on issue/pull request information pages and also to + /// determine who should be notified of comments. + /// + IIssuesEventsClient Events { get; } + /// /// Client for managing milestones. /// diff --git a/Octokit/Clients/IIssuesEventsClient.cs b/Octokit/Clients/IIssuesEventsClient.cs index d0170e0c74..39afa00543 100644 --- a/Octokit/Clients/IIssuesEventsClient.cs +++ b/Octokit/Clients/IIssuesEventsClient.cs @@ -16,7 +16,7 @@ public interface IIssuesEventsClient /// The name of the repository /// The issue number /// - Task> GetForIssue(string owner, string name, int number); + Task> GetForIssue(string owner, string name, int number); /// /// Gets all events for the repository. @@ -37,7 +37,7 @@ public interface IIssuesEventsClient /// /// The owner of the repository /// The name of the repository - /// The issue number + /// The event id /// [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "Method makes a network request")] diff --git a/Octokit/Clients/IssuesClient.cs b/Octokit/Clients/IssuesClient.cs index a868431dc3..2b6f18ef6b 100644 --- a/Octokit/Clients/IssuesClient.cs +++ b/Octokit/Clients/IssuesClient.cs @@ -8,10 +8,12 @@ public class IssuesClient : ApiClient, IIssuesClient public IssuesClient(IApiConnection apiConnection) : base(apiConnection) { Assignee = new AssigneesClient(apiConnection); + Events = new IssuesEventsClient(apiConnection); Milestone = new MilestonesClient(apiConnection); } public IAssigneesClient Assignee { get; private set; } + public IIssuesEventsClient Events { get; private set; } public IMilestonesClient Milestone { get; private set; } /// diff --git a/Octokit/Clients/IssuesEventsClient.cs b/Octokit/Clients/IssuesEventsClient.cs new file mode 100644 index 0000000000..ee06466905 --- /dev/null +++ b/Octokit/Clients/IssuesEventsClient.cs @@ -0,0 +1,39 @@ +using System; +#if NET_45 +using System.Collections.Generic; +#endif +using System.Threading.Tasks; + +namespace Octokit +{ + public class IssuesEventsClient : ApiClient, IIssuesEventsClient + { + public IssuesEventsClient(IApiConnection apiConnection) : base(apiConnection) + { + } + + public Task> GetForIssue(string owner, string name, int number) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(name, "name"); + + return ApiConnection.GetAll(ApiUrls.IssuesEvents(owner, name, number)); + } + + public Task> GetForRepository(string owner, string name) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(name, "name"); + + return ApiConnection.GetAll(ApiUrls.IssuesEvents(owner, name)); + } + + public Task Get(string owner, string name, int number) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(name, "name"); + + return ApiConnection.Get(ApiUrls.IssuesEvent(owner, name, number)); + } + } +} \ No newline at end of file diff --git a/Octokit/Models/Response/IssueEvent.cs b/Octokit/Models/Response/IssueEvent.cs index 654413615e..c1edcb9be1 100644 --- a/Octokit/Models/Response/IssueEvent.cs +++ b/Octokit/Models/Response/IssueEvent.cs @@ -1,8 +1,35 @@ -namespace Octokit +using System; + +namespace Octokit { public class IssueEvent { - public EventInfo EventInfo { get; set; } + /// + /// The id of the issue/pull request event. + /// + public int Id { get; set; } + + public Uri Url { get; set; } + + /// + /// Always the User that generated the event + /// + public Actor Actor { get; set; } + + /// + /// Identifies the actual type of Event that occurred + /// + public EventInfoState InfoState { get; set; } + + /// + /// The String SHA of a commit that referenced this Issue + /// + public string CommitId { get; set; } + + /// + /// Date the event occurred for the issue/pull request. + /// + public DateTimeOffset CreatedAt { get; set; } public Issue Issue { get; set; } } diff --git a/Octokit/Octokit-netcore45.csproj b/Octokit/Octokit-netcore45.csproj index 23698df445..f9857668c6 100644 --- a/Octokit/Octokit-netcore45.csproj +++ b/Octokit/Octokit-netcore45.csproj @@ -53,6 +53,7 @@ + @@ -61,6 +62,7 @@ + @@ -136,13 +138,16 @@ + + + diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index 4356b87be4..80dc796d86 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -55,6 +55,7 @@ +