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

Repository Get Archive Link #765

Merged
merged 10 commits into from
May 8, 2015
39 changes: 39 additions & 0 deletions Octokit.Reactive/Clients/IObservableRepositoryContentsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,45 @@ public interface IObservableRepositoryContentsClient
/// <returns></returns>
IObservable<string> GetReadmeHtml(string owner, string name);

/// <summary>
/// This method will return a 302 to a URL to download a tarball or zipball archive for a repository.
/// Please make sure your HTTP framework is configured to follow redirects or you will need to use the
/// Location header to make a second GET request.
/// Note: For private repositories, these links are temporary and expire quickly.
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/contents/#get-archive-link</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns></returns>
IObservable<string> GetArchiveLink(string owner, string name);

/// <summary>
/// This method will return a 302 to a URL to download a tarball or zipball archive for a repository.
/// Please make sure your HTTP framework is configured to follow redirects or you will need to use the
/// Location header to make a second GET request.
/// Note: For private repositories, these links are temporary and expire quickly.
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/contents/#get-archive-link</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="archiveFormat">The format of the archive. Can be either tarball or zipball</param>
/// <returns></returns>
IObservable<string> GetArchiveLink(string owner, string name, ArchiveFormat archiveFormat);

/// <summary>
/// This method will return a 302 to a URL to download a tarball or zipball archive for a repository.
/// Please make sure your HTTP framework is configured to follow redirects or you will need to use the
/// Location header to make a second GET request.
/// Note: For private repositories, these links are temporary and expire quickly.
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/contents/#get-archive-link</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="archiveFormat">The format of the archive. Can be either tarball or zipball</param>
/// <param name="reference">A valid Git reference.</param>
/// <returns></returns>
IObservable<string> GetArchiveLink(string owner, string name, ArchiveFormat archiveFormat, string reference);

/// <summary>
/// Returns the contents of a file or directory in a repository.
/// </summary>
Expand Down
51 changes: 51 additions & 0 deletions Octokit.Reactive/Clients/ObservableRepositoryContentsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,57 @@ public IObservable<string> GetReadmeHtml(string owner, string name)
}


/// <summary>
/// This method will return a 302 to a URL to download a tarball or zipball archive for a repository.
/// Please make sure your HTTP framework is configured to follow redirects or you will need to use the
/// Location header to make a second GET request.
/// Note: For private repositories, these links are temporary and expire quickly.
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/contents/#get-archive-link</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns></returns>
public IObservable<string> GetArchiveLink(string owner, string name)
{
return GetArchiveLink(owner, name, ArchiveFormat.Tarball, string.Empty);
}

/// <summary>
/// This method will return a 302 to a URL to download a tarball or zipball archive for a repository.
/// Please make sure your HTTP framework is configured to follow redirects or you will need to use the
/// Location header to make a second GET request.
/// Note: For private repositories, these links are temporary and expire quickly.
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/contents/#get-archive-link</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="archiveFormat">The format of the archive. Can be either tarball or zipball</param>
/// <returns></returns>
public IObservable<string> GetArchiveLink(string owner, string name, ArchiveFormat archiveFormat)
{
return GetArchiveLink(owner, name, archiveFormat, String.Empty);
}

/// <summary>
/// This method will return a 302 to a URL to download a tarball or zipball archive for a repository.
/// Please make sure your HTTP framework is configured to follow redirects or you will need to use the
/// Location header to make a second GET request.
/// Note: For private repositories, these links are temporary and expire quickly.
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/contents/#get-archive-link</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="archiveFormat">The format of the archive. Can be either tarball or zipball</param>
/// <param name="reference">A valid Git reference.</param>
/// <returns></returns>
public IObservable<string> GetArchiveLink(string owner, string name, ArchiveFormat archiveFormat, string reference)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");

return _client.Repository.Content.GetArchiveLink(owner, name, archiveFormat, reference).ToObservable();
}

/// <summary>
/// Returns the contents of a file or directory in a repository.
/// </summary>
Expand Down
65 changes: 45 additions & 20 deletions Octokit.Tests.Integration/Clients/RepositoryContentsClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ public class TheGetReadmeMethod
[IntegrationTest]
public async Task ReturnsReadmeForSeeGit()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
var github = Helper.GetAuthenticatedClient();

