[go: up one dir, main page]

octocrab 0.48.1

A modern, extensible GitHub API client.
Documentation
// Tests for calls to the /orgs/{ORG}/actions/secrets API.
mod mock_error;

use chrono::DateTime;
use mock_error::setup_error_handler;
use octocrab::{
    models::{
        orgs::secrets::{
            CreateOrganizationSecret, CreateOrganizationSecretResponse, OrganizationSecret,
            OrganizationSecrets, Visibility,
        },
        PublicKey,
    },
    Octocrab,
};
use wiremock::{
    matchers::{method, path},
    Mock, MockServer, ResponseTemplate,
};

const ORG: &str = "some-org";

async fn setup_get_api(template: ResponseTemplate, secrets_path: &str) -> MockServer {
    let mock_server = MockServer::start().await;

    Mock::given(method("GET"))
        .and(path(format!("/orgs/{ORG}/actions/secrets{secrets_path}")))
        .respond_with(template)
        .mount(&mock_server)
        .await;
    setup_error_handler(
        &mock_server,
        &format!("GET on /orgs/{ORG}/actions/secrets{secrets_path} was not received"),
    )
    .await;
    mock_server
}

async fn setup_put_api(template: ResponseTemplate, secrets_path: &str) -> MockServer {
    let mock_server = MockServer::start().await;

    Mock::given(method("PUT"))
        .and(path(format!("/orgs/{ORG}/actions/secrets{secrets_path}")))
        .respond_with(template)
        .mount(&mock_server)
        .await;
    setup_error_handler(
        &mock_server,
        &format!("PUT on /orgs/{ORG}/actions/secrets{secrets_path} was not received"),
    )
    .await;
    mock_server
}

