refactor: rework api tests

This commit is contained in:
EETagent 2022-11-21 17:36:37 +01:00
parent b8ae1a898d
commit 970c8315d1
6 changed files with 263 additions and 238 deletions

View file

@ -7,7 +7,6 @@ on:
env:
CARGO_TERM_COLOR: always
TEST_API: true
jobs:
build:

View file

@ -20,14 +20,16 @@ impl sea_orm_rocket::Pool for SeaOrmPool {
type Connection = sea_orm::DatabaseConnection;
#[cfg(test)]
async fn init(_figment: &Figment) -> Result<Self, Self::Error> {
let conn = get_memory_sqlite_connection().await;
crate::test::tests::run_test_migrations(&conn).await;
return Ok(Self { conn });
}
#[cfg(not(test))]
async fn init(_figment: &Figment) -> Result<Self, Self::Error> {
dotenv::dotenv().ok();
if std::env::var("TEST_API").is_ok() {
let conn = get_memory_sqlite_connection().await;
crate::test::run_test_migrations(&conn).await;
return Ok(Self { conn });
}
let database_url = std::env::var("DATABASE_URL").unwrap();
let mut options: ConnectOptions = database_url.into();

View file

@ -283,4 +283,145 @@ pub async fn download_portfolio(session: CandidateAuth) -> Result<Vec<u8>, Custo
}
Ok(file.unwrap())
}
#[cfg(test)]
mod tests {
use portfolio_core::{candidate_details::ApplicationDetails, sea_orm::prelude::Uuid, crypto};
use rocket::http::{Status, Cookie};
use crate::test::tests::{create_candidate, admin_login, test_client, candidate_login, APPLICATION_ID};
const CANDIDATE_DETAILS: &'static str = "{
\"name\": \"idk\",
\"surname\": \"idk\",
\"birthplace\": \"Praha 1\",
\"birthdate\": \"2015-09-18\",
\"address\": \"Stefanikova jidelna\",
\"telephone\": \"000111222333\",
\"citizenship\": \"Czech Republic\",
\"email\": \"magor@magor.cz\",
\"sex\": \"MALE\",
\"study\": \"KB\",
\"parent_name\": \"maminka\",
\"parent_surname\": \"chad\",
\"parent_telephone\": \"420111222333\",
\"parent_email\": \"maminka@centrum.cz\"
}";
#[test]
fn test_login_valid_credentials() {
let client = test_client().lock().unwrap();
let _response = candidate_login(&client);
}
#[test]
fn test_create_candidate() {
let client = test_client().lock().unwrap();
let cookies = admin_login(&client);
let password = create_candidate(&client, cookies, 1031511, "0".to_string());
assert_eq!(password.len(), 8);
}
#[test]
fn test_auth_candidate() {
let client = test_client().lock().unwrap();
let cookies = candidate_login(&client);
let response = client
.get("/candidate/whoami")
.cookie(cookies.0)
.cookie(cookies.1)
.dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.into_string().unwrap(), APPLICATION_ID.to_string());
}
#[test]
fn test_add_get_candidate_details() {
let client = test_client().lock().unwrap();
let cookies = candidate_login(&client);
let details_orig: ApplicationDetails = serde_json::from_str(CANDIDATE_DETAILS).unwrap();
let response = client
.post("/candidate/add/details")
.cookie(cookies.0.clone())
.cookie(cookies.1.clone())
.body(CANDIDATE_DETAILS.to_string())
.dispatch();
assert_eq!(response.status(), Status::Ok);
let response = client
.post("/candidate/get_details")
.cookie(cookies.0)
.cookie(cookies.1)
.dispatch();
assert_eq!(response.status(), Status::Ok);
let details_resp: ApplicationDetails = serde_json::from_str(&response.into_string().unwrap()).unwrap();
assert_eq!(details_orig, details_resp);
}
#[test]
fn test_invalid_token_every_secured_endpoint() {
let client = test_client().lock().unwrap();
let id = Cookie::new("id", Uuid::new_v4().to_string());
let (private_key, _) = crypto::create_identity();
let key = Cookie::new("key", private_key);
let response = client
.post("/candidate/add/details")
.cookie(id.clone())
.cookie(key.clone())
.body(CANDIDATE_DETAILS.to_string())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
let response = client
.post("/candidate/get_details")
.cookie(id.clone())
.cookie(key.clone())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
let response = client
.get("/candidate/whoami")
.cookie(id.clone())
.cookie(key.clone())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
}
#[test]
fn test_admin_token_on_secured_candidate_endpoints() {
let client = test_client().lock().unwrap();
let cookies = admin_login(&client);
let response = client
.post("/candidate/add/details")
.cookie(cookies.0.clone())
.cookie(cookies.1.clone())
.body(CANDIDATE_DETAILS.to_string())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
let response = client
.post("/candidate/get_details")
.cookie(cookies.0.clone())
.cookie(cookies.1.clone())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
let response = client
.get("/candidate/whoami")
.cookie(cookies.0.clone())
.cookie(cookies.1.clone())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
}
}

View file

