use chrono::{DateTime, Utc}; use morethantext::{ action::{Addition, CalcValue, Calculation, Field, FieldType, Operand, Query, Record}, MTTError, MoreThanText, Name, TestMoreThanText, Update, }; use std::time::Duration; use uuid::Uuid; fn doc_name() -> Name { Name::english("session") } fn get_session(mtt: &mut MoreThanText, id: &Uuid) -> Result { 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 mtt.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 = Vec::new(); for _ in 0..count { let id = mtt.validate_session(None); assert!(!result.contains(&id), "found {} in {:?}", id, result); result.push(id); } } #[test] fn bad_session_id_returns_new_id() { let mut mtt = MoreThanText::new(); let id1 = mtt.validate_session(Some("stuff".to_string())); let id2 = mtt.validate_session(Some("stuff".to_string())); assert_ne!(id1, id2); } #[test] fn creates_new_session_if_bad_or_expired() { let mut mtt = MoreThanText::new(); let id1 = mtt.validate_session(Some(Uuid::nil().to_string())); let id2 = mtt.validate_session(Some(Uuid::nil().to_string())); assert_ne!(id1, id2); } #[test] fn returns_same_session_id_when_valid() { let mut mtt = MoreThanText::new(); let id = mtt.validate_session(None); let result = mtt.validate_session(Some(id.to_string())); assert_eq!(result, id); } #[test] fn is_expiration_date_set_in_the_future() { let mut mtt = MoreThanText::new(); let start_time = Utc::now() + Duration::from_hours(1); let id = mtt.validate_session(None); let end_time = Utc::now() + Duration::from_hours(1); let rec = get_session(&mut mtt, &id).unwrap(); let holder = rec.get(Name::english("expire")).unwrap(); match holder { Field::DateTime(data) => { assert!(data > start_time, "expire should be after {:?}", start_time); assert!(data < end_time, "expire should be before {:?}", end_time); } _ => unreachable!("got {:?} should have been date time", holder), }; } #[test] #[ignore = "hangs without completing"] fn are_session_ids_unique_on_update() { let mut mtt = MoreThanText::new(); let id = mtt.validate_session(None); let mut addition = Addition::new(doc_name()); addition.add_field(Name::english("id"), id); match mtt.records(addition) { Ok(data) => unreachable!("got {:?} should have been error", data), Err(err) => match err { _ => unreachable!("got {:?}, should have been not unique", err), }, } } #[test] fn does_expire_update_on_query() { let mut mtt = MoreThanText::new(); let id = mtt.validate_session(None); let start_time = Utc::now() + Duration::from_secs(3600); mtt.validate_session(Some(id.to_string())); let end_time = Utc::now() + Duration::from_secs(3601); let rec = get_session(&mut mtt, &id).unwrap(); let holder = rec.get(Name::english("expire")).unwrap(); match holder { Field::DateTime(data) => { assert!(data > start_time, "expire should be after {:?}", start_time); assert!(data < end_time, "expire should be before {:?}", end_time); } _ => unreachable!("got {:?} should have been date time", holder), } } #[test] #[ignore = "failing to update"] fn are_expired_sessions_removed() { let mut mtt = TestMoreThanText::new(); let id = mtt.validate_session(None); let mut update = Update::new(doc_name()); let mut calc = Calculation::new(Operand::Equal); calc.add_value(CalcValue::Existing(FieldType::Uuid)) .unwrap(); calc.add_value(id.clone()).unwrap(); update .get_query_mut() .add(Name::english("id"), calc.clone()); let expire = Utc::now() - Duration::from_secs(10); update .get_values_mut() .add_field(Name::english("expire"), expire); mtt.records(update).unwrap(); mtt.send_time_pulse(); let mut qry = Query::new(doc_name()); qry.add(Name::english("id"), calc.clone()); let result = mtt.records(qry).unwrap(); assert_eq!(result.len(), 0); }