fxa_client/state_machine/internal_machines/
disconnected.rs
1use super::{invalid_transition, Event, InternalStateMachine, State};
6use crate::{Error, FxaEvent, FxaState, Result};
7
8pub struct DisconnectedStateMachine;
9
10use Event::*;
12use State::*;
13
14impl InternalStateMachine for DisconnectedStateMachine {
15 fn initial_state(&self, event: FxaEvent) -> Result<State> {
16 match event {
17 FxaEvent::BeginOAuthFlow { scopes, entrypoint } => {
18 Ok(State::BeginOAuthFlow { scopes, entrypoint })
19 }
20 FxaEvent::BeginPairingFlow {
21 pairing_url,
22 scopes,
23 entrypoint,
24 } => Ok(State::BeginPairingFlow {
25 pairing_url,
26 scopes,
27 entrypoint,
28 }),
29 e => Err(Error::InvalidStateTransition(format!(
30 "Disconnected -> {e}"
31 ))),
32 }
33 }
34
35 fn next_state(&self, state: State, event: Event) -> Result<State> {
36 Ok(match (state, event) {
37 (BeginOAuthFlow { .. }, BeginOAuthFlowSuccess { oauth_url }) => {
38 Complete(FxaState::Authenticating { oauth_url })
39 }
40 (BeginPairingFlow { .. }, BeginPairingFlowSuccess { oauth_url }) => {
41 Complete(FxaState::Authenticating { oauth_url })
42 }
43 (BeginOAuthFlow { .. }, CallError) => Cancel,
44 (BeginPairingFlow { .. }, CallError) => Cancel,
45 (state, event) => return invalid_transition(state, event),
46 })
47 }
48}
49
50#[cfg(test)]
51mod test {
52 use super::super::StateMachineTester;
53 use super::*;
54
55 #[test]
56 fn test_oauth_flow() {
57 let tester = StateMachineTester::new(
58 DisconnectedStateMachine,
59 FxaEvent::BeginOAuthFlow {
60 scopes: vec!["profile".to_owned()],
61 entrypoint: "test-entrypoint".to_owned(),
62 },
63 );
64 assert_eq!(
65 tester.state,
66 BeginOAuthFlow {
67 scopes: vec!["profile".to_owned()],
68 entrypoint: "test-entrypoint".to_owned(),
69 }
70 );
71 assert_eq!(tester.peek_next_state(CallError), Cancel);
72 assert_eq!(
73 tester.peek_next_state(BeginOAuthFlowSuccess {
74 oauth_url: "http://example.com/oauth-start".to_owned(),
75 }),
76 Complete(FxaState::Authenticating {
77 oauth_url: "http://example.com/oauth-start".to_owned(),
78 })
79 );
80 }
81
82 #[test]
83 fn test_pairing_flow() {
84 let tester = StateMachineTester::new(
85 DisconnectedStateMachine,
86 FxaEvent::BeginPairingFlow {
87 pairing_url: "https://example.com/pairing-url".to_owned(),
88 scopes: vec!["profile".to_owned()],
89 entrypoint: "test-entrypoint".to_owned(),
90 },
91 );
92 assert_eq!(
93 tester.state,
94 BeginPairingFlow {
95 pairing_url: "https://example.com/pairing-url".to_owned(),
96 scopes: vec!["profile".to_owned()],
97 entrypoint: "test-entrypoint".to_owned(),
98 }
99 );
100 assert_eq!(tester.peek_next_state(CallError), Cancel);
101 assert_eq!(
102 tester.peek_next_state(BeginPairingFlowSuccess {
103 oauth_url: "http://example.com/oauth-start".to_owned(),
104 }),
105 Complete(FxaState::Authenticating {
106 oauth_url: "http://example.com/oauth-start".to_owned(),
107 })
108 );
109 }
110}