Add comprehensive tests for mentor repository and authentication
- Implemented tests for creating, retrieving, updating, and deleting mentors in `mentor_repository_test.rs`. - Added tests for user authentication, including successful login, invalid email formats, and inactive users in `auth_login_tests.rs`. - Created a mock test environment setup in `mock_test.rs` to facilitate database operations during tests. - Updated module structure to include new test files for mentors and authentication. - Ensured cleanup of the database after tests to maintain isolation and prevent side effects.
This commit is contained in:
@@ -4,7 +4,7 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
imphnen-entities = { path = "../imphnen-entities" }
|
||||
imphnen-entities.workspace = true
|
||||
log.workspace = true
|
||||
axum.workspace = true
|
||||
tokio.workspace = true
|
||||
@@ -15,4 +15,3 @@ chrono.workspace = true
|
||||
surrealdb.workspace = true
|
||||
jsonwebtoken.workspace = true
|
||||
dotenvy.workspace = true
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use argon2::{
|
||||
password_hash::{
|
||||
rand_core::OsRng, Error, PasswordHash, PasswordHasher, PasswordVerifier,
|
||||
SaltString,
|
||||
},
|
||||
Argon2,
|
||||
password_hash::{
|
||||
Error, PasswordHash, PasswordHasher, PasswordVerifier, SaltString,
|
||||
rand_core::OsRng,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn hash_password(password: &str) -> Result<String, Error> {
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
use crate::{load_env, surrealdb_init_mem, surrealdb_init_ws, Env};
|
||||
use crate::{Env, load_env, surrealdb_init_mem, surrealdb_init_ws};
|
||||
use axum::{Router, serve};
|
||||
use imphnen_entities::{SurrealMemClient, SurrealWsClient};
|
||||
use log::{debug, error, info};
|
||||
use std::{future::Future, net::SocketAddr};
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
|
||||
pub async fn axum_init<F, Fut>(router_fn: F)
|
||||
where
|
||||
F: FnOnce(SurrealWsClient, SurrealMemClient) -> Fut,
|
||||
@@ -13,24 +11,19 @@ where
|
||||
{
|
||||
load_env();
|
||||
let env = Env::new();
|
||||
info!("Environment loaded with port: {}", env.port);
|
||||
|
||||
let surrealdb_ws = surrealdb_init_ws().await.expect("Failed surrealdb ws");
|
||||
info!("SurrealDB WS client initialized");
|
||||
|
||||
let surrealdb_mem = surrealdb_init_mem().await.expect("Failed surrealdb mem");
|
||||
info!("SurrealDB MEM client initialized");
|
||||
|
||||
let router = router_fn(surrealdb_ws, surrealdb_mem).await;
|
||||
debug!("Router created successfully");
|
||||
|
||||
let port = env.port;
|
||||
let addr = SocketAddr::from(([0, 0, 0, 0], port));
|
||||
let listener = TcpListener::bind(&addr).await.unwrap();
|
||||
info!("Listening on http://{}", addr);
|
||||
|
||||
match serve(listener, router).await {
|
||||
Ok(_) => info!("Server stopped gracefully."),
|
||||
Err(err) => error!("Server encountered an error: {}", err),
|
||||
Ok(_) => {}
|
||||
Err(_err) => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::env;
|
||||
|
||||
pub fn load_env() {
|
||||
dotenvy::dotenv().ok();
|
||||
if dotenvy::dotenv().is_ok() {}
|
||||
}
|
||||
|
||||
pub struct Env {
|
||||
@@ -13,6 +13,7 @@ pub struct Env {
|
||||
pub surrealdb_password: String,
|
||||
pub surrealdb_namespace: String,
|
||||
pub surrealdb_dbname: String,
|
||||
pub surrealdb_url_ws: String,
|
||||
pub smtp_email: String,
|
||||
pub smtp_password: String,
|
||||
pub smtp_name: String,
|
||||
@@ -31,112 +32,63 @@ impl Env {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
port: env::var("PORT")
|
||||
.unwrap_or_else(|_| {
|
||||
println!("INFO: PORT is not set, using default '3000'.");
|
||||
"3000".to_string()
|
||||
})
|
||||
.unwrap_or_else(|_| "3000".to_string())
|
||||
.parse()
|
||||
.unwrap_or(3000),
|
||||
|
||||
rust_env: env::var("RUST_ENV").unwrap_or_else(|_| {
|
||||
println!("INFO: RUST_ENV is not set, using default 'development'.");
|
||||
"development".to_string()
|
||||
}),
|
||||
rust_env: env::var("RUST_ENV").unwrap_or_else(|_| "development".to_string()),
|
||||
|
||||
access_token_secret: env::var("ACCESS_TOKEN_SECRET").unwrap_or_else(|_| {
|
||||
println!("WARNING: ACCESS_TOKEN_SECRET is not set, using fallback!");
|
||||
"default_access_secret".to_string()
|
||||
}),
|
||||
access_token_secret: env::var("ACCESS_TOKEN_SECRET")
|
||||
.unwrap_or_else(|_| "default_access_secret".to_string()),
|
||||
|
||||
refresh_token_secret: env::var("REFRESH_TOKEN_SECRET").unwrap_or_else(|_| {
|
||||
println!("WARNING: REFRESH_TOKEN_SECRET is not set, using fallback!");
|
||||
"default_refresh_secret".to_string()
|
||||
}),
|
||||
refresh_token_secret: env::var("REFRESH_TOKEN_SECRET")
|
||||
.unwrap_or_else(|_| "default_refresh_secret".to_string()),
|
||||
|
||||
surrealdb_url: env::var("SURREALDB_URL").unwrap_or_else(|_| {
|
||||
println!(
|
||||
"WARNING: SURREALDB_URL is not set, using fallback 'http://localhost:8000'!"
|
||||
);
|
||||
"http://localhost:8000".to_string()
|
||||
}),
|
||||
surrealdb_url: env::var("SURREALDB_URL")
|
||||
.unwrap_or_else(|_| "http://localhost:8000".to_string()),
|
||||
|
||||
surrealdb_username: env::var("SURREALDB_USERNAME").unwrap_or_else(|_| {
|
||||
println!("WARNING: SURREALDB_USERNAME is not set, using fallback 'root'!");
|
||||
"root".to_string()
|
||||
}),
|
||||
surrealdb_username: env::var("SURREALDB_USERNAME")
|
||||
.unwrap_or_else(|_| "root".to_string()),
|
||||
|
||||
surrealdb_password: env::var("SURREALDB_PASSWORD").unwrap_or_else(|_| {
|
||||
println!("WARNING: SURREALDB_PASSWORD is not set, using fallback!");
|
||||
"password".to_string()
|
||||
}),
|
||||
surrealdb_password: env::var("SURREALDB_PASSWORD")
|
||||
.unwrap_or_else(|_| "password".to_string()),
|
||||
|
||||
surrealdb_namespace: env::var("SURREALDB_NAMESPACE").unwrap_or_else(|_| {
|
||||
println!(
|
||||
"WARNING: SURREALDB_NAMESPACE is not set, using fallback 'namespace'!"
|
||||
);
|
||||
"namespace".to_string()
|
||||
}),
|
||||
surrealdb_namespace: env::var("SURREALDB_NAMESPACE")
|
||||
.unwrap_or_else(|_| "namespace".to_string()),
|
||||
|
||||
surrealdb_dbname: env::var("SURREALDB_DBNAME").unwrap_or_else(|_| {
|
||||
println!("WARNING: SURREALDB_DBNAME is not set, using fallback 'database'!");
|
||||
"database".to_string()
|
||||
}),
|
||||
surrealdb_dbname: env::var("SURREALDB_DBNAME")
|
||||
.unwrap_or_else(|_| "database".to_string()),
|
||||
|
||||
smtp_email: env::var("SMTP_EMAIL").unwrap_or_else(|_| {
|
||||
println!(
|
||||
"WARNING: SMTP_EMAIL is not set, using fallback 'no-reply@example.com'!"
|
||||
);
|
||||
"no-reply@example.com".to_string()
|
||||
}),
|
||||
surrealdb_url_ws: env::var("SURREALDB_URL_WS")
|
||||
.unwrap_or_else(|_| "ws://localhost:8000/rpc".to_string()),
|
||||
|
||||
smtp_password: env::var("SMTP_PASSWORD").unwrap_or_else(|_| {
|
||||
println!("WARNING: SMTP_PASSWORD is not set, using fallback!");
|
||||
"default_smtp_password".to_string()
|
||||
}),
|
||||
smtp_email: env::var("SMTP_EMAIL")
|
||||
.unwrap_or_else(|_| "no-reply@example.com".to_string()),
|
||||
|
||||
smtp_name: env::var("SMTP_NAME").unwrap_or_else(|_| {
|
||||
println!("WARNING: SMTP_NAME is not set, using fallback 'MyApp SMTP'!");
|
||||
"MyApp SMTP".to_string()
|
||||
}),
|
||||
smtp_password: env::var("SMTP_PASSWORD")
|
||||
.unwrap_or_else(|_| "default_smtp_password".to_string()),
|
||||
|
||||
smtp_host: env::var("SMTP_HOST").unwrap_or_else(|_| {
|
||||
println!("WARNING: SMTP_HOST is not set, using fallback 'smtp.gmail.com'!");
|
||||
"smtp.gmail.com".to_string()
|
||||
}),
|
||||
smtp_name: env::var("SMTP_NAME").unwrap_or_else(|_| "MyApp SMTP".to_string()),
|
||||
|
||||
redisdb_url: env::var("REDISDB_URL").unwrap_or_else(|_| {
|
||||
println!("WARNING: REDISDB_URL is not set, using fallback 'localhost'!");
|
||||
"localhost".to_string()
|
||||
}),
|
||||
smtp_host: env::var("SMTP_HOST")
|
||||
.unwrap_or_else(|_| "smtp.gmail.com".to_string()),
|
||||
|
||||
fe_url: env::var("FE_URL").unwrap_or_else(|_| {
|
||||
println!("WARNING: FE_URL is not set, using fallback 'http://localhost'!");
|
||||
"http://localhost".to_string()
|
||||
}),
|
||||
redisdb_url: env::var("REDISDB_URL")
|
||||
.unwrap_or_else(|_| "localhost".to_string()),
|
||||
|
||||
minio_endpoint: env::var("MINIO_ENDPOINT").unwrap_or_else(|_| {
|
||||
println!(
|
||||
"WARNING: MINIO_ENDPOINT is not set, using fallback 'http://localhost:9000'!"
|
||||
);
|
||||
"http://localhost:9000".to_string()
|
||||
}),
|
||||
fe_url: env::var("FE_URL").unwrap_or_else(|_| "http://localhost".to_string()),
|
||||
|
||||
minio_bucket_name: env::var("MINIO_BUCKET_NAME").unwrap_or_else(|_| {
|
||||
println!(
|
||||
"WARNING: MINIO_BUCKET_NAME is not set, using fallback 'default_bucket'!"
|
||||
);
|
||||
"default_bucket".to_string()
|
||||
}),
|
||||
minio_endpoint: env::var("MINIO_ENDPOINT")
|
||||
.unwrap_or_else(|_| "http://localhost:9000".to_string()),
|
||||
|
||||
minio_access_key: env::var("MINIO_ACCESS_KEY").unwrap_or_else(|_| {
|
||||
println!("WARNING: MINIO_ACCESS_KEY is not set, using fallback!");
|
||||
"minio_access".to_string()
|
||||
}),
|
||||
minio_bucket_name: env::var("MINIO_BUCKET_NAME")
|
||||
.unwrap_or_else(|_| "default_bucket".to_string()),
|
||||
|
||||
minio_secret_key: env::var("MINIO_SECRET_KEY").unwrap_or_else(|_| {
|
||||
println!("WARNING: MINIO_SECRET_KEY is not set, using fallback!");
|
||||
"minio_secret".to_string()
|
||||
}),
|
||||
minio_access_key: env::var("MINIO_ACCESS_KEY")
|
||||
.unwrap_or_else(|_| "minio_access".to_string()),
|
||||
|
||||
minio_secret_key: env::var("MINIO_SECRET_KEY")
|
||||
.unwrap_or_else(|_| "minio_secret".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use super::Env;
|
||||
use axum::http::StatusCode;
|
||||
use chrono::{Duration, TimeDelta, Utc};
|
||||
use jsonwebtoken::{
|
||||
decode, encode, DecodingKey, EncodingKey, Header, TokenData, Validation,
|
||||
DecodingKey, EncodingKey, Header, TokenData, Validation, decode, encode,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -51,7 +51,7 @@ pub fn decode_access_token(
|
||||
let env = Env::new();
|
||||
let secret: String = env.access_token_secret;
|
||||
let result: Result<TokenData<Claims>, StatusCode> = decode(
|
||||
&jwt_token,
|
||||
jwt_token,
|
||||
&DecodingKey::from_secret(secret.as_ref()),
|
||||
&Validation::default(),
|
||||
)
|
||||
@@ -81,7 +81,7 @@ pub fn decode_refresh_token(
|
||||
let env = Env::new();
|
||||
let secret: String = env.refresh_token_secret;
|
||||
let result: Result<TokenData<Claims>, StatusCode> = decode(
|
||||
&jwt_token,
|
||||
jwt_token,
|
||||
&DecodingKey::from_secret(secret.as_ref()),
|
||||
&Validation::default(),
|
||||
)
|
||||
|
||||
@@ -29,13 +29,7 @@ pub fn send_email(
|
||||
.credentials(smtp_credentials)
|
||||
.build();
|
||||
match mailer.send(&email) {
|
||||
Ok(_) => {
|
||||
println!("Email sent successfully to {}", to);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to send email: {}", e);
|
||||
Err(Box::new(e))
|
||||
}
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(Box::new(e)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::Env;
|
||||
use crate::SurrealMemClient;
|
||||
use surrealdb::engine::local::Mem;
|
||||
use crate::enviroment::load_env;
|
||||
use surrealdb::engine::any;
|
||||
use surrealdb::engine::local::Mem;
|
||||
use surrealdb::opt::auth::Root;
|
||||
use surrealdb::{Result, Surreal};
|
||||
use crate::enviroment::load_env;
|
||||
|
||||
pub mod resource;
|
||||
pub use resource::*;
|
||||
@@ -13,7 +13,6 @@ pub async fn surrealdb_init_ws() -> Result<Surreal<any::Any>> {
|
||||
load_env();
|
||||
let env = Env::new();
|
||||
let db = any::connect(&env.surrealdb_url).await?;
|
||||
|
||||
|
||||
db.signin(Root {
|
||||
username: &env.surrealdb_username,
|
||||
|
||||
@@ -14,6 +14,7 @@ pub enum ResourceEnum {
|
||||
RolesPermissions,
|
||||
Events,
|
||||
Testimonials,
|
||||
Mentors,
|
||||
}
|
||||
|
||||
impl fmt::Display for ResourceEnum {
|
||||
@@ -31,7 +32,8 @@ impl fmt::Display for ResourceEnum {
|
||||
ResourceEnum::GachaCredits => "app_gacha_credits",
|
||||
ResourceEnum::Events => "app_events",
|
||||
ResourceEnum::Testimonials => "app_testimonials",
|
||||
ResourceEnum::Mentors => "app_mentors",
|
||||
};
|
||||
write!(f, "{}", str)
|
||||
write!(f, "{str}")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user