@ -1,40 +1,124 @@
use entity::admin;
use portfolio_core::{sea_orm::{DbConn, Set, ActiveModelTrait}, crypto, services::application_service::ApplicationService};
#[cfg(test)]
pub mod tests {
use crate::rocket;
use entity::admin;
use once_cell::sync::OnceCell;
use portfolio_core::{
crypto,
sea_orm::{ActiveModelTrait, DbConn, Set},
services::application_service::ApplicationService,
};
use rocket::{
http::{Cookie, Status},
local::blocking::Client,
};
use std::sync::Mutex;
pub const ADMIN_ID: i32 = 1;
pub const ADMIN_PASSWORD: &'static str = "test";
pub const ADMIN_ID: i32 = 1;
pub const ADMIN_PASSWORD: &'static str = "test";
pub const APPLICATION_ID: i32 = 103151;
pub const CANDIDATE_PASSWORD: &'static str = "test";
pub const PERSONAL_ID_NUMBER: &'static str = "0101010000";
pub const APPLICATION_ID: i32 = 103151;
pub const CANDIDATE_PASSWORD: &'static str = "test";
pub const PERSONAL_ID_NUMBER: &'static str = "0101010000";
pub async fn run_test_migrations(db: &DbConn) {
let (pubkey, priv_key) = crypto::create_identity();
let priv_key = crypto::encrypt_password(
priv_key,
ADMIN_PASSWORD.to_string()
).await.unwrap();
let password_hash = crypto::hash_password(ADMIN_PASSWORD.to_string()).await.unwrap();
pub async fn run_test_migrations(db: &DbConn) {
let (pubkey, priv_key) = crypto::create_identity();
let priv_key = crypto::encrypt_password(priv_key, ADMIN_PASSWORD.to_string())
.await
.unwrap();
let password_hash = crypto::hash_password(ADMIN_PASSWORD.to_string())
.await
.unwrap();
admin::ActiveModel {
id: Set(ADMIN_ID),
name: Set("admin pepa".to_string()),
public_key: Set(pubkey),
private_key: Set(priv_key),
password: Set(password_hash),
created_at: Set(chrono::Utc::now().naive_utc()),
updated_at: Set(chrono::Utc::now().naive_utc()),
}
admin::ActiveModel {
id: Set(ADMIN_ID),
name: Set("admin pepa".to_string()),
public_key: Set(pubkey),
private_key: Set(priv_key),
password: Set(password_hash),
created_at: Set(chrono::Utc::now().naive_utc()),
updated_at: Set(chrono::Utc::now().naive_utc()),
}
.insert(db)
.await
.unwrap();
ApplicationService::create_candidate_with_parent(
db,
APPLICATION_ID,
&CANDIDATE_PASSWORD.to_string(),
PERSONAL_ID_NUMBER.to_string()
)
ApplicationService::create_candidate_with_parent(
db,
APPLICATION_ID,
&CANDIDATE_PASSWORD.to_string(),
PERSONAL_ID_NUMBER.to_string(),
)
.await
.unwrap();
}
}
pub fn test_client() -> &'static Mutex<Client> {
static INSTANCE: OnceCell<Mutex<Client>> = OnceCell::new();
INSTANCE.get_or_init(|| {
let rocket = rocket();
Mutex::from(Client::tracked(rocket).expect("valid rocket instance"))
})
}
pub fn candidate_login(client: &Client) -> (Cookie, Cookie) {
let response = client
.post("/candidate/login")
.body(format!(
"{{
\"application_id\": {},
\"password\": \"{}\"
}}",
APPLICATION_ID, CANDIDATE_PASSWORD
))
.dispatch();
(
response.cookies().get("id").unwrap().to_owned(),
response.cookies().get("key").unwrap().to_owned(),
)
}
pub fn admin_login(client: &Client) -> (Cookie, Cookie) {
let response = client
.post("/admin/login")
.body(format!(
"{{
\"admin_id\": {},
\"password\": \"{}\"
}}",
ADMIN_ID, ADMIN_PASSWORD
))
.dispatch();
println!("{:?}", response);
(
response.cookies().get("id").unwrap().to_owned(),
response.cookies().get("key").unwrap().to_owned(),
)
}
pub fn create_candidate(
client: &Client,
cookies: (Cookie, Cookie),
id: i32,
pid: String,
) -> String {
let response = client
.post("/admin/create")
.body(format!(
"{{
\"application_id\": {},
\"personal_id_number\": \"{}\"
}}",
id, pid
))
.cookie(cookies.0)
.cookie(cookies.1)
.dispatch();
assert_eq!(response.status(), Status::Ok);
response.into_string().unwrap()
}
}

View file

