Skip to content

Commit

Permalink
[FEAT]: Adds codespaces APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
asklar authored Jun 16, 2023
1 parent 8f0b3a7 commit da5c4d7
Show file tree
Hide file tree
Showing 17 changed files with 480 additions and 1 deletion.
20 changes: 20 additions & 0 deletions Octokit.Reactive/IObservableCodespacesClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Threading.Tasks;

namespace Octokit.Reactive
{
/// <summary>
/// A client for GitHub's Codespaces API.
/// </summary>
/// <remarks>
/// See the codespaces API documentation for more information.
/// </remarks>
public interface IObservableCodespacesClient
{
IObservable<CodespacesCollection> GetAll();
IObservable<CodespacesCollection> GetForRepository(string owner, string repo);
IObservable<Codespace> Get(string codespaceName);
IObservable<Codespace> Start(string codespaceName);
IObservable<Codespace> Stop(string codespaceName);
}
}
1 change: 1 addition & 0 deletions Octokit.Reactive/IObservableGitHubClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@ public interface IObservableGitHubClient : IApiInfoProvider
IObservableRateLimitClient RateLimit { get; }
IObservableMetaClient Meta { get; }
IObservableActionsClient Actions { get; }
IObservableCodespacesClient Codespaces { get; }
}
}
47 changes: 47 additions & 0 deletions Octokit.Reactive/ObservableCodespacesClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Reactive.Threading.Tasks;

namespace Octokit.Reactive
{
public class ObservableCodespacesClient : IObservableCodespacesClient
{
private ICodespacesClient _client;
private IConnection _connection;

public ObservableCodespacesClient(IGitHubClient githubClient)
{
_client = githubClient.Codespaces;
_connection = githubClient.Connection;
}

public IObservable<Codespace> Get(string codespaceName)
{
Ensure.ArgumentNotNull(codespaceName, nameof(codespaceName));
return _client.Get(codespaceName).ToObservable();
}

public IObservable<CodespacesCollection> GetAll()
{
return _client.GetAll().ToObservable();
}

public IObservable<CodespacesCollection> GetForRepository(string owner, string repo)
{
Ensure.ArgumentNotNull(owner, nameof(owner));
Ensure.ArgumentNotNull(repo, nameof(repo));
return _client.GetForRepository(owner, repo).ToObservable();
}

public IObservable<Codespace> Start(string codespaceName)
{
Ensure.ArgumentNotNull(codespaceName, nameof(codespaceName));
return _client.Start(codespaceName).ToObservable();
}

public IObservable<Codespace> Stop(string codespaceName)
{
Ensure.ArgumentNotNull(codespaceName, nameof(codespaceName));
return _client.Stop(codespaceName).ToObservable();
}
}
}
2 changes: 2 additions & 0 deletions Octokit.Reactive/ObservableGitHubClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public ObservableGitHubClient(IGitHubClient gitHubClient)
RateLimit = new ObservableRateLimitClient(gitHubClient);
Meta = new ObservableMetaClient(gitHubClient);
Actions = new ObservableActionsClient(gitHubClient);
Codespaces = new ObservableCodespacesClient(gitHubClient);
}

public IConnection Connection
Expand Down Expand Up @@ -105,6 +106,7 @@ public void SetRequestTimeout(TimeSpan timeout)
public IObservableMetaClient Meta { get; private set; }
public IObservableActionsClient Actions { get; private set; }

public IObservableCodespacesClient Codespaces { get; private set; }
/// <summary>
/// Gets the latest API Info - this will be null if no API calls have been made
/// </summary>
Expand Down
59 changes: 59 additions & 0 deletions Octokit.Tests.Integration/Clients/CodespacesClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Octokit;
using Octokit.Tests.Helpers;
using Octokit.Tests.Integration;
using Xunit;

public class CodespacesClientTests
{
readonly ICodespacesClient _fixture;

public CodespacesClientTests()
{
var github = Helper.GetAuthenticatedClient();
_fixture = github.Codespaces;
}

[IntegrationTest]
public async Task CanGetCodespaces()
{
var retrieved = await _fixture.GetAll();
Assert.NotNull(retrieved);
}

[IntegrationTest]
public async Task CanGetCodespacesForRepo()
{
var retrieved = await _fixture.GetForRepository(Helper.UserName, Helper.RepositoryWithCodespaces);
Assert.NotNull(retrieved);
}

[IntegrationTest]
public async Task CanGetCodespaceByName()
{
var collection = await _fixture.GetForRepository(Helper.UserName, Helper.RepositoryWithCodespaces);
var codespaceName = collection.Codespaces.First().Name;
var retrieved = await _fixture.Get(codespaceName);
Assert.NotNull(retrieved);
}

[IntegrationTest]
public async Task CanStartCodespace()
{
var collection = await _fixture.GetForRepository(Helper.UserName, Helper.RepositoryWithCodespaces);
var codespaceName = collection.Codespaces.First().Name;
var retrieved = await _fixture.Start(codespaceName);
Assert.NotNull(retrieved);
}

[IntegrationTest]
public async Task CanStopCodespace()
{
var collection = await _fixture.GetForRepository(Helper.UserName, Helper.RepositoryWithCodespaces);
var codespaceName = collection.Codespaces.First().Name;
var retrieved = await _fixture.Stop(codespaceName);
Assert.NotNull(retrieved);
}
}
5 changes: 5 additions & 0 deletions Octokit.Tests.Integration/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ public static string GitHubAppSlug
get { return Environment.GetEnvironmentVariable("OCTOKIT_GITHUBAPP_SLUG"); }
}

