use crate::{Action, ActionId};
use fission_ir::Hyperlink;
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum NavigationCommand {
Push(String),
Replace(String),
Open(Hyperlink),
Back,
Forward,
Go(i32),
Reload,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct NavigationRequested {
pub command: NavigationCommand,
}
impl NavigationRequested {
pub fn new(command: NavigationCommand) -> Self {
Self { command }
}
}
impl Action for NavigationRequested {
fn static_id() -> ActionId {
lazy_static! {
static ref ID: ActionId = ActionId::from_name("fission_core::NavigationRequested");
}
*ID
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{LinkTarget, Runtime, WidgetId};
#[test]
fn built_in_navigation_action_queues_without_an_application_reducer() {
let mut runtime = Runtime::default();
let command =
NavigationCommand::Open(Hyperlink::new("/projects/42").target(LinkTarget::NewWindow));
runtime
.dispatch(
NavigationRequested::new(command.clone()).into(),
WidgetId::explicit("projects.link"),
)
.expect("built-in navigation action should dispatch");
assert_eq!(runtime.take_pending_navigation(), vec![command]);
}
#[test]
fn navigation_action_round_trips_complete_hyperlink_metadata() {
let request = NavigationRequested::new(NavigationCommand::Open(
Hyperlink::new("/report")
.target(LinkTarget::Named("preview".into()))
.rel("alternate")
.download("report.pdf"),
));
let envelope: crate::ActionEnvelope = request.clone().into();
assert_eq!(
serde_json::from_slice::<NavigationRequested>(&envelope.payload).unwrap(),
request
);
}
}