#[path = "support/live.rs"]
mod live;
#[path = "support/supervisor.rs"]
mod supervisor;
use std::collections::BTreeMap;
use printobserver_sdk::{Actor, Client, ClientError, JobManifest, RejectionReason};
const REASON: &str = "a generated walk is asking";
const PATIENCE: std::time::Duration = std::time::Duration::from_secs(180);
fn manifest(file_name: &str) -> JobManifest {
JobManifest {
file_name: file_name.to_owned(),
material: "PLA".to_owned(),
nozzle_diameter_mm: 0.4,
slicer_profile: "the all-operation walk's own profile".to_owned(),
allowed: BTreeMap::new(),
metadata: BTreeMap::new(),
}
}
fn ready(client: &Client, print_id: &str, wanted: &str) {
if wanted.is_empty() {
return;
}
let deadline = std::time::Instant::now() + PATIENCE;
let mut last = String::from("nothing was reported");
while std::time::Instant::now() < deadline {
let status = client.status(print_id).expect("a status read is answered");
if let Some(printer) = status.printer {
last = serde_json::to_string(&printer.connection).unwrap_or_default();
if last.trim_matches('"') == wanted {
return;
}
}
std::thread::sleep(std::time::Duration::from_millis(500));
}
panic!("the machine reported {last} and the next step needs `{wanted}`");
}
fn step_status(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.status(&world.print_id)
.expect("`status` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "GET", "`status`");
assert_eq!(
seen.target,
format!("/v1/prints/{print_id}/status", print_id = world.print_id),
"`status`"
);
assert_eq!(seen.status, 200, "`status`");
assert_eq!(seen.body, "", "`status` sends no body");
live::same("status", &answered, &seen.answer);
}
fn step_context(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.context(&world.print_id)
.expect("`context` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "GET", "`context`");
assert_eq!(
seen.target,
format!("/v1/prints/{print_id}/context", print_id = world.print_id),
"`context`"
);
assert_eq!(seen.status, 200, "`context`");
assert_eq!(seen.body, "", "`context` sends no body");
live::same("context", &answered, &seen.answer);
}
fn step_image(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.image(&world.image_id)
.expect("`image` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "GET", "`image`");
assert_eq!(
seen.target,
format!("/v1/images/{image_id}", image_id = world.image_id),
"`image`"
);
assert_eq!(seen.status, 200, "`image`");
assert_eq!(seen.body, "", "`image` sends no body");
live::same("image", &answered, &seen.answer);
}
fn step_manifest_set(
client: &Client,
world: &supervisor::Supervisor,
proxy: &live::Proxy,
manifest: &printobserver_sdk::JobManifest,
) {
ready(client, &world.print_id, "");
let answered = client
.manifest_set(&world.print_id, REASON, manifest)
.expect("`manifest_set` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "PUT", "`manifest_set`");
assert_eq!(
seen.target,
format!("/v1/prints/{print_id}/manifest", print_id = world.print_id),
"`manifest_set`"
);
assert_eq!(seen.status, 200, "`manifest_set`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`manifest_set` sent another `reason`"
);
assert_eq!(
sent["manifest"],
serde_json::to_value(manifest).expect("a value renders"),
"`manifest_set` sent another `manifest`"
);
live::same("manifest_set", &answered, &seen.answer);
}
fn step_manifest_get(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.manifest_get(&world.print_id)
.expect("`manifest_get` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "GET", "`manifest_get`");
assert_eq!(
seen.target,
format!("/v1/prints/{print_id}/manifest", print_id = world.print_id),
"`manifest_get`"
);
assert_eq!(seen.status, 200, "`manifest_get`");
assert_eq!(seen.body, "", "`manifest_get` sends no body");
live::same("manifest_get", &answered, &seen.answer);
}
fn step_history(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.history(&world.print_id, Some(20))
.expect("`history` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "GET", "`history`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/history?limit=20",
print_id = world.print_id
),
"`history`"
);
assert_eq!(seen.status, 200, "`history`");
assert_eq!(seen.body, "", "`history` sends no body");
live::same("history", &answered, &seen.answer);
}
fn step_look(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.look(&world.print_id, Some(0))
.expect("`look` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "GET", "`look`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/look?wait_s=0",
print_id = world.print_id
),
"`look`"
);
assert_eq!(seen.status, 200, "`look`");
assert_eq!(seen.body, "", "`look` sends no body");
live::same("look", &answered, &seen.answer);
}
fn step_cancel(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "printing");
let answered = client
.cancel(&world.print_id, REASON)
.expect("`cancel` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`cancel`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/actions/cancel",
print_id = world.print_id
),
"`cancel`"
);
assert_eq!(seen.status, 200, "`cancel`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(sent["actor"], serde_json::json!("operator"), "`cancel`");
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`cancel` sent another `reason`"
);
live::same("cancel", &answered, &seen.answer);
}
fn step_start_print(
client: &Client,
world: &supervisor::Supervisor,
proxy: &live::Proxy,
manifest: &printobserver_sdk::JobManifest,
) -> supervisor::Supervisor {
ready(client, &world.print_id, "operational");
let answered = client
.start_print(
&world.print_id,
&world.file_name,
manifest,
REASON,
Some(false),
)
.expect("`start_print` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`start_print`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/actions/start_print",
print_id = world.print_id
),
"`start_print`"
);
assert_eq!(seen.status, 200, "`start_print`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["actor"],
serde_json::json!("operator"),
"`start_print`"
);
assert_eq!(
sent["file_name"],
serde_json::to_value(&world.file_name).expect("a value renders"),
"`start_print` sent another `file_name`"
);
assert_eq!(
sent["manifest"],
serde_json::to_value(manifest).expect("a value renders"),
"`start_print` sent another `manifest`"
);
assert_eq!(
sent["override_filament_check"],
serde_json::to_value(false).expect("a value renders"),
"`start_print` sent another `override_filament_check`"
);
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`start_print` sent another `reason`"
);
live::same("start_print", &answered, &seen.answer);
supervisor::Supervisor {
print_id: answered.record.print_id.clone(),
..world.clone()
}
}
fn step_set_feedrate_factor(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "printing");
let answered = client
.set_feedrate_factor(&world.print_id, 1.1, REASON, Some(60))
.expect("`set_feedrate_factor` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`set_feedrate_factor`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/actions/set_feedrate_factor",
print_id = world.print_id
),
"`set_feedrate_factor`"
);
assert_eq!(seen.status, 200, "`set_feedrate_factor`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["actor"],
serde_json::json!("operator"),
"`set_feedrate_factor`"
);
assert_eq!(
sent["duration_s"],
serde_json::to_value(60).expect("a value renders"),
"`set_feedrate_factor` sent another `duration_s`"
);
assert_eq!(
sent["factor"],
serde_json::to_value(1.1).expect("a value renders"),
"`set_feedrate_factor` sent another `factor`"
);
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`set_feedrate_factor` sent another `reason`"
);
live::same("set_feedrate_factor", &answered, &seen.answer);
}
fn step_set_flowrate_factor(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "printing");
let answered = client
.set_flowrate_factor(&world.print_id, 1.0, REASON, Some(60))
.expect("`set_flowrate_factor` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`set_flowrate_factor`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/actions/set_flowrate_factor",
print_id = world.print_id
),
"`set_flowrate_factor`"
);
assert_eq!(seen.status, 200, "`set_flowrate_factor`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["actor"],
serde_json::json!("operator"),
"`set_flowrate_factor`"
);
assert_eq!(
sent["duration_s"],
serde_json::to_value(60).expect("a value renders"),
"`set_flowrate_factor` sent another `duration_s`"
);
assert_eq!(
sent["factor"],
serde_json::to_value(1.0).expect("a value renders"),
"`set_flowrate_factor` sent another `factor`"
);
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`set_flowrate_factor` sent another `reason`"
);
live::same("set_flowrate_factor", &answered, &seen.answer);
}
fn step_set_fan_percent(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "printing");
let answered = client
.set_fan_percent(&world.print_id, 50.0, REASON, Some(60))
.expect("`set_fan_percent` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`set_fan_percent`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/actions/set_fan_percent",
print_id = world.print_id
),
"`set_fan_percent`"
);
assert_eq!(seen.status, 200, "`set_fan_percent`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["actor"],
serde_json::json!("operator"),
"`set_fan_percent`"
);
assert_eq!(
sent["duration_s"],
serde_json::to_value(60).expect("a value renders"),
"`set_fan_percent` sent another `duration_s`"
);
assert_eq!(
sent["percent"],
serde_json::to_value(50.0).expect("a value renders"),
"`set_fan_percent` sent another `percent`"
);
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`set_fan_percent` sent another `reason`"
);
live::same("set_fan_percent", &answered, &seen.answer);
}
fn step_set_tool_target_c(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "printing");
let answered = client
.set_tool_target_c(&world.print_id, REASON, 210.0, 0, Some(60))
.expect("`set_tool_target_c` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`set_tool_target_c`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/actions/set_tool_target_c",
print_id = world.print_id
),
"`set_tool_target_c`"
);
assert_eq!(seen.status, 200, "`set_tool_target_c`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["actor"],
serde_json::json!("operator"),
"`set_tool_target_c`"
);
assert_eq!(
sent["duration_s"],
serde_json::to_value(60).expect("a value renders"),
"`set_tool_target_c` sent another `duration_s`"
);
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`set_tool_target_c` sent another `reason`"
);
assert_eq!(
sent["target_c"],
serde_json::to_value(210.0).expect("a value renders"),
"`set_tool_target_c` sent another `target_c`"
);
assert_eq!(
sent["tool"],
serde_json::to_value(0).expect("a value renders"),
"`set_tool_target_c` sent another `tool`"
);
live::same("set_tool_target_c", &answered, &seen.answer);
}
fn step_set_bed_target_c(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "printing");
let answered = client
.set_bed_target_c(&world.print_id, REASON, 60.0, Some(60))
.expect("`set_bed_target_c` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`set_bed_target_c`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/actions/set_bed_target_c",
print_id = world.print_id
),
"`set_bed_target_c`"
);
assert_eq!(seen.status, 200, "`set_bed_target_c`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["actor"],
serde_json::json!("operator"),
"`set_bed_target_c`"
);
assert_eq!(
sent["duration_s"],
serde_json::to_value(60).expect("a value renders"),
"`set_bed_target_c` sent another `duration_s`"
);
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`set_bed_target_c` sent another `reason`"
);
assert_eq!(
sent["target_c"],
serde_json::to_value(60.0).expect("a value renders"),
"`set_bed_target_c` sent another `target_c`"
);
live::same("set_bed_target_c", &answered, &seen.answer);
}
fn step_acknowledge_failure(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.acknowledge_failure(
&world.print_id,
&printobserver_sdk::AcknowledgementDisposition::Continue,
&world.event_id,
REASON,
)
.expect("`acknowledge_failure` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`acknowledge_failure`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/actions/acknowledge_failure",
print_id = world.print_id
),
"`acknowledge_failure`"
);
assert_eq!(seen.status, 200, "`acknowledge_failure`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["actor"],
serde_json::json!("operator"),
"`acknowledge_failure`"
);
assert_eq!(
sent["disposition"],
serde_json::to_value(printobserver_sdk::AcknowledgementDisposition::Continue)
.expect("a value renders"),
"`acknowledge_failure` sent another `disposition`"
);
assert_eq!(
sent["event_id"],
serde_json::to_value(&world.event_id).expect("a value renders"),
"`acknowledge_failure` sent another `event_id`"
);
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`acknowledge_failure` sent another `reason`"
);
live::same("acknowledge_failure", &answered, &seen.answer);
}
fn step_pause(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "printing");
let answered = client
.pause(&world.print_id, REASON)
.expect("`pause` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`pause`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/actions/pause",
print_id = world.print_id
),
"`pause`"
);
assert_eq!(seen.status, 200, "`pause`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(sent["actor"], serde_json::json!("operator"), "`pause`");
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`pause` sent another `reason`"
);
live::same("pause", &answered, &seen.answer);
}
fn step_resume(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "paused");
let answered = client
.resume(&world.print_id, REASON)
.expect("`resume` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`resume`");
assert_eq!(
seen.target,
format!(
"/v1/prints/{print_id}/actions/resume",
print_id = world.print_id
),
"`resume`"
);
assert_eq!(seen.status, 200, "`resume`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(sent["actor"], serde_json::json!("operator"), "`resume`");
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`resume` sent another `reason`"
);
live::same("resume", &answered, &seen.answer);
}
fn step_spools(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.spools(Some(true))
.expect("`spools` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "GET", "`spools`");
assert_eq!(seen.target, "/v1/spools?include_retired=true", "`spools`");
assert_eq!(seen.status, 200, "`spools`");
assert_eq!(seen.body, "", "`spools` sends no body");
live::same("spools", &answered, &seen.answer);
}
fn step_spool(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.spool(&world.spool_id)
.expect("`spool` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "GET", "`spool`");
assert_eq!(
seen.target,
format!("/v1/spools/{spool_id}", spool_id = world.spool_id),
"`spool`"
);
assert_eq!(seen.status, 200, "`spool`");
assert_eq!(seen.body, "", "`spool` sends no body");
live::same("spool", &answered, &seen.answer);
}
fn step_printer_history(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.printer_history(
Some(vec!["spool_registered".to_owned()]),
Some("2020-01-01T00:00:00Z".to_owned()),
Some("2999-12-31T23:59:59Z".to_owned()),
Some(world.spool_id.clone()),
None,
Some(20),
)
.expect("`printer_history` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "GET", "`printer_history`");
assert_eq!(
seen.target,
format!(
"/v1/history?kinds=spool_registered&since=2020-01-01T00%3A00%3A00Z&until=2999-12-31T23%3A59%3A59Z&spool_id={spool_id}&limit=20",
spool_id = world.spool_id
),
"`printer_history`"
);
assert_eq!(seen.status, 200, "`printer_history`");
assert_eq!(seen.body, "", "`printer_history` sends no body");
live::same("printer_history", &answered, &seen.answer);
}
fn step_preflight(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.preflight(&world.file_name)
.expect("`preflight` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "GET", "`preflight`");
assert_eq!(
seen.target,
format!(
"/v1/preflight?file_name={file_name}",
file_name = world.file_name
),
"`preflight`"
);
assert_eq!(seen.status, 200, "`preflight`");
assert_eq!(seen.body, "", "`preflight` sends no body");
live::same("preflight", &answered, &seen.answer);
}
fn step_register_spool(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.register_spool(
1000.0,
"PLA",
"a spool the generated walk registers",
REASON,
Some("black".to_owned()),
Some(1.24),
Some(1.75),
Some(900.0),
Some(200.0),
)
.expect("`register_spool` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`register_spool`");
assert_eq!(
seen.target, "/v1/spools/actions/register_spool",
"`register_spool`"
);
assert_eq!(seen.status, 200, "`register_spool`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["actor"],
serde_json::json!("operator"),
"`register_spool`"
);
assert_eq!(
sent["color"],
serde_json::to_value("black").expect("a value renders"),
"`register_spool` sent another `color`"
);
assert_eq!(
sent["density_g_cm3"],
serde_json::to_value(1.24).expect("a value renders"),
"`register_spool` sent another `density_g_cm3`"
);
assert_eq!(
sent["diameter_mm"],
serde_json::to_value(1.75).expect("a value renders"),
"`register_spool` sent another `diameter_mm`"
);
assert_eq!(
sent["initial_g"],
serde_json::to_value(1000.0).expect("a value renders"),
"`register_spool` sent another `initial_g`"
);
assert_eq!(
sent["material"],
serde_json::to_value("PLA").expect("a value renders"),
"`register_spool` sent another `material`"
);
assert_eq!(
sent["name"],
serde_json::to_value("a spool the generated walk registers").expect("a value renders"),
"`register_spool` sent another `name`"
);
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`register_spool` sent another `reason`"
);
assert_eq!(
sent["remaining_g"],
serde_json::to_value(900.0).expect("a value renders"),
"`register_spool` sent another `remaining_g`"
);
assert_eq!(
sent["tare_g"],
serde_json::to_value(200.0).expect("a value renders"),
"`register_spool` sent another `tare_g`"
);
live::same("register_spool", &answered, &seen.answer);
}
fn step_load_spool(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.load_spool(&world.spool_id, REASON, 0)
.expect("`load_spool` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`load_spool`");
assert_eq!(
seen.target,
format!(
"/v1/spools/{spool_id}/actions/load_spool",
spool_id = world.spool_id
),
"`load_spool`"
);
assert_eq!(seen.status, 200, "`load_spool`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(sent["actor"], serde_json::json!("operator"), "`load_spool`");
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`load_spool` sent another `reason`"
);
assert_eq!(
sent["tool"],
serde_json::to_value(0).expect("a value renders"),
"`load_spool` sent another `tool`"
);
live::same("load_spool", &answered, &seen.answer);
}
fn step_unload_spool(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.unload_spool(&world.spool_id, REASON)
.expect("`unload_spool` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`unload_spool`");
assert_eq!(
seen.target,
format!(
"/v1/spools/{spool_id}/actions/unload_spool",
spool_id = world.spool_id
),
"`unload_spool`"
);
assert_eq!(seen.status, 200, "`unload_spool`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["actor"],
serde_json::json!("operator"),
"`unload_spool`"
);
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`unload_spool` sent another `reason`"
);
live::same("unload_spool", &answered, &seen.answer);
}
fn step_adjust_spool(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.adjust_spool(&world.spool_id, REASON, None, Some(800.0))
.expect("`adjust_spool` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`adjust_spool`");
assert_eq!(
seen.target,
format!(
"/v1/spools/{spool_id}/actions/adjust_spool",
spool_id = world.spool_id
),
"`adjust_spool`"
);
assert_eq!(seen.status, 200, "`adjust_spool`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["actor"],
serde_json::json!("operator"),
"`adjust_spool`"
);
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`adjust_spool` sent another `reason`"
);
assert_eq!(
sent["remaining_g"],
serde_json::to_value(800.0).expect("a value renders"),
"`adjust_spool` sent another `remaining_g`"
);
live::same("adjust_spool", &answered, &seen.answer);
}
fn step_retire_spool(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.retire_spool(&world.spool_id, REASON)
.expect("`retire_spool` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "POST", "`retire_spool`");
assert_eq!(
seen.target,
format!(
"/v1/spools/{spool_id}/actions/retire_spool",
spool_id = world.spool_id
),
"`retire_spool`"
);
assert_eq!(seen.status, 200, "`retire_spool`");
let sent: serde_json::Value =
serde_json::from_str(&seen.body).expect("the supervisor received a document");
assert_eq!(
sent["actor"],
serde_json::json!("operator"),
"`retire_spool`"
);
assert_eq!(
sent["reason"],
serde_json::to_value(REASON).expect("a value renders"),
"`retire_spool` sent another `reason`"
);
live::same("retire_spool", &answered, &seen.answer);
}
fn step_prints(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
ready(client, &world.print_id, "");
let answered = client
.prints()
.expect("`prints` is answered by a real supervisor");
let seen = proxy.last();
assert_eq!(seen.method, "GET", "`prints`");
assert_eq!(seen.target, "/v1/prints", "`prints`");
assert_eq!(seen.status, 200, "`prints`");
assert_eq!(seen.body, "", "`prints` sends no body");
live::same("prints", &answered, &seen.answer);
}
fn refused_cancel(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
let refused = client
.cancel(&world.print_id, REASON)
.expect_err("`cancel` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`cancel`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`cancel` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`cancel`");
live::same("cancel", &rejection.answer, &seen.answer);
}
fn refused_start_print(
client: &Client,
world: &supervisor::Supervisor,
proxy: &live::Proxy,
manifest: &printobserver_sdk::JobManifest,
) {
let refused = client
.start_print(
&world.print_id,
&world.file_name,
manifest,
REASON,
Some(false),
)
.expect_err("`start_print` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`start_print`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`start_print` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`start_print`");
live::same("start_print", &rejection.answer, &seen.answer);
}
fn refused_set_feedrate_factor(
client: &Client,
world: &supervisor::Supervisor,
proxy: &live::Proxy,
) {
let refused = client
.set_feedrate_factor(&world.print_id, 1.1, REASON, Some(60))
.expect_err("`set_feedrate_factor` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`set_feedrate_factor`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`set_feedrate_factor` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`set_feedrate_factor`");
live::same("set_feedrate_factor", &rejection.answer, &seen.answer);
}
fn refused_set_flowrate_factor(
client: &Client,
world: &supervisor::Supervisor,
proxy: &live::Proxy,
) {
let refused = client
.set_flowrate_factor(&world.print_id, 1.0, REASON, Some(60))
.expect_err("`set_flowrate_factor` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`set_flowrate_factor`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`set_flowrate_factor` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`set_flowrate_factor`");
live::same("set_flowrate_factor", &rejection.answer, &seen.answer);
}
fn refused_set_fan_percent(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
let refused = client
.set_fan_percent(&world.print_id, 50.0, REASON, Some(60))
.expect_err("`set_fan_percent` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`set_fan_percent`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`set_fan_percent` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`set_fan_percent`");
live::same("set_fan_percent", &rejection.answer, &seen.answer);
}
fn refused_set_tool_target_c(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
let refused = client
.set_tool_target_c(&world.print_id, REASON, 210.0, 0, Some(60))
.expect_err("`set_tool_target_c` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`set_tool_target_c`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`set_tool_target_c` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`set_tool_target_c`");
live::same("set_tool_target_c", &rejection.answer, &seen.answer);
}
fn refused_set_bed_target_c(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
let refused = client
.set_bed_target_c(&world.print_id, REASON, 60.0, Some(60))
.expect_err("`set_bed_target_c` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`set_bed_target_c`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`set_bed_target_c` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`set_bed_target_c`");
live::same("set_bed_target_c", &rejection.answer, &seen.answer);
}
fn refused_acknowledge_failure(
client: &Client,
world: &supervisor::Supervisor,
proxy: &live::Proxy,
) {
let refused = client
.acknowledge_failure(
&world.print_id,
&printobserver_sdk::AcknowledgementDisposition::Continue,
&world.event_id,
REASON,
)
.expect_err("`acknowledge_failure` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`acknowledge_failure`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`acknowledge_failure` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`acknowledge_failure`");
live::same("acknowledge_failure", &rejection.answer, &seen.answer);
}
fn refused_pause(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
let refused = client
.pause(&world.print_id, REASON)
.expect_err("`pause` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`pause`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`pause` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`pause`");
live::same("pause", &rejection.answer, &seen.answer);
}
fn refused_resume(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
let refused = client
.resume(&world.print_id, REASON)
.expect_err("`resume` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`resume`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`resume` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`resume`");
live::same("resume", &rejection.answer, &seen.answer);
}
fn refused_register_spool(client: &Client, _world: &supervisor::Supervisor, proxy: &live::Proxy) {
let refused = client
.register_spool(
1000.0,
"PLA",
"a spool the generated walk registers",
REASON,
Some("black".to_owned()),
Some(1.24),
Some(1.75),
Some(900.0),
Some(200.0),
)
.expect_err("`register_spool` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`register_spool`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`register_spool` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`register_spool`");
live::same("register_spool", &rejection.answer, &seen.answer);
}
fn refused_load_spool(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
let refused = client
.load_spool(&world.spool_id, REASON, 0)
.expect_err("`load_spool` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`load_spool`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`load_spool` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`load_spool`");
live::same("load_spool", &rejection.answer, &seen.answer);
}
fn refused_unload_spool(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
let refused = client
.unload_spool(&world.spool_id, REASON)
.expect_err("`unload_spool` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`unload_spool`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`unload_spool` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`unload_spool`");
live::same("unload_spool", &rejection.answer, &seen.answer);
}
fn refused_adjust_spool(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
let refused = client
.adjust_spool(&world.spool_id, REASON, None, Some(800.0))
.expect_err("`adjust_spool` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`adjust_spool`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`adjust_spool` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`adjust_spool`");
live::same("adjust_spool", &rejection.answer, &seen.answer);
}
fn refused_retire_spool(client: &Client, world: &supervisor::Supervisor, proxy: &live::Proxy) {
let refused = client
.retire_spool(&world.spool_id, REASON)
.expect_err("`retire_spool` is refused for an actor granted nothing");
let ClientError::Rejected(rejection) = refused else {
panic!("`retire_spool`: the refusal did not arrive as a rejection");
};
assert!(
matches!(rejection.reason, RejectionReason::ActorMayNotRequest { .. }),
"`retire_spool` was refused for something other than the grant: {:?}",
rejection.reason
);
let seen = proxy.last();
assert_eq!(seen.status, 409, "`retire_spool`");
live::same("retire_spool", &rejection.answer, &seen.answer);
}
fn about_the_running_print(
client: &Client,
world: supervisor::Supervisor,
) -> supervisor::Supervisor {
match client.prints().expect("a listing is answered").active {
Some(print_id) => supervisor::Supervisor { print_id, ..world },
None => world,
}
}
#[test]
fn every_method_is_answered_by_a_real_supervisor() {
let root = tempfile::tempdir().expect("this walk's own root");
let mut standing = supervisor::standing(root.path(), false);
let world = standing.at.clone();
let proxy = live::Proxy::in_front_of(&world.server);
let client = Client::new(proxy.url(), Actor::Operator).with_credential(&*world.credential);
let manifest = manifest(&world.file_name);
step_status(&client, &world, &proxy);
step_context(&client, &world, &proxy);
step_image(&client, &world, &proxy);
step_manifest_set(&client, &world, &proxy, &manifest);
step_manifest_get(&client, &world, &proxy);
step_history(&client, &world, &proxy);
step_look(&client, &world, &proxy);
step_cancel(&client, &world, &proxy);
let world = step_start_print(&client, &world, &proxy, &manifest);
step_set_feedrate_factor(&client, &world, &proxy);
step_set_flowrate_factor(&client, &world, &proxy);
step_set_fan_percent(&client, &world, &proxy);
step_set_tool_target_c(&client, &world, &proxy);
step_set_bed_target_c(&client, &world, &proxy);
step_acknowledge_failure(&client, &world, &proxy);
step_pause(&client, &world, &proxy);
step_resume(&client, &world, &proxy);
step_spools(&client, &world, &proxy);
step_spool(&client, &world, &proxy);
step_printer_history(&client, &world, &proxy);
step_preflight(&client, &world, &proxy);
step_register_spool(&client, &world, &proxy);
step_load_spool(&client, &world, &proxy);
step_unload_spool(&client, &world, &proxy);
step_adjust_spool(&client, &world, &proxy);
step_retire_spool(&client, &world, &proxy);
step_prints(&client, &world, &proxy);
assert!(proxy.calls() >= 27, "every call went through the proxy");
standing.stop();
}
#[test]
fn every_action_is_refused_as_a_typed_rejection_by_a_real_supervisor() {
let root = tempfile::tempdir().expect("this walk's own root");
let mut standing = supervisor::standing(root.path(), true);
let world = standing.at.clone();
let proxy = live::Proxy::in_front_of(&world.server);
let client = Client::new(proxy.url(), Actor::Operator).with_credential(&*world.credential);
let manifest = manifest(&world.file_name);
let world = about_the_running_print(&client, world);
refused_cancel(&client, &world, &proxy);
refused_start_print(&client, &world, &proxy, &manifest);
refused_set_feedrate_factor(&client, &world, &proxy);
refused_set_flowrate_factor(&client, &world, &proxy);
refused_set_fan_percent(&client, &world, &proxy);
refused_set_tool_target_c(&client, &world, &proxy);
refused_set_bed_target_c(&client, &world, &proxy);
refused_acknowledge_failure(&client, &world, &proxy);
refused_pause(&client, &world, &proxy);
refused_resume(&client, &world, &proxy);
refused_register_spool(&client, &world, &proxy);
refused_load_spool(&client, &world, &proxy);
refused_unload_spool(&client, &world, &proxy);
refused_adjust_spool(&client, &world, &proxy);
refused_retire_spool(&client, &world, &proxy);
standing.stop();
}