cellos-ctl 0.5.6

cellctl — kubectl-style CLI for CellOS execution cells and formations. Thin HTTP client over cellos-server with apply/get/describe/logs/events/webui.
Documentation
//! Wave 2 red-team — wire-shape compatibility pin (HIGH-W2D-2).
//!
//! `cellos-server::state::FormationRecord` serialises its lifecycle
//! field as `status` (UPPERCASE enum). `cellctl::model::Formation`
//! historically declared the field as `state`, so deserialisation
//! silently produced an empty string and every `cellctl get formations`
//! row rendered with a blank STATE column. The wave-2 fix adds
//! `#[serde(alias = "status")]` so both shapes deserialise into the same
//! field. This test pins that behaviour at the public-API level so a
//! future drive-by edit that removes the alias breaks at test time, not
//! the next time someone runs `cellctl get formations` against a real
//! server.

use cellos_ctl::model::Formation;

#[test]
fn formation_deserialises_server_status_field_via_alias() {
    // The shape cellos-server actually emits today (status,
    // UPPERCASE-rename_all enum).
    let body = serde_json::json!({
        "id": "f-1",
        "name": "ctr",
        "status": "RUNNING",
    });
    let f: Formation = serde_json::from_value(body).expect("alias must deserialise");
    assert_eq!(
        f.state, "RUNNING",
        "alias `status` must populate the `state` field"
    );
}

#[test]
fn formation_deserialises_canonical_state_field() {
    // The forward-looking canonical shape — `state: "RUNNING"`.
    let body = serde_json::json!({
        "id": "f-2",
        "name": "ctr2",
        "state": "RUNNING",
    });
    let f: Formation = serde_json::from_value(body).expect("state field must deserialise");
    assert_eq!(f.state, "RUNNING");
}

#[test]
fn formation_with_neither_field_defaults_to_empty_state() {
    let body = serde_json::json!({
        "id": "f-3",
        "name": "ctr3",
    });
    let f: Formation = serde_json::from_value(body).expect("missing field uses default");
    assert_eq!(f.state, "", "missing state/status must default to empty");
}