zero-to-axum/tests/auth.rs
azdle ef3cc5a11b only confirmed users can login
Also uses a forked version of `maik` that supports getting mail bodies.
2025-07-25 12:20:02 -05:00

112 lines
2.7 KiB
Rust

pub mod fixture;
use fixture::TestServer;
use anyhow::Result;
use regex::Regex;
use test_log::test as traced;
#[traced(tokio::test)]
async fn login_succeeds_with_valid_credentials() -> Result<()> {
let server = TestServer::spawn().await;
let mut client = server.browser_client();
client.get_csrf_token().await?;
// Signup
let resp = client
.post("/auth/signup")
.csrf_form(&[("email", "admin@example.com"), ("password", "hunter2")])
.send()
.await?;
assert_eq!(resp.status(), 200, "signup succeeds");
let mail = server.mock_smtp_server.receive_mail().expect("recv mail");
let link_regex = Regex::new(r"/auth/confirm\?token\=([a-zA-Z0-9]+)")?;
let confirm_link = link_regex
.find(&mail.body)
.expect("find link in body")
.as_str();
println!("link: {confirm_link}");
// Confirm Account
let resp = client
.post(confirm_link)
.csrf_form::<[(&str, &str); 0]>(&[])
.send()
.await?;
assert_eq!(resp.status(), 200, "confirm succeeds");
// Login
let resp = client
.post("/auth/login")
.csrf_form(&[("email", "admin@example.com"), ("password", "hunter2")])
.send()
.await?;
assert_eq!(resp.status(), 200, "login succeeds");
// Logout
let resp = client
.post("/auth/logout")
.csrf_form::<[(&str, &str)]>(&[])
.send()
.await?;
assert_eq!(resp.status(), 200, "logout succeeds");
server.shutdown().await
}
#[traced(tokio::test)]
async fn login_fails_with_invalid_credentials() -> Result<()> {
let server = TestServer::spawn().await;
let mut client = server.browser_client();
client.get_csrf_token().await?;
// Signup
let resp = client
.post("/auth/signup")
.csrf_form(&[("email", "admin@example.com"), ("password", "hunter2")])
.send()
.await?;
assert_eq!(resp.status(), 200, "signup succeeds");
// Login
let resp = client
.post("/auth/login")
.csrf_form(&[("email", "admin@example.com"), ("password", "hunter3")])
.send()
.await?;
assert_eq!(
resp.status(),
401,
"login didn't reject invalid credentials"
);
server.shutdown().await
}
#[traced(tokio::test)]
async fn login_rejects_missing_credentials() -> Result<()> {
let server = TestServer::spawn().await;
let mut client = server.browser_client();
client.get_csrf_token().await?;
let resp = client
.post("/auth/login")
.csrf_form(&[("email", ""), ("password", "")])
.send()
.await?;
assert_eq!(
resp.status(),
401,
"login didn't reject missing credentials"
);
server.shutdown().await
}