Skip to content

Commit

Permalink
Add list_org_memberships_for_authenticated_user (#357)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmhewitt authored May 12, 2023
1 parent 7061b48 commit 9bf06f5
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 1 deletion.
72 changes: 71 additions & 1 deletion src/api/current.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Get data about the currently authenticated user.
use crate::{
models::{self, gists::Gist, Repository},
models::{self, gists::Gist, orgs::MembershipInvitation, Repository},
Octocrab, Page, Result,
};
use chrono::{DateTime, Utc};
Expand Down Expand Up @@ -123,6 +123,26 @@ impl<'octo> CurrentAuthHandler<'octo> {
pub fn list_gists_starred_by_authenticated_user(&self) -> ListStarredGistsBuilder<'octo> {
ListStarredGistsBuilder::new(self.crab)
}

/// Lists organizations that the current authenticated user is a member of.
///
/// ```no_run
/// # async fn run() -> octocrab::Result<()> {
/// octocrab::instance()
/// .current()
/// .list_org_memberships_for_authenticated_user()
/// .send()
/// .await?;
/// # Ok(())
/// # }
/// ```
///
/// [See the GitHub API documentation](https://docs.github.com/en/rest/orgs/members#list-organization-memberships-for-the-authenticated-user)
pub fn list_org_memberships_for_authenticated_user(
&self,
) -> ListOrgMembershipsForAuthenticatedUserBuilder<'octo> {
ListOrgMembershipsForAuthenticatedUserBuilder::new(self.crab)
}
}

/// A builder pattern struct for listing starred repositories.
Expand Down Expand Up @@ -449,3 +469,53 @@ impl<'octo> ListStarredGistsBuilder<'octo> {
self.crab.get("/gists/starred", Some(&self)).await
}
}

/// A builder pattern struct for listing organizations the authenticated user is a member of.
///
/// Created by [`CurrentAuthHandler::list_org_memberships_for_authenticated_user`].
///
/// [`CurrentAuthHandler::list_org_memberships_for_authenticated_user`]: ./struct.CurrentAuthHandler.html#method.list_org_memberships_for_authenticated_user
#[derive(serde::Serialize)]
pub struct ListOrgMembershipsForAuthenticatedUserBuilder<'octo> {
#[serde(skip)]
crab: &'octo Octocrab,

#[serde(skip_serializing_if = "Option::is_none")]
per_page: Option<u8>,

#[serde(skip_serializing_if = "Option::is_none")]
page: Option<u8>,
}

impl<'octo> ListOrgMembershipsForAuthenticatedUserBuilder<'octo> {
fn new(crab: &'octo Octocrab) -> Self {
Self {
crab,
per_page: None,
page: None,
}
}

/// Results per page (max 100).
///
/// [See the GitHub API documentation](https://docs.github.com/en/rest/orgs/members#list-organization-memberships-for-the-authenticated-user--parameters)
pub fn per_page(mut self, per_page: impl Into<u8>) -> Self {
self.per_page = Some(per_page.into());
self
}

/// Page number of the results to fetch.
///
/// [See the GitHub API documentation](https://docs.github.com/en/rest/orgs/members#list-organization-memberships-for-the-authenticated-user--parameters)
pub fn page(mut self, page: impl Into<u8>) -> Self {
self.page = Some(page.into());
self
}

/// Sends the actual request.
pub async fn send(self) -> crate::Result<Page<MembershipInvitation>> {
self.crab
.get("/user/memberships/orgs", (&self).into())
.await
}
}
66 changes: 66 additions & 0 deletions tests/current_user_orgs_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Tests for calls to the /user/memberships/orgs API.
mod mock_error;

use mock_error::setup_error_handler;
use octocrab::{models::orgs::MembershipInvitation, Octocrab, Page};
use serde::{Deserialize, Serialize};
use wiremock::{
matchers::{method, path},
Mock, MockServer, ResponseTemplate,
};

#[derive(Serialize, Deserialize)]
struct FakePage<T> {
items: Vec<T>,
}

async fn setup_api(template: ResponseTemplate) -> MockServer {
let mock_server = MockServer::start().await;

Mock::given(method("GET"))
.and(path(format!("/user/memberships/orgs")))
.respond_with(template)
.mount(&mock_server)
.await;
setup_error_handler(
&mock_server,
&format!("GET on /user/membership/orgs 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_page_with_invitations() {
let membership_invitations: Vec<MembershipInvitation> =
serde_json::from_str(include_str!("resources/user_membership_orgs_event.json")).unwrap();
let page_response = FakePage {
items: membership_invitations,
};
let template = ResponseTemplate::new(200).set_body_json(&page_response);
let mock_server = setup_api(template).await;
let client = setup_octocrab(&mock_server.uri());
let orgs = client
.current()
.list_org_memberships_for_authenticated_user();

let result = orgs.send().await;
assert!(
result.is_ok(),
"expected successful result, got error: {:#?}",
result
);

let Page { items, .. } = result.unwrap();
{
assert_eq!(items.len(), 2);
assert_eq!(items[0].role, "admin");
assert_eq!(items[0].user.login, "davidmhewitt");
assert_eq!(items[0].organization.login, "elementary");
assert_eq!(items[1].organization.login, "EpicGames");
}
}
82 changes: 82 additions & 0 deletions tests/resources/user_membership_orgs_event.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
[
{
"url": "https://api.github.com/orgs/elementary/memberships/davidmhewitt",
"state": "active",
"role": "admin",
"organization_url": "https://api.github.com/orgs/elementary",
"user": {
"login": "davidmhewitt",
"id": 3372394,
"node_id": "MDQ6VXNlcjMzNzIzOTQ=",
"avatar_url": "https://avatars.githubusercontent.com/u/3372394?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/davidmhewitt",
"html_url": "https://github.com/davidmhewitt",
"followers_url": "https://api.github.com/users/davidmhewitt/followers",
"following_url": "https://api.github.com/users/davidmhewitt/following{/other_user}",
"gists_url": "https://api.github.com/users/davidmhewitt/gists{/gist_id}",
"starred_url": "https://api.github.com/users/davidmhewitt/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/davidmhewitt/subscriptions",
"organizations_url": "https://api.github.com/users/davidmhewitt/orgs",
"repos_url": "https://api.github.com/users/davidmhewitt/repos",
"events_url": "https://api.github.com/users/davidmhewitt/events{/privacy}",
"received_events_url": "https://api.github.com/users/davidmhewitt/received_events",
"type": "User",
"site_admin": false
},
"organization": {
"login": "elementary",
"id": 1978534,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE5Nzg1MzQ=",
"url": "https://api.github.com/orgs/elementary",
"repos_url": "https://api.github.com/orgs/elementary/repos",
"events_url": "https://api.github.com/orgs/elementary/events",
"hooks_url": "https://api.github.com/orgs/elementary/hooks",
"issues_url": "https://api.github.com/orgs/elementary/issues",
"members_url": "https://api.github.com/orgs/elementary/members{/member}",
"public_members_url": "https://api.github.com/orgs/elementary/public_members{/member}",
"avatar_url": "https://avatars.githubusercontent.com/u/1978534?v=4",
"description": "The thoughtful, capable, and ethical replacement for Windows and macOS—plus AppCenter, the pay-what-you-can app store"
}
},
{
"url": "https://api.github.com/orgs/EpicGames/memberships/davidmhewitt",
"state": "active",
"role": "member",
"organization_url": "https://api.github.com/orgs/EpicGames",
"user": {
"login": "davidmhewitt",
"id": 3372394,
"node_id": "MDQ6VXNlcjMzNzIzOTQ=",
"avatar_url": "https://avatars.githubusercontent.com/u/3372394?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/davidmhewitt",
"html_url": "https://github.com/davidmhewitt",
"followers_url": "https://api.github.com/users/davidmhewitt/followers",
"following_url": "https://api.github.com/users/davidmhewitt/following{/other_user}",
"gists_url": "https://api.github.com/users/davidmhewitt/gists{/gist_id}",
"starred_url": "https://api.github.com/users/davidmhewitt/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/davidmhewitt/subscriptions",
"organizations_url": "https://api.github.com/users/davidmhewitt/orgs",
"repos_url": "https://api.github.com/users/davidmhewitt/repos",
"events_url": "https://api.github.com/users/davidmhewitt/events{/privacy}",
"received_events_url": "https://api.github.com/users/davidmhewitt/received_events",
"type": "User",
"site_admin": false
},
"organization": {
"login": "EpicGames",
"id": 6615685,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjY2MTU2ODU=",
"url": "https://api.github.com/orgs/EpicGames",
"repos_url": "https://api.github.com/orgs/EpicGames/repos",
"events_url": "https://api.github.com/orgs/EpicGames/events",
"hooks_url": "https://api.github.com/orgs/EpicGames/hooks",
"issues_url": "https://api.github.com/orgs/EpicGames/issues",
"members_url": "https://api.github.com/orgs/EpicGames/members{/member}",
"public_members_url": "https://api.github.com/orgs/EpicGames/public_members{/member}",
"avatar_url": "https://avatars.githubusercontent.com/u/6615685?v=4",
"description": ""
}
}
]

0 comments on commit 9bf06f5

Please sign in to comment.