use std::{fs::File, io::Read, path::Path, time::Duration};
use chrono::{DateTime, TimeZone, Utc};
pub use dittolive_ditto::{error::DittoError, fs::TempRoot, prelude::*};
use futures::executor::block_on;
pub use safer_ffi::prelude::*;
use serde::{Deserialize, Serialize};
#[allow(dead_code)]
pub const DEFAULT_TEST_TIMEOUT: Duration = Duration::from_secs(10);
#[allow(dead_code)]
pub fn test_license_from_file<P: AsRef<Path>>(path: P) -> std::io::Result<String> {
let mut f = File::open(path)?;
let mut key = String::new();
let _bytes = f.read_to_string(&mut key)?;
let result = key.trim().to_string();
if result.is_empty() {
Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"License Key is empty",
))
} else {
Ok(result)
}
}
#[allow(dead_code)]
pub fn get_test_ditto(database_id: Option<DatabaseId>) -> Result<(TempRoot, Ditto), DittoError> {
let (root, ditto) = get_inactive_ditto(database_id)?;
ditto.set_license_from_env("DITTO_LICENSE")?;
Ok((root, ditto))
}
#[allow(dead_code)]
pub fn get_test_ditto_async_sync(
database_id: Option<DatabaseId>,
) -> Result<(TempRoot, Ditto), DittoError> {
let (root, ditto) = block_on(get_inactive_ditto_async(database_id))?;
ditto.set_license_from_env("DITTO_LICENSE")?;
Ok((root, ditto))
}
#[allow(dead_code)]
pub async fn get_test_ditto_async(
database_id: Option<DatabaseId>,
) -> Result<(TempRoot, Ditto), DittoError> {
let (root, ditto) = get_inactive_ditto_async(database_id).await?;
ditto.set_license_from_env("DITTO_LICENSE")?;
Ok((root, ditto))
}
#[allow(dead_code)]
pub fn get_inactive_ditto(
database_id: Option<DatabaseId>,
) -> Result<(TempRoot, Ditto), DittoError> {
let database_id = database_id.unwrap_or_else(DatabaseId::generate);
let root = TempRoot::new();
let connect = DittoConfigConnect::SmallPeersOnly { private_key: None };
let config = DittoConfig::new(database_id.to_string(), connect)
.with_persistence_directory(root.root_path());
let ditto = Ditto::open_sync(config)?;
Ok((root, ditto))
}
#[allow(dead_code)]
pub async fn get_inactive_ditto_async(
database_id: Option<DatabaseId>,
) -> Result<(TempRoot, Ditto), DittoError> {
let database_id = database_id.unwrap_or_else(DatabaseId::generate);
let root = TempRoot::new();
let connect = DittoConfigConnect::SmallPeersOnly { private_key: None };
let config = DittoConfig::new(database_id.to_string(), connect)
.with_persistence_directory(root.root_path());
let ditto = Ditto::open(config).await?;
Ok((root, ditto))
}
#[allow(dead_code)]
pub fn get_online_ditto() -> Result<(TempRoot, Ditto), DittoError> {
let database_id = DatabaseId::generate();
let root = TempRoot::new();
let config = DittoConfig::new(
database_id.to_string(),
DittoConfigConnect::Server {
url: format!("https://{}.cloud.ditto.live", database_id)
.parse()
.unwrap(),
},
)
.with_persistence_directory(root.root_path());
let ditto = Ditto::open_sync(config)?;
ditto
.auth()
.expect("Server mode should have auth")
.set_expiration_handler(async |_ditto: &Ditto, _duration_remaining| {});
Ok((root, ditto))
}
#[allow(dead_code)]
pub fn get_online_ditto_with_persistent_dir(db_path: &Path) -> Result<Ditto, DittoError> {
let database_id = DatabaseId::generate();
let config = DittoConfig::new(
database_id.to_string(),
DittoConfigConnect::Server {
url: format!("https://{}.cloud.ditto.live", database_id)
.parse()
.unwrap(),
},
)
.with_persistence_directory(db_path);
let ditto = Ditto::open_sync(config)?;
ditto
.auth()
.expect("Server mode should have auth")
.set_expiration_handler(async |_ditto: &Ditto, _duration_remaining| {});
Ok(ditto)
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub enum TestColor {
Red,
Blue,
Crimson,
Orange,
Yellow,
Pink,
White,
Black,
Brown,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct TestType {
pub make: String,
pub color: TestColor,
pub age: u8,
pub mileage: i64,
pub purchased_on: DateTime<Utc>,
pub tags: Vec<String>,
pub data: Vec<u8>, #[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
pub id: Option<DocumentId>,
}
impl TestType {
#[allow(dead_code)] pub fn random() -> TestType {
TestType::random_with_id(None)
}
#[allow(dead_code)] pub fn random_with_id(id: Option<DocumentId>) -> TestType {
use rand::{rngs::StdRng, Rng, SeedableRng};
let mut bytes: Vec<u8> = vec![0; 2048];
let mut rng = StdRng::seed_from_u64(123456789);
rng.fill(bytes.as_mut_slice());
TestType {
make: String::from("Honda"),
color: TestColor::Red,
age: 12,
mileage: 52000,
purchased_on: Utc::now(),
tags: vec![
String::from("a"),
String::from("-1"),
String::from("test_tag"),
],
data: bytes,
id,
}
}
}
impl Default for TestType {
fn default() -> TestType {
TestType {
make: String::default(),
color: TestColor::Red,
age: 0,
mileage: 0,
purchased_on: Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 0).unwrap(),
tags: Vec::new(),
data: Vec::new(),
id: None,
}
}
}