public static string RepositoryWithCodespaces
{
get { return Environment.GetEnvironmentVariable("OCTOKIT_REPOSITORY_WITH_CODESPACES"); }
}

public static void DeleteRepo(IConnection connection, Repository repository)
{
if (repository != null)
Expand Down
72 changes: 72 additions & 0 deletions Octokit.Tests/Clients/CodespacesClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using NSubstitute;
using Octokit.Internal;
using Octokit;
using Octokit.Tests;
using Xunit;

using static Octokit.Internal.TestSetup;

public class CodespacesClientTests
{
public class TheCtor
{
[Fact]
public void EnsuresNonNullArguments()
{
Assert.Throws<ArgumentNullException>(() => new CodespacesClient(null));
}
}

public class TheGetAllMethod
{
[Fact]
public void RequestsCorrectGetAllUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new CodespacesClient(connection);

client.GetAll();
connection.Received().Get<CodespacesCollection>(Arg.Is<Uri>(u => u.ToString() == "user/codespaces"));
}

[Fact]
public void RequestsCorrectGetForRepositoryUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new CodespacesClient(connection);
client.GetForRepository("owner", "repo");
connection.Received().Get<CodespacesCollection>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/repo/codespaces"));
}

[Fact]
public void RequestsCorrectGetUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new CodespacesClient(connection);
client.Get("codespaceName");
connection.Received().Get<Codespace>(Arg.Is<Uri>(u => u.ToString() == "user/codespaces/codespaceName"));
}

[Fact]
public void RequestsCorrectStartUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new CodespacesClient(connection);
client.Start("codespaceName");
connection.Received().Post<Codespace>(Arg.Is<Uri>(u => u.ToString() == "user/codespaces/codespaceName/start"));
}

[Fact]
public void RequestsCorrectStopUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new CodespacesClient(connection);
client.Stop("codespaceName");
connection.Received().Post<Codespace>(Arg.Is<Uri>(u => u.ToString() == "user/codespaces/codespaceName/stop"));
}
}
}
49 changes: 49 additions & 0 deletions Octokit/Clients/Codespace.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;

namespace Octokit
{
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class Codespace
{
public int Id { get; private set; }
public string Name { get; private set; }
public User Owner { get; private set; }
public User BillableOwner { get; private set; }
public Repository Repository { get; private set; }
public Machine Machine { get; private set; }
public DateTime CreatedAt { get;private set; }
public DateTime UpdatedAt { get; private set; }
public DateTime LastUsedAt { get; private set; }
public StringEnum<CodespaceState> State { get; private set; }
public string Url { get; private set; }
public string MachinesUrl { get; private set; }
public string WebUrl { get; private set; }
public string StartUrl { get; private set; }
public string StopUrl { get; private set; }

public Codespace(int id, string name, User owner, User billableOwner, Repository repository, Machine machine, DateTime createdAt, DateTime updatedAt, DateTime lastUsedAt, StringEnum<CodespaceState> state, string url, string machinesUrl, string webUrl, string startUrl, string stopUrl)
{
Id = id;
Name = name;
Owner = owner;
BillableOwner = billableOwner;
Repository = repository;
Machine = machine;
CreatedAt = createdAt;
UpdatedAt = updatedAt;
LastUsedAt = lastUsedAt;
State = state;
Url = url;
MachinesUrl = machinesUrl;
WebUrl = webUrl;
StartUrl = startUrl;
StopUrl = stopUrl;
}

public Codespace() { }
internal string DebuggerDisplay => string.Format(CultureInfo.CurrentCulture, "Codespace: Id: {0}", Id);
}
}
42 changes: 42 additions & 0 deletions Octokit/Clients/CodespaceState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Octokit.Internal;

namespace Octokit
{
public enum CodespaceState
{
[Parameter(Value = "Unknown")]
Unknown,
[Parameter(Value = "Created")]
Created,
[Parameter(Value = "Queued")]
Queued,
[Parameter(Value = "Provisioning")]
Provisioning,
[Parameter(Value = "Available")]
Available,
[Parameter(Value = "Awaiting")]
Awaiting,
[Parameter(Value = "Unavailable")]
Unavailable,
[Parameter(Value = "Deleted")]
Deleted,
[Parameter(Value = "Moved")]
Moved,
[Parameter(Value = "Shutdown")]
Shutdown,
[Parameter(Value = "Archived")]
Archived,
[Parameter(Value = "Starting")]
Starting,
[Parameter(Value = "ShuttingDown")]
ShuttingDown,
[Parameter(Value = "Failed")]
Failed,
[Parameter(Value = "Exporting")]
Exporting,
[Parameter(Value = "Updating")]
Updating,
[Parameter(Value = "Rebuilding")]
Rebuilding,
}
}
Loading

0 comments on commit da5c4d7

Please sign in to comment.