var readme = await github.Repository.Content.GetReadme("octokit", "octokit.net");
Assert.Equal("README.md", readme.Name);
Expand All @@ -28,10 +25,7 @@ public async Task ReturnsReadmeForSeeGit()
[IntegrationTest]
public async Task ReturnsReadmeHtmlForSeeGit()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
var github = Helper.GetAuthenticatedClient();

var readmeHtml = await github.Repository.Content.GetReadmeHtml("octokit", "octokit.net");
Assert.True(readmeHtml.StartsWith("<div class="));
Expand All @@ -45,10 +39,7 @@ public class TheGetContentsMethod
[IntegrationTest]
public async Task GetsFileContent()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
var github = Helper.GetAuthenticatedClient();

var contents = await github
.Repository
Expand All @@ -63,10 +54,7 @@ public async Task GetsFileContent()
[IntegrationTest]
public async Task GetsDirectoryContent()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
var github = Helper.GetAuthenticatedClient();

var contents = await github
.Repository
Expand All @@ -81,10 +69,8 @@ public async Task GetsDirectoryContent()
[IntegrationTest]
public async Task CrudTest()
{
var client = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
var client = Helper.GetAuthenticatedClient();

Repository repository = null;
try
{
Expand Down Expand Up @@ -128,5 +114,44 @@ await Assert.ThrowsAsync<NotFoundException>(
Helper.DeleteRepo(repository);
}
}

[IntegrationTest]
public async Task GetsArchiveLinkAsTarball()
{
var github = Helper.GetAuthenticatedClient();

var archiveLink = await github
.Repository
.Content
.GetArchiveLink("octokit", "octokit.net");

Assert.Equal("https://codeload.github.com/octokit/octokit.net/legacy.tar.gz/master", archiveLink);
}

[IntegrationTest]
public async Task GetsArchiveLinkAsZipball()
{
var github = Helper.GetAuthenticatedClient();

var archiveLink = await github
.Repository
.Content
.GetArchiveLink("octokit", "octokit.net", ArchiveFormat.Zipball, "");

Assert.Equal("https://codeload.github.com/octokit/octokit.net/legacy.zip/master", archiveLink);
}

[IntegrationTest]
public async Task GetsArchiveLinkForReleaseBranchAsTarball()
{
var github = Helper.GetAuthenticatedClient();

var archiveLink = await github
.Repository
.Content
.GetArchiveLink("alfhenrik", "ScriptCs.OctoKit", ArchiveFormat.Tarball, "dev");

Assert.Equal("https://codeload.github.com/alfhenrik/ScriptCs.OctoKit/legacy.tar.gz/dev", archiveLink);
}
}
}
57 changes: 56 additions & 1 deletion Octokit.Tests/Clients/RepositoryContentsClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Text;
using System.Threading.Tasks;
using NSubstitute;
using Octokit.Tests.Helpers;
using Xunit;

namespace Octokit.Tests.Clients
Expand Down Expand Up @@ -52,6 +53,60 @@ public async Task ReturnsReadmeHtml()
connection.Received().GetHtml(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/readme"), null);
Assert.Equal("<html>README</html>", readme);
}
}
}

