From dcc31b8e0c7c424a76f825fa919f86b8c890def6 Mon Sep 17 00:00:00 2001 From: Liam Neville Date: Thu, 21 Sep 2023 17:12:30 -0400 Subject: [PATCH] [Feat] Add `suspended_at` and `suspended_by` to the `Installation` model --- .../Clients/GitHubAppsClientTests.cs | 2 + Octokit.Tests/Models/InstallationTests.cs | 165 ++++++++++++++++++ Octokit/Models/Response/Installation.cs | 17 +- 3 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 Octokit.Tests/Models/InstallationTests.cs diff --git a/Octokit.Tests.Integration/Clients/GitHubAppsClientTests.cs b/Octokit.Tests.Integration/Clients/GitHubAppsClientTests.cs index e5f97e77ef..a445e3c783 100644 --- a/Octokit.Tests.Integration/Clients/GitHubAppsClientTests.cs +++ b/Octokit.Tests.Integration/Clients/GitHubAppsClientTests.cs @@ -74,6 +74,8 @@ public async Task GetsAllInstallations() Assert.Equal(InstallationReadWritePermissionLevel.Read, installation.Permissions.Metadata); Assert.False(string.IsNullOrEmpty(installation.HtmlUrl)); Assert.NotEqual(0, installation.TargetId); + Assert.Null(installation.SuspendedBy); + Assert.Null(installation.SuspendedAt); } } } diff --git a/Octokit.Tests/Models/InstallationTests.cs b/Octokit.Tests/Models/InstallationTests.cs new file mode 100644 index 0000000000..5a5e71ba34 --- /dev/null +++ b/Octokit.Tests/Models/InstallationTests.cs @@ -0,0 +1,165 @@ +using System.Collections.Generic; +using System.Linq; +using Octokit.Internal; +using Xunit; + +namespace Octokit.Tests.Models +{ + public class InstallationResponseTests + { + [Fact] + public void CanBeDeserialized() + { + const string json = @"[ + { + ""id"": 1, + ""account"": { + ""login"": ""octocat"", + ""id"": 1, + ""node_id"": ""MDQ6VXNlcjE="", + ""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"", + ""gravatar_id"": """", + ""url"": ""https://api.github.com/users/octocat"", + ""html_url"": ""https://github.com/octocat"", + ""followers_url"": ""https://api.github.com/users/octocat/followers"", + ""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"", + ""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"", + ""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"", + ""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"", + ""organizations_url"": ""https://api.github.com/users/octocat/orgs"", + ""repos_url"": ""https://api.github.com/users/octocat/repos"", + ""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"", + ""received_events_url"": ""https://api.github.com/users/octocat/received_events"", + ""type"": ""User"", + ""site_admin"": false + }, + ""access_tokens_url"": ""https://api.github.com/app/installations/1/access_tokens"", + ""repositories_url"": ""https://api.github.com/installation/repositories"", + ""html_url"": ""https://github.com/organizations/github/settings/installations/1"", + ""app_id"": 1, + ""target_id"": 1, + ""target_type"": ""Organization"", + ""permissions"": { + ""checks"": ""write"", + ""metadata"": ""read"", + ""contents"": ""read"" + }, + ""events"": [ + ""push"", + ""pull_request"" + ], + ""single_file_name"": ""config.yaml"", + ""has_multiple_single_files"": true, + ""single_file_paths"": [ + ""config.yml"", + "".github/issue_TEMPLATE.md"" + ], + ""repository_selection"": ""selected"", + ""created_at"": ""2017-07-08T16:18:44-04:00"", + ""updated_at"": ""2017-07-08T16:18:44-04:00"", + ""app_slug"": ""github-actions"", + ""suspended_at"": null, + ""suspended_by"": null + } +]"; + + var serializer = new SimpleJsonSerializer(); + + var installations = serializer.Deserialize>(json); + + Assert.NotNull(installations); + Assert.NotEmpty(installations); + Assert.Equal(1, installations.Count); + Assert.Null(installations.First().SuspendedAt); + Assert.Null(installations.First().SuspendedBy); + + } + + [Fact] + public void CanBeDeserializedWithSuspendedAtValues() + { + const string json = @"[ + { + ""id"": 1, + ""account"": { + ""login"": ""octocat"", + ""id"": 1, + ""node_id"": ""MDQ6VXNlcjE="", + ""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"", + ""gravatar_id"": """", + ""url"": ""https://api.github.com/users/octocat"", + ""html_url"": ""https://github.com/octocat"", + ""followers_url"": ""https://api.github.com/users/octocat/followers"", + ""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"", + ""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"", + ""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"", + ""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"", + ""organizations_url"": ""https://api.github.com/users/octocat/orgs"", + ""repos_url"": ""https://api.github.com/users/octocat/repos"", + ""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"", + ""received_events_url"": ""https://api.github.com/users/octocat/received_events"", + ""type"": ""User"", + ""site_admin"": false + }, + ""access_tokens_url"": ""https://api.github.com/app/installations/1/access_tokens"", + ""repositories_url"": ""https://api.github.com/installation/repositories"", + ""html_url"": ""https://github.com/organizations/github/settings/installations/1"", + ""app_id"": 1, + ""target_id"": 1, + ""target_type"": ""Organization"", + ""permissions"": { + ""checks"": ""write"", + ""metadata"": ""read"", + ""contents"": ""read"" + }, + ""events"": [ + ""push"", + ""pull_request"" + ], + ""single_file_name"": ""config.yaml"", + ""has_multiple_single_files"": true, + ""single_file_paths"": [ + ""config.yml"", + "".github/issue_TEMPLATE.md"" + ], + ""repository_selection"": ""selected"", + ""created_at"": ""2017-07-08T16:18:44-04:00"", + ""updated_at"": ""2017-07-08T16:18:44-04:00"", + ""app_slug"": ""github-actions"", + ""suspended_at"": ""2017-07-08T16:18:44-04:00"", + ""suspended_by"": { + ""login"": ""octocat"", + ""id"": 1, + ""node_id"": ""MDQ6VXNlcjE="", + ""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"", + ""gravatar_id"": """", + ""url"": ""https://api.github.com/users/octocat"", + ""html_url"": ""https://github.com/octocat"", + ""followers_url"": ""https://api.github.com/users/octocat/followers"", + ""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"", + ""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"", + ""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"", + ""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"", + ""organizations_url"": ""https://api.github.com/users/octocat/orgs"", + ""repos_url"": ""https://api.github.com/users/octocat/repos"", + ""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"", + ""received_events_url"": ""https://api.github.com/users/octocat/received_events"", + ""type"": ""User"", + ""site_admin"": false + } + } +]"; + + var serializer = new SimpleJsonSerializer(); + + var installations = serializer.Deserialize>(json); + + Assert.NotNull(installations); + Assert.NotEmpty(installations); + Assert.Equal(1, installations.Count); + Assert.NotNull(installations.First().SuspendedAt); + Assert.NotNull(installations.First().SuspendedBy); + + } + } +} diff --git a/Octokit/Models/Response/Installation.cs b/Octokit/Models/Response/Installation.cs index 99d4e372f9..60f4c126e0 100644 --- a/Octokit/Models/Response/Installation.cs +++ b/Octokit/Models/Response/Installation.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using Octokit.Internal; @@ -16,7 +17,7 @@ public class Installation : InstallationId { public Installation() { } - public Installation(long id, User account, string accessTokensUrl, string repositoriesUrl, string htmlUrl, long appId, long targetId, AccountType targetType, InstallationPermissions permissions, IReadOnlyList events, string singleFileName, string repositorySelection) : base(id) + public Installation(long id, User account, string accessTokensUrl, string repositoriesUrl, string htmlUrl, long appId, long targetId, AccountType targetType, InstallationPermissions permissions, IReadOnlyList events, string singleFileName, string repositorySelection, User suspendedBy, DateTimeOffset? suspendedAt) : base(id) { Account = account; AccessTokensUrl = accessTokensUrl; @@ -29,6 +30,8 @@ public Installation(long id, User account, string accessTokensUrl, string reposi Events = events; SingleFileName = singleFileName; RepositorySelection = repositorySelection; + SuspendedBy = suspendedBy; + SuspendedAt = suspendedAt; } /// @@ -80,6 +83,16 @@ public Installation(long id, User account, string accessTokensUrl, string reposi /// public StringEnum RepositorySelection { get; private set; } + /// + /// The user who suspended the Installation. Can be null if the Installation is not suspended. + /// + public User SuspendedBy { get; private set; } + + /// + /// The date the Installation was suspended. Can be null if the Installation is not suspended. + /// + public DateTimeOffset? SuspendedAt { get; private set; } + internal new string DebuggerDisplay => string.Format(CultureInfo.InvariantCulture, "Id: {0} AppId: {1}", Id, AppId); }