diff --git a/backend/src/log.rs b/backend/src/log.rs index 720b2b2..2c86ab0 100644 --- a/backend/src/log.rs +++ b/backend/src/log.rs @@ -35,6 +35,7 @@ pub enum Log { directory: PathBuf, }, StdoutOnly, + NoLog, } impl Log { @@ -85,12 +86,8 @@ impl Log { } pub fn new_to_stdout_only() -> Self { - Self::new_to_stdout_only_with_max_level(None) - } - - pub fn new_to_stdout_only_with_max_level(level: Option) -> Self { let layer_stdout = tracing_subscriber::fmt::layer() - .with_writer(std::io::stdout.with_max_level(level.unwrap_or(TRACING_LEVEL))) + .with_writer(std::io::stdout.with_max_level(TRACING_LEVEL)) .with_thread_ids(TRACING_DISPLAY_THREAD) .with_thread_names(TRACING_DISPLAY_THREAD); @@ -101,6 +98,10 @@ impl Log { Log::StdoutOnly } + pub fn new_no_log() -> Self { + Log::NoLog + } + pub fn file_names(&self) -> std::io::Result> { match self { Log::FileAndStdout { _guard, directory } => { @@ -129,7 +130,7 @@ impl Log { .rev() .collect()) } - Log::StdoutOnly => Ok(vec![]), + Log::StdoutOnly | Log::NoLog => Ok(vec![]), } } @@ -144,7 +145,7 @@ impl Log { .map(|l| l.unwrap_or_default()) .collect()) } - Log::StdoutOnly => Ok(vec![]), + Log::StdoutOnly | Log::NoLog => Ok(vec![]), } } diff --git a/backend/src/services/ron/recipe.rs b/backend/src/services/ron/recipe.rs index fafda6c..ca2f6ac 100644 --- a/backend/src/services/ron/recipe.rs +++ b/backend/src/services/ron/recipe.rs @@ -115,15 +115,7 @@ pub async fn rm_tags( ExtractRon(ron): ExtractRon, ) -> Result { check_user_rights_recipe(&connection, &context.user, ron.recipe_id).await?; - connection - .rm_recipe_tags( - ron.recipe_id, - &ron.tags - .into_iter() - .map(|tag| tag.to_lowercase()) - .collect::>(), - ) - .await?; + connection.rm_recipe_tags(ron.recipe_id, &ron.tags).await?; Ok(StatusCode::OK) } @@ -165,7 +157,7 @@ pub async fn set_language( pub async fn set_is_public( State(connection): State, Extension(context): Extension, - ExtractRon(ron): ExtractRon, + ExtractRon(ron): ExtractRon, ) -> Result { check_user_rights_recipe(&connection, &context.user, ron.recipe_id).await?; connection diff --git a/backend/tests/http.rs b/backend/tests/http.rs index d792622..3fef86f 100644 --- a/backend/tests/http.rs +++ b/backend/tests/http.rs @@ -301,65 +301,7 @@ async fn create_recipe_and_edit_it() -> Result<(), Box> { .await; response.assert_status_ok(); - let response = server - .patch("/ron-api/recipe/estimated_time") - .add_cookie(cookie.clone()) - .add_header(http::header::CONTENT_TYPE, common::consts::MIME_TYPE_RON) - .bytes( - ron_api::to_string(ron_api::SetRecipeEstimatedTime { - recipe_id, - estimated_time: Some(420), - }) - .unwrap() - .into(), - ) - .await; - response.assert_status_ok(); - - let response = server - .patch("/ron-api/recipe/difficulty") - .add_cookie(cookie.clone()) - .add_header(http::header::CONTENT_TYPE, common::consts::MIME_TYPE_RON) - .bytes( - ron_api::to_string(ron_api::SetRecipeDifficulty { - recipe_id, - difficulty: ron_api::Difficulty::Hard, - }) - .unwrap() - .into(), - ) - .await; - response.assert_status_ok(); - - let response = server - .patch("/ron-api/recipe/language") - .add_cookie(cookie.clone()) - .add_header(http::header::CONTENT_TYPE, common::consts::MIME_TYPE_RON) - .bytes( - ron_api::to_string(ron_api::SetRecipeLanguage { - recipe_id, - lang: "fr".into(), - }) - .unwrap() - .into(), - ) - .await; - response.assert_status_ok(); - - let response = server - .patch("/ron-api/recipe/is_public") - .add_cookie(cookie.clone()) - .add_header(http::header::CONTENT_TYPE, common::consts::MIME_TYPE_RON) - .bytes( - ron_api::to_string(ron_api::SetRecipeIsPublic { - recipe_id, - is_public: true, - }) - .unwrap() - .into(), - ) - .await; - response.assert_status_ok(); + // TODO: Set other recipe fields. // Assert. let response = server @@ -385,112 +327,7 @@ async fn create_recipe_and_edit_it() -> Result<(), Box> { let element_servings = document.select(&servings_selector).next().unwrap(); assert_eq!(element_servings.attr("value").unwrap(), "42"); - let estimated_time_selector = Selector::parse("#input-estimated-time").unwrap(); - let element_estimated_time = document.select(&estimated_time_selector).next().unwrap(); - assert_eq!(element_estimated_time.attr("value").unwrap(), "420"); - - let selected_difficulty_selector = - Selector::parse("#select-difficulty option[selected]").unwrap(); - let element_selected_difficulty = document - .select(&selected_difficulty_selector) - .next() - .unwrap(); - assert_eq!(element_selected_difficulty.inner_html(), "Hard"); - - let selected_language_selector = Selector::parse("#select-language option[selected]").unwrap(); - let element_selected_language = document.select(&selected_language_selector).next().unwrap(); - assert_eq!(element_selected_language.inner_html(), "Français"); - - let is_public_selector = Selector::parse("#input-is-public").unwrap(); - let element_is_public = document.select(&is_public_selector).next().unwrap(); - assert!(element_is_public.attr("checked").is_some()); - - Ok(()) -} - -#[tokio::test] -async fn recipe_tags() -> Result<(), Box> { - // Arrange. - let state = utils::common_state().await?; - let user_id = utils::create_user( - &state.db_connection, - "president@spaceball.planet", - "12345678", - ) - .await?; - let token = utils::sign_in( - &state.db_connection, - "president@spaceball.planet", - "12345678", - ) - .await?; - let recipe_id = utils::create_recipe(&state.db_connection, user_id, "spaghetti").await?; - let server = TestServer::new(app::make_service(state))?; - let cookie = Cookie::new("auth_token", token); - - // Act. - // Tags list must be empty. - let response = server - .get("/ron-api/recipe/tags") - .add_cookie(cookie.clone()) - .add_query_param("id", recipe_id) - .await; - response.assert_status_ok(); - let tags: ron_api::Tags = ron::de::from_bytes(response.as_bytes()).unwrap(); - assert!(tags.tags.is_empty()); - - // Add some tags. - let response = server - .post("/ron-api/recipe/tags") - .add_cookie(cookie.clone()) - .add_header(http::header::CONTENT_TYPE, common::consts::MIME_TYPE_RON) - .bytes( - ron_api::to_string(ron_api::Tags { - recipe_id, - tags: vec!["ABC".into(), "xyz".into()], - }) - .unwrap() - .into(), - ) - .await; - response.assert_status_ok(); - - let response = server - .get("/ron-api/recipe/tags") - .add_cookie(cookie.clone()) - .add_query_param("id", recipe_id) - .await; - response.assert_status_ok(); - let tags: ron_api::Tags = ron::de::from_bytes(response.as_bytes()).unwrap(); - assert_eq!(tags.tags.len(), 2); - assert!(tags.tags.contains(&"abc".to_string())); // Tags are in lower case. - assert!(tags.tags.contains(&"xyz".to_string())); - - // Remove some tags. - let response = server - .delete("/ron-api/recipe/tags") - .add_cookie(cookie.clone()) - .add_header(http::header::CONTENT_TYPE, common::consts::MIME_TYPE_RON) - .bytes( - ron_api::to_string(ron_api::Tags { - recipe_id, - tags: vec!["XYZ".into(), "qwe".into()], - }) - .unwrap() - .into(), - ) - .await; - response.assert_status_ok(); - - let response = server - .get("/ron-api/recipe/tags") - .add_cookie(cookie.clone()) - .add_query_param("id", recipe_id) - .await; - response.assert_status_ok(); - let tags: ron_api::Tags = ron::de::from_bytes(response.as_bytes()).unwrap(); - assert_eq!(tags.tags.len(), 1); - assert_eq!(tags.tags[0], "abc".to_string()); + // dbg!(response); Ok(()) } diff --git a/backend/tests/utils/mod.rs b/backend/tests/utils/mod.rs index e38298b..3c209ab 100644 --- a/backend/tests/utils/mod.rs +++ b/backend/tests/utils/mod.rs @@ -13,7 +13,7 @@ pub async fn common_state_with_email_service( ) -> Result> { let db_connection = db::Connection::new_in_memory().await?; let config = config::Config::default(); - let log = log::Log::new_to_stdout_only_with_max_level(Some(tracing::Level::ERROR)); + let log = log::Log::new_no_log(); Ok(app::AppState { config, db_connection, diff --git a/common/src/ron_api.rs b/common/src/ron_api.rs index 175f48e..65f39f3 100644 --- a/common/src/ron_api.rs +++ b/common/src/ron_api.rs @@ -109,7 +109,7 @@ pub struct SetRecipeLanguage { } #[derive(Serialize, Deserialize, Clone)] -pub struct SetRecipeIsPublic { +pub struct SetIsPublic { pub recipe_id: i64, pub is_public: bool, } diff --git a/do.nu b/do.nu index 4127870..9f7b344 100755 --- a/do.nu +++ b/do.nu @@ -52,6 +52,7 @@ def "main deploy" [ } else { cargo build --release } + cd .. invoke_ssh [sudo systemctl stop recipes] copy_ssh ./target/($target)/release/recipes $destination diff --git a/frontend/src/pages/recipe_edit.rs b/frontend/src/pages/recipe_edit.rs index 4524e0d..623767b 100644 --- a/frontend/src/pages/recipe_edit.rs +++ b/frontend/src/pages/recipe_edit.rs @@ -231,7 +231,7 @@ pub fn setup_page(recipe_id: i64) { { let is_public: HtmlInputElement = by_id("input-is-public"); EventListener::new(&is_public.clone(), "input", move |_event| { - let body = ron_api::SetRecipeIsPublic { + let body = ron_api::SetIsPublic { recipe_id, is_public: is_public.checked(), }; diff --git a/frontend/src/request.rs b/frontend/src/request.rs index 68fe5a8..40c1005 100644 --- a/frontend/src/request.rs +++ b/frontend/src/request.rs @@ -59,7 +59,10 @@ where { let mut url = format!("/ron-api/{}?", api_name); serde_html_form::ser::push_to_string(&mut url, params).unwrap(); - let request_builder = method_fn(&url); + let request_builder = method_fn(&url).header( + CONTENT_TYPE, + common::consts::MIME_TYPE_RON.to_str().unwrap(), + ); send_req(request_builder.build()?).await }