public class TheGetArchiveLinkMethod
{
[Fact]
public async Task ReturnsArchiveLinkWithDefaults()
{
var connection = Substitute.For<IApiConnection>();
connection.GetRedirect(Args.Uri).Returns(Task.FromResult("https://codeload.github.com/fake/repo/legacy.tar.gz/master"));
var contentsClient = new RepositoryContentsClient(connection);

var archiveLink = await contentsClient.GetArchiveLink("fake", "repo");

connection.Received().GetRedirect(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/tarball/"));
Assert.Equal("https://codeload.github.com/fake/repo/legacy.tar.gz/master", archiveLink);
}

[Fact]
public async Task ReturnsArchiveLinkAsZipball()
{
var connection = Substitute.For<IApiConnection>();
connection.GetRedirect(Args.Uri).Returns(Task.FromResult("https://codeload.github.com/fake/repo/legacy.tar.gz/master"));
var contentsClient = new RepositoryContentsClient(connection);

var archiveLink = await contentsClient.GetArchiveLink("fake", "repo", ArchiveFormat.Zipball);

connection.Received().GetRedirect(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/zipball/"));
Assert.Equal("https://codeload.github.com/fake/repo/legacy.tar.gz/master", archiveLink);
}

[Fact]
public async Task ReturnsArchiveLinkWithSpecifiedValues()
{
var connection = Substitute.For<IApiConnection>();
connection.GetRedirect(Args.Uri).Returns(Task.FromResult("https://codeload.github.com/fake/repo/legazy.zip/release"));
var contentsClient = new RepositoryContentsClient(connection);

var archiveLink = await contentsClient.GetArchiveLink("fake", "repo", ArchiveFormat.Zipball, "release");

connection.Received().GetRedirect(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/zipball/release"));
Assert.Equal("https://codeload.github.com/fake/repo/legazy.zip/release", archiveLink);
}

[Fact]
public async Task EnsuresArgumentsNotNull()
{
var connection = Substitute.For<IApiConnection>();
var contentsClient = new RepositoryContentsClient(connection);

AssertEx.Throws<ArgumentNullException>(async () => await contentsClient.GetArchiveLink(null, "name"));
AssertEx.Throws<ArgumentNullException>(async () => await contentsClient.GetArchiveLink("owner", null));
AssertEx.Throws<ArgumentException>(async () => await contentsClient.GetArchiveLink("", "name"));
AssertEx.Throws<ArgumentException>(async () => await contentsClient.GetArchiveLink("owner", ""));
}
}
}
}
50 changes: 50 additions & 0 deletions Octokit/Clients/IRepositoryContentsClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Octokit.Internal;

namespace Octokit
{
Expand Down Expand Up @@ -46,6 +47,45 @@ public interface IRepositoryContentsClient
/// <returns></returns>
Task<string> GetReadmeHtml(string owner, string name);

/// <summary>
/// This method will return a 302 to a URL to download a tarball or zipball archive for a repository.
/// Please make sure your HTTP framework is configured to follow redirects or you will need to use the
/// Location header to make a second GET request.
/// Note: For private repositories, these links are temporary and expire quickly.
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/contents/#get-archive-link</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns></returns>
Task<string> GetArchiveLink(string owner, string name);

/// <summary>
/// This method will return a 302 to a URL to download a tarball or zipball archive for a repository.
/// Please make sure your HTTP framework is configured to follow redirects or you will need to use the
/// Location header to make a second GET request.
/// Note: For private repositories, these links are temporary and expire quickly.
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/contents/#get-archive-link</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="archiveFormat">The format of the archive. Can be either tarball or zipball</param>
/// <returns></returns>
Task<string> GetArchiveLink(string owner, string name, ArchiveFormat archiveFormat);

/// <summary>
/// This method will return a 302 to a URL to download a tarball or zipball archive for a repository.
/// Please make sure your HTTP framework is configured to follow redirects or you will need to use the
/// Location header to make a second GET request.
/// Note: For private repositories, these links are temporary and expire quickly.
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/contents/#get-archive-link</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="archiveFormat">The format of the archive. Can be either tarball or zipball</param>
/// <param name="reference">A valid Git reference.</param>
/// <returns></returns>
Task<string> GetArchiveLink(string owner, string name, ArchiveFormat archiveFormat, string reference);

/// <summary>
/// Creates a commit that creates a new file in a repository.
/// </summary>
Expand Down Expand Up @@ -75,4 +115,14 @@ public interface IRepositoryContentsClient
/// <param name="request">Information about the file to delete</param>
Task DeleteFile(string owner, string name, string path, DeleteFileRequest request);
}

public enum ArchiveFormat
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tarball")]
[Parameter(Value = "tarball")]
Tarball,
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Zipball")]
[Parameter(Value = "zipball")]
Zipball
}
}
Loading