More login testing, added reference user factory fn.
This commit is contained in:
parent
569b19e837
commit
30169733a0
3 changed files with 64 additions and 20 deletions
|
@ -15,8 +15,8 @@ use uuid::Uuid;
|
||||||
|
|
||||||
use crate::User;
|
use crate::User;
|
||||||
|
|
||||||
const MAX_CONNS: u32 = 100;
|
const MAX_CONNS: u32 = 200;
|
||||||
const MIN_CONNS: u32 = 10;
|
const MIN_CONNS: u32 = 5;
|
||||||
const TIMEOUT: u64 = 11;
|
const TIMEOUT: u64 = 11;
|
||||||
const SESSION_TTL: Duration = Duration::from_secs((365.2422 * 24. * 3600.0) as u64);
|
const SESSION_TTL: Duration = Duration::from_secs((365.2422 * 24. * 3600.0) as u64);
|
||||||
|
|
||||||
|
@ -34,6 +34,9 @@ pub async fn get_pool() -> SqlitePool {
|
||||||
use rand_core::RngCore;
|
use rand_core::RngCore;
|
||||||
let mut rng = rand_core::OsRng;
|
let mut rng = rand_core::OsRng;
|
||||||
let id = rng.next_u64();
|
let id = rng.next_u64();
|
||||||
|
// see https://www.sqlite.org/inmemorydb.html for meaning of the string;
|
||||||
|
// it allows each separate test to have its own dedicated memory-backed db that
|
||||||
|
// will live as long as the whole process
|
||||||
format!("file:testdb-{id}?mode=memory&cache=shared")
|
format!("file:testdb-{id}?mode=memory&cache=shared")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -51,7 +54,7 @@ pub async fn get_pool() -> SqlitePool {
|
||||||
let pool = SqlitePoolOptions::new()
|
let pool = SqlitePoolOptions::new()
|
||||||
.max_connections(MAX_CONNS)
|
.max_connections(MAX_CONNS)
|
||||||
.min_connections(MIN_CONNS)
|
.min_connections(MIN_CONNS)
|
||||||
.idle_timeout(Some(Duration::from_secs(10)))
|
.idle_timeout(Some(Duration::from_secs(30)))
|
||||||
.max_lifetime(Some(Duration::from_secs(3600)))
|
.max_lifetime(Some(Duration::from_secs(3600)))
|
||||||
.connect_with(conn_opts)
|
.connect_with(conn_opts)
|
||||||
.await
|
.await
|
||||||
|
|
73
src/login.rs
73
src/login.rs
|
@ -103,32 +103,40 @@ pub async fn post_logout(mut auth: AuthContext) -> impl IntoResponse {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use axum::body::Bytes;
|
use axum::body::Bytes;
|
||||||
use axum_test::TestServer;
|
use axum_test::TestServer;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db,
|
db,
|
||||||
signup::create_user,
|
signup::create_user,
|
||||||
templates::{LoginGet, LogoutGet, LogoutPost},
|
templates::{Index, LoginGet, LogoutGet, LogoutPost},
|
||||||
|
User,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn get_user() -> User {
|
||||||
|
User {
|
||||||
|
username: "test_user".to_string(),
|
||||||
|
pwhash: "$argon2id$v=19$m=19456,t=2,p=1$GWsCH1w5RYaP9WWmq+xw0g$hmOEqC+MU+vnEk3bOdkoE+z01mOmmOeX08XyPyjqua8".to_string(),
|
||||||
|
id: Uuid::nil(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn tserver() -> TestServer {
|
async fn tserver() -> TestServer {
|
||||||
let pool = db::get_pool().await;
|
let pool = db::get_pool().await;
|
||||||
let secret = [0u8; 64];
|
let secret = [0u8; 64];
|
||||||
|
|
||||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
let user = get_user();
|
||||||
|
sqlx::query(crate::signup::CREATE_QUERY)
|
||||||
let _user = create_user(
|
.bind(user.id)
|
||||||
"test_user",
|
.bind(&user.username)
|
||||||
&Some("Test User".to_string()),
|
.bind(&user.displayname)
|
||||||
&Some("mail@email".to_string()),
|
.bind(&user.email)
|
||||||
"aaaa".as_bytes(),
|
.bind(&user.pwhash)
|
||||||
&pool,
|
.execute(&pool)
|
||||||
)
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let r = sqlx::query("select count(*) from witches")
|
let r = sqlx::query("select count(*) from witches")
|
||||||
.fetch_one(&pool)
|
.fetch_one(&pool)
|
||||||
|
@ -152,7 +160,7 @@ mod test {
|
||||||
async fn post_login_success() {
|
async fn post_login_success() {
|
||||||
let s = tserver().await;
|
let s = tserver().await;
|
||||||
|
|
||||||
let form = "username=test_user&password=aaaa".to_string();
|
let form = "username=test_user&password=a".to_string();
|
||||||
let bytes = form.as_bytes();
|
let bytes = form.as_bytes();
|
||||||
let body = Bytes::copy_from_slice(bytes);
|
let body = Bytes::copy_from_slice(bytes);
|
||||||
|
|
||||||
|
@ -182,6 +190,23 @@ mod test {
|
||||||
assert_eq!(resp.status_code(), 200);
|
assert_eq!(resp.status_code(), 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn post_login_bad_password() {
|
||||||
|
let s = tserver().await;
|
||||||
|
|
||||||
|
let form = "username=test_user&password=bbbb".to_string();
|
||||||
|
let bytes = form.as_bytes();
|
||||||
|
let body = Bytes::copy_from_slice(bytes);
|
||||||
|
|
||||||
|
let resp = s
|
||||||
|
.post("/login")
|
||||||
|
.expect_success()
|
||||||
|
.content_type("application/x-www-form-urlencoded")
|
||||||
|
.bytes(body)
|
||||||
|
.await;
|
||||||
|
assert_eq!(resp.status_code(), 200);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn get_logout() {
|
async fn get_logout() {
|
||||||
let s = tserver().await;
|
let s = tserver().await;
|
||||||
|
@ -191,7 +216,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn post_logout() {
|
async fn post_logout_not_logged_in() {
|
||||||
let s = tserver().await;
|
let s = tserver().await;
|
||||||
let resp = s.post("/logout").await;
|
let resp = s.post("/logout").await;
|
||||||
resp.assert_status_ok();
|
resp.assert_status_ok();
|
||||||
|
@ -199,4 +224,20 @@ mod test {
|
||||||
let default = LogoutPost.to_string();
|
let default = LogoutPost.to_string();
|
||||||
assert_eq!(body, &default);
|
assert_eq!(body, &default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn post_logout_logged_in() {
|
||||||
|
let s = tserver().await;
|
||||||
|
// let resp = s
|
||||||
|
// .post("/login")
|
||||||
|
// .content_type("x-www-form-urlencoded")
|
||||||
|
// .text("username=test_user&password=a")
|
||||||
|
// .await;
|
||||||
|
|
||||||
|
let resp = s.post("/logout").await;
|
||||||
|
resp.assert_status_ok();
|
||||||
|
let body = std::str::from_utf8(resp.bytes()).unwrap();
|
||||||
|
let default = LogoutPost.to_string();
|
||||||
|
assert_eq!(body, &default);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{templates::CreateUser, User};
|
use crate::{templates::CreateUser, User};
|
||||||
|
|
||||||
const CREATE_QUERY: &str =
|
pub(crate) const CREATE_QUERY: &str =
|
||||||
"insert into witches (id, username, displayname, email, pwhash) values ($1, $2, $3, $4, $5)";
|
"insert into witches (id, username, displayname, email, pwhash) values ($1, $2, $3, $4, $5)";
|
||||||
const ID_QUERY: &str = "select * from witches where id = $1";
|
const ID_QUERY: &str = "select * from witches where id = $1";
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue