Compare commits

...

4 commits

6 changed files with 104 additions and 27 deletions

41
Cargo.lock generated
View file

@ -627,6 +627,7 @@ dependencies = [
"migration", "migration",
"sea-orm", "sea-orm",
"serde", "serde",
"serial_test",
"temp-env", "temp-env",
"thiserror 2.0.12", "thiserror 2.0.12",
"tracing-actix-web", "tracing-actix-web",
@ -2803,12 +2804,27 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "scc"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22b2d775fb28f245817589471dd49c5edf64237f4a19d10ce9a92ff4651a27f4"
dependencies = [
"sdd",
]
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sdd"
version = "3.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "584e070911c7017da6cb2eb0788d09f43d789029b5877d3e5ecc8acf86ceee21"
[[package]] [[package]]
name = "sea-bae" name = "sea-bae"
version = "0.2.1" version = "0.2.1"
@ -3024,6 +3040,31 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serial_test"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9"
dependencies = [
"futures",
"log",
"once_cell",
"parking_lot",
"scc",
"serial_test_derive",
]
[[package]]
name = "serial_test_derive"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.100",
]
[[package]] [[package]]
name = "sha1" name = "sha1"
version = "0.10.6" version = "0.10.6"

View file

@ -31,6 +31,7 @@ dotenvy = "0.15"
[dev-dependencies] [dev-dependencies]
temp-env = "*" temp-env = "*"
serial_test = "*"
[features] [features]
serve = [] serve = []

View file

