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]]
name = "clap"
version = "4.5.37"
version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
dependencies = [
"clap_builder",
"clap_derive",
@ -550,9 +550,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.37"
version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
dependencies = [
"anstream",
"anstyle",
@ -640,6 +640,35 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "cookie"
version = "0.18.1"
@ -1024,7 +1053,6 @@ dependencies = [
"futures",
"gloo",
"ron",
"scanf",
"serde",
"serde_html_form",
"thiserror 2.0.12",
@ -1681,9 +1709,9 @@ dependencies = [
[[package]]
name = "lettre"
version = "0.11.15"
version = "0.11.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "759bc2b8eabb6a30b235d6f716f7f36479f4b38cbe65b8747aefee51f89e8437"
checksum = "87ffd14fa289730e3ad68edefdc31f603d56fe716ec38f2076bb7410e09147c2"
dependencies = [
"async-trait",
"base64",
@ -1705,7 +1733,7 @@ dependencies = [
"tokio",
"tokio-rustls",
"url",
"webpki-roots 0.26.11",
"webpki-roots",
]
[[package]]
@ -2400,10 +2428,10 @@ dependencies = [
"rand 0.9.1",
"rand_core 0.9.3",
"ron",
"scanf",
"scraper",
"serde",
"sqlx",
"sscanf",
"strum",
"thiserror 2.0.12",
"tokio",
@ -2619,15 +2647,6 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "scanf"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db2388de1e65f8545db637b467e3a8ed3c85357ff098c16aa4e9493561e49d03"
dependencies = [
"nom",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -3062,6 +3081,33 @@ dependencies = [
"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]]
name = "stable_deref_trait"
version = "1.2.0"
@ -3204,9 +3250,9 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.19.1"
version = "3.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
dependencies = [
"fastrand",
"getrandom 0.3.3",
@ -3429,9 +3475,9 @@ dependencies = [
[[package]]
name = "tower-http"
version = "0.6.2"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697"
checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e"
dependencies = [
"bitflags 2.9.0",
"bytes",
@ -3590,10 +3636,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
[[package]]
name = "unicode-width"
version = "0.1.14"
name = "unicode-segmentation"
version = "1.12.0"
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]]
name = "unicode_categories"
@ -3794,15 +3852,6 @@ dependencies = [
"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]]
name = "webpki-roots"
version = "1.0.0"

View file

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

View file

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

View file

@ -1,11 +1,14 @@
use std::{error::Error, sync::Arc};
use axum::http;
use axum_test::TestServer;
use common::ron_api;
use cookie::Cookie;
use scraper::{ElementRef, Html, Selector};
use serde::Serialize;
use sscanf::sscanf;
use recipes::{app, email};
use serde::Serialize;
mod utils;
@ -109,7 +112,6 @@ pub struct SignUpFormData {
#[tokio::test]
async fn sign_up() -> Result<(), Box<dyn Error>> {
use scanf::sscanf;
use std::{cell::RefCell, rc::Rc};
// Arrange.
@ -124,12 +126,12 @@ async fn sign_up() -> Result<(), Box<dyn Error>> {
})
.times(1)
.returning_st(move |_email_sender, _email_receiver, _title, message| {
sscanf!(
let url = sscanf!(
message,
"Follow this link to confirm your inscription, http://127.0.0.1:8000{}",
*validation_url_clone.borrow_mut()
"Follow this link to confirm your inscription, http://127.0.0.1:8000{String}"
)
.unwrap();
*validation_url_clone.borrow_mut() = url;
Ok(())
});
@ -219,8 +221,113 @@ async fn sign_in() -> Result<(), Box<dyn Error>> {
// Assert.
response.assert_status_see_other(); // Redirection after successful sign in.
response.assert_text("");
// English is the default language.
response.assert_header("location", "/?user_message=16&user_message_icon=0");
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(())
}