// ironforge -- Forgejo Actions <-> shields.io bridge // Copyright (C) 2023 Gergely Nagy // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, version 3 of the // License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . use axum::{body::BoxBody, http::StatusCode, response::Response}; use ironforge::app::Ironforge; use tower::util::ServiceExt; #[allow(dead_code)] mod mock; #[allow(dead_code)] mod shared; async fn exercise_uri_full( server: &str, mock: Option<&mockito::Mock>, uri: &str, ) -> Response { let config = shared::setup_config(server); let app = Ironforge::make_app(&config); let response = app.oneshot(shared::send_get_request(uri)).await.unwrap(); if let Some(mock) = mock { mock.assert(); } response } async fn exercise_uri(server: &str, mock: Option<&mockito::Mock>, uri: &str) -> Response { let uri = &format!("/actions/test/test/{}", uri); exercise_uri_full(server, mock, uri).await } async fn test_badge_status(status: &str, color: &str) { let (server, mock) = mock::status_with_relative_url(status); let response = exercise_uri(&server.url(), Some(&mock), "badge").await; assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT); assert_eq!( response.headers()["location"], &format!( "https://img.shields.io/badge/ci-{}-{}?style=for-the-badge", status, color ) ); } #[tokio::test] async fn badge_statuses() { let success_color_map = &[ ("success", "brightgreen"), ("pending", "lightgrey"), ("error", "lightgrey"), ("failure", "crimson"), ("warning", "orange"), ("running", "gold"), ("no-such-status", "lightgrey"), ]; for (status, color) in success_color_map { test_badge_status(status, color).await; } } #[tokio::test] async fn badge_success_with_query_params() { let (server, mock) = mock::status_with_relative_url("success"); let response = exercise_uri( &server.url(), Some(&mock), "badge?label=build&style=flat&branch=main", ) .await; assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT); assert_eq!( response.headers()["location"], "https://img.shields.io/badge/build-success-brightgreen?style=flat" ); } #[tokio::test] async fn badge_fail_if_no_repo() { let (server, _mock) = mock::status_with_relative_url("success"); let response = exercise_uri_full( &server.url(), None, "/actions/no-such-owner/no-such-repo/badge", ) .await; assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT); assert_eq!( response.headers()["location"], "https://img.shields.io/badge/ci-internal%20error-lightgrey?style=for-the-badge" ); } #[tokio::test] async fn badge_fail_if_no_server() { let response = exercise_uri("http://no-such-server", None, "badge").await; assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT); assert_eq!( response.headers()["location"], "https://img.shields.io/badge/ci-internal%20error-lightgrey?style=for-the-badge" ); } #[tokio::test] async fn badge_fail_if_no_statuses() { let (server, mock) = mock::no_statuses(); let response = exercise_uri(&server.url(), Some(&mock), "badge").await; assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT); assert_eq!( response.headers()["location"], "https://img.shields.io/badge/ci-internal%20error-lightgrey?style=for-the-badge" ); } #[tokio::test] async fn badge_fail_if_bad_json() { let (server, mock) = mock::status_with_bad_json(); let response = exercise_uri(&server.url(), Some(&mock), "badge").await; assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT); assert_eq!( response.headers()["location"], "https://img.shields.io/badge/ci-internal%20error-lightgrey?style=for-the-badge" ); } #[tokio::test] async fn log_success() { let (server, mock) = mock::status_with_relative_url("success"); let response = exercise_uri(&server.url(), Some(&mock), "latest-log").await; assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT); assert_eq!( response.headers()["location"], &format!("{}/totally-latest-log", &server.url()), ); } #[tokio::test] async fn log_success_absolute_url() { let (server, mock) = mock::status_with_absolute_url("success"); let response = exercise_uri(&server.url(), Some(&mock), "latest-log").await; assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT); assert_eq!( response.headers()["location"], "https://somewhere/totally-latest-log" ); } #[tokio::test] async fn log_fail_if_no_statuses() { let (server, mock) = mock::no_statuses(); let response = exercise_uri(&server.url(), Some(&mock), "latest-log").await; assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT); assert_eq!( response.headers()["location"], &format!("{}/test/test/actions/", &server.url()) ); }