diff --git a/Octokit.Tests/Clients/GistsClientTests.cs b/Octokit.Tests/Clients/GistsClientTests.cs index 2477fe5e..48a1bd6c 100644 --- a/Octokit.Tests/Clients/GistsClientTests.cs +++ b/Octokit.Tests/Clients/GistsClientTests.cs @@ -23,6 +23,107 @@ public class GistsClientTests } } + public class TheGetAllMethods + { + [Fact] + public void RequestsCorrectGetAllUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + client.GetAll(); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "gists"), null); + } + + [Fact] + public void RequestsCorrectGetAllWithSinceUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + DateTimeOffset since = DateTimeOffset.Now; + client.GetAll(since); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "gists"), + Arg.Is>(x => x.ContainsKey("since"))); + } + + [Fact] + public void RequestsCorrectGetAllPublicUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + client.GetAllPublic(); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "gists/public"), + Arg.Is>(x => x.ContainsKey("since"))); + } + + [Fact] + public void RequestsCorrectGetAllPublicWithSinceUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + DateTimeOffset since = DateTimeOffset.Now; + client.GetAllPublic(since); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "gists/public"), + Arg.Is>(x => x.ContainsKey("since"))); + } + + [Fact] + public void RequestsCorrectGetAllStarredUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + client.GetAllStarred(); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "gists/starred"), + Arg.Is>(x => x.ContainsKey("since"))); + } + + [Fact] + public void RequestsCorrectGetAllStarredWithSinceUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + DateTimeOffset since = DateTimeOffset.Now; + client.GetAllStarred(since); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "gists/starred"), + Arg.Is>(x => x.ContainsKey("since"))); + } + + [Fact] + public void RequestsCorrectGetGistsForAUserUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + client.GetAllForUser("octokit"); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "users/octokit/gists"), + Arg.Is>(x => x.ContainsKey("since"))); + } + + [Fact] + public void RequestsCorrectGetGistsForAUserWithSinceUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + DateTimeOffset since = DateTimeOffset.Now; + client.GetAllForUser("octokit", since); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "users/octokit/gists"), + Arg.Is>(x => x.ContainsKey("since"))); + } + } + public class TheCreateMethod { [Fact] @@ -67,6 +168,81 @@ public class GistsClientTests } } + public class TheStarMethods + { + [Fact] + public void RequestsCorrectStarUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + client.Star("1"); + + connection.Received().Get(Arg.Is(u => u.ToString() == "gists/1/star"), null); + } + + [Fact] + public void RequestsCorrectUnstarUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + client.Unstar("1"); + + connection.Received().Get(Arg.Is(u => u.ToString() == "gists/1/star"), null); + } + + [Fact] + public void RequestsCorrectCheckIfStarredUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + client.IsStarred("1"); + + connection.Received().Get(Arg.Is(u => u.ToString() == "gists/1/star"), null); + } + } + + public class TheForkMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + client.Fork("1"); + + connection.Received().Post(Arg.Is(u => u.ToString() == "gists/1/fork"), + Arg.Is(o => o == null)); + } + } + + public class TheEditMethod + { + [Fact] + public void PostsToTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new GistsClient(connection); + + var updateGist = new GistUpdate(); + updateGist.Description = "my newly updated gist"; + var gistFileUpdate = new GistFileUpdate + { + NewFileName = "myNewGistTestFile.cs", + Content = "new GistsClient(connection).Edit();" + }; + + updateGist.Files.Add("myGistTestFile.cs", gistFileUpdate); + + client.Edit("1", updateGist); + + connection.Received().Post(Arg.Is(u => u.ToString() == "gists/1"), Arg.Any()); + } + } + public class TheCtor { [Fact] diff --git a/Octokit/Clients/GistsClient.cs b/Octokit/Clients/GistsClient.cs index 7dc92efc..ae816607 100644 --- a/Octokit/Clients/GistsClient.cs +++ b/Octokit/Clients/GistsClient.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Net; using System.Threading.Tasks; namespace Octokit @@ -64,6 +66,18 @@ namespace Octokit return ApiConnection.Post(ApiUrls.Gist(), gist); } + /// + /// Creates a fork of a gist + /// + /// + /// http://developer.github.com/v3/gists/#fork-a-gist + /// + /// The id of the gist to fork + public Task Fork(string id) + { + return ApiConnection.Post(ApiUrls.ForkGist(id), new object()); + } + /// /// Deletes a gist /// @@ -77,5 +91,189 @@ namespace Octokit return ApiConnection.Delete(ApiUrls.Gist(id)); } + + /// + /// List the authenticated user’s gists or if called anonymously, + /// this will return all public gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + /// Only gists updated at or after this time are returned + public Task> GetAll() + { + return ApiConnection.GetAll(ApiUrls.Gist()); + } + + /// + /// List the authenticated user’s gists or if called anonymously, + /// this will return all public gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + /// Only gists updated at or after this time are returned + public Task> GetAll(DateTimeOffset since) + { + var request = new GistRequest(since); + return ApiConnection.GetAll(ApiUrls.Gist(), request.ToParametersDictionary()); + } + + /// + /// Lists all public gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + public Task> GetAllPublic() + { + return ApiConnection.GetAll(ApiUrls.PublicGists()); + } + + /// + /// Lists all public gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + /// Only gists updated at or after this time are returned + public Task> GetAllPublic(DateTimeOffset since) + { + var request = new GistRequest(since); + return ApiConnection.GetAll(ApiUrls.PublicGists(), request.ToParametersDictionary()); + } + + /// + /// List the authenticated user’s starred gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + public Task> GetAllStarred() + { + return ApiConnection.GetAll(ApiUrls.StarredGists()); + } + + /// + /// List the authenticated user’s starred gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + /// Only gists updated at or after this time are returned + public Task> GetAllStarred(DateTimeOffset since) + { + var request = new GistRequest(since); + return ApiConnection.GetAll(ApiUrls.StarredGists(), request.ToParametersDictionary()); + } + + /// + /// List a user's gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + /// The user + public Task> GetAllForUser(string user) + { + Ensure.ArgumentNotNull(user, "user"); + + return ApiConnection.GetAll(ApiUrls.UsersGists(user)); + } + + /// + /// List a user's gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + /// The user + /// Only gists updated at or after this time are returned + public Task> GetAllForUser(string user, DateTimeOffset since) + { + Ensure.ArgumentNotNull(user, "user"); + + var request = new GistRequest(since); + return ApiConnection.GetAll(ApiUrls.UsersGists(user), request.ToParametersDictionary()); + } + + /// + /// Edits a gist + /// + /// + /// http://developer.github.com/v3/gists/#edit-a-gist + /// + /// The id of the gist + /// The update to the gist + public Task Edit(string id, GistUpdate gistUpdate) + { + Ensure.ArgumentNotNull(id, "id"); + Ensure.ArgumentNotNull(gistUpdate, "gistUpdate"); + + var filesAsJsonObject = new JsonObject(); + foreach (var kvp in gistUpdate.Files) + { + filesAsJsonObject.Add(kvp.Key, new { Content = kvp.Value.Content, Filename = kvp.Value.NewFileName }); + } + + var gist = new + { + Description = gistUpdate.Description, + Files = filesAsJsonObject + }; + + return ApiConnection.Patch(ApiUrls.Gist(id), gist); + } + + /// + /// Stars a gist + /// + /// + /// http://developer.github.com/v3/gists/#star-a-gist + /// + /// The id of the gist + public Task Star(string id) + { + return ApiConnection.Put(ApiUrls.StarGist(id)); + } + + /// + /// Unstars a gist + /// + /// + /// http://developer.github.com/v3/gists/#unstar-a-gist + /// + /// The id of the gist + public Task Unstar(string id) + { + return ApiConnection.Delete(ApiUrls.StarGist(id)); + } + + /// + /// Checks if the gist is starred + /// + /// + /// http://developer.github.com/v3/gists/#check-if-a-gist-is-starred + /// + /// The id of the gist + public async Task IsStarred(string id) + { + Ensure.ArgumentNotNullOrEmptyString(id, "id"); + + try + { + var response = await Connection.GetAsync(ApiUrls.StarGist(id), null, null) + .ConfigureAwait(false); + if (response.StatusCode != HttpStatusCode.NotFound && response.StatusCode != HttpStatusCode.NoContent) + { + throw new ApiException("Invalid Status Code returned. Expected a 204 or a 404", response.StatusCode); + } + return response.StatusCode == HttpStatusCode.NoContent; + } + catch (NotFoundException) + { + return false; + } + } } } \ No newline at end of file diff --git a/Octokit/Clients/IGistsClient.cs b/Octokit/Clients/IGistsClient.cs index 587d0b4f..9ffdfbb5 100644 --- a/Octokit/Clients/IGistsClient.cs +++ b/Octokit/Clients/IGistsClient.cs @@ -1,4 +1,6 @@ -using System.Diagnostics.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; namespace Octokit @@ -24,6 +26,78 @@ namespace Octokit Justification = "Method makes a network request")] Task Get(string id); + /// + /// List the authenticated user’s gists or if called anonymously, + /// this will return all public gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + Task> GetAll(); + + /// + /// List the authenticated user’s gists or if called anonymously, + /// this will return all public gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + /// Only gists updated at or after this time are returned + Task> GetAll(DateTimeOffset since); + + /// + /// Lists all public gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + Task> GetAllPublic(); + + /// + /// Lists all public gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + /// Only gists updated at or after this time are returned + Task> GetAllPublic(DateTimeOffset since); + + /// + /// List the authenticated user’s starred gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + Task> GetAllStarred(); + + /// + /// List the authenticated user’s starred gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + /// Only gists updated at or after this time are returned + Task> GetAllStarred(DateTimeOffset since); + + /// + /// List a user's gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + /// The user + Task> GetAllForUser(string user); + + /// + /// List a user's gists + /// + /// + /// http://developer.github.com/v3/gists/#list-gists + /// + /// The user + /// Only gists updated at or after this time are returned + Task> GetAllForUser(string user, DateTimeOffset since); + /// /// Creates a new gist /// @@ -33,6 +107,25 @@ namespace Octokit /// The new gist to create Task Create(NewGist newGist); + /// + /// Creates a fork of a gist + /// + /// + /// http://developer.github.com/v3/gists/#fork-a-gist + /// + /// The id of the gist to fork + Task Fork(string id); + + /// + /// Edits a gist + /// + /// + /// http://developer.github.com/v3/gists/#delete-a-gist + /// + /// The id of the gist + /// The update to the gist + Task Edit(string id, GistUpdate gistUpdate); + /// /// Deletes a gist /// @@ -41,5 +134,33 @@ namespace Octokit /// /// The id of the gist Task Delete(string id); + + /// + /// Stars a gist + /// + /// + /// http://developer.github.com/v3/gists/#star-a-gist + /// + /// The id of the gist + Task Star(string id); + + /// + /// Unstars a gist + /// + /// + /// http://developer.github.com/v3/gists/#unstar-a-gist + /// + /// The id of the gist + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Unstar")] + Task Unstar(string id); + + /// + /// Checks if the gist is starred + /// + /// + /// http://developer.github.com/v3/gists/#check-if-a-gist-is-starred + /// + /// The id of the gist + Task IsStarred(string id); } } \ No newline at end of file diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index 7a9770fc..a861044d 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -622,6 +622,31 @@ namespace Octokit return "gists/{0}".FormatUri(id); } + public static Uri ForkGist(string id) + { + return "gists/{0}/forks".FormatUri(id); + } + + public static Uri PublicGists() + { + return "gists/public".FormatUri(); + } + + public static Uri StarredGists() + { + return "gists/starred".FormatUri(); + } + + public static Uri UsersGists(string user) + { + return "users/{0}/gists".FormatUri(user); + } + + public static Uri StarGist(string id) + { + return "gists/{0}/star".FormatUri(id); + } + /// /// Returns the for the comments for the specified gist. /// diff --git a/Octokit/Models/Request/GistRequest.cs b/Octokit/Models/Request/GistRequest.cs new file mode 100644 index 00000000..d37133e7 --- /dev/null +++ b/Octokit/Models/Request/GistRequest.cs @@ -0,0 +1,15 @@ +using System; +using Octokit.Internal; + +namespace Octokit +{ + public class GistRequest : RequestParameters + { + public GistRequest(DateTimeOffset since) + { + Since = since; + } + + public DateTimeOffset Since { get; set; } + } +} diff --git a/Octokit/Models/Request/GistUpdate.cs b/Octokit/Models/Request/GistUpdate.cs new file mode 100644 index 00000000..1d89b251 --- /dev/null +++ b/Octokit/Models/Request/GistUpdate.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using Octokit.Internal; + +namespace Octokit +{ + public class GistUpdate + { + public GistUpdate() + { + Files = new Dictionary(); + } + + public string Description { get; set; } + public IDictionary Files { get; private set; } + } + + public class GistFileUpdate + { + public string NewFileName { get; set; } + public string Content { get; set; } + } +} diff --git a/Octokit/Octokit-Mono.csproj b/Octokit/Octokit-Mono.csproj index 0ba47a12..a8b6e175 100644 --- a/Octokit/Octokit-Mono.csproj +++ b/Octokit/Octokit-Mono.csproj @@ -89,6 +89,8 @@ + + diff --git a/Octokit/Octokit-netcore45.csproj b/Octokit/Octokit-netcore45.csproj index c52fd9d8..c8803836 100644 --- a/Octokit/Octokit-netcore45.csproj +++ b/Octokit/Octokit-netcore45.csproj @@ -166,6 +166,8 @@ + + diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index c2fe81e0..e672a525 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -99,6 +99,8 @@ + +