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
);
}