use crate::mail::{Mail, Mailbox}; use poem::{ endpoint::{EmbeddedFileEndpoint, EmbeddedFilesEndpoint}, get, handler, listener::TcpListener, middleware::AddData, web::{Data, Json}, EndpointExt, Route, Server, }; use rust_embed::RustEmbed; #[derive(RustEmbed)] #[folder = "ui/build"] pub struct Files; #[handler] async fn messages(mailbox: Data<&Mailbox>) -> Json> { Json(mailbox.all().await) } #[handler] async fn clear(mailbox: Data<&Mailbox>) -> String { mailbox.clear().await; "OK".to_string() } pub async fn server(mailbox: Mailbox, port: u16) -> anyhow::Result<()> { tokio::spawn(async move { let app = Route::new() .at("/messages", get(messages)) .at("/", EmbeddedFileEndpoint::::new("index.html")) .nest("/", EmbeddedFilesEndpoint::::new()) .with(AddData::new(mailbox)); if let Err(e) = Server::new(TcpListener::bind(format!("0.0.0.0:{}", port))) .run(app) .await { tracing::error!("Webserver error: {}", e); } }); Ok(()) } #[cfg(test)] mod tests { use super::{clear, messages}; use crate::mail::{Mail, Mailbox}; use poem::{ middleware::AddData, test::{TestClient, TestJson}, EndpointExt, Route, }; async fn request_data<'a>(url: &str, mb: &Mailbox) -> TestJson { let app = Route::new() .at("/messages", messages) .at("/clear", clear) .with(AddData::new(mb.clone())); let client = TestClient::new(app); let resp = client.get(url).send().await; resp.assert_status_is_ok(); resp.json().await } async fn request_void<'a>(url: &str, mb: &Mailbox) { let app = Route::new() .at("/messages", messages) .at("/clear", clear) .with(AddData::new(mb.clone())); let client = TestClient::new(app); let resp = client.get(url).send().await; resp.assert_status_is_ok(); } #[tokio::test] async fn test_messages_endpoint() { let mb = Mailbox::new(); let resp = request_data("/messages", &mb).await; let data = resp.value(); data.array().assert_is_empty(); mb.store(Mail::default()).await; let resp = request_data("/messages", &mb).await; let data = resp.value(); assert_eq!(data.array().len(), 1); } #[tokio::test] async fn test_clear_endpoint() { let mb = Mailbox::new(); mb.store(Mail::default()).await; request_void("/clear", &mb).await; assert_eq!(mb.len().await, 0); } }