use crate::prelude::*;
use beet_core::prelude::*;
use beet_flow::prelude::*;
use beet_rsx::prelude::*;
pub fn fallback() -> impl Bundle {
(
Name::new("Fallback Predicate"),
OnSpawn::observe(
|ev: On<GetOutcome>,
mut commands: Commands,
agent_query: AgentQuery<
(),
(With<Request>, Without<ResponseMarker>),
>| {
let action = ev.target();
let outcome = match agent_query.contains(action) {
true => Outcome::Pass,
false => Outcome::Fail,
};
commands.entity(action).trigger_target(outcome);
},
),
)
}
pub fn no_response() -> impl Bundle {
(
Name::new("No Response Predicate"),
OnSpawn::observe(
|ev: On<GetOutcome>,
mut commands: Commands,
agent_query: AgentQuery<(), Without<ResponseMarker>>| {
let action = ev.target();
let outcome = match agent_query.contains(action) {
true => Outcome::Pass,
false => Outcome::Fail,
};
commands.entity(action).trigger_target(outcome);
},
),
)
}
pub fn contains_handler_bundle() -> impl Bundle {
(
Name::new("Handler Bundle Predicate"),
OnSpawn::observe(
|ev: On<GetOutcome>,
mut commands: Commands,
children: Query<&Children>,
agents: AgentQuery,
handler_bundles: Query<(), With<HtmlBundle>>| {
let action = ev.target();
let agent = agents.entity(action);
let outcome = match children
.iter_direct_descendants(agent)
.any(|child| handler_bundles.contains(child))
{
true => Outcome::Pass,
false => Outcome::Fail,
};
commands.entity(action).trigger_target(outcome);
},
),
)
}
pub fn is_ssr() -> impl Bundle {
(
Name::new("SSR Predicate"),
OnSpawn::observe(
|ev: On<GetOutcome>,
mut commands: Commands,
render_mode: Res<RenderMode>| {
let action = ev.target();
let outcome = match *render_mode {
RenderMode::Ssr => Outcome::Pass,
_ => Outcome::Fail,
};
commands.entity(action).trigger_target(outcome);
},
),
)
}
#[cfg(test)]
mod test {
use crate::prelude::*;
use beet_core::prelude::*;
use beet_flow::prelude::*;
use beet_net::exports::http;
use beet_net::prelude::*;
#[beet_core::test]
async fn fallback_no_response() {
RouterPlugin::world()
.spawn(ExchangeSpawner::new_flow(|| {
(Sequence, children![
common_predicates::fallback(),
EndpointBuilder::get()
])
}))
.oneshot(Request::get("/"))
.await
.status()
.xpect_eq(StatusCode::Ok);
}
#[beet_core::test]
async fn fallback_request_consumed() {
RouterPlugin::world()
.spawn(ExchangeSpawner::new_flow(|| {
(Sequence, children![
EndpointBuilder::get().with_handler(StatusCode::Http(
http::StatusCode::IM_A_TEAPOT
)),
common_predicates::fallback(),
EndpointBuilder::get().with_handler(|| -> () {
unreachable!();
}),
])
}))
.oneshot(Request::get("/"))
.await
.status()
.xpect_eq(StatusCode::Http(http::StatusCode::IM_A_TEAPOT));
}
#[beet_core::test]
async fn is_ssr_true() {
RouterPlugin::world()
.xtap(|world| world.insert_resource(RenderMode::Ssr))
.spawn(ExchangeSpawner::new_flow(|| {
(Sequence, children![
common_predicates::is_ssr(),
EndpointBuilder::get()
])
}))
.oneshot(Request::get("/"))
.await
.status()
.xpect_eq(StatusCode::Ok);
}
#[beet_core::test]
async fn is_ssr_false() {
RouterPlugin::world()
.xtap(|world| world.insert_resource(RenderMode::Ssg))
.spawn(ExchangeSpawner::new_flow(|| {
(Sequence, children![
common_predicates::is_ssr(),
EndpointBuilder::get(),
])
}))
.oneshot(Request::get("/"))
.await
.status()
.xpect_eq(StatusCode::InternalError);
}
#[beet_core::test]
async fn contains_handler_bundle_pass() {
use beet_rsx::prelude::HtmlBundle;
RouterPlugin::world()
.spawn(ExchangeSpawner::new_flow(|| {
(Sequence, children![
OnSpawn::observe(
|ev: On<GetOutcome>,
agents: AgentQuery,
mut commands: Commands| {
let agent = agents.entity(ev.target());
commands.entity(agent).with_children(|parent| {
parent.spawn(HtmlBundle);
});
commands
.entity(ev.target())
.trigger_target(Outcome::Pass);
},
),
common_predicates::contains_handler_bundle(),
EndpointBuilder::get()
])
}))
.oneshot(Request::get("/"))
.await
.status()
.xpect_eq(StatusCode::Ok);
}
#[beet_core::test]
async fn contains_handler_bundle_fail() {
RouterPlugin::world()
.spawn(ExchangeSpawner::new_flow(|| {
(Sequence, children![
common_predicates::contains_handler_bundle(),
EndpointBuilder::get(),
])
}))
.oneshot(Request::get("/"))
.await
.status()
.xpect_eq(StatusCode::InternalError);
}
}