Skip to main content

turnframe_test/workflows/trip/
mod.rs

1//! The trip sample: the disruption case of one booking.
2//!
3//! It is the awkward workflow on purpose: several obligations are open at once,
4//! one of them per extra; the rebooking card is a persistent card bound to the
5//! case revision and to the quote it shows, so a new quote makes a click on it
6//! stale; the rebooking goes to an airline that may answer late or never, and the
7//! states after it are never collapsed into "done"; and a leg the traveler asked
8//! to keep is refused any change, by the domain, whatever was read.
9//!
10//! ```
11//! use turnframe_core::case::CaseRef;
12//! use turnframe_core::flow::{WorkflowDefinition, check_view};
13//! use turnframe_core::ids::CaseRevision;
14//! use turnframe_test::workflows::trip::{TripPhase, TripWorkflow, awaiting_rebooking_confirmation};
15//!
16//! let workflow = TripWorkflow::default();
17//! let state = awaiting_rebooking_confirmation();
18//! let view = workflow.project(CaseRef::new("trip", "trip-1", CaseRevision(7)), Some(&state));
19//!
20//! assert_eq!(view.phase, TripPhase::AwaitingRebookingConfirmation);
21//! assert!(view.obligations.is_empty());
22//! assert!(view.blocking_interaction.is_some());
23//! assert!(check_view(&workflow, &view).is_ok());
24//! ```
25
26pub mod airline;
27pub mod apply;
28pub mod command;
29pub mod definition;
30pub mod model;
31pub mod state;
32
33pub use airline::{AirlineMode, airline_answer};
34pub use apply::{apply, extra_id_for, next_status_for, rejection, validate};
35pub use command::{
36    AddExtraArgs, AssignPayerArgs, ChangeExtraArgs, ChangeTravelerArgs, LegArgs, OpenArgs,
37    SetNameArgs, SetTravelDateArgs, SetTravelerArgs, TravelerRecord, TripCommand, TripEvent,
38    operations,
39};
40pub use definition::{
41    REBOOK_CONFIRM_OPTION, REBOOK_DECLINE_OPTION, REBOOKING_CONFIRMATION_KEY, TripWorkflow,
42};
43pub use model::{
44    OTHER_TRAVELER_ID, REQUOTED_FARE_DIFFERENCE_CENTS, SAMPLE_EXTRA_DESCRIPTIONS,
45    SAMPLE_FARE_DIFFERENCE_CENTS, SAMPLE_NAME, SAMPLE_REFUSAL_CODE, SAMPLE_TICKET_NUMBER,
46    SAMPLE_TRAVELER_ID, TripModel, awaiting_rebooking_confirmation,
47    awaiting_rebooking_confirmation_at, complete_case, incomplete_case, other_traveler,
48    sample_legs, sample_new_extra, sample_offer, sample_quote, sample_travel_date, sample_traveler,
49    unassigned_case, with_offer,
50};
51pub use state::{
52    Extra, Leg, LegStatus, NewExtra, Offer, Payer, TripObligation, TripOutcome, TripPhase,
53    TripState, TripStatus, TripTraveler,
54};
55
56/// An in-memory executor for the trip workflow.
57pub type TripExecutor = crate::workflows::InMemoryExecutor<TripWorkflow>;
58
59/// Case identifier the executor conformance suite runs against.
60pub const CONFORMANCE_CASE_ID: &str = "trip-conformance";
61
62/// Revision the conformance case is seeded at, chosen so a failure that reports
63/// `0` or `1` is obviously wrong rather than accidentally right.
64pub const CONFORMANCE_REVISION: u64 = 4;
65
66/// The trip sample wired up for [`executors::run_all`](crate::executors::run_all).
67///
68/// The trip is the sample the executor suite uses because `AddExtra` appends: an
69/// executor that ran a replayed key again instead of replaying it would leave a
70/// state the suite can tell apart, which an assignment would not.
71///
72/// * `first` adds a second extra to a complete case;
73/// * `second` names the trip otherwise, which serializes differently;
74/// * `refused` sets an empty name, refused in every editable state.
75#[must_use]
76pub fn conformance_case() -> crate::executors::InMemoryCase<TripWorkflow> {
77    crate::executors::InMemoryCase::new(
78        turnframe_core::case::CaseRef::new(
79            "trip",
80            CONFORMANCE_CASE_ID,
81            turnframe_core::ids::CaseRevision(CONFORMANCE_REVISION),
82        ),
83        Some(complete_case()),
84        TripCommand::AddExtra {
85            extra: sample_new_extra(1),
86        },
87        TripCommand::SetName {
88            value: "A different name".to_owned(),
89        },
90        TripCommand::SetName {
91            value: String::new(),
92        },
93    )
94}