Files
morethantext/tests/session_test.rs
Jeff Baskin 3a608967ef
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
Moved session tests to client.
2026-03-26 07:50:04 -04:00

237 lines
7.4 KiB
Rust

use chrono::{DateTime, Utc};
use isolang::Language;
use morethantext::{
action::{Addition, CalcValue, Calculation, Field, FieldType, Operand, Query, Record},
Action, ErrorID, Include, MTTError, MoreThanText, Name, Path, TestMoreThanText, Update,
};
use std::time::Duration;
use uuid::Uuid;
const DELAY: Duration = Duration::from_hours(1);
fn doc_name() -> Name {
Name::english("session")
}
fn id_name() -> Name {
Name::english("id")
}
fn expire_name() -> Name {
Name::english("expire")
}
fn lang_name() -> Name {
Name::english("language")
}
fn get_session(mtt: &mut MoreThanText, id: &Uuid) -> Result<Record, MTTError> {
let client = mtt.client();
let mut qry = Query::new(doc_name());
let mut calc = Calculation::new(Operand::Equal);
calc.add_value(CalcValue::Existing(FieldType::Uuid))
.unwrap();
calc.add_value(id.clone()).unwrap();
qry.add(Name::english("id"), calc.clone());
match client.records(qry) {
Ok(data) => Ok(data.iter().last().unwrap()),
Err(err) => Err(err),
}
}
#[test]
fn are_session_ids_unique() {
let mut mtt = MoreThanText::new();
let count = 10;
let mut result: Vec<String> = Vec::new();
for _ in 0..count {
let id = mtt.client().session_id();
assert!(!result.contains(&id), "found {} in {:?}", id, result);
result.push(id);
}
}
#[test]
fn bad_session_id_returns_new_id() {
let id = "stuff".to_string();
let result = MoreThanText::new().client().session_id();
assert_ne!(result, id);
}
#[test]
fn creates_new_session_if_missing_or_expired() {
let id = Uuid::nil().to_string();
let result = MoreThanText::new()
.client_with_session(id.clone(), None)
.session_id();
assert_ne!(result, id);
}
#[test]
fn returns_same_session_id_when_valid() {
let mut mtt = MoreThanText::new();
let expected = mtt.client().session_id();
let result = mtt.client_with_session(expected.clone(), None).session_id();
assert_eq!(result, expected);
}
#[test]
fn is_expiration_date_set_in_the_future() {
let mut test_env = TestMoreThanText::new();
let path = Path::new(
Include::All,
Include::Just(doc_name().into()),
Include::Just(Action::OnAddition),
);
test_env.register_channel(vec![path]);
let start_time = Utc::now() + DELAY;
let id = test_env.get_morethantext().client();
let end_time = Utc::now() + DELAY;
let result = test_env.get_trigger_records(Action::OnAddition);
let rec = result.iter().last().unwrap();
let expire = rec.get(&expire_name()).unwrap();
assert!(
expire > start_time.into(),
"{:?} should be after {:?}",
expire,
start_time
);
assert!(
expire < end_time.into(),
"{:?} should be after {:?}",
expire,
end_time
);
}
#[test]
fn are_session_ids_unique_in_storage() {
let mut mtt = MoreThanText::new();
let client = mtt.client();
let id: Uuid = mtt.client().session_id().try_into().unwrap();
let mut addition = Addition::new(doc_name());
addition.add_field(id_name(), id);
let mut error = MTTError::new(ErrorID::IndexEntryAlreadyExists(id.into()));
error.add_parent(ErrorID::Field(id_name().into()));
error.add_parent(ErrorID::Document(doc_name().into()));
match client.records(addition) {
Ok(data) => unreachable!("got {:?} should have been error", data),
Err(err) => assert_eq!(err.to_string(), error.to_string()),
}
}
#[test]
fn does_expire_updates_on_query() {
let mut test_env = TestMoreThanText::new();
let mut mtt = test_env.get_morethantext();
let id = mtt.client().session_id();
let path = Path::new(
Include::All,
Include::Just(doc_name().into()),
Include::Just(Action::OnUpdate),
);
test_env.register_channel(vec![path]);
let start_time = Utc::now() + DELAY;
mtt.client_with_session(id, None);
let result = test_env.get_trigger_records(Action::OnUpdate);
let rec = result.iter().last().unwrap();
let expire = rec.get(&expire_name()).unwrap();
assert!(
expire > start_time.into(),
"{:?} should be after {:?}",
expire,
start_time
);
}
#[test]
fn are_expired_sessions_removed() {
let mut test_env = TestMoreThanText::new();
let client = test_env.get_morethantext().client();
let id: Uuid = test_env
.get_morethantext()
.client()
.session_id()
.try_into()
.unwrap();
let mut calc = Calculation::new(Operand::Equal);
calc.add_value(CalcValue::Existing(FieldType::Uuid))
.unwrap();
calc.add_value(id.clone()).unwrap();
let mut update = Update::new(doc_name());
let expire = Utc::now() - Duration::from_secs(10);
update.get_query_mut().add(id_name(), calc.clone());
update.get_values_mut().add_field(expire_name(), expire);
client.records(update).unwrap();
let path = Path::new(
Include::All,
Include::Just(doc_name().into()),
Include::Just(Action::OnDelete),
);
test_env.register_channel(vec![path]);
test_env.send_time_pulse();
let result = test_env.get_trigger_records(Action::OnDelete);
assert_eq!(result.len(), 1, "incorrect number of records\n{:?}", result);
let rec = result.iter().last().unwrap();
assert_eq!(rec.get(id_name()).unwrap(), id.into());
}
#[test]
fn is_english_the_default_language() {
let lang_name = Name::english("language");
let lang = Language::from_639_1("en").unwrap();
let mut test_env = TestMoreThanText::new();
let mut mtt = test_env.get_morethantext();
let path = Path::new(
Include::All,
Include::Just(doc_name().into()),
Include::Just(Action::OnAddition),
);
test_env.register_channel(vec![path]);
mtt.client();
let result = test_env.get_trigger_records(Action::OnAddition);
assert_eq!(result.len(), 1, "incorrect number of records");
let rec = result.iter().last().unwrap();
assert_eq!(rec.get(&lang_name).unwrap(), lang.into());
}
#[test]
fn can_language_be_assigned() {
let lang_name = Name::english("language");
let lang = Language::from_639_1("ja").unwrap();
let mut test_env = TestMoreThanText::new();
let mut mtt = test_env.get_morethantext();
let path = Path::new(
Include::All,
Include::Just(doc_name().into()),
Include::Just(Action::OnAddition),
);
test_env.register_channel(vec![path]);
mtt.client_with_language(lang.clone());
let result = test_env.get_trigger_records(Action::OnAddition);
assert_eq!(result.len(), 1, "incorrect number of records");
let rec = result.iter().last().unwrap();
assert_eq!(rec.get(&lang_name).unwrap(), lang.into());
}
#[test]
fn does_not_change_language() {
let lang_name = Name::english("language");
let elang = Language::from_639_1("en").unwrap();
let jlang = Language::from_639_1("ja").unwrap();
let mut test_env = TestMoreThanText::new();
let mut mtt = test_env.get_morethantext();
let id = mtt.client_with_language(jlang.clone()).session_id();
let path = Path::new(
Include::All,
Include::Just(doc_name().into()),
Include::Just(Action::OnUpdate),
);
test_env.register_channel(vec![path]);
mtt.client_with_session(id, Some(elang));
let result = test_env.get_trigger_records(Action::OnUpdate);
assert_eq!(result.len(), 1, "incorrect number of records");
let rec = result.iter().last().unwrap();
assert_eq!(rec.get(&lang_name).unwrap(), jlang.into());
}