Add a HTTP test for recipe edit (WIP)

This commit is contained in:
Greg Burri 2025-05-14 00:30:40 +02:00
parent a4e321e66d
commit 9c368e82ab
4 changed files with 197 additions and 42 deletions

117
Cargo.lock generated
View file

@ -540,9 +540,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.37" version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@ -550,9 +550,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.37" version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@ -640,6 +640,35 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "const_format"
version = "0.2.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c990efc7a285731f9a4378d81aff2f0e85a2c8781a05ef0f8baa8dac54d0ff48"
dependencies = [
"const_format_proc_macros",
]
[[package]]
name = "const_format_proc_macros"
version = "0.2.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e026b6ce194a874cb9cf32cd5772d1ef9767cc8fcb5765948d74f37a9d8b2bf6"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "convert_case"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
dependencies = [
"unicode-segmentation",
]
[[package]] [[package]]
name = "cookie" name = "cookie"
version = "0.18.1" version = "0.18.1"
@ -1024,7 +1053,6 @@ dependencies = [
"futures", "futures",
"gloo", "gloo",
"ron", "ron",
"scanf",
"serde", "serde",
"serde_html_form", "serde_html_form",
"thiserror 2.0.12", "thiserror 2.0.12",
@ -1681,9 +1709,9 @@ dependencies = [
[[package]] [[package]]
name = "lettre" name = "lettre"
version = "0.11.15" version = "0.11.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "759bc2b8eabb6a30b235d6f716f7f36479f4b38cbe65b8747aefee51f89e8437" checksum = "87ffd14fa289730e3ad68edefdc31f603d56fe716ec38f2076bb7410e09147c2"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"base64", "base64",
@ -1705,7 +1733,7 @@ dependencies = [
"tokio", "tokio",
"tokio-rustls", "tokio-rustls",
"url", "url",
"webpki-roots 0.26.11", "webpki-roots",
] ]
[[package]] [[package]]
@ -2400,10 +2428,10 @@ dependencies = [
"rand 0.9.1", "rand 0.9.1",
"rand_core 0.9.3", "rand_core 0.9.3",
"ron", "ron",
"scanf",
"scraper", "scraper",
"serde", "serde",
"sqlx", "sqlx",
"sscanf",
"strum", "strum",
"thiserror 2.0.12", "thiserror 2.0.12",
"tokio", "tokio",
@ -2619,15 +2647,6 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "scanf"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db2388de1e65f8545db637b467e3a8ed3c85357ff098c16aa4e9493561e49d03"
dependencies = [
"nom",
]
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
@ -3062,6 +3081,33 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "sscanf"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbd1009b536a04035c8ffcf967496c7726c6b4971c9939b20ad085ac9377d4f0"
dependencies = [
"const_format",
"lazy_static",
"regex",
"sscanf_macro",
]
[[package]]
name = "sscanf_macro"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cffce0630a574bbcda2476cf733363c7e077001c386b0dea87b77eb397ca1a37"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"regex-syntax 0.6.29",
"strsim",
"syn",
"unicode-width",
]
[[package]] [[package]]
name = "stable_deref_trait" name = "stable_deref_trait"
version = "1.2.0" version = "1.2.0"
@ -3204,9 +3250,9 @@ dependencies = [
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.19.1" version = "3.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
dependencies = [ dependencies = [
"fastrand", "fastrand",
"getrandom 0.3.3", "getrandom 0.3.3",
@ -3429,9 +3475,9 @@ dependencies = [
[[package]] [[package]]
name = "tower-http" name = "tower-http"
version = "0.6.2" version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697" checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e"
dependencies = [ dependencies = [
"bitflags 2.9.0", "bitflags 2.9.0",
"bytes", "bytes",
@ -3590,10 +3636,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
[[package]] [[package]]
name = "unicode-width" name = "unicode-segmentation"
version = "0.1.14" version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]]
name = "unicode-width"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
[[package]]
name = "unicode-xid"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]] [[package]]
name = "unicode_categories" name = "unicode_categories"
@ -3794,15 +3852,6 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "webpki-roots"
version = "0.26.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
dependencies = [
"webpki-roots 1.0.0",
]
[[package]] [[package]]
name = "webpki-roots" name = "webpki-roots"
version = "1.0.0" version = "1.0.0"

View file

@ -56,4 +56,4 @@ axum-test = "17"
cookie = "0.18" cookie = "0.18"
scraper = "0.23" scraper = "0.23"
mockall = "0.13" mockall = "0.13"
scanf = "1.2" sscanf = "0.4"

View file

@ -13,7 +13,6 @@ use crate::{
data::db, data::db,
html_templates::*, html_templates::*,
log::Log, log::Log,
ron_utils,
translation::Sentence, translation::Sentence,
}; };

View file

@ -1,11 +1,14 @@
use std::{error::Error, sync::Arc}; use std::{error::Error, sync::Arc};
use axum::http;
use axum_test::TestServer; use axum_test::TestServer;
use common::ron_api;
use cookie::Cookie; use cookie::Cookie;
use scraper::{ElementRef, Html, Selector}; use scraper::{ElementRef, Html, Selector};
use serde::Serialize;
use sscanf::sscanf;
use recipes::{app, email}; use recipes::{app, email};
use serde::Serialize;
mod utils; mod utils;
@ -109,7 +112,6 @@ pub struct SignUpFormData {
#[tokio::test] #[tokio::test]
async fn sign_up() -> Result<(), Box<dyn Error>> { async fn sign_up() -> Result<(), Box<dyn Error>> {
use scanf::sscanf;
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
// Arrange. // Arrange.
@ -124,12 +126,12 @@ async fn sign_up() -> Result<(), Box<dyn Error>> {
}) })
.times(1) .times(1)
.returning_st(move |_email_sender, _email_receiver, _title, message| { .returning_st(move |_email_sender, _email_receiver, _title, message| {
sscanf!( let url = sscanf!(
message, message,
"Follow this link to confirm your inscription, http://127.0.0.1:8000{}", "Follow this link to confirm your inscription, http://127.0.0.1:8000{String}"
*validation_url_clone.borrow_mut()
) )
.unwrap(); .unwrap();
*validation_url_clone.borrow_mut() = url;
Ok(()) Ok(())
}); });
@ -219,8 +221,113 @@ async fn sign_in() -> Result<(), Box<dyn Error>> {
// Assert. // Assert.
response.assert_status_see_other(); // Redirection after successful sign in. response.assert_status_see_other(); // Redirection after successful sign in.
response.assert_text(""); response.assert_text("");
// English is the default language.
response.assert_header("location", "/?user_message=16&user_message_icon=0"); response.assert_header("location", "/?user_message=16&user_message_icon=0");
Ok(()) Ok(())
} }
#[tokio::test]
async fn create_recipe_and_edit_it() -> Result<(), Box<dyn Error>> {
// 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 server = TestServer::new(app::make_service(state))?;
// Act.
let cookie = Cookie::new("auth_token", token);
let response = server.get("/recipe/new").add_cookie(cookie.clone()).await;
response.assert_status_see_other();
let location = response.header("location").to_str().unwrap().to_string();
let recipe_id = sscanf!(&location, "/en/recipe/edit/{i64}").unwrap();
let response = server.get(&location).add_cookie(cookie.clone()).await;
response.assert_status_ok();
let response = server
.patch("/ron-api/recipe/title")
.add_cookie(cookie.clone())
.add_header(http::header::CONTENT_TYPE, common::consts::MIME_TYPE_RON)
.bytes(
ron_api::to_string(ron_api::SetRecipeTitle {
recipe_id,
title: "AAA".into(),
})
.unwrap()
.into(),
)
.await;
response.assert_status_ok();
let response = server
.patch("/ron-api/recipe/description")
.add_cookie(cookie.clone())
.add_header(http::header::CONTENT_TYPE, common::consts::MIME_TYPE_RON)
.bytes(
ron_api::to_string(ron_api::SetRecipeDescription {
recipe_id,
description: "BBB".into(),
})
.unwrap()
.into(),
)
.await;
response.assert_status_ok();
let response = server
.patch("/ron-api/recipe/servings")
.add_cookie(cookie.clone())
.add_header(http::header::CONTENT_TYPE, common::consts::MIME_TYPE_RON)
.bytes(
ron_api::to_string(ron_api::SetRecipeServings {
recipe_id,
servings: Some(42),
})
.unwrap()
.into(),
)
.await;
response.assert_status_ok();
// TODO: Set other recipe fields.
// Assert.
let response = server
.get(&format!("/recipe/edit/{}", recipe_id))
.add_cookie(cookie.clone())
.await;
response.assert_status_ok();
let document = Html::parse_document(&response.text());
if !document.errors.is_empty() {
panic!("{:?}", document.errors);
}
let title_selector = Selector::parse("#input-title").unwrap();
let element_title = document.select(&title_selector).next().unwrap();
assert_eq!(element_title.attr("value").unwrap(), "AAA");
let description_selector = Selector::parse("#text-area-description").unwrap();
let element_description = document.select(&description_selector).next().unwrap();
assert_eq!(element_description.inner_html(), "BBB");
let servings_selector = Selector::parse("#input-servings").unwrap();
let element_servings = document.select(&servings_selector).next().unwrap();
assert_eq!(element_servings.attr("value").unwrap(), "42");
// dbg!(response);
Ok(())
}