Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 29 additions & 14 deletions Octokit.Tests/Clients/RepositoriesClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ public void UsesTheUserReposUrl()

client.Create(new NewRepository("aName"));

connection.Received().Post<Repository>(Arg.Is<Uri>(u => u.ToString() == "user/repos"), Arg.Any<NewRepository>());
connection.Received().Post<Repository>(Arg.Is<Uri>(u => u.ToString() == "user/repos"),
Arg.Any<NewRepository>(),
"application/vnd.github.nebula-preview+json");
}

[Fact]
Expand All @@ -52,7 +54,7 @@ public void TheNewRepositoryDescription()

client.Create(newRepository);

connection.Received().Post<Repository>(Args.Uri, newRepository);
connection.Received().Post<Repository>(Args.Uri, newRepository, "application/vnd.github.nebula-preview+json");
}

[Fact]
Expand All @@ -68,7 +70,7 @@ public async Task ThrowsRepositoryExistsExceptionWhenRepositoryExistsForCurrentU
var connection = Substitute.For<IApiConnection>();
connection.Connection.BaseAddress.Returns(GitHubClient.GitHubApiUrl);
connection.Connection.Credentials.Returns(credentials);
connection.Post<Repository>(Args.Uri, newRepository)
connection.Post<Repository>(Args.Uri, newRepository, "application/vnd.github.nebula-preview+json")
.Returns<Task<Repository>>(_ => { throw new ApiValidationException(response); });
var client = new RepositoriesClient(connection);

Expand All @@ -95,7 +97,7 @@ public async Task ThrowsExceptionWhenPrivateRepositoryQuotaExceeded()
var connection = Substitute.For<IApiConnection>();
connection.Connection.BaseAddress.Returns(GitHubClient.GitHubApiUrl);
connection.Connection.Credentials.Returns(credentials);
connection.Post<Repository>(Args.Uri, newRepository)
connection.Post<Repository>(Args.Uri, newRepository, "application/vnd.github.nebula-preview+json")
.Returns<Task<Repository>>(_ => { throw new ApiValidationException(response); });
var client = new RepositoriesClient(connection);

Expand Down Expand Up @@ -127,7 +129,8 @@ public async Task UsesTheOrganizationsReposUrl()

connection.Received().Post<Repository>(
Arg.Is<Uri>(u => u.ToString() == "orgs/theLogin/repos"),
Args.NewRepository);
Args.NewRepository,
"application/vnd.github.nebula-preview+json");
}

[Fact]
Expand All @@ -139,7 +142,7 @@ public async Task TheNewRepositoryDescription()

await client.Create("aLogin", newRepository);

connection.Received().Post<Repository>(Args.Uri, newRepository);
connection.Received().Post<Repository>(Args.Uri, newRepository, "application/vnd.github.nebula-preview+json");
}

[Fact]
Expand All @@ -153,7 +156,7 @@ public async Task ThrowsRepositoryExistsExceptionWhenRepositoryExistsForSpecifie
+ @"""code"":""custom"",""field"":""name"",""message"":""name already exists on this account""}]}");
var connection = Substitute.For<IApiConnection>();
connection.Connection.BaseAddress.Returns(GitHubClient.GitHubApiUrl);
connection.Post<Repository>(Args.Uri, newRepository)
connection.Post<Repository>(Args.Uri, newRepository, "application/vnd.github.nebula-preview+json")
.Returns<Task<Repository>>(_ => { throw new ApiValidationException(response); });
var client = new RepositoriesClient(connection);

Expand All @@ -178,7 +181,7 @@ public async Task ThrowsValidationException()
+ @"""http://developer.github.com/v3/repos/#create"",""errors"":[]}");
var connection = Substitute.For<IApiConnection>();
connection.Connection.BaseAddress.Returns(GitHubClient.GitHubApiUrl);
connection.Post<Repository>(Args.Uri, newRepository)
connection.Post<Repository>(Args.Uri, newRepository, "application/vnd.github.nebula-preview+json")
.Returns<Task<Repository>>(_ => { throw new ApiValidationException(response); });
var client = new RepositoriesClient(connection);

