#![cfg(feature = "db")]
use autumn_web::model;
use autumn_web::prelude::*;
use autumn_web::reexports::diesel_async::AsyncPgConnection;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
struct EffectArgs {
idempotency_key: String,
}
#[job(name = "on_commit_send_shipped_email")]
#[allow(clippy::unused_async)] async fn send_shipped_email(_state: AppState, _args: EffectArgs) -> AutumnResult<()> {
Ok(())
}
#[job(name = "on_commit_announce_archive")]
#[allow(clippy::unused_async)] async fn announce_archive(_state: AppState, _args: EffectArgs) -> AutumnResult<()> {
Ok(())
}
diesel::table! {
on_commit_orders (id) {
id -> BigInt,
status -> Text,
}
}
#[model(table = "on_commit_orders")]
pub struct Order {
#[id]
pub id: i64,
#[state_machine(transitions(
pending -> processing,
processing -> shipped: on_commit = SendShippedEmailJob,
shipped -> archived: guard = "can_archive", on_commit = AnnounceArchiveJob,
))]
pub status: String,
}
impl Order {
#[allow(clippy::missing_const_for_fn)]
fn can_archive(&self) -> bool {
!self.status.is_empty()
}
}
fn order(status: &str) -> Order {
Order {
id: 7,
status: status.to_string(),
}
}
#[test]
fn pure_validator_still_governs_allowed_edges() {
assert!(order("pending").can_transition_status_to("processing"));
assert!(order("processing").can_transition_status_to("shipped"));
assert!(order("shipped").can_transition_status_to("archived"));
assert!(!order("pending").can_transition_status_to("shipped"));
assert!(order("pending").transition_status_to("shipped").is_err());
assert_eq!(
order("processing")
.transition_status_to("shipped")
.expect("declared edge"),
"shipped"
);
}
#[allow(dead_code)]
async fn _assert_on_conn_signature(
order: &Order,
conn: &mut AsyncPgConnection,
) -> AutumnResult<String> {
order.transition_status_to_on_conn(conn, "shipped").await
}
#[test]
fn transition_effect_payload_is_public_and_serializable() {
let effect = autumn_web::TransitionEffect {
model: "Order".to_string(),
field: "status".to_string(),
record_id: "7".to_string(),
from_state: "processing".to_string(),
to_state: "shipped".to_string(),
idempotency_key: "Order:status:7:processing:shipped".to_string(),
};
let json = serde_json::to_value(&effect).expect("serializes");
assert_eq!(json["idempotency_key"], "Order:status:7:processing:shipped");
let round: autumn_web::TransitionEffect = serde_json::from_value(json).expect("round-trips");
assert_eq!(round, effect);
}