Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement improved labels API #1802

Merged
merged 10 commits into from
May 17, 2018
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
36 changes: 18 additions & 18 deletions Octokit.Tests/Clients/IssuesLabelsClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public async Task RequestsCorrectUrl()

await client.GetAllForIssue("fake", "repo", 42);

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/issues/42/labels"), Args.ApiOptions);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/issues/42/labels"), null, "application/vnd.github.symmetra-preview+json", Args.ApiOptions);
}

[Fact]
Expand All @@ -39,7 +39,7 @@ public async Task RequestsCorrectUrlWithRepositoryId()

await client.GetAllForIssue(1, 42);

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/issues/42/labels"), Args.ApiOptions);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/issues/42/labels"), null, "application/vnd.github.symmetra-preview+json", Args.ApiOptions);
}

[Fact]
Expand All @@ -57,7 +57,7 @@ public async Task RequestsCorrectUrlWithApiOptions()

await client.GetAllForIssue("fake", "repo", 42, options);

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/issues/42/labels"), options);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/issues/42/labels"), null, "application/vnd.github.symmetra-preview+json", options);
}

[Fact]
Expand All @@ -75,7 +75,7 @@ public async Task RequestsCorrectUrlWithApiOptionsWithRepositoryId()

await client.GetAllForIssue(1, 42, options);

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/issues/42/labels"), options);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/issues/42/labels"), null, "application/vnd.github.symmetra-preview+json", options);
}

[Fact]
Expand Down Expand Up @@ -108,7 +108,7 @@ public async Task RequestsCorrectUrl()

await client.GetAllForRepository("fake", "repo");

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/labels"), Args.ApiOptions);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/labels"), null, "application/vnd.github.symmetra-preview+json", Args.ApiOptions);
}

[Fact]
Expand All @@ -119,7 +119,7 @@ public async Task RequestsCorrectUrlWithRepositoryId()

await client.GetAllForRepository(1);

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/labels"), Args.ApiOptions);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/labels"), null, "application/vnd.github.symmetra-preview+json", Args.ApiOptions);
}

[Fact]
Expand All @@ -137,7 +137,7 @@ public async Task RequestsCorrectUrlWithApiOptions()

await client.GetAllForRepository("fake", "repo", options);

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/labels"), options);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/labels"), null, "application/vnd.github.symmetra-preview+json", options);
}

[Fact]
Expand All @@ -155,7 +155,7 @@ public async Task RequestsCorrectUrlWithApiOptionsWithRepositoryId()

await client.GetAllForRepository(1, options);

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/labels"), options);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/labels"), null, "application/vnd.github.symmetra-preview+json", options);
}

[Fact]
Expand Down Expand Up @@ -188,7 +188,7 @@ public async Task RequestsCorrectUrl()

await client.GetAllForMilestone("fake", "repo", 42);

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/milestones/42/labels"), Args.ApiOptions);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/milestones/42/labels"), null, "application/vnd.github.symmetra-preview+json", Args.ApiOptions);
}

[Fact]
Expand All @@ -199,7 +199,7 @@ public async Task RequestsCorrectUrlWithRepositoryId()

await client.GetAllForMilestone(1, 42);

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/milestones/42/labels"), Args.ApiOptions);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/milestones/42/labels"), null, "application/vnd.github.symmetra-preview+json", Args.ApiOptions);
}

[Fact]
Expand All @@ -217,7 +217,7 @@ public async Task RequestsCorrectUrlWithApiOptions()

await client.GetAllForMilestone("fake", "repo", 42, options);

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/milestones/42/labels"), options);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/milestones/42/labels"), null, "application/vnd.github.symmetra-preview+json", options);
}

[Fact]
Expand All @@ -235,7 +235,7 @@ public async Task RequestsCorrectUrlWithApiOptionsWithRepositoryId()

await client.GetAllForMilestone(1, 42, options);

connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/milestones/42/labels"), options);
connection.Received().GetAll<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/milestones/42/labels"), null, "application/vnd.github.symmetra-preview+json", options);
}

[Fact]
Expand Down Expand Up @@ -268,7 +268,7 @@ public async Task RequestsCorrectUrl()

await client.Get("fake", "repo", "label");

connection.Received().Get<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/labels/label"));
connection.Received().Get<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/labels/label"), null, "application/vnd.github.symmetra-preview+json");
}

[Fact]
Expand All @@ -279,7 +279,7 @@ public async Task RequestsCorrectUrlWithRepositoryId()

await client.Get(1, "label");

connection.Received().Get<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/labels/label"));
connection.Received().Get<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/labels/label"), null, "application/vnd.github.symmetra-preview+json");
}

[Fact]
Expand Down Expand Up @@ -520,7 +520,7 @@ public void CreatesCorrectUrl()

client.Create("fake", "repo", newLabel);

connection.Received().Post<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/labels"), newLabel);
connection.Received().Post<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/labels"), newLabel, "application/vnd.github.symmetra-preview+json");
}

[Fact]
Expand All @@ -533,7 +533,7 @@ public void CreatesCorrectUrlWithRepositoryId()

client.Create(1, newLabel);

connection.Received().Post<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/labels"), newLabel);
connection.Received().Post<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/labels"), newLabel, "application/vnd.github.symmetra-preview+json");
}

[Fact]
Expand Down Expand Up @@ -565,7 +565,7 @@ public void UpdatesCorrectUrl()

client.Update("fake", "repo", "labelName", labelUpdate);

connection.Received().Post<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/labels/labelName"), labelUpdate);
connection.Received().Post<Label>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/labels/labelName"), labelUpdate, "application/vnd.github.symmetra-preview+json");
}

[Fact]
Expand All @@ -578,7 +578,7 @@ public void UpdatesCorrectUrlWithRepositoryId()