Expand All @@ -199,7 +202,7 @@ public async Task ThrowsRepositoryExistsExceptionForEnterpriseInstance()
+ @"""code"":""custom"",""field"":""name"",""message"":""name already exists on this account""}]}");
var connection = Substitute.For<IApiConnection>();
connection.Connection.BaseAddress.Returns(new Uri("https://example.com"));
connection.Post<Repository>(Args.Uri, newRepository)
connection.Post<Repository>(Args.Uri, newRepository, "application/vnd.github.nebula-preview+json")
.Returns<Task<Repository>>(_ => { throw new ApiValidationException(response); });
var client = new RepositoriesClient(connection);

Expand Down Expand Up @@ -402,7 +405,9 @@ public async Task RequestsCorrectUrl()
await client.Get("owner", "name");

connection.Received()
.Get<Repository>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/name"));
.Get<Repository>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/name"),
null,
"application/vnd.github.nebula-preview+json");
}

[Fact]
Expand Down Expand Up @@ -483,7 +488,10 @@ public async Task RequestsTheCorrectUrlAndReturnsRepositories()
await client.GetAllForCurrent();

connection.Received()
.GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "user/repos"), Args.ApiOptions);
.GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "user/repos"),
null,
"application/vnd.github.nebula-preview+json",
Args.ApiOptions);
}

[Fact]
Expand All @@ -503,6 +511,7 @@ public async Task CanFilterByType()
.GetAll<Repository>(
Arg.Is<Uri>(u => u.ToString() == "user/repos"),
Arg.Is<Dictionary<string, string>>(d => d["type"] == "all"),
"application/vnd.github.nebula-preview+json",
Args.ApiOptions);
}

Expand All @@ -524,6 +533,7 @@ public async Task CanFilterBySort()
.GetAll<Repository>(
Arg.Is<Uri>(u => u.ToString() == "user/repos"),
Arg.Is<Dictionary<string, string>>(d => d["type"] == "private" && d["sort"] == "full_name"),
"application/vnd.github.nebula-preview+json",
Args.ApiOptions);
}

Expand All @@ -546,6 +556,7 @@ public async Task CanFilterBySortDirection()
.GetAll<Repository>(
Arg.Is<Uri>(u => u.ToString() == "user/repos"),
Arg.Is<Dictionary<string, string>>(d => d["type"] == "member" && d["sort"] == "updated" && d["direction"] == "asc"),
"application/vnd.github.nebula-preview+json",
Args.ApiOptions);
}

Expand All @@ -557,7 +568,7 @@ public async Task CanFilterByVisibility()

var request = new RepositoryRequest
{
Visibility = RepositoryVisibility.Private
Visibility = RepositoryRequestVisibility.Private
};

await client.GetAllForCurrent(request);
Expand All @@ -566,6 +577,7 @@ public async Task CanFilterByVisibility()
.GetAll<Repository>(
Arg.Is<Uri>(u => u.ToString() == "user/repos"),
Arg.Is<Dictionary<string, string>>(d => d["visibility"] == "private"),
"application/vnd.github.nebula-preview+json",
Args.ApiOptions);
}

Expand All @@ -587,6 +599,7 @@ public async Task CanFilterByAffiliation()
.GetAll<Repository>(
Arg.Is<Uri>(u => u.ToString() == "user/repos"),
Arg.Is<Dictionary<string, string>>(d => d["affiliation"] == "owner" && d["sort"] == "full_name"),
"application/vnd.github.nebula-preview+json",
Args.ApiOptions);
}
}
Expand Down Expand Up @@ -631,7 +644,7 @@ public async Task RequestsTheCorrectUrl()
await client.GetAllForOrg("orgname");

connection.Received()
.GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "orgs/orgname/repos"), Args.ApiOptions);
.GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "orgs/orgname/repos"), null, "application/vnd.github.nebula-preview+json", Args.ApiOptions);
}

[Fact]
Expand Down Expand Up @@ -1063,7 +1076,9 @@ public void PatchesCorrectUrl()
client.Edit("owner", "repo", update);

connection.Received()
.Patch<Repository>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/repo"), Arg.Any<RepositoryUpdate>());
.Patch<Repository>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/repo"),
Arg.Any<RepositoryUpdate>(),
"application/vnd.github.nebula-preview+json");
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion Octokit.Tests/Models/RepositoryRequestTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void ContainsSetValues()
request = new RepositoryRequest
{
Affiliation = RepositoryAffiliation.All,
Visibility = RepositoryVisibility.Public
Visibility = RepositoryRequestVisibility.Public
};

parameters = request.ToParametersDictionary();
Expand Down
24 changes: 17 additions & 7 deletions Octokit/Clients/RepositoriesClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public RepositoriesClient(IApiConnection apiConnection) : base(apiConnection)
/// <param name="newRepository">A <see cref="NewRepository"/> instance describing the new repository to create</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>A <see cref="Repository"/> instance for the created repository.</returns>
[Preview("nebula")]
[ManualRoute("POST", "/user/repos")]
public Task<Repository> Create(NewRepository newRepository)
{
Expand All @@ -68,6 +69,7 @@ public Task<Repository> Create(NewRepository newRepository)
/// <param name="newRepository">A <see cref="NewRepository"/> instance describing the new repository to create</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>A <see cref="Repository"/> instance for the created repository</returns>
[Preview("nebula")]
[ManualRoute("POST", "/orgs/{org}/repos")]
public Task<Repository> Create(string organizationLogin, NewRepository newRepository)
{
Expand All @@ -83,7 +85,7 @@ async Task<Repository> Create(Uri url, string organizationLogin, NewRepository n
{
try
{
return await ApiConnection.Post<Repository>(url, newRepository).ConfigureAwait(false);
return await ApiConnection.Post<Repository>(url, newRepository, AcceptHeaders.VisibilityPreview).ConfigureAwait(false);
}
catch (ApiValidationException e)
{
Expand Down Expand Up @@ -211,6 +213,7 @@ public Task<Repository> Transfer(long repositoryId, RepositoryTransfer repositor
/// <param name="name">The name of the repository</param>
/// <param name="update">New values to update the repository with</param>
/// <returns>The updated <see cref="T:Octokit.Repository"/></returns>
[Preview("nebula")]
[ManualRoute("PATCH", "/repos/{owner}/{repo}")]
public Task<Repository> Edit(string owner, string name, RepositoryUpdate update)
{
Expand All @@ -219,7 +222,7 @@ public Task<Repository> Edit(string owner, string name, RepositoryUpdate update)
Ensure.ArgumentNotNull(update, nameof(update));
Ensure.ArgumentNotNull(update.Name, nameof(update.Name));

return ApiConnection.Patch<Repository>(ApiUrls.Repository(owner, name), update);
return ApiConnection.Patch<Repository>(ApiUrls.Repository(owner, name), update, AcceptHeaders.VisibilityPreview);
}

/// <summary>
Expand All @@ -246,13 +249,14 @@ public Task<Repository> Edit(long repositoryId, RepositoryUpdate update)
/// <param name="name">The name of the repository</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>A <see cref="Repository"/></returns>
[Preview("nebula")]
[ManualRoute("GET", "/repos/{owner}/{repo}")]
public Task<Repository> Get(string owner, string name)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));

return ApiConnection.Get<Repository>(ApiUrls.Repository(owner, name));
return ApiConnection.Get<Repository>(ApiUrls.Repository(owner, name), null, AcceptHeaders.VisibilityPreview);
}

/// <summary>
Expand All @@ -279,7 +283,7 @@ public Task<Repository> Get(long repositoryId)
/// </remarks>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>A <see cref="IReadOnlyList{Repository}"/> of <see cref="Repository"/>.</returns>
/// <returns>A <see cref="IReadOnlyList{Repository}"/> of <see cref="Repository"/>.</returns>
[ManualRoute("GET", "/repositories")]
public Task<IReadOnlyList<Repository>> GetAllPublic()
{
Expand Down Expand Up @@ -317,6 +321,7 @@ public Task<IReadOnlyList<Repository>> GetAllPublic(PublicRepositoryRequest requ
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>A <see cref="IReadOnlyList{Repository}"/> of <see cref="Repository"/>.</returns>
[Preview("nebula")]
[ManualRoute("GET", "/user/repos")]
public Task<IReadOnlyList<Repository>> GetAllForCurrent()
{
Expand All @@ -333,12 +338,13 @@ public Task<IReadOnlyList<Repository>> GetAllForCurrent()
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>A <see cref="IReadOnlyList{Repository}"/> of <see cref="Repository"/>.</returns>
[Preview("nebula")]
[ManualRoute("GET", "/user/repos")]
public Task<IReadOnlyList<Repository>> GetAllForCurrent(ApiOptions options)
{
Ensure.ArgumentNotNull(options, nameof(options));

return ApiConnection.GetAll<Repository>(ApiUrls.Repositories(), options);
return ApiConnection.GetAll<Repository>(ApiUrls.Repositories(), null, AcceptHeaders.VisibilityPreview, options);
}

/// <summary>
Expand All @@ -352,6 +358,7 @@ public Task<IReadOnlyList<Repository>> GetAllForCurrent(ApiOptions options)
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>A <see cref="IReadOnlyList{Repository}"/> of <see cref="Repository"/>.</returns>
[Preview("nebula")]
[ManualRoute("GET", "/user/repos")]
public Task<IReadOnlyList<Repository>> GetAllForCurrent(RepositoryRequest request)
{
Expand All @@ -372,13 +379,14 @@ public Task<IReadOnlyList<Repository>> GetAllForCurrent(RepositoryRequest reques
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>A <see cref="IReadOnlyList{Repository}"/> of <see cref="Repository"/>.</returns>
[Preview("nebula")]
[ManualRoute("GET", "/user/repos")]
public Task<IReadOnlyList<Repository>> GetAllForCurrent(RepositoryRequest request, ApiOptions options)
{
Ensure.ArgumentNotNull(request, nameof(request));
Ensure.ArgumentNotNull(options, nameof(options));

return ApiConnection.GetAll<Repository>(ApiUrls.Repositories(), request.ToParametersDictionary(), options);
return ApiConnection.GetAll<Repository>(ApiUrls.Repositories(), request.ToParametersDictionary(), AcceptHeaders.VisibilityPreview, options);
}

/// <summary>
Expand Down Expand Up @@ -427,6 +435,7 @@ public Task<IReadOnlyList<Repository>> GetAllForUser(string login, ApiOptions op
/// </remarks>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>A <see cref="IReadOnlyList{Repository}"/> of <see cref="Repository"/>.</returns>
[Preview("nebula")]
[ManualRoute("GET", "/orgs/{org}/repos")]
public Task<IReadOnlyList<Repository>> GetAllForOrg(string organization)
{
Expand All @@ -445,13 +454,14 @@ public Task<IReadOnlyList<Repository>> GetAllForOrg(string organization)
/// <param name="options">Options for changing the API response</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>A <see cref="IReadOnlyList{Repository}"/> of <see cref="Repository"/>.</returns>
[Preview("nebula")]
[ManualRoute("GET", "/orgs/{org}/repos")]
public Task<IReadOnlyList<Repository>> GetAllForOrg(string organization, ApiOptions options)
{
Ensure.ArgumentNotNullOrEmptyString(organization, nameof(organization));
Ensure.ArgumentNotNull(options, nameof(options));

return ApiConnection.GetAll<Repository>(ApiUrls.OrganizationRepositories(organization), options);
return ApiConnection.GetAll<Repository>(ApiUrls.OrganizationRepositories(organization), null, AcceptHeaders.VisibilityPreview, options);
}

/// <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 @@ -50,6 +50,8 @@ public static class AcceptHeaders

public const string OAuthApplicationsPreview = "application/vnd.github.doctor-strange-preview+json";

public const string VisibilityPreview = "application/vnd.github.nebula-preview+json";

/// <summary>
/// Combines multiple preview headers. GitHub API supports Accept header with multiple
/// values separated by comma.
Expand Down
Loading