#![allow(unused)] use std::sync::OnceLock; use api::app; use axum_test::{TestResponse, TestServer}; use serde::de::DeserializeOwned; use services::User; use tracing::Level; use types::{Category, Tag, Todo}; use uuid::Uuid; pub struct Client { pub server: TestServer, } impl Client { async fn get(&self, path: &str) -> TestResponse { self.server.get(&format!("/api/{}", path)).await } async fn post(&self, path: &str) -> TestResponse { self.server.post(&format!("/api/{}", path)).await } async fn post_json(&self, path: &str, body: serde_json::Value) -> TestResponse { self.server .post(&format!("/api/{}", path)) .json(&body) .await } async fn delete(&self, path: &str) -> TestResponse { self.server.delete(&format!("/api/{}", path)).await } fn json(response: TestResponse) -> T { response.assert_status_success(); response.json() } pub async fn get_todos(&self) -> TestResponse { self.get("todos").await } pub async fn get_todos_json(&self) -> Vec { Self::json(self.get_todos().await) } pub async fn add_todo(&self, todo: serde_json::Value) -> TestResponse { self.post_json("todos", todo).await } pub async fn add_todo_json(&self, todo: serde_json::Value) -> Todo { Self::json(self.add_todo(todo).await) } pub async fn delete_todo(&self, todo_uuid: Uuid) -> TestResponse { self.delete(&format!("todos/{}", todo_uuid)).await } pub async fn delete_todo_json(&self, todo_uuid: Uuid) -> Todo { Self::json(self.delete_todo(todo_uuid).await) } pub async fn check_todo(&self, todo_uuid: Uuid) -> TestResponse { self.post(&format!("todos/check/{}", todo_uuid)).await } pub async fn remove_check_todo(&self, todo_uuid: Uuid) -> TestResponse { self.delete(&format!("todos/check/{}", todo_uuid)).await } pub async fn get_tags(&self) -> TestResponse { self.get("tags").await } pub async fn get_tags_json(&self) -> Vec { Self::json(self.get_tags().await) } pub async fn add_tag(&self, tag: serde_json::Value) -> TestResponse { self.post_json("tags", tag).await } pub async fn add_tag_json(&self, tag: serde_json::Value) -> Tag { Self::json(self.add_tag(tag).await) } pub async fn delete_tag(&self, tag_uuid: Uuid) -> TestResponse { self.delete(&format!("tags/{}", tag_uuid)).await } pub async fn delete_tag_json(&self, tag_uuid: Uuid) -> Tag { Self::json(self.delete_tag(tag_uuid).await) } pub async fn get_categories(&self) -> TestResponse { self.get("categories").await } pub async fn get_categories_json(&self) -> Vec { Self::json(self.get_categories().await) } pub async fn add_category(&self, category: serde_json::Value) -> TestResponse { self.post_json("categories", category).await } pub async fn add_category_json(&self, category: serde_json::Value) -> Category { Self::json(self.add_category(category).await) } pub async fn delete_category(&self, category_uuid: Uuid) -> TestResponse { self.delete(&format!("categories/{}", category_uuid)).await } pub async fn delete_category_json(&self, category_uuid: Uuid) -> Category { Self::json(self.delete_category(category_uuid).await) } pub async fn move_todo(&self, value: serde_json::Value) -> TestResponse { self.post_json("todos/move", value).await } pub async fn add_web_push_subscription(&self, subscription: serde_json::Value) -> TestResponse { self.post_json("subscription", subscription).await } } static TRACING: OnceLock<()> = OnceLock::new(); pub async fn get_client() -> Client { TRACING.get_or_init(|| { tracing_subscriber::fmt() .with_max_level(Level::ERROR) .init(); }); let user = User { id: Uuid::new_v4().to_string(), }; let app = app( "sqlite::memory:", Some(user), None, "http://localhost:3000".to_string(), "http://localhost:8080".to_string(), ) .await .unwrap(); Client { server: TestServer::builder().http_transport().build(app), } }