@ -8,26 +8,31 @@ pub fn setup(cfg: &mut actix_web::web::ServiceConfig) {
.service(delete_class); .service(delete_class);
} }
// TODO
#[get("")] #[get("")]
async fn get_classes() -> impl Responder { async fn get_classes() -> impl Responder {
"" ""
} }
// TODO
#[get("/{id}")] #[get("/{id}")]
async fn get_class() -> impl Responder { async fn get_class() -> impl Responder {
"" ""
} }
// TODO
#[post("")] #[post("")]
async fn create_class() -> impl Responder { async fn create_class() -> impl Responder {
"" ""
} }
// TODO
#[put("")] #[put("")]
async fn update_class() -> impl Responder { async fn update_class() -> impl Responder {
"" ""
} }
// TODO
#[delete("/{id}")] #[delete("/{id}")]
async fn delete_class() -> impl Responder { async fn delete_class() -> impl Responder {
"" ""

View file

@ -8,26 +8,31 @@ pub fn setup(cfg: &mut actix_web::web::ServiceConfig) {
.service(delete_group); .service(delete_group);
} }
// TODO
#[get("")] #[get("")]
async fn get_groups() -> impl Responder { async fn get_groups() -> impl Responder {
"" ""
} }
// TODO
#[get("/{project}")] #[get("/{project}")]
async fn get_groups_for_project() -> impl Responder { async fn get_groups_for_project() -> impl Responder {
"" ""
} }
// TODO
#[post("")] #[post("")]
async fn create_group() -> impl Responder { async fn create_group() -> impl Responder {
"" ""
} }
// TODO
#[put("")] #[put("")]
async fn update_group() -> impl Responder { async fn update_group() -> impl Responder {
"" ""
} }
// TODO
#[delete("/{id}")] #[delete("/{id}")]
async fn delete_group() -> impl Responder { async fn delete_group() -> impl Responder {
"" ""

View file

@ -8,26 +8,31 @@ pub fn setup(cfg: &mut actix_web::web::ServiceConfig) {
.service(delete_template); .service(delete_template);
} }
// TODO
#[get("")] #[get("")]
async fn get_templates() -> impl Responder { async fn get_templates() -> impl Responder {
"" ""
} }
// TODO
#[get("/{id}")] #[get("/{id}")]
async fn get_template() -> impl Responder { async fn get_template() -> impl Responder {
"" ""
} }
// TODO
#[post("")] #[post("")]
async fn create_template() -> impl Responder { async fn create_template() -> impl Responder {
"" ""
} }
// TODO
#[put("")] #[put("")]
async fn update_template() -> impl Responder { async fn update_template() -> impl Responder {
"" ""
} }
// TODO
#[delete("/{id}")] #[delete("/{id}")]
async fn delete_template() -> impl Responder { async fn delete_template() -> impl Responder {
"" ""

View file

@ -76,9 +76,19 @@ async fn main() -> std::io::Result<()> {
.await .await
} }
#[cfg(not(test))]
fn get_env_var(name: &str) -> dotenvy::Result<String> {
dotenvy::var(name)
}
#[cfg(test)]
fn get_env_var(name: &str) -> Result<String, std::env::VarError> {
std::env::var(name)
}
async fn connect_to_redis_database() -> RedisSessionStore { async fn connect_to_redis_database() -> RedisSessionStore {
let redis_host = dotenvy::var("REDIS_HOST").expect("REDIS_HOST must be set in .env"); let redis_host = get_env_var("REDIS_HOST").expect("REDIS_HOST must be set in .env");
let redis_port = dotenvy::var("REDIS_PORT") let redis_port = get_env_var("REDIS_PORT")
.map(|x| x.parse::<u16>().expect("REDIS_PORT is not a valid port")) .map(|x| x.parse::<u16>().expect("REDIS_PORT is not a valid port"))
.unwrap_or(6379); .unwrap_or(6379);
let redis_connection_string = format!("redis://{}:{}", redis_host, redis_port); let redis_connection_string = format!("redis://{}:{}", redis_host, redis_port);
@ -86,15 +96,15 @@ async fn connect_to_redis_database() -> RedisSessionStore {
.await .await
.unwrap(); .unwrap();
return store; store
} }
fn build_database_url() -> String { fn build_database_url() -> String {
let db_user = dotenvy::var("DB_USER").unwrap_or("pgg".to_owned()); let db_user = get_env_var("DB_USER").unwrap_or_else(|_| "pgg".to_owned());
let db_name = dotenvy::var("DB_NAME").unwrap_or("pgg".to_owned()); let db_name = get_env_var("DB_NAME").unwrap_or_else(|_| "pgg".to_owned());
let db_password = dotenvy::var("DB_PASSWORD").unwrap_or("pgg".to_owned()); let db_password = get_env_var("DB_PASSWORD").unwrap_or_else(|_| "pgg".to_owned());
let db_host = dotenvy::var("DB_HOST").expect("DB_HOST must be set in .env"); let db_host = get_env_var("DB_HOST").expect("DB_HOST must be set in .env");
let db_port = dotenvy::var("DB_PORT") let db_port = get_env_var("DB_PORT")
.map(|x| x.parse::<u16>().expect("DB_PORT is not a valid port")) .map(|x| x.parse::<u16>().expect("DB_PORT is not a valid port"))
.unwrap_or(5432); .unwrap_or(5432);
@ -109,18 +119,17 @@ fn build_database_url() -> String {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::env;
use serial_test::serial;
use super::*; use super::*;
use temp_env::{with_vars, with_vars_unset}; use temp_env::{with_var, with_vars};
#[test] #[test]
#[serial]
fn build_database_url_with_defaults() { fn build_database_url_with_defaults() {
temp_env::with_vars( with_vars(
[ [
("DB_USER", None::<&str>),
("DB_NAME", None::<&str>),
("DB_PASSWORD", None::<&str>),
("DB_HOST", Some("localhost")), ("DB_HOST", Some("localhost")),
("DB_PORT", None::<&str>),
], ],
|| { || {
let expected_url = "postgresql://pgg:pgg@localhost:5432/pgg"; let expected_url = "postgresql://pgg:pgg@localhost:5432/pgg";
@ -134,6 +143,7 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn build_database_url_with_all_vars() { fn build_database_url_with_all_vars() {
with_vars( with_vars(
[ [
@ -155,29 +165,26 @@ mod tests {
} }
#[test] #[test]
#[serial]
#[should_panic(expected = "DB_HOST must be set in .env")] #[should_panic(expected = "DB_HOST must be set in .env")]
fn build_database_url_missing_host_panics() { fn build_database_url_missing_host_panics() {
// Clear the environment variable completely with_var("DB_HOST", None::<&str>, || {
unsafe { std::env::remove_var("DB_HOST") }; build_database_url();
build_database_url(); });
} }
#[test] #[test]
#[serial]
fn connect_to_redis_database_with_defaults() { fn connect_to_redis_database_with_defaults() {
// This test requires a running Redis instance
// We're mocking the successful connection here
with_vars( with_vars(
[ [
("REDIS_HOST", Some("localhost")), ("REDIS_HOST", Some("localhost")),
("REDIS_PORT", None::<&str>),
], ],
|| { || {
let expected_conn_string = "redis://localhost:6379"; let expected_conn_string = "redis://localhost:6379";
// Just verify the connection string format is correct let redis_host = get_env_var("REDIS_HOST").unwrap_or_default();
// Actual connection would need integration tests let redis_port = get_env_var("REDIS_PORT")
let redis_host = dotenvy::var("REDIS_HOST").unwrap_or_default();
let redis_port = dotenvy::var("REDIS_PORT")
.map(|x| x.parse::<u16>().unwrap_or(6379)) .map(|x| x.parse::<u16>().unwrap_or(6379))
.unwrap_or(6379); .unwrap_or(6379);
let actual_conn_string = format!("redis://{}:{}", redis_host, redis_port); let actual_conn_string = format!("redis://{}:{}", redis_host, redis_port);
@ -191,6 +198,7 @@ mod tests {
} }
#[test] #[test]
#[serial]
fn connect_to_redis_database_with_custom_port() { fn connect_to_redis_database_with_custom_port() {
with_vars( with_vars(
[ [
@ -200,9 +208,8 @@ mod tests {
|| { || {
let expected_conn_string = "redis://redis.internal:6380"; let expected_conn_string = "redis://redis.internal:6380";
// Verify connection string format let redis_host = get_env_var("REDIS_HOST").unwrap_or_default();
let redis_host = dotenvy::var("REDIS_HOST").unwrap_or_default(); let redis_port = get_env_var("REDIS_PORT")
let redis_port = dotenvy::var("REDIS_PORT")
.map(|x| x.parse::<u16>().unwrap_or(6379)) .map(|x| x.parse::<u16>().unwrap_or(6379))
.unwrap_or(6379); .unwrap_or(6379);
let actual_conn_string = format!("redis://{}:{}", redis_host, redis_port); let actual_conn_string = format!("redis://{}:{}", redis_host, redis_port);
@ -214,4 +221,17 @@ mod tests {
}, },
); );
} }
#[test]
#[serial]
fn check_if_no_env_variables_are_loaded_from_environment_file() {
assert_eq!(env::var("DB_NAME"), Err(env::VarError::NotPresent));
assert_eq!(env::var("DB_USER"), Err(env::VarError::NotPresent));
assert_eq!(env::var("DB_PASSWORD"), Err(env::VarError::NotPresent));
assert_eq!(env::var("DB_HOST"), Err(env::VarError::NotPresent));
assert_eq!(env::var("DB_PORT"), Err(env::VarError::NotPresent));
assert_eq!(env::var("REDIS_PORT"), Err(env::VarError::NotPresent));
assert_eq!(env::var("REDIS_HOST"), Err(env::VarError::NotPresent));
}
} }