mod common; use df_st_core::config::*; #[allow(unused_imports)] use log::{debug, error, info, trace, warn}; use serde_json::json; use std::path::PathBuf; fn setup() { common::setup(); } // ----------------------------- // --------- Unit Tests -------- // ----------------------------- mod get_database_url_tests { use super::*; #[test] #[should_panic] fn get_database_url_unknown_service() { let config = RootConfig { database: DatabaseConfig { service: Some("".to_owned()), ..Default::default() }, ..Default::default() }; // Should panic here get_database_url(&config, &DBService::Unknown); } #[test] fn get_database_url_default_service() { let config = RootConfig { ..Default::default() }; assert_eq!( get_database_url(&config, &DBService::SQLite), Some( get_default_store_sqlite_db_path() .to_str() .unwrap() .to_string() ), "Database url default incorrect." ); } #[test] fn get_database_url_none_service() { let config = RootConfig { database: DatabaseConfig { service: None, ..Default::default() }, ..Default::default() }; assert_eq!( get_database_url(&config, &DBService::SQLite), Some( get_default_store_sqlite_db_path() .to_str() .unwrap() .to_string() ), "Database url for `None` service incorrect." ); } #[test] fn get_database_url_sqlite_default_path() { let config = RootConfig { database: DatabaseConfig { service: Some("sqlite".to_owned()), config: DBURLConfig { db_path: None, ..Default::default() }, ..Default::default() }, ..Default::default() }; assert_eq!( get_database_url(&config, &DBService::SQLite), Some("df_st_database.db".to_owned()), "Database url sqlite `db_path` incorrect." ); } #[test] fn get_database_url_sqlite() { let config = RootConfig { database: DatabaseConfig { service: Some("sqlite".to_owned()), config: DBURLConfig { db_path: Some(PathBuf::from("testfile.db")), ..Default::default() }, ..Default::default() }, ..Default::default() }; assert_eq!( get_database_url(&config, &DBService::SQLite), Some("testfile.db".to_owned()), "Database url sqlite `db_path` incorrect." ); } #[test] fn get_database_url_postgres() { let config = RootConfig { database: DatabaseConfig { service: Some("postgres".to_owned()), config: DBURLConfig { user: Some("username".to_owned()), password: "password".to_owned(), host: Some("hostname".to_owned()), port: Some(5400), database: Some("db_name".to_owned()), ..Default::default() }, ..Default::default() }, ..Default::default() }; assert_eq!( get_database_url(&config, &DBService::Postgres), Some("postgres://username:password@hostname:5400/db_name?sslmode=prefer&application_name=DF_Storyteller".to_owned()), "Database url postgres: normal format incorrect." ); // Use SSL Cert + None values let config = RootConfig { database: DatabaseConfig { service: Some("postgres".to_owned()), config: DBURLConfig { user: None, password: "password".to_owned(), host: None, port: None, database: None, ssl_mode: Some("require".to_owned()), ssl_cert: Some(std::path::PathBuf::from("./ssl_my_cert.crt")), ssl_key: Some(std::path::PathBuf::from("./ssl_my_cert.key")), ..Default::default() }, ..Default::default() }, ..Default::default() }; assert_eq!( get_database_url(&config, &DBService::Postgres), Some( "postgres://df_storyteller:password@localhost:5432/df_storyteller?sslmode=require\ &sslcert=./ssl_my_cert.crt&sslkey=./ssl_my_cert.key\ &application_name=DF_Storyteller" .to_owned() ), "Database url postgres: SSL + None values incorrect." ); // Use SSL Cert no key let config = RootConfig { database: DatabaseConfig { service: Some("postgres".to_owned()), config: DBURLConfig { user: Some("username".to_owned()), password: "password".to_owned(), host: Some("hostname".to_owned()), port: Some(5400), database: Some("db_name".to_owned()), ssl_mode: Some("require".to_owned()), ssl_cert: Some(std::path::PathBuf::from("./ssl_my_cert.crt")), ..Default::default() }, ..Default::default() }, ..Default::default() }; assert_eq!( get_database_url(&config, &DBService::Postgres), Some( "postgres://username:password@hostname:5400/db_name?sslmode=require\ &sslcert=./ssl_my_cert.crt\ &application_name=DF_Storyteller" .to_owned() ), "Database url postgres: normal format incorrect." ); } #[test] fn get_database_url_uri() { let config = RootConfig { database: DatabaseConfig { // See if switching service works service: Some("postgres".to_owned()), uri: Some("test_sqlite.db".to_owned()), ..Default::default() }, ..Default::default() }; assert_eq!( get_database_url(&config, &DBService::SQLite), Some("test_sqlite.db".to_owned()), "Database url set in config is not used." ); } } mod get_db_system_url_tests { use super::*; #[test] fn get_db_system_url_postgres() { let config = RootConfig { database: DatabaseConfig { service: Some("postgres".to_owned()), config: DBURLConfig { user: Some("username".to_owned()), password: "password".to_owned(), host: Some("hostname".to_owned()), port: Some(5400), database: Some("db_name".to_owned()), ..Default::default() }, ..Default::default() }, ..Default::default() }; assert_eq!( get_db_system_url(&config, &DBService::Postgres), Some("postgres://username:password@hostname:5400/postgres".to_owned()), "Database system url for postgres incorrect." ); } #[test] #[should_panic] fn get_db_system_url_non_postgres() { let config = RootConfig { database: DatabaseConfig { service: Some("sqlite".to_owned()), ..Default::default() }, ..Default::default() }; assert_eq!( get_db_system_url(&config, &DBService::SQLite), None, "Database system url should only be used with postgres service." ); } #[test] fn get_database_url_defaults() { let config = RootConfig { database: DatabaseConfig { service: Some("postgres".to_owned()), config: DBURLConfig { user: None, password: "password".to_owned(), host: None, port: None, ..Default::default() }, ..Default::default() }, ..Default::default() }; assert_eq!( get_db_system_url(&config, &DBService::Postgres), Some("postgres://postgres:password@localhost:5432/postgres".to_owned()), "Database system url default incorrect." ); } #[test] fn get_database_url_default_service() { let config = RootConfig { database: DatabaseConfig { service: None, ..Default::default() }, ..Default::default() }; assert_eq!( get_db_system_url(&config, &DBService::Postgres), Some("postgres://df_storyteller:@localhost:5432/postgres".to_owned()), "Database system url default incorrect." ); } #[test] fn get_db_system_url_uri() { let config = RootConfig { database: DatabaseConfig { service: Some("postgres".to_owned()), uri: Some("postgres://user:pass@host:5400/db_name".to_owned()), ..Default::default() }, ..Default::default() }; assert_eq!( get_db_system_url(&config, &DBService::Postgres), Some("postgres://user:pass@host:5400/db_name".to_owned()), "Database system uri set in config is not used." ); } } #[test] fn db_url_config_debug() { let config = DBURLConfig { db_path: Some(std::path::PathBuf::from("db_path.db")), user: Some("username".to_owned()), password: "password".to_owned(), host: Some("hostname".to_owned()), port: Some(5400), database: Some("db_name".to_owned()), ssl_mode: Some("require".to_owned()), ssl_cert: Some(std::path::PathBuf::from("./ssl_my_cert.crt")), ssl_key: Some(std::path::PathBuf::from("./ssl_my_cert.key")), ..Default::default() }; assert_eq!( format!("{:#?}", config), "DBURLConfig { db_path: Some( \"db_path.db\", ), user: Some( \"username\", ), password: \"[redacted]\", host: Some( \"hostname\", ), port: Some( 5400, ), database: Some( \"db_name\", ), ssl_mode: Some( \"require\", ), ssl_cert: Some( \"./ssl_my_cert.crt\", ), ssl_key: Some( \"./ssl_my_cert.key\", ), }" .to_owned(), "Printing of Debug info incorrect." ); } // ----------------------------- // ----- Integration Tests ----- // ----------------------------- #[test] fn create_default_config_file() { setup(); let temp_dir = common::get_temp_dir(); let filename = temp_dir.path().join("./df_storyteller-config-1.json"); let config = RootConfig::default(); store_config_to_file(config, Some(&filename)); let db_path = get_default_store_sqlite_db_path() .to_str() .unwrap() .to_string(); let result = json!({ "local_address": "127.0.0.1", "server": { "address": "127.0.0.1", "port": 20350 }, "database": { "service": "sqlite", "config": { "db_path": db_path, "user": "df_storyteller", "password": "", "host": "localhost", "port": 5432, "database": "df_storyteller" } } }); assert_eq!( common::get_file(&filename), serde_json::to_string_pretty(&result).unwrap() ); } #[test] fn get_config_file_default() { setup(); let temp_dir = common::get_temp_dir(); let filename = temp_dir.path().join("./df_storyteller-config-2.json"); let config = RootConfig::default(); store_config_to_file(config.clone(), Some(&filename)); assert_eq!(get_config(&filename), config); } #[test] fn get_config_file_custom() { setup(); let temp_dir = common::get_temp_dir(); let filename = temp_dir.path().join("./df_storyteller-config-3.json"); let config = RootConfig { local_address: "127.0.0.1".to_owned(), server: ServerConfig { address: Some("127.0.0.1".to_owned()), port: Some(20350), workers: Some(8), keep_alive: Some(20), log_level: Some("Normal".to_owned()), secret_key: Some("FYyW1t+y.y+nBppoFx..$..VVVs5XrQD/yC.yHZFqZw=".to_owned()), tls: Some(TLSConfig { certs: "./cert.pem".to_owned(), private_key: "./key.pem".to_owned(), }), limits: Some(LimitsConfig { values: { let mut values = std::collections::HashMap::::new(); values.insert("json".to_owned(), 256); values }, }), }, database: DatabaseConfig { service: Some("postgres".to_owned()), uri: Some("test_sqlite.db".to_owned()), config: DBURLConfig { db_path: Some(PathBuf::from("db_name.db")), user: Some("username".to_owned()), password: "password".to_owned(), host: Some("hostname".to_owned()), port: Some(5400), database: Some("db_name".to_owned()), ssl_mode: Some("require".to_owned()), ssl_cert: Some(PathBuf::from("./ssl_my_cert.crt")), ssl_key: Some(PathBuf::from("./ssl_my_cert.key")), }, pool_size: Some(12), }, ..Default::default() }; store_config_to_file(config.clone(), Some(&filename)); assert_eq!(get_config(&filename), config); } #[test] fn get_config_file_missing() { setup(); let temp_dir = common::get_temp_dir(); let filename = temp_dir.path().join("./df_storyteller-config-missing.json"); let config = RootConfig::default(); assert_eq!(get_config(&filename), config); } #[test] fn get_config_file_is_dir() { setup(); let temp_dir = common::get_temp_dir(); let filename = temp_dir.path().join("./df_storyteller-config-dir.json"); if !filename.exists() { std::fs::create_dir(&filename).unwrap(); } let config = RootConfig::default(); assert_eq!(get_config(&filename), config); } #[test] fn get_config_file_is_invalid_json() { use std::io::prelude::*; setup(); let temp_dir = common::get_temp_dir(); let filename = temp_dir .path() .join("./df_storyteller-config-invalid-json.json"); let mut file = std::fs::File::create(&filename).unwrap(); file.write_all( b"{ \"local_address\": \"127.0.0.1\", \"error here: \"and extra comma\", }", ) .unwrap(); let config = RootConfig::default(); assert_eq!(get_config(&filename), config); } /// Returns an IO error /// kind: InvalidInput, error: "data provided contains a nul byte" #[test] fn get_config_file_invalid_filename() { setup(); let temp_dir = common::get_temp_dir(); let filename = temp_dir .path() .join("./df_storyteller-invalid-filename\0.json"); let config = RootConfig::default(); assert_eq!(get_config(&filename), config); }