226 lines
6.6 KiB
Rust
226 lines
6.6 KiB
Rust
use std::{error::Error, sync::Arc};
|
|
|
|
use axum_test::TestServer;
|
|
use cookie::Cookie;
|
|
use scraper::{ElementRef, Html, Selector};
|
|
|
|
use recipes::{app, email};
|
|
use serde::Serialize;
|
|
|
|
mod utils;
|
|
|
|
#[tokio::test]
|
|
async fn homepage() -> Result<(), Box<dyn Error>> {
|
|
// Arrange.
|
|
let state = utils::common_state().await?;
|
|
let user_id =
|
|
utils::create_user(&state.db_connection, "president@spaceball.planet", "12345").await?;
|
|
let _recipe_id = utils::create_recipe(&state.db_connection, user_id, "spaghetti").await?;
|
|
let server = TestServer::new(app::make_service(state))?;
|
|
|
|
// Act.
|
|
let response = server.get("/").await;
|
|
|
|
// Assert.
|
|
response.assert_status_ok();
|
|
|
|
let document = Html::parse_document(&response.text());
|
|
if !document.errors.is_empty() {
|
|
panic!("{:?}", document.errors);
|
|
}
|
|
|
|
let first_recipe_title =
|
|
Selector::parse("#recipes-list .recipes-list-public .recipe-item").unwrap();
|
|
let elements: Vec<ElementRef> = document.select(&first_recipe_title).collect();
|
|
assert_eq!(elements.len(), 1);
|
|
assert_eq!(elements[0].inner_html(), "spaghetti");
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn recipe_view() -> Result<(), Box<dyn Error>> {
|
|
// Arrange.
|
|
let state = utils::common_state().await?;
|
|
let user_id =
|
|
utils::create_user(&state.db_connection, "president@spaceball.planet", "12345").await?;
|
|
let recipe_id = utils::create_recipe(&state.db_connection, user_id, "spaghetti").await?;
|
|
let server = TestServer::new(app::make_service(state))?;
|
|
|
|
// Act.
|
|
let response = server.get(&format!("/recipe/view/{}", recipe_id)).await;
|
|
|
|
// Assert.
|
|
response.assert_status_ok();
|
|
|
|
let document = Html::parse_document(&response.text());
|
|
if !document.errors.is_empty() {
|
|
panic!("{:?}", document.errors);
|
|
}
|
|
|
|
let recipe_title = Selector::parse("#recipe-view .recipe-title").unwrap();
|
|
let elements: Vec<ElementRef> = document.select(&recipe_title).collect();
|
|
assert_eq!(elements.len(), 1);
|
|
assert_eq!(elements[0].inner_html(), "spaghetti");
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn user_edit() -> Result<(), Box<dyn Error>> {
|
|
// Arrange.
|
|
let state = utils::common_state().await?;
|
|
let _user_id =
|
|
utils::create_user(&state.db_connection, "president@spaceball.planet", "12345").await?;
|
|
let token = utils::sign_in(&state.db_connection, "president@spaceball.planet", "12345").await?;
|
|
let server = TestServer::new(app::make_service(state))?;
|
|
|
|
// Act.
|
|
let response = server
|
|
.get("/user/edit")
|
|
.add_cookie(Cookie::new("auth_token", token))
|
|
.await;
|
|
|
|
// Assert.
|
|
response.assert_status_ok();
|
|
|
|
let document = Html::parse_document(&response.text());
|
|
if !document.errors.is_empty() {
|
|
panic!("{:?}", document.errors);
|
|
}
|
|
|
|
let user_email = Selector::parse("#input-email").unwrap();
|
|
let elements: Vec<ElementRef> = document.select(&user_email).collect();
|
|
assert_eq!(elements.len(), 1);
|
|
assert_eq!(
|
|
elements[0].attr("value").unwrap(),
|
|
"president@spaceball.planet"
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[derive(Serialize, Debug)]
|
|
pub struct SignUpFormData {
|
|
email: String,
|
|
password_1: String,
|
|
password_2: String,
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn sign_up() -> Result<(), Box<dyn Error>> {
|
|
use scanf::sscanf;
|
|
use std::{cell::RefCell, rc::Rc};
|
|
|
|
// Arrange.
|
|
let validation_url: Rc<RefCell<String>> = Rc::new(RefCell::new(String::new()));
|
|
|
|
let validation_url_clone = validation_url.clone();
|
|
let mut mock_email_service = utils::mock_email::MockEmailService::new();
|
|
mock_email_service
|
|
.expect_send_email()
|
|
.withf_st(move |email, _title, message| {
|
|
sscanf!(
|
|
message,
|
|
"Follow this link to confirm your inscription, http://127.0.0.1:8000{}",
|
|
*validation_url_clone.borrow_mut()
|
|
)
|
|
.unwrap();
|
|
println!("{}", message);
|
|
email == "president@spaceball.planet"
|
|
})
|
|
.times(1)
|
|
.returning(|_email, _title, _message| Ok(()));
|
|
|
|
let state = utils::common_state_with_email_service(Arc::new(mock_email_service)).await?;
|
|
let server = TestServer::new(app::make_service(state))?;
|
|
|
|
let tr = recipes::translation::Tr::new("en");
|
|
|
|
// Sign up page.
|
|
{
|
|
// Act.
|
|
let response = server
|
|
.post("/signup")
|
|
.form(&SignUpFormData {
|
|
email: "president@spaceball.planet".into(),
|
|
password_1: "12345678".into(),
|
|
password_2: "12345678".into(),
|
|
})
|
|
.await;
|
|
|
|
// Assert.
|
|
response.assert_status_ok();
|
|
let document = Html::parse_document(&response.text());
|
|
if !document.errors.is_empty() {
|
|
panic!("{:?}", document.errors);
|
|
}
|
|
|
|
let message_selector = Selector::parse("#message").unwrap();
|
|
let element = document.select(&message_selector).next().unwrap();
|
|
assert_eq!(
|
|
element.inner_html(),
|
|
tr.t(common::translation::Sentence::SignUpEmailSent)
|
|
);
|
|
}
|
|
|
|
// Validation page.
|
|
{
|
|
// Act.
|
|
let response = server.get(&validation_url.borrow());
|
|
let response = response.await;
|
|
|
|
// Assert.
|
|
response.assert_status_ok();
|
|
let document = Html::parse_document(&response.text());
|
|
if !document.errors.is_empty() {
|
|
panic!("{:?}", document.errors);
|
|
}
|
|
|
|
let message_selector = Selector::parse("#message").unwrap();
|
|
let element = document.select(&message_selector).next().unwrap();
|
|
assert_eq!(
|
|
element.inner_html(),
|
|
tr.t(common::translation::Sentence::SignUpEmailValidationSuccess)
|
|
);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[derive(Serialize, Debug)]
|
|
pub struct SignInFormData {
|
|
email: String,
|
|
password: String,
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn sign_in() -> 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 server = TestServer::new(app::make_service(state))?;
|
|
|
|
// Act.
|
|
let response = server
|
|
.post("/signin")
|
|
.form(&SignInFormData {
|
|
email: "president@spaceball.planet".into(),
|
|
password: "12345678".into(),
|
|
})
|
|
.await;
|
|
|
|
// Assert.
|
|
response.assert_status_see_other(); // Redirection after successful sign in.
|
|
response.assert_text("");
|
|
// English is the default language.
|
|
response.assert_header("location", "/en/?user_message=16&user_message_icon=0");
|
|
dbg!(&response);
|
|
|
|
Ok(())
|
|
}
|