async fn setup_delete_api(template: ResponseTemplate, secrets_path: &str) -> MockServer {
    let mock_server = MockServer::start().await;

    Mock::given(method("DELETE"))
        .and(path(format!("/orgs/{ORG}/actions/secrets{secrets_path}")))
        .respond_with(template)
        .mount(&mock_server)
        .await;
    setup_error_handler(
        &mock_server,
        &format!("DELETE on /orgs/{ORG}/actions/secrets{secrets_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_org_secrets() {
    let org_secrets: OrganizationSecrets =
        serde_json::from_str(include_str!("resources/org_secrets.json")).unwrap();

    let template = ResponseTemplate::new(200).set_body_json(&org_secrets);
    let mock_server = setup_get_api(template, "").await;
    let result = setup_octocrab(&mock_server.uri())
        .orgs(ORG.to_owned())
        .secrets()
        .get_secrets()
        .await;
    assert!(
        result.is_ok(),
        "expected successful result, got error: {:#?}",
        result
    );
    let item = result.unwrap();

    assert_eq!(item.total_count, 3);
    assert_eq!(
        item.secrets,
        vec![
            OrganizationSecret {
                name: String::from("GIST_ID"),
                visibility: Visibility::Private,
                selected_repositories_url: None,
                created_at: DateTime::parse_from_rfc3339("2019-08-10T14:59:22Z")
                    .unwrap()
                    .into(),
                updated_at: DateTime::parse_from_rfc3339("2020-01-10T14:59:22Z")
                    .unwrap()
                    .into(),
            },
            OrganizationSecret {
                name: String::from("DEPLOY_TOKEN"),
                visibility: Visibility::All,
                selected_repositories_url: None,
                created_at: DateTime::parse_from_rfc3339("2019-08-10T14:59:22Z")
                    .unwrap()
                    .into(),
                updated_at: DateTime::parse_from_rfc3339("2020-01-10T14:59:22Z")
                    .unwrap()
                    .into(),
            },
            OrganizationSecret {
                name: String::from("GH_TOKEN"),
                visibility: Visibility::Selected,
                selected_repositories_url: Some(String::from("https://api.github.com/orgs/octo-org/actions/secrets/SUPER_SECRET/repositories")),
                created_at: DateTime::parse_from_rfc3339("2019-08-10T14:59:22Z")
                    .unwrap()
                    .into(),
                updated_at: DateTime::parse_from_rfc3339("2020-01-10T14:59:22Z")
                    .unwrap()
                    .into(),
            },
        ]
    );
}

#[tokio::test]
async fn should_return_org_public_key() {
    let org_secrets: PublicKey =
        serde_json::from_str(include_str!("resources/org_public_key.json")).unwrap();

    let template = ResponseTemplate::new(200).set_body_json(&org_secrets);
    let mock_server = setup_get_api(template, "/public-key").await;
    let result = setup_octocrab(&mock_server.uri())
        .orgs(ORG.to_owned())
        .secrets()
        .get_public_key()
        .await;
    assert!(
        result.is_ok(),
        "expected successful result, got error: {:#?}",
        result
    );
    let item = result.unwrap();

    assert_eq!(item.key_id, String::from("012345678912345678"));
    assert_eq!(
        item.key,
        String::from("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")
    );
}

#[tokio::test]
async fn should_return_org_secret() {
    let org_secrets: OrganizationSecret =
        serde_json::from_str(include_str!("resources/org_secret.json")).unwrap();

    let template = ResponseTemplate::new(200).set_body_json(&org_secrets);
    let mock_server = setup_get_api(template, "/GH_TOKEN").await;
    let result = setup_octocrab(&mock_server.uri())
        .orgs(ORG.to_owned())
        .secrets()
        .get_secret("GH_TOKEN")
        .await;
    assert!(
        result.is_ok(),
        "expected successful result, got error: {:#?}",
        result
    );
    let item = result.unwrap();
    assert_eq!(
        item,
        OrganizationSecret {
            name: String::from("GH_TOKEN"),
            visibility: Visibility::Selected,
            selected_repositories_url: Some(String::from(
                "https://api.github.com/orgs/octo-org/actions/secrets/SUPER_SECRET/repositories"
            )),
            created_at: DateTime::parse_from_rfc3339("2019-08-10T14:59:22Z")
                .unwrap()
                .into(),
            updated_at: DateTime::parse_from_rfc3339("2020-01-10T14:59:22Z")
                .unwrap()
                .into(),
        }
    );
}

#[tokio::test]
async fn should_add_secret() {
    let template = ResponseTemplate::new(201);
    let mock_server = setup_put_api(template, "/GH_TOKEN").await;
    let result = setup_octocrab(&mock_server.uri())
        .orgs(ORG.to_owned())
        .secrets()
        .create_or_update_secret(
            "GH_TOKEN",
            &CreateOrganizationSecret {
                visibility: Visibility::All,
                selected_repository_ids: None,
                key_id: "123456",
                encrypted_value: "some-b64-string",
            },
        )
        .await;
    assert!(
        result.is_ok(),
        "expected successful result, got error: {:#?}",
        result
    );
    let item = result.unwrap();
    assert_eq!(item, CreateOrganizationSecretResponse::Created);
}

#[tokio::test]
async fn should_update_secret_204() {
    let template = ResponseTemplate::new(204);
    let mock_server = setup_put_api(template, "/GH_TOKEN").await;
    let result = setup_octocrab(&mock_server.uri())
        .orgs(ORG.to_owned())
        .secrets()
        .create_or_update_secret(
            "GH_TOKEN",
            &CreateOrganizationSecret {
                visibility: Visibility::All,
                selected_repository_ids: None,
                key_id: "123456",
                encrypted_value: "some-b64-string",
            },
        )
        .await;
    assert!(
        result.is_ok(),
        "expected successful result, got error: {:#?}",
        result
    );
    let item = result.unwrap();
    assert_eq!(item, CreateOrganizationSecretResponse::Updated);
}

#[tokio::test]
async fn should_delete_secret() {
    let template = ResponseTemplate::new(204);
    let mock_server = setup_delete_api(template, "/GH_TOKEN").await;
    let result = setup_octocrab(&mock_server.uri())
        .orgs(ORG.to_owned())
        .secrets()
        .delete_secret("GH_TOKEN")
        .await;

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

#[tokio::test]
async fn should_noop_secret_500() {
    let template = ResponseTemplate::new(500);
    let mock_server = setup_delete_api(template, "/GH_TOKEN").await;
    let result = setup_octocrab(&mock_server.uri())
        .orgs(ORG.to_owned())
        .secrets()
        .delete_secret("GH_TOKEN")
        .await;

    assert!(
        result.is_err(),
        "expected error result, got success somehow: {:#?}",
        result
    );
}