fix and chore: refactor tests to minimize initializing DB connections

SUMMARY
    The test suite was spinning up way too many database connections that what's
    strictly needed and so the test suite was failing with[0]:
	code: "53300", message: "sorry, too many clients already"

EXPERIMENTS
    Tried sharing database connection pool across all tests with
    async_once[0] but faced:
	- IO errors
	    The connections were probably getting dropped in between tests
	- actix Actor errors
	    The actor was probably not getting initialized before a
	    a reference to the async_once initialized app
	    context(crate::data::Data) is retrieved and used

FIX
    crate::tests was spinning up an App context
    instance(crate::data::Data) for most utility functions, which was
    unnecessarily excessive.

    Each test now creates an instance of the application context at the
    beginning and shared a reference with all test utility functions. So
    number of database connections/app context instance = number of unit
    tests.

[0]: permanently fixes #22
[1]: https://docs.rs/async_once/latest/async_once/
This commit is contained in:
realaravinth 2022-05-14 12:55:56 +05:30
parent 176df3c7a7
commit a971d4209d
No known key found for this signature in database
GPG key ID: AD9F0F08E855ED88
24 changed files with 243 additions and 274 deletions

42
Cargo.lock generated
View file

@ -1727,25 +1727,14 @@ dependencies = [
[[package]]
name = "mio"
version = "0.8.2"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
dependencies = [
"libc",
"log",
"miow",
"ntapi",
"wasi 0.11.0+wasi-snapshot-preview1",
"winapi",
]
[[package]]
name = "miow"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
dependencies = [
"winapi",
"windows-sys",
]
[[package]]
@ -1793,15 +1782,6 @@ dependencies = [
"minimal-lexical",
]
[[package]]
name = "ntapi"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
dependencies = [
"winapi",
]
[[package]]
name = "num"
version = "0.4.0"
@ -2892,9 +2872,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
version = "1.0.92"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ff7c592601f11445996a06f8ad0c27f094a58857c2f89e97974ab9235b92c52"
checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a"
dependencies = [
"proc-macro2",
"quote",
@ -3028,9 +3008,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.18.1"
version = "1.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dce653fb475565de9f6fb0614b28bca8df2c430c0cf84bcd9c843f15de5414cc"
checksum = "4903bf0427cf68dddd5aa6a93220756f8be0c34fcfa9f5e6191e103e15a31395"
dependencies = [
"bytes",
"libc",
@ -3491,18 +3471,18 @@ dependencies = [
[[package]]
name = "zstd"
version = "0.10.0+zstd.1.5.2"
version = "0.10.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b1365becbe415f3f0fcd024e2f7b45bacfb5bdd055f0dc113571394114e7bdd"
checksum = "5f4a6bd64f22b5e3e94b4e238669ff9f10815c27a5180108b849d24174a83847"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "4.1.4+zstd.1.5.2"
version = "4.1.6+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f7cd17c9af1a4d6c24beb1cc54b17e2ef7b593dc92f19e9d9acad8b182bbaee"
checksum = "94b61c51bb270702d6167b8ce67340d2754b088d0c091b06e593aa772c3ee9bb"
dependencies = [
"libc",
"zstd-sys",

View file

@ -97,8 +97,8 @@ test: frontend-test frontend ## Run all available tests
cd db/db-sqlx-postgres &&\
DATABASE_URL=${POSTGRES_DATABASE_URL}\
cargo test --no-fail-fast
./scripts/tests.sh
# cargo test --all-features --no-fail-fast
cargo test --all-features --no-fail-fast
# ./scripts/tests.sh
xml-test-coverage: migrate ## Generate code coverage report in XML format
cargo tarpaulin -t 1200 --out Xml

View file

@ -96,28 +96,27 @@ pub fn services(cfg: &mut actix_web::web::ServiceConfig) {
}
#[cfg(test)]
mod tests {
pub mod tests {
use super::*;
use actix_web::http::StatusCode;
use actix_web::test;
use crate::api::v1::ROUTES;
use crate::data::Data;
use crate::tests::*;
#[actix_rt::test]
async fn update_password_works() {
pub async fn update_password_works() {
const NAME: &str = "updatepassuser";
const PASSWORD: &str = "longpassword2";
const EMAIL: &str = "updatepassuser@a.com";
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
let data = crate::data::Data::new().await;
let data = &data;
let (data, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
delete_user(data, NAME).await;
let (_, signin_resp) = register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
@ -129,7 +128,7 @@ mod tests {
confirm_new_password: PASSWORD.into(),
};
let res = update_password_runner(NAME, update_password.into(), &data).await;
let res = update_password_runner(NAME, update_password.into(), data).await;
assert!(res.is_err());
assert_eq!(res, Err(ServiceError::PasswordsDontMatch));
@ -139,7 +138,7 @@ mod tests {
confirm_new_password: new_password.into(),
};
assert!(update_password_runner(NAME, update_password.into(), &data)
assert!(update_password_runner(NAME, update_password.into(), data)
.await
.is_ok());
@ -150,6 +149,7 @@ mod tests {
};
bad_post_req_test(
data,
NAME,
new_password,
ROUTES.account.update_password,
@ -165,6 +165,7 @@ mod tests {
};
bad_post_req_test(
data,
NAME,
new_password,
ROUTES.account.update_password,

View file

@ -1,19 +1,19 @@
/*
* Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
* Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use actix_web::http::StatusCode;
use actix_web::test;
@ -23,24 +23,21 @@ use super::username::Username;
use super::*;
use crate::api::v1::auth::runners::Password;
use crate::api::v1::ROUTES;
use crate::data::Data;
use crate::*;
use crate::errors::*;
use crate::tests::*;
#[actix_rt::test]
async fn uname_email_exists_works() {
pub async fn uname_email_exists_works() {
const NAME: &str = "testuserexists";
const PASSWORD: &str = "longpassword2";
const EMAIL: &str = "testuserexists@a.com2";
let data = crate::data::Data::new().await;
let data = &data;
delete_user(data, NAME).await;
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
let (data, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let (_, signin_resp) = register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
@ -118,21 +115,20 @@ async fn uname_email_exists_works() {
}
#[actix_rt::test]
async fn email_udpate_password_validation_del_userworks() {
pub async fn email_udpate_password_validation_del_userworks() {
const NAME: &str = "testuser2";
const PASSWORD: &str = "longpassword2";
const EMAIL: &str = "testuser1@a.com2";
const NAME2: &str = "eupdauser";
const EMAIL2: &str = "eupdauser@a.com";
{
let data = Data::new().await;
delete_user(NAME, &data).await;
delete_user(NAME2, &data).await;
}
let data = crate::data::Data::new().await;
let data = &data;
delete_user(data, NAME).await;
delete_user(data, NAME2).await;
let _ = register_and_signin(NAME2, EMAIL2, PASSWORD).await;
let (data, _creds, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let _ = register_and_signin(data, NAME2, EMAIL2, PASSWORD).await;
let (_creds, signin_resp) = register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
@ -153,6 +149,7 @@ async fn email_udpate_password_validation_del_userworks() {
// check duplicate email while duplicate email
email_payload.email = EMAIL2.into();
bad_post_req_test(
data,
NAME,
PASSWORD,
ROUTES.account.update_email,
@ -166,6 +163,7 @@ async fn email_udpate_password_validation_del_userworks() {
password: NAME.into(),
};
bad_post_req_test(
data,
NAME,
PASSWORD,
ROUTES.account.delete,
@ -200,7 +198,7 @@ async fn email_udpate_password_validation_del_userworks() {
}
#[actix_rt::test]
async fn username_update_works() {
pub async fn username_update_works() {
const NAME: &str = "testuserupda";
const EMAIL: &str = "testuserupda@sss.com";
const EMAIL2: &str = "testuserupda2@sss.com";
@ -208,18 +206,17 @@ async fn username_update_works() {
const NAME2: &str = "terstusrtds";
const NAME_CHANGE: &str = "terstusrtdsxx";
{
let data = Data::new().await;
let data = crate::data::Data::new().await;
let data = &data;
futures::join!(
delete_user(NAME, &data),
delete_user(NAME2, &data),
delete_user(NAME_CHANGE, &data)
);
}
futures::join!(
delete_user(data, NAME),
delete_user(data, NAME2),
delete_user(data, NAME_CHANGE),
);
let _ = register_and_signin(NAME2, EMAIL2, PASSWORD).await;
let (data, _creds, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let _ = register_and_signin(data, NAME2, EMAIL2, PASSWORD).await;
let (_creds, signin_resp) = register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
@ -239,6 +236,7 @@ async fn username_update_works() {
// check duplicate username with duplicate username
username_udpate.username = NAME2.into();
bad_post_req_test(
data,
NAME_CHANGE,
PASSWORD,
ROUTES.account.update_username,

View file

@ -216,7 +216,7 @@ async fn update(
}
#[cfg(test)]
mod tests {
pub mod tests {
use actix_web::http::StatusCode;
use actix_web::test;
use actix_web::web::Bytes;
@ -227,7 +227,6 @@ mod tests {
use crate::tests::*;
use crate::*;
#[cfg(test)]
mod isoloated_test {
use super::{LevelBuilder, TrafficPattern};
@ -303,18 +302,17 @@ mod tests {
}
#[actix_rt::test]
async fn easy_works() {
pub async fn easy_works() {
const NAME: &str = "defaultuserconfgworks";
const PASSWORD: &str = "longpassworddomain";
const EMAIL: &str = "defaultuserconfgworks@a.com";
let data = crate::data::Data::new().await;
let data = &data;
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
delete_user(data, NAME).await;
let (data, _creds, signin_resp) =
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (_creds, signin_resp) =
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;

View file

@ -23,7 +23,6 @@ use libmcaptcha::defense::Level;
use crate::api::v1::mcaptcha::update::UpdateCaptcha;
use crate::api::v1::ROUTES;
use crate::data::Data;
use crate::errors::*;
use crate::tests::*;
use crate::*;
@ -38,19 +37,18 @@ const L2: Level = Level {
};
#[actix_rt::test]
async fn level_routes_work() {
pub async fn level_routes_work() {
const NAME: &str = "testuserlevelroutes";
const PASSWORD: &str = "longpassworddomain";
const EMAIL: &str = "testuserlevelrouts@a.com";
let data = crate::data::Data::new().await;
let data = &data;
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
delete_user(data, NAME).await;
register_and_signin(NAME, EMAIL, PASSWORD).await;
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
// create captcha
let (data, _, signin_resp, key) = add_levels_util(NAME, PASSWORD).await;
let (_, signin_resp, key) = add_levels_util(data, NAME, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
@ -103,6 +101,7 @@ async fn level_routes_work() {
};
bad_post_req_test(
data,
NAME,
PASSWORD,
ROUTES.captcha.delete,

View file

@ -123,7 +123,7 @@ pub mod runner {
description: &payload.description,
};
data.dblib.update_captcha_metadata(&username, &m).await?;
data.dblib.update_captcha_metadata(username, &m).await?;
data.dblib
.add_captcha_levels(username, &payload.key, &payload.levels)
@ -159,15 +159,13 @@ mod tests {
const NAME: &str = "updateusermcaptcha";
const PASSWORD: &str = "longpassworddomain";
const EMAIL: &str = "testupdateusermcaptcha@a.com";
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
let data = crate::data::Data::new().await;
let data = &data;
delete_user(data, NAME).await;
// 1. add mcaptcha token
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (data, _, signin_resp, token_key) = add_levels_util(NAME, PASSWORD).await;
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let (_, signin_resp, token_key) = add_levels_util(data, NAME, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;

View file

@ -99,7 +99,7 @@ pub fn services(cfg: &mut web::ServiceConfig) {
}
#[cfg(test)]
mod tests {
pub mod tests {
use actix_web::{http::StatusCode, test, App};
use super::*;
@ -121,9 +121,10 @@ mod tests {
}
#[actix_rt::test]
async fn health_works() {
pub async fn health_works() {
println!("{}", V1_API_ROUTES.meta.health);
let data = Data::new().await;
let data = crate::data::Data::new().await;
let data = &data;
let app = get_app!(data).await;
let resp = test::call_service(

View file

@ -60,7 +60,7 @@ pub async fn add_notification(
}
#[cfg(test)]
mod tests {
pub mod tests {
use actix_web::http::StatusCode;
use actix_web::test;
@ -69,22 +69,22 @@ mod tests {
use crate::*;
#[actix_rt::test]
async fn notification_works() {
pub async fn notification_works() {
const NAME1: &str = "notifuser1";
const NAME2: &str = "notiuser2";
const PASSWORD: &str = "longpassworddomain";
const EMAIL1: &str = "testnotification1@a.com";
const EMAIL2: &str = "testnotification2@a.com";
{
let data = Data::new().await;
delete_user(NAME1, &data).await;
delete_user(NAME2, &data).await;
}
let data = crate::data::Data::new().await;
let data = &data;
register_and_signin(NAME1, EMAIL1, PASSWORD).await;
register_and_signin(NAME2, EMAIL2, PASSWORD).await;
let (data, _creds, signin_resp) = signin(NAME1, PASSWORD).await;
delete_user(data, NAME1).await;
delete_user(data, NAME2).await;
register_and_signin(data, NAME1, EMAIL1, PASSWORD).await;
register_and_signin(data, NAME2, EMAIL2, PASSWORD).await;
let (_creds, signin_resp) = signin(data, NAME1, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;

View file

@ -97,7 +97,7 @@ pub mod runner {
}
#[cfg(test)]
mod tests {
pub mod tests {
use actix_web::http::StatusCode;
use actix_web::test;
@ -107,7 +107,7 @@ mod tests {
use crate::*;
#[actix_rt::test]
async fn notification_get_works() {
pub async fn notification_get_works() {
const NAME1: &str = "notifuser12";
const NAME2: &str = "notiuser22";
const PASSWORD: &str = "longpassworddomain";
@ -116,16 +116,16 @@ mod tests {
const HEADING: &str = "testing notifications get";
const MESSAGE: &str = "testing notifications get message";
{
let data = Data::new().await;
delete_user(NAME1, &data).await;
delete_user(NAME2, &data).await;
}
let data = crate::data::Data::new().await;
let data = &data;
register_and_signin(NAME1, EMAIL1, PASSWORD).await;
register_and_signin(NAME2, EMAIL2, PASSWORD).await;
let (data, _creds, signin_resp) = signin(NAME1, PASSWORD).await;
let (_data, _creds2, signin_resp2) = signin(NAME2, PASSWORD).await;
delete_user(data, NAME1).await;
delete_user(data, NAME2).await;
register_and_signin(data, NAME1, EMAIL1, PASSWORD).await;
register_and_signin(data, NAME2, EMAIL2, PASSWORD).await;
let (_creds, signin_resp) = signin(data, NAME1, PASSWORD).await;
let (_creds2, signin_resp2) = signin(data, NAME2, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let cookies2 = get_cookie!(signin_resp2);
let app = get_app!(data).await;

View file

@ -62,7 +62,7 @@ pub async fn mark_read(
}
#[cfg(test)]
mod tests {
pub mod tests {
use actix_web::http::StatusCode;
use actix_web::test;
@ -72,7 +72,7 @@ mod tests {
use crate::*;
#[actix_rt::test]
async fn notification_mark_read_works() {
pub async fn notification_mark_read_works() {
const NAME1: &str = "notifuser122";
const NAME2: &str = "notiuser222";
const PASSWORD: &str = "longpassworddomain";
@ -80,17 +80,16 @@ mod tests {
const EMAIL2: &str = "testnotification222@a.com";
const HEADING: &str = "testing notifications get";
const MESSAGE: &str = "testing notifications get message";
let data = crate::data::Data::new().await;
let data = &data;
{
let data = Data::new().await;
delete_user(NAME1, &data).await;
delete_user(NAME2, &data).await;
}
delete_user(data, NAME1).await;
delete_user(data, NAME2).await;
register_and_signin(NAME1, EMAIL1, PASSWORD).await;
register_and_signin(NAME2, EMAIL2, PASSWORD).await;
let (data, _creds, signin_resp) = signin(NAME1, PASSWORD).await;
let (_data, _creds2, signin_resp2) = signin(NAME2, PASSWORD).await;
register_and_signin(data, NAME1, EMAIL1, PASSWORD).await;
register_and_signin(data, NAME2, EMAIL2, PASSWORD).await;
let (_creds, signin_resp) = signin(data, NAME1, PASSWORD).await;
let (_creds2, signin_resp2) = signin(data, NAME2, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let cookies2 = get_cookie!(signin_resp2);
let app = get_app!(data).await;

View file

@ -159,11 +159,12 @@ async fn init_mcaptcha(data: &AppData, key: &str) -> ServiceResult<()> {
}
#[cfg(test)]
mod tests {
pub mod tests {
use crate::*;
use libmcaptcha::pow::PoWConfig;
#[actix_rt::test]
async fn get_pow_config_works() {
pub async fn get_pow_config_works() {
use super::*;
use crate::tests::*;
use crate::*;
@ -173,13 +174,13 @@ mod tests {
const PASSWORD: &str = "testingpas";
const EMAIL: &str = "randomuser@a.com";
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
let data = crate::data::Data::new().await;
let data = &data;
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (data, _, _signin_resp, token_key) = add_levels_util(NAME, PASSWORD).await;
delete_user(data, NAME).await;
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let (_, _signin_resp, token_key) = add_levels_util(data, NAME, PASSWORD).await;
let app = get_app!(data).await;
let get_config_payload = GetConfigPayload {

View file

@ -49,7 +49,7 @@ pub async fn verify_pow(
}
#[cfg(test)]
mod tests {
pub mod tests {
use actix_web::http::StatusCode;
use actix_web::test;
use libmcaptcha::pow::PoWConfig;
@ -60,18 +60,17 @@ mod tests {
use crate::*;
#[actix_rt::test]
async fn verify_pow_works() {
pub async fn verify_pow_works() {
const NAME: &str = "powverifyusr";
const PASSWORD: &str = "testingpas";
const EMAIL: &str = "verifyuser@a.com";
let data = crate::data::Data::new().await;
let data = &data;
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
delete_user(data, NAME).await;
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (data, _, _signin_resp, token_key) = add_levels_util(NAME, PASSWORD).await;
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let (_, _signin_resp, token_key) = add_levels_util(data, NAME, PASSWORD).await;
let app = get_app!(data).await;
let get_config_payload = GetConfigPayload {

View file

@ -50,7 +50,7 @@ pub async fn validate_captcha_token(
}
#[cfg(test)]
mod tests {
pub mod tests {
use actix_web::http::StatusCode;
use actix_web::test;
use libmcaptcha::pow::PoWConfig;
@ -63,7 +63,7 @@ mod tests {
use crate::*;
#[actix_rt::test]
async fn validate_captcha_token_works() {
pub async fn validate_captcha_token_works() {
const NAME: &str = "enterprisetken";
const PASSWORD: &str = "testingpas";
const EMAIL: &str = "verifyuser@enter.com";
@ -72,13 +72,12 @@ mod tests {
const VERIFY_TOKEN_URL: &str = "/api/v1/pow/siteverify";
// const UPDATE_URL: &str = "/api/v1/mcaptcha/domain/token/duration/update";
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
let data = crate::data::Data::new().await;
let data = &data;
delete_user(data, NAME).await;
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (data, _, _signin_resp, token_key) = add_levels_util(NAME, PASSWORD).await;
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let (_, _signin_resp, token_key) = add_levels_util(data, NAME, PASSWORD).await;
let app = get_app!(data).await;
let get_config_payload = GetConfigPayload {

View file

@ -20,22 +20,23 @@ use actix_web::test;
use crate::api::v1::auth::runners::{Login, Register};
use crate::api::v1::ROUTES;
use crate::data::Data;
use crate::errors::*;
use crate::*;
use crate::tests::*;
#[actix_rt::test]
async fn auth_works() {
let data = Data::new().await;
pub async fn auth_works() {
const NAME: &str = "testuser";
const PASSWORD: &str = "longpassword";
const EMAIL: &str = "testuser1@a.com";
let data = crate::data::Data::new().await;
let data = &data;
let app = get_app!(data).await;
delete_user(NAME, &data).await;
delete_user(data, NAME).await;
// 1. Register with email == None
let msg = Register {
@ -49,14 +50,14 @@ async fn auth_works() {
.await;
assert_eq!(resp.status(), StatusCode::OK);
// delete user
delete_user(NAME, &data).await;
delete_user(data, NAME).await;
// 1. Register and signin
let (_, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let (_, signin_resp) = register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
// Sign in with email
signin(EMAIL, PASSWORD).await;
signin(data, EMAIL, PASSWORD).await;
// 2. check if duplicate username is allowed
let mut msg = Register {
@ -66,6 +67,7 @@ async fn auth_works() {
email: Some(EMAIL.into()),
};
bad_post_req_test(
data,
NAME,
PASSWORD,
ROUTES.auth.register,
@ -77,6 +79,7 @@ async fn auth_works() {
let name = format!("{}dupemail", NAME);
msg.username = name;
bad_post_req_test(
data,
NAME,
PASSWORD,
ROUTES.auth.register,
@ -91,6 +94,7 @@ async fn auth_works() {
password: msg.password.clone(),
};
bad_post_req_test(
data,
NAME,
PASSWORD,
ROUTES.auth.login,
@ -101,6 +105,7 @@ async fn auth_works() {
creds.login = "nonexistantuser@example.com".into();
bad_post_req_test(
data,
NAME,
PASSWORD,
ROUTES.auth.login,
@ -114,6 +119,7 @@ async fn auth_works() {
creds.password = NAME.into();
bad_post_req_test(
data,
NAME,
PASSWORD,
ROUTES.auth.login,
@ -137,12 +143,13 @@ async fn auth_works() {
}
#[actix_rt::test]
async fn serverside_password_validation_works() {
pub async fn serverside_password_validation_works() {
const NAME: &str = "testuser542";
const PASSWORD: &str = "longpassword2";
let data = Data::new().await;
delete_user(NAME, &data).await;
let data = crate::data::Data::new().await;
let data = &data;
delete_user(data, NAME).await;
let app = get_app!(data).await;

View file

@ -18,7 +18,6 @@
use actix_web::http::StatusCode;
use actix_web::test;
use crate::data::Data;
use crate::*;
use crate::tests::*;
@ -28,6 +27,8 @@ async fn protected_routes_work() {
const NAME: &str = "testuser619";
const PASSWORD: &str = "longpassword2";
const EMAIL: &str = "testuser119@a.com2";
let data = crate::data::Data::new().await;
let data = &data;
let _post_protected_urls = [
"/api/v1/account/secret/",
@ -47,12 +48,9 @@ async fn protected_routes_work() {
let get_protected_urls = ["/logout"];
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
delete_user(data, NAME).await;
let (data, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let (_, signin_resp) = register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;

View file

@ -115,11 +115,10 @@ mod tests {
#[actix_rt::test]
async fn demo_account_works() {
{
let data = Data::new().await;
crate::tests::delete_user(DEMO_USER, &data).await;
}
let data = AppData::new(Data::new().await);
let data_inner = crate::data::Data::new().await;
let data_inner = &data_inner;
let data = AppData::new(data_inner.clone());
crate::tests::delete_user(data_inner, DEMO_USER).await;
let duration = Duration::from_secs(DURATION);
// register works
@ -128,7 +127,7 @@ mod tests {
val: DEMO_USER.into(),
};
assert!(username_exists(&payload, &data).await.unwrap().exists);
signin(DEMO_USER, DEMO_PASSWORD).await;
signin(data_inner, DEMO_USER, DEMO_PASSWORD).await;
// deletion works
assert!(DemoUser::delete_demo_user(&data).await.is_ok());
@ -136,8 +135,8 @@ mod tests {
// test the runner
let user = DemoUser::spawn(data, duration).await.unwrap();
let (data_inner, _, signin_resp, token_key) =
add_levels_util(DEMO_USER, DEMO_PASSWORD).await;
let (_, signin_resp, token_key) =
add_levels_util(data_inner, DEMO_USER, DEMO_PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data_inner).await;

View file

@ -94,7 +94,8 @@ pub const PKG_HOMEPAGE: &str = env!("CARGO_PKG_HOMEPAGE");
pub const CACHE_AGE: u32 = 604800;
pub type AppData = actix_web::web::Data<Arc<crate::data::Data>>;
pub type ArcData = Arc<crate::data::Data>;
pub type AppData = actix_web::web::Data<ArcData>;
#[cfg(not(tarpaulin_include))]
#[actix_web::main]

View file

@ -51,13 +51,12 @@ mod tests {
const PASSWORD: &str = "longpassword";
const EMAIL: &str = "templateuser@a.com";
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
let data = crate::data::Data::new().await;
let data = &data;
delete_user(data, NAME).await;
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (data, _, signin_resp, token_key) = add_levels_util(NAME, PASSWORD).await;
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let (_, signin_resp, token_key) = add_levels_util(data, NAME, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
@ -95,7 +94,7 @@ mod tests {
assert_eq!(authenticated_resp.status(), StatusCode::OK);
}
delete_user(NAME, &data).await;
delete_user(data, NAME).await;
}
#[actix_rt::test]

View file

@ -225,14 +225,12 @@ mod test {
const NAME: &str = "editsitekeyuser";
const PASSWORD: &str = "longpassworddomain";
const EMAIL: &str = "editsitekeyuser@a.com";
let data = crate::data::Data::new().await;
let data = &data;
delete_user(data, NAME).await;
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (data, _, signin_resp, key) = add_levels_util(NAME, PASSWORD).await;
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let (_, signin_resp, key) = add_levels_util(data, NAME, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;

View file

@ -81,13 +81,12 @@ mod test {
const PASSWORD: &str = "longpassworddomain";
const EMAIL: &str = "listsitekeyuser@a.com";
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
let data = crate::data::Data::new().await;
let data = &data;
delete_user(data, NAME).await;
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (data, _, signin_resp, key) = add_levels_util(NAME, PASSWORD).await;
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let (_, signin_resp, key) = add_levels_util(data, NAME, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;

View file

@ -126,13 +126,12 @@ mod test {
const PASSWORD: &str = "longpassworddomain";
const EMAIL: &str = "viewsitekeyuser@a.com";
{
let data = Data::new().await;
delete_user(NAME, &data).await;
}
let data = crate::data::Data::new().await;
let data = &data;
delete_user(data, NAME).await;
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (data, _, signin_resp, key) = add_levels_util(NAME, PASSWORD).await;
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let (_, signin_resp, key) = add_levels_util(data, NAME, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;

View file

@ -178,7 +178,6 @@ mod tests {
use super::*;
use crate::stats::record::*;
use crate::tests::*;
use crate::*;
#[actix_rt::test]
async fn stats_works() {
@ -186,11 +185,13 @@ mod tests {
const PASSWORD: &str = "testingpas";
const EMAIL: &str = "statsuser@a.com";
let data = Data::new().await;
delete_user(NAME, &data).await;
let data = crate::data::Data::new().await;
let data = &data;
let data = &data;
delete_user(data, NAME).await;
register_and_signin(NAME, EMAIL, PASSWORD).await;
let (_, _, _, token_key) = add_levels_util(NAME, PASSWORD).await;
register_and_signin(data, NAME, EMAIL, PASSWORD).await;
let (_, _, token_key) = add_levels_util(data, NAME, PASSWORD).await;
let key = token_key.key.clone();
let stats = Stats::new(NAME, &key, &data.db).await.unwrap();

View file

@ -1,5 +1,3 @@
use std::sync::Arc;
use actix_web::test;
use actix_web::{
body::{BoxBody, EitherBody},
@ -16,8 +14,8 @@ use crate::api::v1::auth::runners::{Login, Register};
use crate::api::v1::mcaptcha::create::CreateCaptcha;
use crate::api::v1::mcaptcha::create::MCaptchaDetails;
use crate::api::v1::ROUTES;
use crate::data::Data;
use crate::errors::*;
use crate::ArcData;
#[macro_export]
macro_rules! get_cookie {
@ -26,14 +24,6 @@ macro_rules! get_cookie {
};
}
pub async fn delete_user(name: &str, data: &Data) {
let x = data.dblib.delete_user(name).await;
println!();
println!();
println!();
println!("Deleting user: {:?}", &x);
}
#[macro_export]
macro_rules! post_request {
($uri:expr) => {
@ -81,19 +71,27 @@ macro_rules! get_app {
};
}
pub async fn delete_user(data: &ArcData, name: &str) {
let x = data.dblib.delete_user(name).await;
println!();
println!();
println!();
println!("Deleting user: {:?}", &x);
}
/// register and signin utility
pub async fn register_and_signin(
data: &ArcData,
name: &str,
email: &str,
password: &str,
) -> (Arc<data::Data>, Login, ServiceResponse<EitherBody<BoxBody>>) {
register(name, email, password).await;
signin(name, password).await
) -> (Login, ServiceResponse<EitherBody<BoxBody>>) {
register(data, name, email, password).await;
signin(data, name, password).await
}
/// register utility
pub async fn register(name: &str, email: &str, password: &str) {
let data = Data::new().await;
pub async fn register(data: &ArcData, name: &str, email: &str, password: &str) {
let app = get_app!(data).await;
// 1. Register
@ -111,10 +109,10 @@ pub async fn register(name: &str, email: &str, password: &str) {
/// signin util
pub async fn signin(
data: &ArcData,
name: &str,
password: &str,
) -> (Arc<Data>, Login, ServiceResponse<EitherBody<BoxBody>>) {
let data = Data::new().await;
) -> (Login, ServiceResponse<EitherBody<BoxBody>>) {
let app = get_app!(data.clone()).await;
// 2. signin
@ -126,18 +124,19 @@ pub async fn signin(
test::call_service(&app, post_request!(&creds, ROUTES.auth.login).to_request())
.await;
assert_eq!(signin_resp.status(), StatusCode::OK);
(data, creds, signin_resp)
(creds, signin_resp)
}
/// pub duplicate test
pub async fn bad_post_req_test<T: Serialize>(
data: &ArcData,
name: &str,
password: &str,
url: &str,
payload: &T,
err: ServiceError,
) {
let (data, _, signin_resp) = signin(name, password).await;
let (_, signin_resp) = signin(data, name, password).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
@ -158,6 +157,31 @@ pub async fn bad_post_req_test<T: Serialize>(
assert_eq!(resp_err.error, format!("{}", err));
}
pub async fn add_levels_util(
data: &ArcData,
name: &str,
password: &str,
) -> (Login, ServiceResponse<EitherBody<BoxBody>>, MCaptchaDetails) {
let (creds, signin_resp) = signin(data, name, password).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
let add_level = get_level_data();
// 1. add level
let add_token_resp = test::call_service(
&app,
post_request!(&add_level, ROUTES.captcha.create)
.cookie(cookies.clone())
.to_request(),
)
.await;
assert_eq!(add_token_resp.status(), StatusCode::OK);
let token_key: MCaptchaDetails = test::read_body_json(add_token_resp).await;
(creds, signin_resp, token_key)
}
pub const L1: Level = Level {
difficulty_factor: 50,
visitor_threshold: 50,
@ -176,32 +200,3 @@ pub fn get_level_data() -> CreateCaptcha {
description: "dummy".into(),
}
}
pub async fn add_levels_util(
name: &str,
password: &str,
) -> (
Arc<data::Data>,
Login,
ServiceResponse<EitherBody<BoxBody>>,
MCaptchaDetails,
) {
let (data, creds, signin_resp) = signin(name, password).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
let add_level = get_level_data();
// 1. add level
let add_token_resp = test::call_service(
&app,
post_request!(&add_level, ROUTES.captcha.create)
.cookie(cookies.clone())
.to_request(),
)
.await;
assert_eq!(add_token_resp.status(), StatusCode::OK);
let token_key: MCaptchaDetails = test::read_body_json(add_token_resp).await;
(data, creds, signin_resp, token_key)
}