Skip to content

Commit

Permalink
Add CommitHandler::associated_check_runs (#450)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamjpotts authored Aug 31, 2023
1 parent 4b9c26e commit 71ad4a7
Show file tree
Hide file tree
Showing 4 changed files with 391 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/api/commits.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! The commit API.
mod associated_check_runs;
mod associated_pull_requests;
mod compare_commit;
mod create_comment;

pub use associated_pull_requests::PullRequestTarget;

pub use self::create_comment::CreateCommentBuilder;
use crate::params::repos::Reference;
use crate::{models, Octocrab, Result};

pub struct CommitHandler<'octo> {
Expand All @@ -31,6 +33,13 @@ impl<'octo> CommitHandler<'octo> {
compare_commit::CompareCommitsBuilder::new(self, base.into(), head.into())
}

pub fn associated_check_runs(
&self,
reference: impl Into<Reference>,
) -> associated_check_runs::AssociatedCheckRunsBuilder<'_, '_> {
associated_check_runs::AssociatedCheckRunsBuilder::new(self, reference)
}

pub fn associated_pull_requests(
&self,
target: PullRequestTarget,
Expand Down
51 changes: 51 additions & 0 deletions src/api/commits/associated_check_runs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use crate::commits::CommitHandler;
use crate::models::checks::ListCheckRuns;
use crate::params::repos::Reference;
use crate::Result;

#[derive(serde::Serialize)]
pub struct AssociatedCheckRunsBuilder<'octo, 'r> {
#[serde(skip)]
handler: &'r CommitHandler<'octo>,
#[serde(skip)]
reference: Reference,
#[serde(skip_serializing_if = "Option::is_none")]
per_page: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
page: Option<u32>,
}

impl<'octo, 'r> AssociatedCheckRunsBuilder<'octo, 'r> {
pub(crate) fn new(handler: &'r CommitHandler<'octo>, reference: impl Into<Reference>) -> Self {
Self {
handler,
reference: reference.into(),
per_page: None,
page: None,
}
}

/// Results per page (max 100).
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.
pub fn page(mut self, page: impl Into<u32>) -> Self {
self.page = Some(page.into());
self
}

/// Send the actual request.
pub async fn send(self) -> Result<ListCheckRuns> {
let route = format!(
"/repos/{owner}/{repo}/commits/{reference}/check-runs",
owner = self.handler.owner,
repo = self.handler.repo,
reference = self.reference.full_ref_url()
);

self.handler.crab.get(route, Some(&self)).await
}
}
102 changes: 102 additions & 0 deletions tests/commit_associated_check_runs_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/// Tests API calls related to check runs of a specific commit.
mod mock_error;

use mock_error::setup_error_handler;
use octocrab::models::checks::ListCheckRuns;
use octocrab::models::CheckRunId;
use octocrab::params::repos::Reference;
use octocrab::{Error, Octocrab};
use serde_json::{json, Value};
use wiremock::{
matchers::{method, path},
Mock, MockServer, ResponseTemplate,
};

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

let mocked_path = "/repos/some-owner/some-repo/commits/refs/heads/some-branch/check-runs";

Mock::given(method("GET"))
.and(path(mocked_path))
.respond_with(template)
.mount(&mock_server)
.await;
setup_error_handler(
&mock_server,
&format!("GET on {mocked_path} 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_check_runs() {
let mocked_response: ListCheckRuns =
serde_json::from_str(include_str!("resources/commit_check_runs.json")).unwrap();
let template = ResponseTemplate::new(200).set_body_json(&mocked_response);
let mock_server = setup_api(template).await;
let client = setup_octocrab(&mock_server.uri());
let result = client
.commits("some-owner", "some-repo")
.associated_check_runs(Reference::Branch("some-branch".into()))
.send()
.await;

assert!(
result.is_ok(),
"expected successful result, got error: {:#?}",
result
);

let response = result.unwrap();
assert_eq!(response.total_count, 2);

let items = response.check_runs;
assert_eq!(items.len(), 2);

{
let item = &items[0];

assert_eq!(CheckRunId(16354767716), item.id);
assert_eq!("Cargo test on nix (ubuntu-20.04, stable)", item.name);
assert_eq!(Some("success".into()), item.conclusion);
}

{
let item = &items[1];

assert_eq!(CheckRunId(16354767496), item.id);
assert_eq!("Cargo test on nix (ubuntu-20.04, 1.68)", item.name);
assert_eq!(Some("success".into()), item.conclusion);
}
}

#[tokio::test]
async fn should_fail_when_not_found() {
let mocked_response = json!({
"documentation_url": json!("rtm"),
"errors": Value::Null,
"message": json!("Its gone")
});

let template = ResponseTemplate::new(404).set_body_json(&mocked_response);
let mock_server = setup_api(template).await;
let client = setup_octocrab(&mock_server.uri());
let result = client
.commits("some-owner", "some-repo")
.associated_check_runs(Reference::Branch("some-branch".into()))
.send()
.await;

match result.unwrap_err() {
Error::GitHub { source, .. } => {
assert_eq!("Its gone", source.message)
}
other => panic!("Unexpected error: {:?}", other),
}
}
Loading

0 comments on commit 71ad4a7

Please sign in to comment.