From 2bcfd8802c440eb45e94c5dd7f70e4bcf643c0e1 Mon Sep 17 00:00:00 2001 From: half-ogre Date: Tue, 1 Oct 2013 17:15:28 -0700 Subject: [PATCH 01/16] add model for creating a new repository --- Octokit/GitHubModels.cs | 60 +++++++++++++++++++++++++++++++++++++++++ Octokit/Octokit.csproj | 1 + 2 files changed, 61 insertions(+) diff --git a/Octokit/GitHubModels.cs b/Octokit/GitHubModels.cs index 4d6b00f5..1a68bde8 100644 --- a/Octokit/GitHubModels.cs +++ b/Octokit/GitHubModels.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using Octokit.Http; @@ -452,4 +453,63 @@ namespace Octokit public bool Primary { get; set; } } + + /// + /// Describes a new repository to create via the method. + /// + public class NewRepository + { + /// + /// Optional. Gets or sets whether to create an initial commit with empty README. The default is false. + /// + public bool? AutoInit { get; set; } + + /// + /// Required. Gets or sets the new repository's description + /// + public string Description { get; set; } + + /// s + /// Optional. Gets or sets whether to the enable downloads for the new repository. The default is true. + /// + [DataMember(Name="has_downloads")] + public bool? HasDownloads { get; set; } + + /// s + /// Optional. Gets or sets whether to the enable issues for the new repository. The default is true. + /// + [DataMember(Name = "has_issues")] + public bool? HasIssues { get; set; } + + /// s + /// Optional. Gets or sets whether to the enable the wiki for the new repository. The default is true. + /// + [DataMember(Name = "has_wiki")] + public bool? HasWiki { get; set; } + + /// + /// Optional. Gets or sets the new repository's optional website. + /// + public string Homepage { get; set; } + + /// + /// Optional. Gets or sets the desired language's or platform's .gitignore template to apply. Use the name of the template without the extension; "Haskell", for example. Ignored if is null or false. + /// + public string GitIgnoreTemplate { get; set; } + + /// + /// Required. Gets or sets the new repository's name. + /// + public string Name { get; set; } + + /// + /// Optional. Gets or sets whether the new repository is private; the default is false. + /// + public bool? Private { get; set; } + + /// + /// Optional. Gets or sets the ID of the team to grant access to this repository. This is only valid when creating a repository for an organization. + /// + public int? TeamId { get; set; } + } } diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index 887fc4b6..780a2072 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -72,6 +72,7 @@ ..\packages\Microsoft.Bcl.1.1.3\lib\net40\System.Runtime.dll + ..\packages\Microsoft.Bcl.1.1.3\lib\net40\System.Threading.Tasks.dll From 5993c50bd22aa2734f33ca812faad3fad9985266 Mon Sep 17 00:00:00 2001 From: half-ogre Date: Tue, 1 Oct 2013 17:16:01 -0700 Subject: [PATCH 02/16] add helper to make collision-safe names --- Octokit.Tests.Integration/AutomationSettings.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Octokit.Tests.Integration/AutomationSettings.cs b/Octokit.Tests.Integration/AutomationSettings.cs index fca5ac97..ea7ae1df 100644 --- a/Octokit.Tests.Integration/AutomationSettings.cs +++ b/Octokit.Tests.Integration/AutomationSettings.cs @@ -57,5 +57,15 @@ namespace Octokit.Tests.Integration /// Username of a GitHub test account (DO NOT USE A "REAL" ACCOUNT). /// public string GitHubUsername { get; private set; } + + /// + /// Makes a name with an appended timestamp so that it's safe for testing (i.e., won't collide with existing names). + /// + /// The name to use as a base, to which a timestamp will be appended + /// The name with a timestamp appended + public static string MakeNameWithTimestamp(string name) + { + return string.Concat(name, "-", DateTime.UtcNow.ToString("yyyyMMddhhmmssfff")); + } } } From e1dbeb4551e4913bea181e2b4d0ffe2470328578 Mon Sep 17 00:00:00 2001 From: half-ogre Date: Tue, 1 Oct 2013 17:16:30 -0700 Subject: [PATCH 03/16] add method to create a repository --- .../Clients/RepositoriesClientTests.cs | 35 +++++++++++++++++++ Octokit/Clients/RepositoriesClient.cs | 15 ++++++++ Octokit/IRepositoriesClient.cs | 7 ++++ 3 files changed, 57 insertions(+) diff --git a/Octokit.Tests/Clients/RepositoriesClientTests.cs b/Octokit.Tests/Clients/RepositoriesClientTests.cs index 08a0ec5b..2c9a698d 100644 --- a/Octokit.Tests/Clients/RepositoriesClientTests.cs +++ b/Octokit.Tests/Clients/RepositoriesClientTests.cs @@ -24,6 +24,41 @@ namespace Octokit.Tests.Clients } } + public class TheCreateMethod + { + [Fact] + public async Task EnsuresNonNullArguments() + { + var repositoriesClient = new RepositoriesClient(Substitute.For>()); + + await AssertEx.Throws(async () => await repositoriesClient.Create(null)); + await AssertEx.Throws(async () => await repositoriesClient.Create(new NewRepository { Name = null })); + } + + [Fact] + public void UsesTheUserReposUrl() + { + var client = Substitute.For>(); + var repositoriesClient = new RepositoriesClient(client); + + repositoriesClient.Create(new NewRepository { Name = "aName" }); + + client.Received().Create(Arg.Is(u => u.ToString() == "user/repos"), Arg.Any()); + } + + [Fact] + public void TheNewRepositoryDescription() + { + var client = Substitute.For>(); + var repositoriesClient = new RepositoriesClient(client); + var newRepository = new NewRepository { Name = "aName" }; + + repositoriesClient.Create(newRepository); + + client.Received().Create(Arg.Any(), newRepository); + } + } + public class TheGetMethod { [Fact] diff --git a/Octokit/Clients/RepositoriesClient.cs b/Octokit/Clients/RepositoriesClient.cs index e09e0dbb..37bca958 100644 --- a/Octokit/Clients/RepositoriesClient.cs +++ b/Octokit/Clients/RepositoriesClient.cs @@ -11,6 +11,21 @@ namespace Octokit.Clients { } + /// + /// Creates a new repository for the current user. + /// + /// A instance describing the new repository to create + /// A instance for the created repository + public async Task Create(NewRepository newRepository) + { + Ensure.ArgumentNotNull(newRepository, "newRepository"); + if (string.IsNullOrEmpty(newRepository.Name)) + throw new ArgumentException("The new repository's name must not be null."); + + var endpoint = new Uri("user/repos", UriKind.Relative); + return await Client.Create(endpoint, newRepository); + } + public async Task Get(string owner, string name) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); diff --git a/Octokit/IRepositoriesClient.cs b/Octokit/IRepositoriesClient.cs index b417028b..9d806439 100644 --- a/Octokit/IRepositoriesClient.cs +++ b/Octokit/IRepositoriesClient.cs @@ -6,6 +6,13 @@ namespace Octokit { public interface IRepositoriesClient { + /// + /// Creates a new repository for the current user. + /// + /// A instance describing the new repository to create + /// A instance for the created repository + Task Create(NewRepository newRepository); + /// /// Retrieves the for the specified owner and name. /// From 9ee08362e1bd98c242e653fa7c4be44f97e7eeb2 Mon Sep 17 00:00:00 2001 From: half-ogre Date: Tue, 1 Oct 2013 17:16:47 -0700 Subject: [PATCH 04/16] add create public repo integration test --- .../RepositoriesClientTests.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Octokit.Tests.Integration/RepositoriesClientTests.cs b/Octokit.Tests.Integration/RepositoriesClientTests.cs index 3b55a09c..ebac340a 100644 --- a/Octokit.Tests.Integration/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/RepositoriesClientTests.cs @@ -6,6 +6,29 @@ namespace Octokit.Tests.Integration { public class RepositoriesClientTests { + public class TheCreateMethod + { + [IntegrationTest] + public async Task CreatesANewPublicRepository() + { + var github = new GitHubClient + { + Credentials = AutomationSettings.Current.GitHubCredentials + }; + var repoName = AutomationSettings.MakeNameWithTimestamp("public-repo"); + + var createdRepository = await github.Repository.Create(new NewRepository { Name = repoName }); + + var cloneUrl = string.Format("https://github.com/{0}/{1}.git", github.Credentials.Login, repoName); + Assert.Equal(repoName, createdRepository.Name); + Assert.Equal(cloneUrl, createdRepository.CloneUrl); + Assert.False(createdRepository.Private); + var repository = await github.Repository.Get(github.Credentials.Login, repoName); + Assert.Equal(repoName, repository.Name); + Assert.False(repository.Private); + } + } + public class TheGetAsyncMethod { [IntegrationTest] From a77513738bd5c9478fd8dcc3cbfa3ff2949e635a Mon Sep 17 00:00:00 2001 From: half-ogre Date: Tue, 1 Oct 2013 17:54:45 -0700 Subject: [PATCH 05/16] add create private repo integration test --- .../RepositoriesClientTests.cs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Octokit.Tests.Integration/RepositoriesClientTests.cs b/Octokit.Tests.Integration/RepositoriesClientTests.cs index ebac340a..1bbfbb1b 100644 --- a/Octokit.Tests.Integration/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/RepositoriesClientTests.cs @@ -22,10 +22,28 @@ namespace Octokit.Tests.Integration var cloneUrl = string.Format("https://github.com/{0}/{1}.git", github.Credentials.Login, repoName); Assert.Equal(repoName, createdRepository.Name); Assert.Equal(cloneUrl, createdRepository.CloneUrl); - Assert.False(createdRepository.Private); var repository = await github.Repository.Get(github.Credentials.Login, repoName); Assert.Equal(repoName, repository.Name); - Assert.False(repository.Private); + } + + [IntegrationTest] + public async Task CreatesANewPrivateRepository() + { + var github = new GitHubClient + { + Credentials = AutomationSettings.Current.GitHubCredentials + }; + var repoName = AutomationSettings.MakeNameWithTimestamp("private-repo"); + + var createdRepository = await github.Repository.Create(new NewRepository + { + Name = repoName, + Private = true + }); + + Assert.True(createdRepository.Private); + var repository = await github.Repository.Get(github.Credentials.Login, repoName); + Assert.True(repository.Private); } } From 1b6810ac0bec384753e8be7b8534470881bb2736 Mon Sep 17 00:00:00 2001 From: half-ogre Date: Wed, 2 Oct 2013 14:41:01 -0700 Subject: [PATCH 06/16] remove needless DataMember stuff This wasn't actually being used because the POCO serializer strategy was already translating property names to JSON-friendly names. --- Octokit/GitHubModels.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Octokit/GitHubModels.cs b/Octokit/GitHubModels.cs index 1a68bde8..22ec7fb0 100644 --- a/Octokit/GitHubModels.cs +++ b/Octokit/GitHubModels.cs @@ -472,19 +472,16 @@ namespace Octokit /// s /// Optional. Gets or sets whether to the enable downloads for the new repository. The default is true. /// - [DataMember(Name="has_downloads")] public bool? HasDownloads { get; set; } /// s /// Optional. Gets or sets whether to the enable issues for the new repository. The default is true. /// - [DataMember(Name = "has_issues")] public bool? HasIssues { get; set; } /// s /// Optional. Gets or sets whether to the enable the wiki for the new repository. The default is true. /// - [DataMember(Name = "has_wiki")] public bool? HasWiki { get; set; } /// From 0444f8630aa4d29f2ec090a9dd702400b7b0e7dc Mon Sep 17 00:00:00 2001 From: half-ogre Date: Mon, 7 Oct 2013 17:06:20 -0700 Subject: [PATCH 07/16] omit null values from serialized objects --- Octokit/Http/SimpleJsonSerializer.cs | 34 +++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/Octokit/Http/SimpleJsonSerializer.cs b/Octokit/Http/SimpleJsonSerializer.cs index 8c846cf4..8876b95b 100644 --- a/Octokit/Http/SimpleJsonSerializer.cs +++ b/Octokit/Http/SimpleJsonSerializer.cs @@ -1,4 +1,10 @@ -namespace Octokit.Http +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using Octokit.Reflection; + +namespace Octokit.Http { public class SimpleJsonSerializer : IJsonSerializer { @@ -20,6 +26,32 @@ { return clrPropertyName.ToRubyCase(); } + + // This is overridden so that null values are omitted from serialized objects. + [SuppressMessage("Microsoft.Design", "CA1007:UseGenericsWhereAppropriate", Justification = "Need to support .NET 2")] + protected override bool TrySerializeUnknownTypes(object input, out object output) + { + if (input == null) throw new ArgumentNullException("input"); + output = null; + Type type = input.GetType(); + if (type.FullName == null) + return false; + IDictionary obj = new JsonObject(); + IDictionary getters = GetCache[type]; + foreach (KeyValuePair getter in getters) + { + if (getter.Value != null) + { + var value = getter.Value(input); + if (value == null) + continue; + + obj.Add(MapClrMemberNameToJsonFieldName(getter.Key), value); + } + } + output = obj; + return true; + } } } } From 3bdc8948a3e3880e7f0f30972a46f4134a0ee544 Mon Sep 17 00:00:00 2001 From: half-ogre Date: Mon, 7 Oct 2013 17:08:48 -0700 Subject: [PATCH 08/16] add has_xxx integration tests --- .../RepositoriesClientTests.cs | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/Octokit.Tests.Integration/RepositoriesClientTests.cs b/Octokit.Tests.Integration/RepositoriesClientTests.cs index 1bbfbb1b..db6ef919 100644 --- a/Octokit.Tests.Integration/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/RepositoriesClientTests.cs @@ -21,9 +21,14 @@ namespace Octokit.Tests.Integration var cloneUrl = string.Format("https://github.com/{0}/{1}.git", github.Credentials.Login, repoName); Assert.Equal(repoName, createdRepository.Name); + Assert.False(createdRepository.Private); Assert.Equal(cloneUrl, createdRepository.CloneUrl); var repository = await github.Repository.Get(github.Credentials.Login, repoName); Assert.Equal(repoName, repository.Name); + Assert.False(repository.Private); + Assert.True(repository.HasDownloads); + Assert.True(repository.HasIssues); + Assert.True(repository.HasWiki); } [IntegrationTest] @@ -45,6 +50,66 @@ namespace Octokit.Tests.Integration var repository = await github.Repository.Get(github.Credentials.Login, repoName); Assert.True(repository.Private); } + + [IntegrationTest] + public async Task CreatesARepositoryWithoutDownloads() + { + var github = new GitHubClient + { + Credentials = AutomationSettings.Current.GitHubCredentials + }; + var repoName = AutomationSettings.MakeNameWithTimestamp("repo-without-downloads"); + + var createdRepository = await github.Repository.Create(new NewRepository + { + Name = repoName, + HasDownloads = false + }); + + Assert.False(createdRepository.HasDownloads); + var repository = await github.Repository.Get(github.Credentials.Login, repoName); + Assert.False(repository.HasDownloads); + } + + [IntegrationTest] + public async Task CreatesARepositoryWithoutIssues() + { + var github = new GitHubClient + { + Credentials = AutomationSettings.Current.GitHubCredentials + }; + var repoName = AutomationSettings.MakeNameWithTimestamp("repo-without-issues"); + + var createdRepository = await github.Repository.Create(new NewRepository + { + Name = repoName, + HasIssues = false + }); + + Assert.False(createdRepository.HasIssues); + var repository = await github.Repository.Get(github.Credentials.Login, repoName); + Assert.False(repository.HasIssues); + } + + [IntegrationTest] + public async Task CreatesARepositoryWithoutAWiki() + { + var github = new GitHubClient + { + Credentials = AutomationSettings.Current.GitHubCredentials + }; + var repoName = AutomationSettings.MakeNameWithTimestamp("repo-without-wiki"); + + var createdRepository = await github.Repository.Create(new NewRepository + { + Name = repoName, + HasWiki = false + }); + + Assert.False(createdRepository.HasWiki); + var repository = await github.Repository.Get(github.Credentials.Login, repoName); + Assert.False(repository.HasWiki); + } } public class TheGetAsyncMethod From c92e1f9286254841270ddbd4fa656dd691a62b9f Mon Sep 17 00:00:00 2001 From: half-ogre Date: Mon, 7 Oct 2013 17:14:34 -0700 Subject: [PATCH 09/16] add description integration test for new repo --- .../RepositoriesClientTests.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Octokit.Tests.Integration/RepositoriesClientTests.cs b/Octokit.Tests.Integration/RepositoriesClientTests.cs index db6ef919..a9e700da 100644 --- a/Octokit.Tests.Integration/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/RepositoriesClientTests.cs @@ -25,6 +25,7 @@ namespace Octokit.Tests.Integration Assert.Equal(cloneUrl, createdRepository.CloneUrl); var repository = await github.Repository.Get(github.Credentials.Login, repoName); Assert.Equal(repoName, repository.Name); + Assert.Null(repository.Description); Assert.False(repository.Private); Assert.True(repository.HasDownloads); Assert.True(repository.HasIssues); @@ -110,6 +111,26 @@ namespace Octokit.Tests.Integration var repository = await github.Repository.Get(github.Credentials.Login, repoName); Assert.False(repository.HasWiki); } + + [IntegrationTest] + public async Task CreatesARepositoryWithADescription() + { + var github = new GitHubClient + { + Credentials = AutomationSettings.Current.GitHubCredentials + }; + var repoName = AutomationSettings.MakeNameWithTimestamp("repo-with-description"); + + var createdRepository = await github.Repository.Create(new NewRepository + { + Name = repoName, + Description = "theDescription" + }); + + Assert.Equal("theDescription", createdRepository.Description); + var repository = await github.Repository.Get(github.Credentials.Login, repoName); + Assert.Equal("theDescription", repository.Description); + } } public class TheGetAsyncMethod From 68cea65de4945bbf931c169910084f981c8fa532 Mon Sep 17 00:00:00 2001 From: half-ogre Date: Mon, 7 Oct 2013 17:20:07 -0700 Subject: [PATCH 10/16] add homepage integration test for new repo --- .../RepositoriesClientTests.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Octokit.Tests.Integration/RepositoriesClientTests.cs b/Octokit.Tests.Integration/RepositoriesClientTests.cs index a9e700da..a2f8cc23 100644 --- a/Octokit.Tests.Integration/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/RepositoriesClientTests.cs @@ -30,6 +30,7 @@ namespace Octokit.Tests.Integration Assert.True(repository.HasDownloads); Assert.True(repository.HasIssues); Assert.True(repository.HasWiki); + Assert.Null(repository.Homepage); } [IntegrationTest] @@ -131,6 +132,26 @@ namespace Octokit.Tests.Integration var repository = await github.Repository.Get(github.Credentials.Login, repoName); Assert.Equal("theDescription", repository.Description); } + + [IntegrationTest] + public async Task CreatesARepositoryWithAHomepage() + { + var github = new GitHubClient + { + Credentials = AutomationSettings.Current.GitHubCredentials + }; + var repoName = AutomationSettings.MakeNameWithTimestamp("repo-with-description"); + + var createdRepository = await github.Repository.Create(new NewRepository + { + Name = repoName, + Homepage = "http://aUrl.to/nowhere" + }); + + Assert.Equal("http://aUrl.to/nowhere", createdRepository.Homepage); + var repository = await github.Repository.Get(github.Credentials.Login, repoName); + Assert.Equal("http://aUrl.to/nowhere", repository.Homepage); + } } public class TheGetAsyncMethod From 7705aa3b63f403083e6d8b19a1ddc87e80139b24 Mon Sep 17 00:00:00 2001 From: half-ogre Date: Mon, 7 Oct 2013 17:43:07 -0700 Subject: [PATCH 11/16] fix property name for proper serialization --- Octokit/GitHubModels.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Octokit/GitHubModels.cs b/Octokit/GitHubModels.cs index 22ec7fb0..5600ea81 100644 --- a/Octokit/GitHubModels.cs +++ b/Octokit/GitHubModels.cs @@ -492,7 +492,8 @@ namespace Octokit /// /// Optional. Gets or sets the desired language's or platform's .gitignore template to apply. Use the name of the template without the extension; "Haskell", for example. Ignored if is null or false. /// - public string GitIgnoreTemplate { get; set; } + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gitignore", Justification="It needs to be this way for proper serialization.")] + public string GitignoreTemplate { get; set; } /// /// Required. Gets or sets the new repository's name. From 527d1fb52caef2d24937886091f8977ade31f13f Mon Sep 17 00:00:00 2001 From: half-ogre Date: Mon, 7 Oct 2013 17:43:25 -0700 Subject: [PATCH 12/16] add auto_init and gitignore integration tests --- .../RepositoriesClientTests.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/Octokit.Tests.Integration/RepositoriesClientTests.cs b/Octokit.Tests.Integration/RepositoriesClientTests.cs index a2f8cc23..5ae5b4c4 100644 --- a/Octokit.Tests.Integration/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/RepositoriesClientTests.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; using System.Threading.Tasks; using Xunit; @@ -152,6 +153,49 @@ namespace Octokit.Tests.Integration var repository = await github.Repository.Get(github.Credentials.Login, repoName); Assert.Equal("http://aUrl.to/nowhere", repository.Homepage); } + + [IntegrationTest] + public async Task CreatesARepositoryWithAutoInit() + { + var github = new GitHubClient + { + Credentials = AutomationSettings.Current.GitHubCredentials + }; + var repoName = AutomationSettings.MakeNameWithTimestamp("repo-with-autoinit"); + + var createdRepository = await github.Repository.Create(new NewRepository + { + Name = repoName, + AutoInit = true + }); + + // TODO: Once the contents API has been added, check the actual files in the created repo + Assert.Equal(repoName, createdRepository.Name); + var repository = await github.Repository.Get(github.Credentials.Login, repoName); + Assert.Equal(repoName, repository.Name); + } + + [IntegrationTest] + public async Task CreatesARepositoryWithAGitignoreTemplate() + { + var github = new GitHubClient + { + Credentials = AutomationSettings.Current.GitHubCredentials + }; + var repoName = AutomationSettings.MakeNameWithTimestamp("repo-with-gitignore"); + + var createdRepository = await github.Repository.Create(new NewRepository + { + Name = repoName, + AutoInit = true, + GitignoreTemplate = "visualstudio" + }); + + // TODO: Once the contents API has been added, check the actual files in the created repo + Assert.Equal(repoName, createdRepository.Name); + var repository = await github.Repository.Get(github.Credentials.Login, repoName); + Assert.Equal(repoName, repository.Name); + } } public class TheGetAsyncMethod From 25180d12fdeebd9f0439488be13416888cb06ed1 Mon Sep 17 00:00:00 2001 From: half-ogre Date: Mon, 7 Oct 2013 17:44:10 -0700 Subject: [PATCH 13/16] fix missed rename in test repo name --- Octokit.Tests.Integration/RepositoriesClientTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Octokit.Tests.Integration/RepositoriesClientTests.cs b/Octokit.Tests.Integration/RepositoriesClientTests.cs index 5ae5b4c4..0a4e8af5 100644 --- a/Octokit.Tests.Integration/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/RepositoriesClientTests.cs @@ -141,7 +141,7 @@ namespace Octokit.Tests.Integration { Credentials = AutomationSettings.Current.GitHubCredentials }; - var repoName = AutomationSettings.MakeNameWithTimestamp("repo-with-description"); + var repoName = AutomationSettings.MakeNameWithTimestamp("repo-with-homepage"); var createdRepository = await github.Repository.Create(new NewRepository { From 9725cc52b1902fde2481d8115a0e818166ffa260 Mon Sep 17 00:00:00 2001 From: half-ogre Date: Mon, 7 Oct 2013 17:45:32 -0700 Subject: [PATCH 14/16] add note to add team_id test later --- Octokit.Tests.Integration/RepositoriesClientTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Octokit.Tests.Integration/RepositoriesClientTests.cs b/Octokit.Tests.Integration/RepositoriesClientTests.cs index 0a4e8af5..7def5d40 100644 --- a/Octokit.Tests.Integration/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/RepositoriesClientTests.cs @@ -196,6 +196,8 @@ namespace Octokit.Tests.Integration var repository = await github.Repository.Get(github.Credentials.Login, repoName); Assert.Equal(repoName, repository.Name); } + + // TODO: Add a test for the team_id param once an overload that takes an oranization is added } public class TheGetAsyncMethod From 13dbfea5837a2a96ac4b4b100f72bb5fbc1e209c Mon Sep 17 00:00:00 2001 From: half-ogre Date: Tue, 8 Oct 2013 09:43:52 -0700 Subject: [PATCH 15/16] add reactive counter-part --- .../Clients/ObservableRepositoriesClient.cs | 14 ++++++++++++++ Octokit.Reactive/IObservableRepositoriesClient.cs | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs b/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs index 6084e1c7..1511259c 100644 --- a/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs +++ b/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs @@ -15,6 +15,20 @@ namespace Octokit.Reactive.Clients _client = client; } + /// + /// Creates a new repository for the current user. + /// + /// A instance describing the new repository to create + /// An instance for the created repository + public IObservable Create(NewRepository newRepository) + { + Ensure.ArgumentNotNull(newRepository, "newRepository"); + if (string.IsNullOrEmpty(newRepository.Name)) + throw new ArgumentException("The new repository's name must not be null."); + + return _client.Create(newRepository).ToObservable(); + } + public IObservable Get(string owner, string name) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); diff --git a/Octokit.Reactive/IObservableRepositoriesClient.cs b/Octokit.Reactive/IObservableRepositoriesClient.cs index bc8a1a32..2dc6bb33 100644 --- a/Octokit.Reactive/IObservableRepositoriesClient.cs +++ b/Octokit.Reactive/IObservableRepositoriesClient.cs @@ -6,6 +6,13 @@ namespace Octokit.Reactive { public interface IObservableRepositoriesClient { + /// + /// Creates a new repository for the current user. + /// + /// A instance describing the new repository to create + /// An instance for the created repository + IObservable Create(NewRepository newRepository); + /// /// Retrieves the for the specified owner and name. /// From 77bf8f23e7cf90e52fe9c78761520b8477fdfaf3 Mon Sep 17 00:00:00 2001 From: half-ogre Date: Tue, 8 Oct 2013 09:53:07 -0700 Subject: [PATCH 16/16] unit tests for serializer changes --- Octokit.Tests/SimpleJsonSerializerTests.cs | 49 +++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/Octokit.Tests/SimpleJsonSerializerTests.cs b/Octokit.Tests/SimpleJsonSerializerTests.cs index 0c69c8ba..cf523cfa 100644 --- a/Octokit.Tests/SimpleJsonSerializerTests.cs +++ b/Octokit.Tests/SimpleJsonSerializerTests.cs @@ -1,4 +1,5 @@ -using Octokit.Http; +using System; +using Octokit.Http; using Xunit; namespace Octokit.Tests @@ -16,6 +17,52 @@ namespace Octokit.Tests Assert.Equal("{\"id\":42,\"first_name\":\"Phil\",\"is_something\":true,\"private\":true}", json); } + + [Fact] + public void OmitsPropertiesWithNullValue() + { + var item = new + { + Object = (object)null, + NullableInt = (int?)null, + NullableBool = (bool?)null + }; + + var json = new SimpleJsonSerializer().Serialize(item); + + Assert.Equal("{}", json); + } + + [Fact] + public void DoesNotOmitsNullablePropertiesWithAValue() + { + var item = new + { + Object = new { Id = 42 }, + NullableInt = (int?)1066, + NullableBool = (bool?)true + }; + + var json = new SimpleJsonSerializer().Serialize(item); + + Assert.Equal("{\"object\":{\"id\":42},\"nullable_int\":1066,\"nullable_bool\":true}", json); + } + + [Fact] + public void HandlesMixingNullAndNotNullData() + { + var item = new + { + Int = 42, + Bool = true, + NullableInt = (int?)null, + NullableBool = (bool?)null + }; + + var json = new SimpleJsonSerializer().Serialize(item); + + Assert.Equal("{\"int\":42,\"bool\":true}", json); + } } public class TheDeserializeMethod