diff --git a/src/main/java/org/kohsuke/github/GHPerson.java b/src/main/java/org/kohsuke/github/GHPerson.java index 175883b3b3..1ef07032af 100644 --- a/src/main/java/org/kohsuke/github/GHPerson.java +++ b/src/main/java/org/kohsuke/github/GHPerson.java @@ -316,7 +316,9 @@ public int getFollowersCount() throws IOException { * the io exception */ public String getType() throws IOException { - populate(); + if (type == null) { + populate(); + } return type; } diff --git a/src/test/java/org/kohsuke/github/GHAppTest.java b/src/test/java/org/kohsuke/github/GHAppTest.java index 8b74185140..b0369c4b99 100644 --- a/src/test/java/org/kohsuke/github/GHAppTest.java +++ b/src/test/java/org/kohsuke/github/GHAppTest.java @@ -57,6 +57,7 @@ public void getGitHubApp() throws IOException { assertThat(app.getId(), is((long) 82994)); assertThat(app.getOwner().getId(), is((long) 7544739)); assertThat(app.getOwner().getLogin(), is("hub4j-test-org")); + assertThat(app.getOwner().getType(), is("Organization")); assertThat(app.getName(), is("GHApi Test app 1")); assertThat(app.getSlug(), is("ghapi-test-app-1")); assertThat(app.getDescription(), is("")); @@ -85,8 +86,10 @@ public void listInstallationRequests() throws IOException { assertThat(appInstallation.getId(), is((long) 1037204)); assertThat(appInstallation.getAccount().getId(), is((long) 195438329)); assertThat(appInstallation.getAccount().getLogin(), is("approval-test")); + assertThat(appInstallation.getAccount().getType(), is("Organization")); assertThat(appInstallation.getRequester().getId(), is((long) 195437694)); assertThat(appInstallation.getRequester().getLogin(), is("kaladinstormblessed2")); + assertThat(appInstallation.getRequester().getType(), is("User")); assertThat(appInstallation.getCreatedAt(), is(GitHubClient.parseDate("2025-01-17T15:50:51Z"))); assertThat(appInstallation.getNodeId(), is("MDMwOkludGVncmF0aW9uSW5zdGFsbGF0aW9uUmVxdWVzdDEwMzcyMDQ=")); } @@ -275,6 +278,7 @@ private void testAppInstallation(GHAppInstallation appInstallation) throws IOExc assertThat(appInstallation.getId(), is((long) 11111111)); assertThat(appAccount.getId(), is((long) 111111111)); assertThat(appAccount.login, is("bogus")); + assertThat(appAccount.getType(), is("Organization")); assertThat(appInstallation.getRepositorySelection(), is(GHRepositorySelection.SELECTED)); assertThat(appInstallation.getAccessTokenUrl(), endsWith("/app/installations/11111111/access_tokens")); assertThat(appInstallation.getRepositoriesUrl(), endsWith("/installation/repositories")); diff --git a/src/test/java/org/kohsuke/github/GitHubTest.java b/src/test/java/org/kohsuke/github/GitHubTest.java index fe277899ed..f8f352179d 100644 --- a/src/test/java/org/kohsuke/github/GitHubTest.java +++ b/src/test/java/org/kohsuke/github/GitHubTest.java @@ -96,6 +96,22 @@ public void getOrgs() throws IOException { assertThat(org, not(sameInstance(org2))); } + /** + * Verifies that the `type` field is correctly fetched when listing organizations. + *
+ * Since the `type` field is not included by default in the list of organizations, this test ensures that calling + * {@code getType()} retrieves the expected value. + *
+ * + * @throws IOException + * if an I/O error occurs while fetching the organizations. + */ + @Test + public void listOrganizationsFetchesType() throws IOException { + String type = gitHub.listOrganizations().withPageSize(1).iterator().next().getType(); + assertThat(type, equalTo("Organization")); + } + /** * Search users. * diff --git a/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/__files/1-user.json b/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/__files/1-user.json new file mode 100644 index 0000000000..bc76bc73d6 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/__files/1-user.json @@ -0,0 +1,48 @@ +{ + "login": "anujhydrabadi", + "id": 129152617, + "node_id": "U_kgDOB7K2aQ", + "avatar_url": "https://avatars.githubusercontent.com/u/129152617?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/anujhydrabadi", + "html_url": "https://github.com/anujhydrabadi", + "followers_url": "https://api.github.com/users/anujhydrabadi/followers", + "following_url": "https://api.github.com/users/anujhydrabadi/following{/other_user}", + "gists_url": "https://api.github.com/users/anujhydrabadi/gists{/gist_id}", + "starred_url": "https://api.github.com/users/anujhydrabadi/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/anujhydrabadi/subscriptions", + "organizations_url": "https://api.github.com/users/anujhydrabadi/orgs", + "repos_url": "https://api.github.com/users/anujhydrabadi/repos", + "events_url": "https://api.github.com/users/anujhydrabadi/events{/privacy}", + "received_events_url": "https://api.github.com/users/anujhydrabadi/received_events", + "type": "User", + "user_view_type": "private", + "site_admin": false, + "name": "Anuj Hydrabadi", + "company": "@Facets-cloud", + "blog": "", + "location": null, + "email": null, + "hireable": null, + "bio": null, + "twitter_username": null, + "notification_email": null, + "public_repos": 6, + "public_gists": 1, + "followers": 0, + "following": 0, + "created_at": "2023-03-28T07:02:48Z", + "updated_at": "2025-01-31T11:08:30Z", + "private_gists": 0, + "total_private_repos": 28, + "owned_private_repos": 28, + "disk_usage": 1269, + "collaborators": 2, + "two_factor_authentication": true, + "plan": { + "name": "free", + "space": 976562499, + "collaborators": 0, + "private_repos": 10000 + } +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/__files/2-organizations.json b/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/__files/2-organizations.json new file mode 100644 index 0000000000..3c98fb9cef --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/__files/2-organizations.json @@ -0,0 +1,16 @@ +[ + { + "login": "errfree", + "id": 44, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjQ0", + "url": "https://api.github.com/orgs/errfree", + "repos_url": "https://api.github.com/orgs/errfree/repos", + "events_url": "https://api.github.com/orgs/errfree/events", + "hooks_url": "https://api.github.com/orgs/errfree/hooks", + "issues_url": "https://api.github.com/orgs/errfree/issues", + "members_url": "https://api.github.com/orgs/errfree/members{/member}", + "public_members_url": "https://api.github.com/orgs/errfree/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/44?v=4", + "description": null + } +] \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/__files/3-orgs_errfree.json b/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/__files/3-orgs_errfree.json new file mode 100644 index 0000000000..1f6b52cf4a --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/__files/3-orgs_errfree.json @@ -0,0 +1,26 @@ +{ + "login": "errfree", + "id": 44, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjQ0", + "url": "https://api.github.com/orgs/errfree", + "repos_url": "https://api.github.com/orgs/errfree/repos", + "events_url": "https://api.github.com/orgs/errfree/events", + "hooks_url": "https://api.github.com/orgs/errfree/hooks", + "issues_url": "https://api.github.com/orgs/errfree/issues", + "members_url": "https://api.github.com/orgs/errfree/members{/member}", + "public_members_url": "https://api.github.com/orgs/errfree/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/44?v=4", + "description": null, + "is_verified": false, + "has_organization_projects": true, + "has_repository_projects": true, + "public_repos": 2, + "public_gists": 0, + "followers": 14, + "following": 0, + "html_url": "https://github.com/errfree", + "created_at": "2008-01-24T02:08:37Z", + "updated_at": "2020-05-13T06:35:19Z", + "archived_at": null, + "type": "Organization" +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/mappings/1-user.json b/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/mappings/1-user.json new file mode 100644 index 0000000000..e1a7e928a1 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/mappings/1-user.json @@ -0,0 +1,47 @@ +{ + "id": "cd7530db-bd05-4525-9136-0bf80e609c23", + "name": "user", + "request": { + "url": "/user", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "application/vnd.github+json" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "1-user.json", + "headers": { + "Date": "Sun, 16 Feb 2025 09:01:24 GMT", + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "ETag": "W/\"2288274ffc402f5864177c99f29e71d41d774342ce2b6fc9d2b12db0df22c6ef\"", + "Last-Modified": "Fri, 31 Jan 2025 11:08:30 GMT", + "X-OAuth-Scopes": "admin:enterprise, admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, admin:ssh_signing_key, audit_log, codespace, delete:packages, delete_repo, gist, notifications, project, repo, user, workflow, write:discussion, write:packages", + "X-Accepted-OAuth-Scopes": "", + "X-GitHub-Media-Type": "github.v3; format=json", + "x-github-api-version-selected": "2022-11-28", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4962", + "X-RateLimit-Reset": "1739697044", + "X-RateLimit-Used": "38", + "X-RateLimit-Resource": "core", + "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "0", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "Server": "github.com", + "X-GitHub-Request-Id": "415A:2933E2:783482:ABFF69:67B1A964" + } + }, + "uuid": "cd7530db-bd05-4525-9136-0bf80e609c23", + "persistent": true, + "insertionIndex": 1 +} \ No newline at end of file diff --git a/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/mappings/2-organizations.json b/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/mappings/2-organizations.json new file mode 100644 index 0000000000..e53cbf1764 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GitHubTest/wiremock/listOrganizationsFetchesType/mappings/2-organizations.json @@ -0,0 +1,47 @@ +{ + "id": "87f5d76b-1169-4caf-ab76-04ac6b1e78b9", + "name": "organizations", + "request": { + "url": "/organizations?per_page=1", + "method": "GET", + "headers": { + "Accept": { + "equalTo": "application/vnd.github+json" + } + } + }, + "response": { + "status": 200, + "bodyFileName": "2-organizations.json", + "headers": { + "Date": "Sun, 16 Feb 2025 09:01:25 GMT", + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "private, max-age=60, s-maxage=60", + "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With", + "ETag": "W/\"575d7c16fc728d88180cb71aecfb2c215cdf28f0259a6eac1d93c607816f3722\"", + "X-OAuth-Scopes": "admin:enterprise, admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, admin:ssh_signing_key, audit_log, codespace, delete:packages, delete_repo, gist, notifications, project, repo, user, workflow, write:discussion, write:packages", + "X-Accepted-OAuth-Scopes": "", + "X-GitHub-Media-Type": "github.v3; format=json", + "x-github-api-version-selected": "2022-11-28", + "X-RateLimit-Limit": "5000", + "X-RateLimit-Remaining": "4960", + "X-RateLimit-Reset": "1739697044", + "X-RateLimit-Used": "40", + "X-RateLimit-Resource": "core", + "Access-Control-Expose-Headers": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset", + "Access-Control-Allow-Origin": "*", + "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", + "X-Frame-Options": "deny", + "X-Content-Type-Options": "nosniff", + "X-XSS-Protection": "0", + "Referrer-Policy": "origin-when-cross-origin, strict-origin-when-cross-origin", + "Content-Security-Policy": "default-src 'none'", + "Server": "github.com", + "X-GitHub-Request-Id": "58BE:2FA953:5F36F5:9301D2:67B1A965", + "Link": "