WP-11: contract and failing tests for package upgrades
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
83
backend/crates/api/tests/upgrade.rs
Normal file
83
backend/crates/api/tests/upgrade.rs
Normal file
@ -0,0 +1,83 @@
|
||||
//! WP-11: POST /api/system/upgrade
|
||||
mod common;
|
||||
|
||||
use axum::http::StatusCode;
|
||||
use common::{get, post, test_app_with_admin};
|
||||
use serde_json::json;
|
||||
|
||||
const ADMIN: &str = "admin@example.com";
|
||||
const PW: &str = "admin-password-123";
|
||||
|
||||
async fn wait_done(app: &axum::Router, token: &str, id: &str) -> serde_json::Value {
|
||||
for _ in 0..100 {
|
||||
let r = get(app, &format!("/api/jobs/{id}"), Some(token)).await;
|
||||
if r.json["status"] != "running" {
|
||||
return r.json;
|
||||
}
|
||||
tokio::time::sleep(std::time::Duration::from_millis(30)).await;
|
||||
}
|
||||
panic!("job did not finish");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn admin_upgrades_selected_packages_and_log_shows_output() {
|
||||
let app = test_app_with_admin().await;
|
||||
let token = common::login(&app, ADMIN, PW).await.access;
|
||||
let res = post(
|
||||
&app,
|
||||
"/api/system/upgrade",
|
||||
json!({"packages": ["openssl", "curl"]}),
|
||||
Some(&token),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(res.status, StatusCode::ACCEPTED, "{}", res.json);
|
||||
assert_eq!(res.json["kind"], "package_upgrade");
|
||||
let run = wait_done(&app, &token, res.json["id"].as_str().unwrap()).await;
|
||||
assert_eq!(run["status"], "success", "{}", run["log"]);
|
||||
let log = run["log"].as_str().unwrap();
|
||||
assert!(log.contains("openssl curl"), "{log}");
|
||||
assert!(log.contains("Setting up"), "{log}");
|
||||
// inventory was refreshed afterwards
|
||||
let inv = get(&app, "/api/system/inventory", Some(&token)).await;
|
||||
assert!(inv.json["refreshed_at"].is_string());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn upgrade_all_validation_and_permissions() {
|
||||
let app = test_app_with_admin().await;
|
||||
let admin = common::login(&app, ADMIN, PW).await.access;
|
||||
let res = post(
|
||||
&app,
|
||||
"/api/system/upgrade",
|
||||
json!({"packages": []}),
|
||||
Some(&admin),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(res.status, StatusCode::ACCEPTED);
|
||||
wait_done(&app, &admin, res.json["id"].as_str().unwrap()).await;
|
||||
|
||||
let res = post(
|
||||
&app,
|
||||
"/api/system/upgrade",
|
||||
json!({"packages": ["bad name"]}),
|
||||
Some(&admin),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(res.status, StatusCode::UNPROCESSABLE_ENTITY);
|
||||
|
||||
post(&app, "/api/users", json!({"email": "u@x.de", "display_name": "U", "password": "user-password-123", "role": "user"}), Some(&admin)).await;
|
||||
let user = common::login(&app, "u@x.de", "user-password-123")
|
||||
.await
|
||||
.access;
|
||||
assert_eq!(
|
||||
post(
|
||||
&app,
|
||||
"/api/system/upgrade",
|
||||
json!({"packages": []}),
|
||||
Some(&user)
|
||||
)
|
||||
.await
|
||||
.status,
|
||||
StatusCode::FORBIDDEN
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user