Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/monetize

crates/monetize-server/src/estate_order/tests/update_over_grpc.rs

//! ★ **`EstateOrder.UpdateEstate` over the wire** (OX-WIRED 2026-10-28, highlight 1 of e9b67af5):
//! the operator's `monetize estate update <estate>` reaches the server as this gRPC call (the
//! door's `POST /estate/update`, monetize-admin). Every other test opened the update by calling
//! [`update::start`] directly; this one asks the real router on a local port, through its real
//! interceptors (the service bearer, the operator bearer), with a real tonic client, on an estate
//! laid in the mock cloud:
//!
//! * the service bearer and no bearer are refused, by name, and nothing is opened;
//! * the operator's update opens, and FRONT FIRST, since the front never took an update (it could
//!   never pull this one): the shop keep-boots the front from the release's `front-keep` medium.

use super::paired_update::runs_older;
use super::*;
use monetize_proto as pb;
use monetize_proto::estate_order_client::EstateOrderClient;

const SERVICE: &str = "update-over-grpc-service-bearer-0123456789";
const OPERATOR: &str = "update-over-grpc-operator-bearer-0123456789";

fn bearing<T>(r: T, bearer: &str) -> tonic::Request<T> {
    let mut req = tonic::Request::new(r);
    req.metadata_mut()
        .insert("authorization", format!("Bearer {bearer}").parse().unwrap());
    req
}

fn ask() -> pb::EstateUpdateRequest {
    pb::EstateUpdateRequest {
        estate: "acme".into(),
        release: String::new(),
        front_first: false,
    }
}

#[test]
fn the_operators_update_estate_over_grpc_opens_front_first_and_anyone_else_is_refused_by_name() {
    let r = delivered("update-over-grpc", release_cfg("r10", true));
    runs_older(&r.state, "acme");
    assert_eq!(
        r.state.estates.get("acme").unwrap().update_taken_at_ms,
        0,
        "its front never took an update"
    );
    let rt = tokio::runtime::Builder::new_multi_thread()
        .worker_threads(2)
        .enable_all()
        .build()
        .unwrap();
    let state = r.state.clone();
    let opened = rt.block_on(async move {
        let server =
            crate::testing::TestServer::spawn_with_operator(state.clone(), SERVICE, OPERATOR).await;
        let mut c = EstateOrderClient::connect(server.endpoint())
            .await
            .expect("the router answers on its port");

        let e = c
            .update_estate(bearing(ask(), SERVICE))
            .await
            .expect_err("the service bearer is not the operator");
        assert_eq!(e.code(), tonic::Code::PermissionDenied, "{e:?}");
        assert!(
            e.message().contains("updating an estate is the operator's"),
            "refused by name: {e:?}"
        );
        let e = c
            .update_estate(tonic::Request::new(ask()))
            .await
            .expect_err("no bearer");
        assert_eq!(e.code(), tonic::Code::Unauthenticated, "{e:?}");
        assert!(
            state.estates.get("acme").unwrap().update.is_none(),
            "nothing was opened by a refused call"
        );

        let u = c
            .update_estate(bearing(ask(), OPERATOR))
            .await
            .expect("the operator's update is taken")
            .into_inner();
        server.stop().await;
        u
    });
    assert_eq!(
        opened.state,
        update::state::FRONT_KEEP,
        "the front never took one: front first — {}",
        opened.words
    );
    assert_eq!(opened.update_release, "r10-gunnar", "{}", opened.words);
    assert_eq!(
        opened.steps.first().map(|s| s.role.as_str()),
        Some("front"),
        "the front goes first: {:?}",
        opened.steps
    );
    let run = r.state.estates.get("acme").unwrap();
    let open = run
        .update
        .clone()
        .expect("the update is open on the estate");
    assert_eq!(
        (open.state.as_str(), open.release.as_str()),
        (update::state::FRONT_KEEP, "r10-gunnar"),
        "{}",
        open.line()
    );
    assert!(
        run.history
            .iter()
            .any(|t| t.note.starts_with("operator opened an update")),
        "{:#?}",
        run.history
    );
}