client.Update(1, "labelName", labelUpdate);

connection.Received().Post<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/labels/labelName"), labelUpdate);
connection.Received().Post<Label>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/labels/labelName"), labelUpdate, "application/vnd.github.symmetra-preview+json");
}

[Fact]
Expand Down
24 changes: 12 additions & 12 deletions Octokit/Clients/IssuesLabelsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public Task<IReadOnlyList<Label>> GetAllForIssue(string owner, string name, int
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNull(options, nameof(options));

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

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

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

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

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

/// <summary>
Expand All @@ -139,7 +139,7 @@ public Task<IReadOnlyList<Label>> GetAllForRepository(long repositoryId, ApiOpti
{
Ensure.ArgumentNotNull(options, nameof(options));

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

/// <summary>
Expand Down Expand Up @@ -188,7 +188,7 @@ public Task<IReadOnlyList<Label>> GetAllForMilestone(string owner, string name,
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNull(options, nameof(options));

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

/// <summary>
Expand All @@ -204,7 +204,7 @@ public Task<IReadOnlyList<Label>> GetAllForMilestone(long repositoryId, int numb
{
Ensure.ArgumentNotNull(options, nameof(options));

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

/// <summary>
Expand All @@ -222,7 +222,7 @@ public Task<Label> Get(string owner, string name, string labelName)
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNullOrEmptyString(labelName, nameof(labelName));

return ApiConnection.Get<Label>(ApiUrls.Label(owner, name, labelName));
return ApiConnection.Get<Label>(ApiUrls.Label(owner, name, labelName), null, AcceptHeaders.LabelsApiPreview);
}

/// <summary>
Expand All @@ -237,7 +237,7 @@ public Task<Label> Get(long repositoryId, string labelName)
{
Ensure.ArgumentNotNullOrEmptyString(labelName, nameof(labelName));

return ApiConnection.Get<Label>(ApiUrls.Label(repositoryId, labelName));
return ApiConnection.Get<Label>(ApiUrls.Label(repositoryId, labelName), null, AcceptHeaders.LabelsApiPreview);
}

/// <summary>
Expand Down Expand Up @@ -288,7 +288,7 @@ public Task<Label> Create(string owner, string name, NewLabel newLabel)
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNull(newLabel, nameof(newLabel));

return ApiConnection.Post<Label>(ApiUrls.Labels(owner, name), newLabel);
return ApiConnection.Post<Label>(ApiUrls.Labels(owner, name), newLabel, AcceptHeaders.LabelsApiPreview);
}

/// <summary>
Expand All @@ -303,7 +303,7 @@ public Task<Label> Create(long repositoryId, NewLabel newLabel)
{
Ensure.ArgumentNotNull(newLabel, nameof(newLabel));

return ApiConnection.Post<Label>(ApiUrls.Labels(repositoryId), newLabel);
return ApiConnection.Post<Label>(ApiUrls.Labels(repositoryId), newLabel, AcceptHeaders.LabelsApiPreview);
}

/// <summary>
Expand All @@ -323,7 +323,7 @@ public Task<Label> Update(string owner, string name, string labelName, LabelUpda
Ensure.ArgumentNotNullOrEmptyString(labelName, nameof(labelName));
Ensure.ArgumentNotNull(labelUpdate, nameof(labelUpdate));

return ApiConnection.Post<Label>(ApiUrls.Label(owner, name, labelName), labelUpdate);
return ApiConnection.Post<Label>(ApiUrls.Label(owner, name, labelName), labelUpdate, AcceptHeaders.LabelsApiPreview);
}

/// <summary>
Expand All @@ -340,7 +340,7 @@ public Task<Label> Update(long repositoryId, string labelName, LabelUpdate label
Ensure.ArgumentNotNullOrEmptyString(labelName, nameof(labelName));
Ensure.ArgumentNotNull(labelUpdate, nameof(labelUpdate));

return ApiConnection.Post<Label>(ApiUrls.Label(repositoryId, labelName), labelUpdate);
return ApiConnection.Post<Label>(ApiUrls.Label(repositoryId, labelName), labelUpdate, AcceptHeaders.LabelsApiPreview);
}

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions Octokit/Helpers/AcceptHeaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public static class AcceptHeaders

public const string PreReceiveEnvironmentsPreview = "application/vnd.github.eye-scream-preview+json";

public const string LabelsApiPreview = "application/vnd.github.symmetra-preview+json";

/// <summary>
/// Combines multiple preview headers. GitHub API supports Accept header with multiple
/// values separated by comma.
Expand Down
5 changes: 5 additions & 0 deletions Octokit/Models/Request/LabelUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public string Color
}
}

/// <summary>
/// A short description of the label (optional).
/// </summary>
public string Description { get; set; }

internal string DebuggerDisplay
{
get
Expand Down
12 changes: 12 additions & 0 deletions Octokit/Models/Request/NewLabel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,18 @@ public NewLabel(string name, string color)
/// <summary>
/// Name of the label (required).
/// </summary>
/// <remarks>
/// Emoji can be added to label names, using either native emoji or colon-style markup. For example,
/// typing :strawberry: will render the emoji for strawberry. For a full list of available emoji and codes, see http://emoji-cheat-sheet.com/.
/// </remarks>
public string Name { get; set; }

/// <summary>
/// Color of the label (required).
/// </summary>
/// <remarks>
/// The hexadecimal color code for the label, without the leading #.
/// </remarks>
public string Color
{
get { return _color; }
Expand All @@ -49,6 +56,11 @@ public string Color
}
}

/// <summary>
/// A short description of the label (optional).
/// </summary>
public string Description { get; set; }

internal string DebuggerDisplay
{
get
Expand Down
Loading