diff --git a/src/provision.rs b/src/provision.rs index f2881e5..f494652 100644 --- a/src/provision.rs +++ b/src/provision.rs @@ -201,6 +201,38 @@ mod behaviour { let _ = std::fs::remove_file(path); } + /// The success path, using the OctoPrint client because its `connect` is + /// the one that succeeds without a real machine (the driver is a stub). + /// What this proves is the plumbing, not a vendor: a connected printer is + /// saved, joins the running fleet, and is still there after a "restart" + /// that reopens the store and rebuilds the fleet from it. + #[tokio::test] + async fn an_added_printer_joins_the_fleet_and_survives_a_restart() { + let (store, path) = store(); + let fleet = empty_fleet(); + let mut req = request("octo1"); + req.vendor = "octoprint".into(); + req.sn = None; + req.access_code = None; + req.api_key = Some("key-123".into()); + + add(&fleet, &store, req.clone()).await.unwrap(); + assert!(fleet.lock().await.iter().any(|p| p.base().id == "octo1")); + + // Same id again: refused, and the first is untouched. + let again = add(&fleet, &store, req).await.unwrap_err(); + assert!(again.contains("already has"), "{again}"); + assert_eq!(fleet.lock().await.len(), 1); + + // "Restart": reopen the store, rebuild what main would. + drop(store); + let reopened = Store::open(&path).unwrap(); + let rebuilt: Vec<_> = reopened.printers().unwrap().into_iter().map(|e| crate::fleet::build(e).unwrap()).collect(); + assert_eq!(rebuilt.len(), 1); + assert_eq!(rebuilt[0].base().id, "octo1"); + let _ = std::fs::remove_file(path); + } + #[test] fn the_wire_message_parses_and_its_debug_hides_the_credential() { let json = r#"{"type":"provision_printer","request_id":"r1","printer":{"id":"p1","name":"Bench","vendor":"bambu","host":"10.0.0.5","access_code":"98765432","sn":"SN1"}}"#;