Add tests recipe_view and user_edit
This commit is contained in:
parent
710a134966
commit
ee4c2038b8
3 changed files with 132 additions and 56 deletions
|
|
@ -13,13 +13,15 @@ use crate::{
|
||||||
#[derive(Debug, Display)]
|
#[derive(Debug, Display)]
|
||||||
pub enum SignUpResult {
|
pub enum SignUpResult {
|
||||||
UserAlreadyExists,
|
UserAlreadyExists,
|
||||||
UserCreatedWaitingForValidation(String), // Validation token.
|
/// Validation token.
|
||||||
|
UserCreatedWaitingForValidation(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Display)]
|
#[derive(Debug, Display)]
|
||||||
pub enum UpdateUserResult {
|
pub enum UpdateUserResult {
|
||||||
EmailAlreadyTaken,
|
EmailAlreadyTaken,
|
||||||
UserUpdatedWaitingForRevalidation(String), // Validation token.
|
/// Validation token.
|
||||||
|
UserUpdatedWaitingForRevalidation(String),
|
||||||
Ok,
|
Ok,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,7 +29,7 @@ pub enum UpdateUserResult {
|
||||||
pub enum ValidationResult {
|
pub enum ValidationResult {
|
||||||
UnknownUser,
|
UnknownUser,
|
||||||
ValidationExpired,
|
ValidationExpired,
|
||||||
/// Returns token and user id.
|
/// Returns login token and user id.
|
||||||
Ok(String, i64),
|
Ok(String, i64),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,7 +38,7 @@ pub enum SignInResult {
|
||||||
UserNotFound,
|
UserNotFound,
|
||||||
WrongPassword,
|
WrongPassword,
|
||||||
AccountNotValidated,
|
AccountNotValidated,
|
||||||
/// Returns token and user id.
|
/// Returns login token and user id.
|
||||||
Ok(String, i64),
|
Ok(String, i64),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
use axum_test::TestServer;
|
use axum_test::TestServer;
|
||||||
use scraper::Html;
|
use cookie::Cookie;
|
||||||
|
use scraper::{ElementRef, Html, Selector};
|
||||||
|
|
||||||
use recipes::{app, config, data::db, log};
|
use recipes::app;
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn homepage() -> Result<(), Box<dyn Error>> {
|
async fn homepage() -> Result<(), Box<dyn Error>> {
|
||||||
// Arrange.
|
// Arrange.
|
||||||
let state = common_state().await?;
|
let state = utils::common_state().await?;
|
||||||
let user_id = create_user(&state.db_connection, "president@spaceball.planet", "12345").await?;
|
let user_id =
|
||||||
let _recipe_id = create_recipe(&state.db_connection, user_id, "spaghetti").await?;
|
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))?;
|
let server = TestServer::new(app::make_service(state))?;
|
||||||
|
|
||||||
// Act.
|
// Act.
|
||||||
|
|
@ -18,61 +22,73 @@ async fn homepage() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
// Assert.
|
// Assert.
|
||||||
response.assert_status_ok();
|
response.assert_status_ok();
|
||||||
// TODO: check if 'spaghetti' is in the list.
|
|
||||||
let document = Html::parse_document(&response.text());
|
let document = Html::parse_document(&response.text());
|
||||||
assert_eq!(document.errors.len(), 0);
|
assert_eq!(document.errors.len(), 0);
|
||||||
|
|
||||||
// println!("{:?}", document.errors);
|
let first_recipe_title =
|
||||||
// println!("{:?}", response);
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_user(
|
#[tokio::test]
|
||||||
db_connection: &db::Connection,
|
async fn recipe_view() -> Result<(), Box<dyn Error>> {
|
||||||
email: &str,
|
// Arrange.
|
||||||
password: &str,
|
let state = utils::common_state().await?;
|
||||||
) -> Result<i64, Box<dyn Error>> {
|
let user_id =
|
||||||
if let db::user::SignUpResult::UserCreatedWaitingForValidation(token) = db_connection
|
utils::create_user(&state.db_connection, "president@spaceball.planet", "12345").await?;
|
||||||
.sign_up(email, password, chrono::Weekday::Mon)
|
let recipe_id = utils::create_recipe(&state.db_connection, user_id, "spaghetti").await?;
|
||||||
.await?
|
let server = TestServer::new(app::make_service(state))?;
|
||||||
{
|
|
||||||
if let db::user::ValidationResult::Ok(_, user_id) = db_connection
|
// Act.
|
||||||
.validation(
|
let response = server.get(&format!("/recipe/view/{}", recipe_id)).await;
|
||||||
&token,
|
|
||||||
chrono::Duration::hours(1),
|
// Assert.
|
||||||
"127.0.0.1",
|
response.assert_status_ok();
|
||||||
"Mozilla/5.0",
|
|
||||||
)
|
let document = Html::parse_document(&response.text());
|
||||||
.await?
|
assert_eq!(document.errors.len(), 0);
|
||||||
{
|
|
||||||
Ok(user_id)
|
let recipe_title = Selector::parse("#recipe-view .recipe-title").unwrap();
|
||||||
} else {
|
let elements: Vec<ElementRef> = document.select(&recipe_title).collect();
|
||||||
Err(Box::<dyn Error>::from("Unable to validate user"))
|
assert_eq!(elements.len(), 1);
|
||||||
}
|
assert_eq!(elements[0].inner_html(), "spaghetti");
|
||||||
} else {
|
|
||||||
Err(Box::<dyn Error>::from("Unable to sign up"))
|
Ok(())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_recipe(
|
#[tokio::test]
|
||||||
db_connection: &db::Connection,
|
async fn user_edit() -> Result<(), Box<dyn Error>> {
|
||||||
user_id: i64,
|
// Arrange.
|
||||||
title: &str,
|
let state = utils::common_state().await?;
|
||||||
) -> Result<i64, Box<dyn Error>> {
|
let _user_id =
|
||||||
let recipe_id = db_connection.create_recipe(user_id).await?;
|
utils::create_user(&state.db_connection, "president@spaceball.planet", "12345").await?;
|
||||||
db_connection.set_recipe_title(recipe_id, title).await?;
|
let token = utils::sign_in(&state.db_connection, "president@spaceball.planet", "12345").await?;
|
||||||
db_connection.set_recipe_is_public(recipe_id, true).await?;
|
let server = TestServer::new(app::make_service(state))?;
|
||||||
Ok(recipe_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn common_state() -> Result<app::AppState, Box<dyn Error>> {
|
// Act.
|
||||||
let db_connection = db::Connection::new_in_memory().await?;
|
let response = server
|
||||||
let config = config::Config::default();
|
.get("/user/edit")
|
||||||
let log = log::Log::new_stdout_only();
|
.add_cookie(Cookie::new("auth_token", token))
|
||||||
Ok(app::AppState {
|
.await;
|
||||||
config,
|
|
||||||
db_connection,
|
// Assert.
|
||||||
log,
|
response.assert_status_ok();
|
||||||
})
|
|
||||||
|
let document = Html::parse_document(&response.text());
|
||||||
|
assert_eq!(document.errors.len(), 0);
|
||||||
|
|
||||||
|
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(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
58
backend/tests/utils.rs
Normal file
58
backend/tests/utils.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
use recipes::{app, config, data::db, log};
|
||||||
|
|
||||||
|
pub async fn common_state() -> Result<app::AppState, Box<dyn Error>> {
|
||||||
|
let db_connection = db::Connection::new_in_memory().await?;
|
||||||
|
let config = config::Config::default();
|
||||||
|
let log = log::Log::new_stdout_only();
|
||||||
|
Ok(app::AppState {
|
||||||
|
config,
|
||||||
|
db_connection,
|
||||||
|
log,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_user(
|
||||||
|
db_connection: &db::Connection,
|
||||||
|
email: &str,
|
||||||
|
password: &str,
|
||||||
|
) -> Result<i64, Box<dyn Error>> {
|
||||||
|
if let db::user::SignUpResult::UserCreatedWaitingForValidation(token) = db_connection
|
||||||
|
.sign_up(email, password, chrono::Weekday::Mon)
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
if let db::user::ValidationResult::Ok(_, user_id) = db_connection
|
||||||
|
.validation(&token, chrono::Duration::hours(1), "", "")
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
Ok(user_id)
|
||||||
|
} else {
|
||||||
|
Err(Box::<dyn Error>::from("Unable to validate user"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(Box::<dyn Error>::from("Unable to sign up"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn sign_in(
|
||||||
|
db_connection: &db::Connection,
|
||||||
|
email: &str,
|
||||||
|
password: &str,
|
||||||
|
) -> Result<String, Box<dyn Error>> {
|
||||||
|
match db_connection.sign_in(email, password, "", "").await? {
|
||||||
|
db::user::SignInResult::Ok(token, _) => Ok(token),
|
||||||
|
_ => Err(Box::<dyn Error>::from("Unable to sign in")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_recipe(
|
||||||
|
db_connection: &db::Connection,
|
||||||
|
user_id: i64,
|
||||||
|
title: &str,
|
||||||
|
) -> Result<i64, Box<dyn Error>> {
|
||||||
|
let recipe_id = db_connection.create_recipe(user_id).await?;
|
||||||
|
db_connection.set_recipe_title(recipe_id, title).await?;
|
||||||
|
db_connection.set_recipe_is_public(recipe_id, true).await?;
|
||||||
|
Ok(recipe_id)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue