Skip to content

Commit

Permalink
Implement improved labels API (#1802)
Browse files Browse the repository at this point in the history
* Implement new attributes for labels

* Include correct API header in all Labels calls

* Add integration tests for Create and Update methods for labels

* Use improved labels API in observable client

* found even more endpoints that need the preview header!

* RemoveFromIssue actually returns the list of remaining labels rather than null.  This change should be source compatible but not binary compatible

* Implement new labels search method in SearchClient

* Implement reactive client SearchLabels

* Improve documentation for label search methods

* more comment tidy up
  • Loading branch information
jozefizso authored and ryangribble committed May 17, 2018
1 parent f771147 commit fc3e9c2
Show file tree
Hide file tree
Showing 21 changed files with 436 additions and 74 deletions.
4 changes: 2 additions & 2 deletions Octokit.Reactive/Clients/IObservableIssuesLabelsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ public interface IObservableIssuesLabelsClient
/// <param name="name">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <param name="labelName">The name of the label to remove</param>
IObservable<Unit> RemoveFromIssue(string owner, string name, int number, string labelName);
IObservable<Label> RemoveFromIssue(string owner, string name, int number, string labelName);

/// <summary>
/// Removes a label from an issue
Expand All @@ -274,7 +274,7 @@ public interface IObservableIssuesLabelsClient
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The number of the issue</param>
/// <param name="labelName">The name of the label to remove</param>
IObservable<Unit> RemoveFromIssue(long repositoryId, int number, string labelName);
IObservable<Label> RemoveFromIssue(long repositoryId, int number, string labelName);

/// <summary>
/// Replaces all labels on the specified issues with the provided labels
Expand Down
8 changes: 8 additions & 0 deletions Octokit.Reactive/Clients/IObservableSearchClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,13 @@ public interface IObservableSearchClient
/// <param name="search"></param>
/// <returns>List of files</returns>
IObservable<SearchCodeResult> SearchCode(SearchCodeRequest search);

/// <summary>
/// search labels
/// https://developer.github.com/v3/search/#search-labels
/// </summary>
/// <param name="search"></param>
/// <returns>List of labels</returns>
IObservable<SearchLabelsResult> SearchLabels(SearchLabelsRequest search);
}
}
24 changes: 14 additions & 10 deletions Octokit.Reactive/Clients/ObservableIssuesLabelsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public IObservable<Label> GetAllForIssue(string owner, string name, int number,
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<Label>(ApiUrls.IssueLabels(owner, name, number), options);
return _connection.GetAndFlattenAllPages<Label>(ApiUrls.IssueLabels(owner, name, number), null, AcceptHeaders.LabelsApiPreview, options);
}

/// <summary>
Expand All @@ -87,7 +87,7 @@ public IObservable<Label> GetAllForIssue(long repositoryId, int number, ApiOptio
{
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<Label>(ApiUrls.IssueLabels(repositoryId, number), options);
return _connection.GetAndFlattenAllPages<Label>(ApiUrls.IssueLabels(repositoryId, number), null, AcceptHeaders.LabelsApiPreview, options);
}

/// <summary>
Expand Down Expand Up @@ -133,7 +133,7 @@ public IObservable<Label> GetAllForRepository(string owner, string name, ApiOpti
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<Label>(ApiUrls.Labels(owner, name), options);
return _connection.GetAndFlattenAllPages<Label>(ApiUrls.Labels(owner, name), null, AcceptHeaders.LabelsApiPreview, options);
}

/// <summary>
Expand All @@ -148,7 +148,7 @@ public IObservable<Label> GetAllForRepository(long repositoryId, ApiOptions opti
{
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<Label>(ApiUrls.Labels(repositoryId), options);
return _connection.GetAndFlattenAllPages<Label>(ApiUrls.Labels(repositoryId), null, AcceptHeaders.LabelsApiPreview, options);
}

/// <summary>
Expand Down Expand Up @@ -197,7 +197,7 @@ public IObservable<Label> GetAllForMilestone(string owner, string name, int numb
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<Label>(ApiUrls.MilestoneLabels(owner, name, number), options);
return _connection.GetAndFlattenAllPages<Label>(ApiUrls.MilestoneLabels(owner, name, number), null, AcceptHeaders.LabelsApiPreview, options);
}

/// <summary>
Expand All @@ -213,7 +213,7 @@ public IObservable<Label> GetAllForMilestone(long repositoryId, int number, ApiO
{
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<Label>(ApiUrls.MilestoneLabels(repositoryId, number), options);
return _connection.GetAndFlattenAllPages<Label>(ApiUrls.MilestoneLabels(repositoryId, number), null, AcceptHeaders.LabelsApiPreview, options);
}

/// <summary>
Expand Down Expand Up @@ -401,13 +401,15 @@ public IObservable<Label> AddToIssue(long repositoryId, int number, string[] lab
/// <param name="name">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <param name="labelName">The name of the label to remove</param>
public IObservable<Unit> RemoveFromIssue(string owner, string name, int number, string labelName)
public IObservable<Label> RemoveFromIssue(string owner, string name, int number, string labelName)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNullOrEmptyString(labelName, nameof(labelName));

return _client.RemoveFromIssue(owner, name, number, labelName).ToObservable();
return _client.RemoveFromIssue(owner, name, number, labelName)
.ToObservable()
.SelectMany(x => x); // HACK: DELETE is not compatible with GetAndFlattenPages
}

/// <summary>
Expand All @@ -419,11 +421,13 @@ public IObservable<Unit> RemoveFromIssue(string owner, string name, int number,
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The number of the issue</param>
/// <param name="labelName">The name of the label to remove</param>
public IObservable<Unit> RemoveFromIssue(long repositoryId, int number, string labelName)
public IObservable<Label> RemoveFromIssue(long repositoryId, int number, string labelName)
{
Ensure.ArgumentNotNullOrEmptyString(labelName, nameof(labelName));

return _client.RemoveFromIssue(repositoryId, number, labelName).ToObservable();
return _client.RemoveFromIssue(repositoryId, number, labelName)
.ToObservable()
.SelectMany(x => x); // HACK: DELETE is not compatible with GetAndFlattenPages
}

/// <summary>
Expand Down
12 changes: 12 additions & 0 deletions Octokit.Reactive/Clients/ObservableSearchClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,17 @@ public IObservable<SearchCodeResult> SearchCode(SearchCodeRequest search)
Ensure.ArgumentNotNull(search, nameof(search));
return _client.SearchCode(search).ToObservable();
}

/// <summary>
/// search labels
/// https://developer.github.com/v3/search/#search-labels
/// </summary>
/// <param name="search"></param>
/// <returns>List of labels</returns>
public IObservable<SearchLabelsResult> SearchLabels(SearchLabelsRequest search)
{
Ensure.ArgumentNotNull(search, nameof(search));
return _client.SearchLabels(search).ToObservable();
}
}
}
48 changes: 48 additions & 0 deletions Octokit.Tests.Integration/Clients/IssuesLabelsClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public async Task CanListIssueLabelsForAnIssue()

Assert.Equal(1, issueLabelsInfo.Count);
Assert.Equal(newLabel.Color, issueLabelsInfo[0].Color);
Assert.Equal(newLabel.Description, issueLabelsInfo[0].Description);
}