@ -1,139 +0,0 @@
mod common;
use common::*;
use portfolio_api::test::APPLICATION_ID;
use portfolio_core::{candidate_details::ApplicationDetails, sea_orm::prelude::Uuid, crypto};
use rocket::{http::{Status, Cookie}};
const CANDIDATE_DETAILS: &'static str = "{
\"name\": \"idk\",
\"surname\": \"idk\",
\"birthplace\": \"Praha 1\",
\"birthdate\": \"2015-09-18\",
\"address\": \"Stefanikova jidelna\",
\"telephone\": \"000111222333\",
\"citizenship\": \"Czech Republic\",
\"email\": \"magor@magor.cz\",
\"sex\": \"MALE\",
\"study\": \"KB\",
\"parent_name\": \"maminka\",
\"parent_surname\": \"chad\",
\"parent_telephone\": \"420111222333\",
\"parent_email\": \"maminka@centrum.cz\"
}";
#[test]
fn test_login_valid_credentials() {
let client = test_client().lock().unwrap();
let _response = candidate_login(&client);
}
#[test]
fn test_create_candidate() {
let client = test_client().lock().unwrap();
let cookies = admin_login(&client);
let password = create_candidate(&client, cookies, 1031511, "0".to_string());
assert_eq!(password.len(), 8);
}
#[test]
fn test_auth_candidate() {
let client = test_client().lock().unwrap();
let cookies = candidate_login(&client);
let response = client
.get("/candidate/whoami")
.cookie(cookies.0)
.cookie(cookies.1)
.dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.into_string().unwrap(), APPLICATION_ID.to_string());
}
#[test]
fn test_add_get_candidate_details() {
let client = test_client().lock().unwrap();
let cookies = candidate_login(&client);
let details_orig: ApplicationDetails = serde_json::from_str(CANDIDATE_DETAILS).unwrap();
let response = client
.post("/candidate/add/details")
.cookie(cookies.0.clone())
.cookie(cookies.1.clone())
.body(CANDIDATE_DETAILS.to_string())
.dispatch();
assert_eq!(response.status(), Status::Ok);
let response = client
.post("/candidate/get_details")
.cookie(cookies.0)
.cookie(cookies.1)
.dispatch();
assert_eq!(response.status(), Status::Ok);
let details_resp: ApplicationDetails = serde_json::from_str(&response.into_string().unwrap()).unwrap();
assert_eq!(details_orig, details_resp);
}
#[test]
fn test_invalid_token_every_secured_endpoint() {
let client = test_client().lock().unwrap();
let id = Cookie::new("id", Uuid::new_v4().to_string());
let (private_key, _) = crypto::create_identity();
let key = Cookie::new("key", private_key);
let response = client
.post("/candidate/add/details")
.cookie(id.clone())
.cookie(key.clone())
.body(CANDIDATE_DETAILS.to_string())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
let response = client
.post("/candidate/get_details")
.cookie(id.clone())
.cookie(key.clone())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
let response = client
.get("/candidate/whoami")
.cookie(id.clone())
.cookie(key.clone())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
}
#[test]
fn test_admin_token_on_secured_candidate_endpoints() {
let client = test_client().lock().unwrap();
let cookies = admin_login(&client);
let response = client
.post("/candidate/add/details")
.cookie(cookies.0.clone())
.cookie(cookies.1.clone())
.body(CANDIDATE_DETAILS.to_string())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
let response = client
.post("/candidate/get_details")
.cookie(cookies.0.clone())
.cookie(cookies.1.clone())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
let response = client
.get("/candidate/whoami")
.cookie(cookies.0.clone())
.cookie(cookies.1.clone())
.dispatch();
assert_eq!(response.status(), Status::Unauthorized);
}

View file

@ -1,62 +0,0 @@
use once_cell::sync::OnceCell;
use std::sync::Mutex;
use rocket::http::{Cookie, Status};
use rocket::local::blocking::{Client};
use portfolio_api::rocket;
use portfolio_api::test::{ADMIN_ID, ADMIN_PASSWORD, APPLICATION_ID, CANDIDATE_PASSWORD};
pub fn test_client() -> &'static Mutex<Client> {
static INSTANCE: OnceCell<Mutex<Client>> = OnceCell::new();
INSTANCE.get_or_init(|| {
let rocket = rocket();
Mutex::from(Client::tracked(rocket).expect("valid rocket instance"))
})
}
pub fn candidate_login(client: &Client) -> (Cookie, Cookie) {
let response = client
.post("/candidate/login")
.body(format!("{{
\"application_id\": {},
\"password\": \"{}\"
}}", APPLICATION_ID, CANDIDATE_PASSWORD))
.dispatch();
(
response.cookies().get("id").unwrap().to_owned(),
response.cookies().get("key").unwrap().to_owned()
)
}
pub fn admin_login(client: &Client) -> (Cookie, Cookie) {
let response = client
.post("/admin/login")
.body(format!("{{
\"admin_id\": {},
\"password\": \"{}\"
}}", ADMIN_ID, ADMIN_PASSWORD))
.dispatch();
println!("{:?}", response);
(
response.cookies().get("id").unwrap().to_owned(),
response.cookies().get("key").unwrap().to_owned(),
)
}
pub fn create_candidate(client: &Client, cookies: (Cookie, Cookie), id: i32, pid: String) -> String {
let response = client
.post("/admin/create")
.body(format!("{{
\"application_id\": {},
\"personal_id_number\": \"{}\"
}}", id, pid))
.cookie(cookies.0)
.cookie(cookies.1)
.dispatch();
assert_eq!(response.status(), Status::Ok);
response.into_string().unwrap()
}