381 lines
14 KiB
Rust
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());
|
|
}
|