From 37a7fcc4858826d81ac3ad3dfe26546c674cea06 Mon Sep 17 00:00:00 2001 From: Marcus Pettersen Irgens Date: Tue, 1 Aug 2023 16:01:32 +0200 Subject: [PATCH] Add get_org_installation to AppsRequestHandler Similarly to get_repository_installation, this fetches the installation for the given organization. Sample response payload copied from the API docs: https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#get-an-organization-installation-for-the-authenticated-app --- src/api/apps.rs | 10 ++++ tests/org_installations_test.rs | 57 ++++++++++++++++++++ tests/resources/orgs_installation_event.json | 50 +++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 tests/org_installations_test.rs create mode 100644 tests/resources/orgs_installation_event.json diff --git a/src/api/apps.rs b/src/api/apps.rs index 00ad681c..d3f8d907 100644 --- a/src/api/apps.rs +++ b/src/api/apps.rs @@ -97,4 +97,14 @@ impl<'octo> AppsRequestHandler<'octo> { self.crab.get(&route, None::<&()>).await } + + /// Get an organization installation for the authenticated app. + pub async fn get_org_installation( + &self, + owner: impl AsRef, + ) -> crate::Result { + let route = format!("/orgs/{owner}/installation", owner = owner.as_ref(),); + + self.crab.get(&route, None::<&()>).await + } } diff --git a/tests/org_installations_test.rs b/tests/org_installations_test.rs new file mode 100644 index 00000000..75450edd --- /dev/null +++ b/tests/org_installations_test.rs @@ -0,0 +1,57 @@ +// Tests for calls to the /orgs/{org}/installation endpoint. +mod mock_error; + +use mock_error::setup_error_handler; +use octocrab::models::{Author, Installation, InstallationId}; +use octocrab::Octocrab; +use wiremock::{ + matchers::{method, path}, + Mock, MockServer, ResponseTemplate, +}; + +async fn setup_api(template: ResponseTemplate) -> MockServer { + let mock_server = MockServer::start().await; + + Mock::given(method("GET")) + .and(path("/orgs/github/installation")) + .respond_with(template) + .mount(&mock_server) + .await; + setup_error_handler( + &mock_server, + "GET on /orgs/github/installation was not received", + ) + .await; + mock_server +} + +fn setup_octocrab(uri: &str) -> Octocrab { + Octocrab::builder().base_uri(uri).unwrap().build().unwrap() +} + +#[tokio::test] +async fn should_return_org_installation() { + let org_installation_response: Installation = + serde_json::from_str(include_str!("resources/orgs_installation_event.json")).unwrap(); + let template = ResponseTemplate::new(200).set_body_json(&org_installation_response); + let mock_server = setup_api(template).await; + let client = setup_octocrab(&mock_server.uri()); + + let result = client.apps().get_org_installation("github").await; + + assert!( + result.is_ok(), + "expected successful result, got error: {:#?}", + result + ); + + let Installation { + id: installation_id, + account: Author { login, .. }, + .. + } = result.unwrap(); + { + assert_eq!(installation_id, InstallationId(1)); + assert_eq!(login, "github"); + } +} diff --git a/tests/resources/orgs_installation_event.json b/tests/resources/orgs_installation_event.json new file mode 100644 index 00000000..2a1a8e6a --- /dev/null +++ b/tests/resources/orgs_installation_event.json @@ -0,0 +1,50 @@ +{ + "id": 1, + "account": { + "login": "github", + "id": 1, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE=", + "avatar_url": "https://github.com/images/error/hubot_happy.gif", + "gravatar_id": "", + "url": "https://api.github.com/orgs/github", + "html_url": "https://github.com/github", + "followers_url": "https://api.github.com/users/github/followers", + "following_url": "https://api.github.com/users/github/following{/other_user}", + "gists_url": "https://api.github.com/users/github/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github/subscriptions", + "organizations_url": "https://api.github.com/users/github/orgs", + "repos_url": "https://api.github.com/orgs/github/repos", + "events_url": "https://api.github.com/orgs/github/events", + "received_events_url": "https://api.github.com/users/github/received_events", + "type": "Organization", + "site_admin": false + }, + "repository_selection": "all", + "access_tokens_url": "https://api.github.com/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" + ], + "created_at": "2018-02-09T20:51:14Z", + "updated_at": "2018-02-09T20:51:14Z", + "single_file_name": "config.yml", + "has_multiple_single_files": true, + "single_file_paths": [ + "config.yml", + ".github/issue_TEMPLATE.md" + ], + "app_slug": "github-actions", + "suspended_at": null, + "suspended_by": null +} \ No newline at end of file