[IntegrationTest]
Expand All @@ -69,6 +70,7 @@ public async Task CanListIssueLabelsForAnIssueWithRepositoryId()

Assert.Equal(1, issueLabelsInfo.Count);
Assert.Equal(newLabel.Color, issueLabelsInfo[0].Color);
Assert.Equal(newLabel.Description, issueLabelsInfo[0].Description);
}

[IntegrationTest]
Expand Down Expand Up @@ -792,6 +794,7 @@ public async Task CanRetrieveIssueLabelByName()

Assert.Equal(label.Name, issueLabelLookupByName.Name);
Assert.Equal(label.Color, issueLabelLookupByName.Color);
Assert.Equal(label.Description, issueLabelLookupByName.Description);
}

[IntegrationTest]
Expand All @@ -807,6 +810,51 @@ public async Task CanRetrieveIssueLabelByNameWithRepositoryId()
Assert.Equal(label.Color, issueLabelLookupByName.Color);
}

[IntegrationTest]
public async Task CanCreateIssueLabel()
{
var newLabel = new NewLabel("test label", "FFFFFF");
var label = await _issuesLabelsClient.Create(_context.RepositoryOwner, _context.RepositoryName, newLabel);
Assert.NotNull(label);

var issueLabelLookupByName = await _issuesLabelsClient.Get(_context.RepositoryOwner, _context.RepositoryName, label.Name);

Assert.Equal(label.Name, issueLabelLookupByName.Name);
Assert.Equal(label.Color, issueLabelLookupByName.Color);
}

[IntegrationTest]
public async Task CanCreateIssueLabelWithDescription()
{
var newLabel = new NewLabel("test label", "FFFFFF") { Description = "Test label description." };
var label = await _issuesLabelsClient.Create(_context.RepositoryOwner, _context.RepositoryName, newLabel);
Assert.NotNull(label);

var issueLabelLookupByName = await _issuesLabelsClient.Get(_context.RepositoryOwner, _context.RepositoryName, label.Name);

Assert.Equal(label.Name, issueLabelLookupByName.Name);
Assert.Equal(label.Color, issueLabelLookupByName.Color);
Assert.Equal(label.Description, issueLabelLookupByName.Description);
}

[IntegrationTest]
public async Task CanUpdateIssueLabel()
{
var newLabel = new NewLabel("test label", "FFFFFF") { Description = "Test label description." };
var label = await _issuesLabelsClient.Create(_context.RepositoryOwner, _context.RepositoryName, newLabel);
Assert.NotNull(label);

var labelUpdate = new LabelUpdate("test label", "000000") { Description = "Updated label description." };
label = await _issuesLabelsClient.Update(_context.RepositoryOwner, _context.RepositoryName, labelUpdate.Name, labelUpdate);
Assert.NotNull(label);

var issueLabelLookupByName = await _issuesLabelsClient.Get(_context.RepositoryOwner, _context.RepositoryName, label.Name);

Assert.Equal(labelUpdate.Name, issueLabelLookupByName.Name);
Assert.Equal(labelUpdate.Color, issueLabelLookupByName.Color);
Assert.Equal(labelUpdate.Description, issueLabelLookupByName.Description);
}

[IntegrationTest]
public async Task CanDeleteIssueLabelByName()
{
Expand Down
10 changes: 10 additions & 0 deletions Octokit.Tests.Integration/Clients/SearchClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -616,4 +616,14 @@ public async Task SearchForExcludedBase()
// Ensure no items from the first search are in the results for the second
Assert.DoesNotContain(issues.Items, x1 => otherIssues.Items.Any(x2 => x2.Id == x1.Id));
}

[IntegrationTest]
public async Task SearchForAllLabelsUsingTermAndRepositoryId()
{
var request = new SearchLabelsRequest("category", 7528679);

var labels = await _gitHubClient.Search.SearchLabels(request);

Assert.NotEmpty(labels.Items);
}
}
Loading

0 comments on commit fc3e9c2

Please sign in to comment.