Avarice_old/src/database/tests.rs

381 lines
14 KiB
Rust

use super::*;
use serde_json::json;
use std::fs;
use std::path;
const TEST_DB_PATH: &str = "./fixtures/database";
const TEST_DB_MOVED_PATH: &str = "./fixtures/moved";
const NO_DB_MESSAGE: &str = "Can not find/load test database";
struct TestCleanup {
path: String,
clear_moved: bool,
}
impl Drop for TestCleanup {
fn drop(&mut self) {
let _ = fs::remove_dir_all(&self.path);
if self.clear_moved {
let _ = fs::remove_dir_all(TEST_DB_MOVED_PATH);
}
}
}
fn prepare_db_copy(copy_id: &str, clear_moved: bool) -> (String, TestCleanup) {
let path = format!("{}_{}", TEST_DB_PATH, copy_id);
let original_db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
original_db
.write_copy(path::Path::new(&path))
.expect("Should be able to create a new copy of the fixture database.");
(
path.clone(),
TestCleanup {
path: path.to_owned(),
clear_moved: clear_moved,
},
)
}
#[test]
fn db_path() {
let mut db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
assert!(db.path() == path::Path::new(TEST_DB_PATH));
}
#[test]
fn db_clear() {
let mut db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
db.clear();
assert!(!db.contains_group("game"));
assert!(!db.contains_file("administration", "registered"));
let names = db.group_names();
assert_eq!(names.len(), 0);
}
#[test]
fn db_group_names() {
let db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
let names = db.group_names();
assert!(names.contains(&"administration".to_owned()));
assert!(names.contains(&"game".to_owned()));
assert_eq!(names.len(), 2);
}
#[test]
fn db_file_names() {
let db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
let names_admin = db.file_names_in("administration");
let names_game = db.file_names_in("game");
assert!(names_admin.contains(&"registered".to_owned()));
assert!(names_game.contains(&"general".to_owned()));
assert!(names_game.contains(&"perks".to_owned()));
assert_eq!(names_admin.len(), 1);
assert_eq!(names_game.len(), 2);
}
#[test]
fn db_group_check() {
let db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
assert!(db.contains_group("game"));
assert!(db.contains_group("administration"));
assert!(!db.contains_group("perks"));
assert!(!db.contains_group("7random7"));
assert!(!db.contains_group(""));
}
#[test]
fn db_group_remove() -> Result<(), Box<dyn Error>> {
let mut db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
// Success
db.remove_group("administration")?;
db.remove_group("game")?;
assert!(!db.contains_group("administration"));
assert!(!db.contains_group("game"));
// Failure
db.remove_group("test")
.expect_err("Testing whether removing non-existent groups with incorrect ASCII characters causes errors.");
db.remove_group("administration")
.expect_err("Testing whether removing non-existent groups with incorrect ASCII characters causes errors.");
db.remove_group("game group").expect_err(
"Testing whether removing non-existent groups with whitespace characters causes errors.",
);
Ok(())
}
#[test]
fn db_group_create() -> Result<(), Box<dyn Error>> {
let mut db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
// Success
db.create_group("7random7")?;
assert!(db.contains_group("7random7"));
assert!(db.contains_group("game"));
// Failure
db.create_group("my_group").expect_err(
"Testing whether creating groups with incorrect ASCII characters causes errors.",
);
db.create_group("my group")
.expect_err("Testing whether creating groups with whitespace characters causes errors.");
db.create_group("Жgroup")
.expect_err("Testing whether creating groups with non-ASCII characters causes errors.");
// Create after removal
db.remove_group("game")?;
assert!(!db.contains_group("game"));
db.create_group("game")?;
assert!(db.contains_group("game"));
assert!(db.file_names_in("game").is_empty());
Ok(())
}
#[test]
fn db_file_check() {
let mut db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
// Success
assert!(db.contains_file("administration", "registered"));
assert!(db.file("game", "general").is_some());
assert!(db.file_mut("game", "perks").is_some());
// Failure
assert!(!db.contains_file("game", "perk"));
assert!(db.file("games", "perks").is_none());
assert!(db.file_mut("random", "rnd_file").is_none());
}
#[test]
fn db_file_create() -> Result<(), Box<dyn Error>> {
let mut db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
// Success
let file = db.create_file("administration", "secrets")?;
assert_eq!(file.to_string(), "{}");
assert!(db.contains_file("administration", "secrets"));
assert!(db.contains_file("game", "perks"));
// Failure
db.create_file("administration", "secrets")
.expect_err("Testing whether creating existing file causes errors.");
db.create_file("none", "secrets")
.expect_err("Testing whether creating existing file in non-existent group causes errors.");
db.create_file("game", "sec_rets")
.expect_err("Testing whether creating existing file with invalid name causes errors.");
Ok(())
}
#[test]
fn db_file_remove() -> Result<(), Box<dyn Error>> {
let mut db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
// Success
db.remove_file("administration", "registered")?;
assert!(!db.contains_file("administration", "registered"));
assert!(db.contains_group("administration"));
db.remove_file("game", "perks")?;
assert_eq!(db.file_names_in("game").len(), 1);
// Failure
db.remove_file("administration", "registered")
.expect_err("Testing whether removing non-existent files causes errors.");
db.remove_file("administration", "never")
.expect_err("Testing whether removing non-existent files causes errors.");
db.remove_file("never", "file")
.expect_err("Testing whether removing non-existent files causes errors.");
Ok(())
}
#[test]
fn file_json_contents() {
let db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
let registered = db.file("administration", "registered").unwrap().root();
let user_map = registered
.as_object()
.expect("Read value is not an object.");
assert_eq!(user_map.len(), 2);
assert!(user_map.contains_key("76561198025127722"));
let user_record = user_map
.get("76561198044316328")
.unwrap()
.as_object()
.unwrap();
assert_eq!(user_record.len(), 3);
assert_eq!(user_record.get("ip_lock").unwrap().as_bool(), Some(false));
assert_eq!(
user_record.get("password_hash").unwrap().as_str(),
Some("fce798e0804dfb217f929bdba26745024f37f6b6ba7406f3775176e20dd5089d")
);
let groups_arrays = user_record.get("groups").unwrap().as_array().unwrap();
assert_eq!(groups_arrays.len(), 1);
assert_eq!(groups_arrays[0], "admin");
}
#[test]
fn file_json_get() {
let db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
// Test empty path
let file = db.file("administration", "registered").unwrap();
assert_eq!(file.root(), file.get("").unwrap());
// Test complex path
let expected = file.get("/76561198025127722/allowed_ips/1").unwrap();
assert_eq!(expected.as_str().unwrap(), "192.168.0.100");
// Test bad paths
assert!(file.get("/777") == None);
assert!(file.get("/76561198025127722/allowed_ips/2") == None);
}
#[test]
fn file_contains_check() {
let db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
let registered_file = db.file("administration", "registered").unwrap();
let perks_file = db.file("game", "perks").unwrap();
// These exist
assert!(registered_file.contains("/76561198025127722/password_hash"));
assert!(registered_file.contains("/76561198044316328/groups/0"));
assert!(perks_file.contains("/76561198025127722/headshots"));
assert!(perks_file.contains("/76561198044316328"));
// These do not exist
assert!(!registered_file.contains("/76561198025127722/password/"));
assert!(!registered_file.contains("/76561198044316328/groups/2"));
assert!(!perks_file.contains("/76561198025127722/assault_rifle_damage/9067"));
assert!(!perks_file.contains("/76561198044316328/headshots"));
}
#[test]
fn db_insert_success() -> Result<(), Box<dyn Error>> {
let mut db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
let registered_file = db.file_mut("administration", "registered").unwrap();
// Modify existing
registered_file.insert("/76561198025127722/ip_lock", json!(false))?;
assert_eq!(
registered_file
.get("/76561198025127722/ip_lock")
.unwrap()
.to_string(),
"false"
);
registered_file.insert("/76561198044316328/password_hash", json!({"var":13524}))?;
assert_eq!(
registered_file
.get("/76561198044316328/password_hash")
.unwrap()
.to_string(),
r#"{"var":13524}"#
);
// Reset whole file
registered_file.insert("", json!({}))?;
assert_eq!(registered_file.root().to_string(), "{}");
// Add new values
registered_file.insert("/new_var", json!([42, {"word":"life"}, null]))?;
assert_eq!(
registered_file.root().to_string(),
r#"{"new_var":[42,{"word":"life"},null]}"#
);
let general_file = db.file_mut("game", "general").unwrap();
general_file.insert("/76561198025127722/achievements/5", json!("kf:bugged"))?;
assert_eq!(
general_file
.get("/76561198025127722/achievements")
.unwrap()
.to_string(),
r#"["kf:LabCleaner","kf:ChickenFarmer","scrn:playedscrn",null,null,"kf:bugged"]"#
);
Ok(())
}
#[test]
fn db_set_failure() {
let mut db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
let file = db.file_mut("administration", "registered").unwrap();
file.insert("/76561198025127722/dir/var", json!(null))
.expect_err("Testing panic at trying to set a value in non-existing object/array.");
file.insert("/76561198044316328/groups/d", json!(null))
.expect_err("Testing panic at trying to set a value at non-numeric index in an array.");
file.insert("/76561198044316328/groups/-1", json!(null))
.expect_err("Testing panic at trying to set a value at negative index in an array.");
}
#[test]
fn db_remove_value() {
let mut db = Database::load(path::Path::new(TEST_DB_PATH)).expect(NO_DB_MESSAGE);
let file = db.file_mut("administration", "registered").unwrap();
// Removing non-existent value
assert_eq!(file.remove("/76561198025127722/something"), None);
// Remove simple value
assert_eq!(
file.remove("/76561198025127722/password_hash").unwrap(),
json!("fce798e0804dfb217f929bdba26745024f37f6b6ba7406f3775176e20dd5089d")
);
assert!(!file.contains("/76561198025127722/password_hash"));
// Remove complex value (array)
assert_eq!(
file.remove("/76561198044316328/groups").unwrap(),
json!(["admin"])
);
assert!(!file.contains("/76561198044316328/groups/0"));
assert!(!file.contains("/76561198044316328/groups"));
// Remove array elements
assert_eq!(
file.remove("/76561198025127722/allowed_ips/0").unwrap(),
json!("127.0.0.1")
);
assert!(file.contains("/76561198025127722/allowed_ips/0"));
assert!(!file.contains("/76561198025127722/allowed_ips/1"));
assert_eq!(
file.remove("/76561198025127722/allowed_ips/0").unwrap(),
json!("192.168.0.100")
);
assert!(file.contains("/76561198025127722/allowed_ips"));
assert!(!file.contains("/76561198025127722/allowed_ips/0"));
}
#[test]
fn db_save() {
let (path, _cleanup) = prepare_db_copy("db_save", false);
// Change something up and save
let mut db = Database::load(path::Path::new(&path)).expect(NO_DB_MESSAGE);
db.remove_group("administration")
.expect(r#"Should be able to remove "administration" group"#);
db.save()
.expect("Should be able to save copy of the database.");
// Reload and check changes
let db = Database::load(path::Path::new(&path)).expect(NO_DB_MESSAGE);
assert_eq!(db.group_names().len(), 1);
assert_eq!(db.group_names().get(0), Some(&"game".to_owned()));
assert_eq!(db.file_names_in("game").len(), 2);
assert!(db.contains_file("game", "general"));
assert!(db.contains_file("game", "perks"));
}
#[test]
fn db_change_path() {
let (path, _cleanup) = prepare_db_copy("db_change_path", true);
// Change something up and move
let mut db = Database::load(path::Path::new(&path)).expect(NO_DB_MESSAGE);
db.remove_group("administration")
.expect(r#"Should be able to remove "administration" group"#);
db.file_mut("game", "perks")
.unwrap()
.insert("", json!({"var":7}))
.expect("Should be able to insert into root.");
db.change_path(path::Path::new(TEST_DB_MOVED_PATH))
.expect("Should be able to change database's path.");
assert!(!path::Path::new(&path).exists());
assert!(path::Path::new(TEST_DB_MOVED_PATH).exists());
// Reload and check the changes
let db = Database::load(path::Path::new(TEST_DB_MOVED_PATH)).expect(NO_DB_MESSAGE);
assert_eq!(db.group_names().len(), 1);
assert_eq!(db.group_names().get(0), Some(&"game".to_owned()));
assert_eq!(db.file_names_in("game").len(), 2);
assert!(db.contains_file("game", "general"));
assert!(db.contains_file("game", "perks"));
assert_eq!(
db.file("game", "perks").unwrap().root().to_string(),
r#"{"var":7}"#.to_owned()
);
}
#[test]
fn db_erase() {
let (path, _cleanup) = prepare_db_copy("db_erase", false);
let db = Database::load(path::Path::new(&path)).expect(NO_DB_MESSAGE);
db.erase().expect("Should be able to erase data.");
assert!(!path::Path::new(&path).exists());
}