fxa_client/state_machine/internal_machines/
authenticating.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use super::{invalid_transition, Event, InternalStateMachine, State};
6use crate::{Error, FxaEvent, FxaState, Result};
7
8pub struct AuthenticatingStateMachine;
9
10// Save some typing
11use Event::*;
12use State::*;
13
14impl InternalStateMachine for AuthenticatingStateMachine {
15    fn initial_state(&self, event: FxaEvent) -> Result<State> {
16        match event {
17            FxaEvent::CompleteOAuthFlow { code, state } => Ok(CompleteOAuthFlow {
18                code: code.clone(),
19                state: state.clone(),
20            }),
21            FxaEvent::CancelOAuthFlow => Ok(Complete(FxaState::Disconnected)),
22            e => Err(Error::InvalidStateTransition(format!(
23                "Authenticating -> {e}"
24            ))),
25        }
26    }
27
28    fn next_state(&self, state: State, event: Event) -> Result<State> {
29        Ok(match (state, event) {
30            (CompleteOAuthFlow { .. }, CompleteOAuthFlowSuccess) => InitializeDevice,
31            (CompleteOAuthFlow { .. }, CallError) => Complete(FxaState::Disconnected),
32            (InitializeDevice, InitializeDeviceSuccess) => Complete(FxaState::Connected),
33            (InitializeDevice, CallError) => Complete(FxaState::Disconnected),
34            (state, event) => return invalid_transition(state, event),
35        })
36    }
37}
38
39#[cfg(test)]
40mod test {
41    use super::super::StateMachineTester;
42    use super::*;
43
44    #[test]
45    fn test_complete_oauth_flow() {
46        let mut tester = StateMachineTester::new(
47            AuthenticatingStateMachine,
48            FxaEvent::CompleteOAuthFlow {
49                code: "test-code".to_owned(),
50                state: "test-state".to_owned(),
51            },
52        );
53        assert_eq!(
54            tester.state,
55            CompleteOAuthFlow {
56                code: "test-code".to_owned(),
57                state: "test-state".to_owned(),
58            }
59        );
60        assert_eq!(
61            tester.peek_next_state(CallError),
62            Complete(FxaState::Disconnected)
63        );
64
65        tester.next_state(CompleteOAuthFlowSuccess);
66        assert_eq!(tester.state, InitializeDevice);
67        assert_eq!(
68            tester.peek_next_state(CallError),
69            Complete(FxaState::Disconnected)
70        );
71        assert_eq!(
72            tester.peek_next_state(InitializeDeviceSuccess),
73            Complete(FxaState::Connected)
74        );
75    }
76
77    #[test]
78    fn test_cancel_oauth_flow() {
79        let tester = StateMachineTester::new(AuthenticatingStateMachine, FxaEvent::CancelOAuthFlow);
80        assert_eq!(tester.state, Complete(FxaState::Disconnected));
81    }
82}