From 9df6c4db42422688b98bf89b27c01c0076c2f8e1 Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Wed, 24 Dec 2025 16:56:43 -0500 Subject: [PATCH] Removed old code. --- src/client.rs | 178 ---------------------- src/clock.rs | 91 ------------ src/doctype.rs | 48 ------ src/document.rs | 348 ------------------------------------------- src/field.rs | 350 ------------------------------------------- src/lib.rs-old | 202 ------------------------- src/queue.rs | 346 ------------------------------------------- src/session.rs | 384 ------------------------------------------------ 8 files changed, 1947 deletions(-) delete mode 100644 src/client.rs delete mode 100644 src/clock.rs delete mode 100644 src/doctype.rs delete mode 100644 src/document.rs delete mode 100644 src/field.rs delete mode 100644 src/lib.rs-old delete mode 100644 src/queue.rs delete mode 100644 src/session.rs diff --git a/src/client.rs b/src/client.rs deleted file mode 100644 index cee723b..0000000 --- a/src/client.rs +++ /dev/null @@ -1,178 +0,0 @@ -use crate::queue::{Message, MsgType, Queue}; -use std::{ - collections::HashMap, - sync::{ - mpsc::{channel, Receiver, Sender}, - Arc, Mutex, - }, - thread::spawn, -}; -use uuid::Uuid; - -const RESPONS_TO: [MsgType; 4] = [ - MsgType::ActionOk, - MsgType::Document, - MsgType::Error, - MsgType::SessionValidated, -]; - -#[derive(Clone)] -pub struct ClientChannel { - queue: Queue, - registry: Arc>>>, -} - -impl ClientChannel { - fn new(queue: Queue) -> Self { - Self { - queue: queue, - registry: Arc::new(Mutex::new(HashMap::new())), - } - } - - pub fn send(&self, mut msg: Message) -> Receiver { - let mut reg = self.registry.lock().unwrap(); - while reg.contains_key(&msg.get_id()) { - msg.reset_id(); - } - let (tx, rx) = channel(); - reg.insert(msg.get_id(), tx); - self.queue.send(msg).unwrap(); - rx - } - - fn reply(&self, msg: Message) { - let mut reg = self.registry.lock().unwrap(); - match reg.remove(&msg.get_id()) { - Some(tx) => tx.send(msg).unwrap(), - None => {} - } - } -} - -#[cfg(test)] -mod client_channels { - use super::*; - use std::time::Duration; - - static TIMEOUT: Duration = Duration::from_millis(500); - - #[test] - fn fowards_message() { - let msg_type = MsgType::Document; - let reply_type = MsgType::Time; - let queue = Queue::new(); - let (tx, rx) = channel(); - queue.add(tx, [msg_type.clone()].to_vec()); - let chan = ClientChannel::new(queue); - let msg = Message::new(msg_type.clone()); - let client_rx = chan.send(msg.clone()); - let reply = rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(reply.get_id(), msg.get_id()); - assert_eq!(reply.get_msg_type().clone(), msg_type); - let client_reply = reply.reply(MsgType::Time); - chan.reply(client_reply); - let client_msg = client_rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(client_msg.get_id(), msg.get_id()); - assert_eq!(client_msg.get_msg_type().clone(), reply_type); - } - - #[test] - fn no_duplicate_ids() { - let (tx, rx) = channel(); - let queue = Queue::new(); - queue.add(tx, [MsgType::Time].to_vec()); - let chan = ClientChannel::new(queue); - let msg1 = Message::new(MsgType::Time); - let msg2 = msg1.reply(MsgType::Time); - let rx1 = chan.send(msg1); - let rx2 = chan.send(msg2); - let queue1 = rx.recv_timeout(TIMEOUT).unwrap(); - let queue2 = rx.recv_timeout(TIMEOUT).unwrap(); - assert_ne!(queue1.get_id(), queue2.get_id()); - chan.reply(queue1.reply(MsgType::Document)); - chan.reply(queue2.reply(MsgType::Document)); - let reply1 = rx1.recv_timeout(TIMEOUT).unwrap(); - let reply2 = rx2.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(reply1.get_id(), queue1.get_id()); - assert_eq!(reply2.get_id(), queue2.get_id()); - } - - #[test] - fn ignore_unrequested() { - let queue = Queue::new(); - let chan = ClientChannel::new(queue); - chan.reply(Message::new(MsgType::Document)); - } -} - -pub struct Client { - channel: ClientChannel, - rx: Receiver, -} - -impl Client { - fn new(chan: ClientChannel, rx: Receiver) -> Self { - Self { - channel: chan, - rx: rx, - } - } - - pub fn start(queue: Queue) -> ClientChannel { - let (tx, rx) = channel(); - queue.add(tx.clone(), RESPONS_TO.to_vec()); - let chan = ClientChannel::new(queue.clone()); - let client = Client::new(chan.clone(), rx); - spawn(move || { - client.listen(); - }); - chan - } - - fn listen(&self) { - loop { - let msg = self.rx.recv().unwrap(); - self.channel.reply(msg); - } - } -} - -#[cfg(test)] -mod clients { - use super::*; - use crate::session::sessions::create_validated_reply; - use std::time::Duration; - - static TIMEOUT: Duration = Duration::from_millis(500); - - #[test] - fn session_validated() { - let queue = Queue::new(); - let (queue_tx, queue_rx) = channel(); - queue.add(queue_tx, [MsgType::SessionValidate].to_vec()); - let chan = Client::start(queue.clone()); - let chan_rx = chan.send(Message::new(MsgType::SessionValidate)); - let msg = queue_rx.recv_timeout(TIMEOUT).unwrap(); - let expected = create_validated_reply(msg); - queue.send(expected.clone()).unwrap(); - let result = chan_rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(result.get_id(), expected.get_id()); - assert_eq!(result.get_msg_type(), expected.get_msg_type()); - } - - #[test] - fn document_return() { - let queue = Queue::new(); - let (queue_tx, queue_rx) = channel(); - queue.add(queue_tx, [MsgType::DocumentRequest].to_vec()); - let chan = Client::start(queue.clone()); - let chan_rx = chan.send(Message::new(MsgType::DocumentRequest)); - let msg = queue_rx.recv_timeout(TIMEOUT).unwrap(); - let expected = msg.reply(MsgType::Document); - queue.send(expected.clone()).unwrap(); - let result = chan_rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(result.get_id(), expected.get_id()); - assert_eq!(result.get_msg_type(), expected.get_msg_type()); - } -} diff --git a/src/clock.rs b/src/clock.rs deleted file mode 100644 index f70264b..0000000 --- a/src/clock.rs +++ /dev/null @@ -1,91 +0,0 @@ -use crate::queue::{Message, MsgType, Queue}; -use chrono::prelude::*; -use std::{ - thread::{sleep, spawn}, - time::Duration, -}; - -const SLEEP_FOR: Duration = Duration::from_secs(1); - -pub struct Clock { - queue: Queue, -} - -impl Clock { - fn new(queue: Queue) -> Self { - Self { queue: queue } - } - - pub fn start(queue: Queue) { - let clock = Clock::new(queue); - spawn(move || { - clock.listen(); - }); - } - - fn listen(&self) { - loop { - let mut msg = Message::new(MsgType::Time); - msg.add_data("time", Utc::now()); - match self.queue.send(msg) { - Ok(_) => {} - Err(_) => {} - }; - sleep(SLEEP_FOR); - } - } -} - -#[cfg(test)] -mod clocks { - use super::*; - use std::{ - sync::mpsc::{channel, Receiver}, - time::{Duration, Instant}, - }; - - static TIMEOUT: Duration = Duration::from_millis(500); - - fn start_clock(listen_for: Vec) -> Receiver { - let queue = Queue::new(); - let (tx, rx) = channel(); - queue.add(tx, listen_for); - Clock::start(queue); - rx - } - - #[test] - fn sends_timestamp() { - let rx = start_clock([MsgType::Time].to_vec()); - let msg = rx.recv_timeout(TIMEOUT).unwrap(); - match msg.get_msg_type() { - MsgType::Time => { - msg.get_data("time").unwrap().to_datetime().unwrap(); - } - _ => unreachable!("should have been a time message"), - } - } - - #[test] - fn continues_to_send_time() { - let start = Instant::now(); - let rx = start_clock([MsgType::Time].to_vec()); - let msg1 = rx.recv_timeout(TIMEOUT).unwrap(); - let msg2 = rx.recv().unwrap(); - assert!( - start.elapsed() >= SLEEP_FOR, - "did not pause long enough between sends" - ); - assert!( - msg2.get_data("time").unwrap().to_datetime().unwrap() - >= msg1.get_data("time").unwrap().to_datetime().unwrap() + SLEEP_FOR, - "should present the latest time" - ); - } - - #[test] - fn does_not_panic_without_listeners() { - let rx = start_clock([MsgType::SessionValidate].to_vec()); - assert!(rx.recv_timeout(TIMEOUT).is_err(), "should timeout"); - } -} diff --git a/src/doctype.rs b/src/doctype.rs deleted file mode 100644 index fbfe0ce..0000000 --- a/src/doctype.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::queue::{Message, MsgType, Queue}; -use std::{ - sync::mpsc::{channel, Receiver}, - thread::spawn, -}; - -const RESPONDS_TO: [MsgType; 0] = []; - -/// Definition of the document type. -struct DocType { - queue: Queue, - rx: Receiver, -} - -impl DocType { - fn new(queue: Queue, rx: Receiver) -> Self { - Self { - queue: queue, - rx: rx, - } - } - - fn start(queue: Queue) { - let (tx, rx) = channel(); - let mut doctype = DocType::new(queue, rx); - doctype.queue.add(tx, RESPONDS_TO.to_vec()); - spawn(move || { - doctype.listen(); - }); - } - - fn listen(&self) { - loop { - self.rx.recv().unwrap(); - } - } -} - -#[cfg(test)] -mod doctypes { - use super::*; - - #[test] - fn create_empty() { - let queue = Queue::new(); - DocType::start(queue.clone()); - } -} diff --git a/src/document.rs b/src/document.rs deleted file mode 100644 index 6fee024..0000000 --- a/src/document.rs +++ /dev/null @@ -1,348 +0,0 @@ -use crate::{ - queue::{Message, MsgType, Queue}, - ActionType, ErrorType, -}; -use serde_json::Value; -use std::{ - collections::HashMap, - sync::mpsc::{channel, Receiver}, - thread::spawn, -}; - -const RESPONDS_TO: [MsgType; 1] = [MsgType::DocumentRequest]; - -struct Table; - -impl Table { - fn new() -> Self { - Self {} - } - - fn add_column(&self) {} -} - -#[cfg(test)] -mod tables { - use super::*; - - #[test] - fn create_table() { - let tbl = Table::new(); - tbl.add_column(); - } -} - -pub struct Document { - data: HashMap, - queue: Queue, - rx: Receiver, -} - -impl Document { - fn new(queue: Queue, rx: Receiver) -> Self { - let mut data = HashMap::new(); - data.insert("root".to_string(), "Something goes here.".to_string()); - Self { - data: data, - queue: queue, - rx: rx, - } - } - - pub fn start(queue: Queue) { - let (tx, rx) = channel(); - let mut document = Document::new(queue, rx); - document.queue.add(tx, RESPONDS_TO.to_vec()); - spawn(move || { - document.listen(); - }); - } - - fn listen(&mut self) { - loop { - let msg = self.rx.recv().unwrap(); - match msg.get_data("action") { - Some(action_field) => { - let action = action_field.to_action().unwrap(); - match action { - ActionType::Add | ActionType::Update => self.add(action, msg), - _ => self.get(msg), - } - } - None => self.get(msg), - } - } - } - - fn add(&mut self, action: ActionType, msg: Message) { - let name = msg.get_data("name").unwrap().to_string(); - match self.data.get(&name) { - Some(_) => match action { - ActionType::Add => { - self.queue - .send(msg.reply_with_error(ErrorType::DocumentAlreadyExists)) - .unwrap(); - return; - } - ActionType::Update => {} - _ => unreachable!("listen should prevent anything else"), - }, - None => match action { - ActionType::Add => {} - ActionType::Update => { - self.queue - .send(msg.reply_with_error(ErrorType::DocumentNotFound)) - .unwrap(); - return; - } - _ => unreachable!("listen should prevent anything else"), - }, - } - let doc: Value = match serde_json::from_str(&msg.get_data("doc").unwrap().to_string()) { - Ok(value) => value, - Err(_) => { - self.queue - .send(msg.reply_with_error(ErrorType::DocumentInvalidRequest)) - .unwrap(); - return; - } - }; - let reply = match doc["template"].as_str() { - Some(content) => { - self.data.insert(name, content.to_string()); - msg.reply(MsgType::ActionOk) - } - None => msg.reply_with_error(ErrorType::DocumentInvalidRequest), - }; - self.queue.send(reply).unwrap(); - } - - fn get(&self, msg: Message) { - let name = match msg.get_data("name") { - Some(doc) => doc.to_string(), - None => "root".to_string(), - }; - let reply = match self.data.get(&name) { - Some(data) => { - let mut holder = msg.reply(MsgType::Document); - holder.add_data("doc", data.clone()); - holder - } - None => msg.reply_with_error(ErrorType::DocumentNotFound), - }; - self.queue.send(reply).unwrap(); - } -} - -#[cfg(test)] -pub mod documents { - use super::*; - use serde_json::json; - use std::time::Duration; - use uuid::Uuid; - - const TIMEOUT: Duration = Duration::from_millis(500); - - fn setup_document() -> (Queue, Receiver) { - let queue = Queue::new(); - let (tx, rx) = channel(); - queue.add( - tx, - [MsgType::ActionOk, MsgType::Document, MsgType::Error].to_vec(), - ); - Document::start(queue.clone()); - (queue, rx) - } - - #[test] - fn start_service() { - let (queue, rx) = setup_document(); - let id = Uuid::new_v4(); - let mut msg = Message::new(MsgType::DocumentRequest); - msg.add_data("sess_id", id.clone()); - queue.send(msg.clone()).unwrap(); - let reply = rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(reply.get_id(), msg.get_id()); - match reply.get_msg_type() { - MsgType::Document => {} - _ => unreachable!("got {:?} should have gotten document", msg.get_msg_type()), - } - assert!(reply.get_data("doc").is_some()); - } - - #[test] - fn no_existing_document() { - let (queue, rx) = setup_document(); - let name = format!("name-{}", Uuid::new_v4()); - let mut msg = Message::new(MsgType::DocumentRequest); - msg.add_data("name", name.clone()); - queue.send(msg.clone()).unwrap(); - let reply = rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(reply.get_id(), msg.get_id()); - match reply.get_msg_type() { - MsgType::Error => {} - _ => unreachable!("got {:?}: shoud have been error", reply.get_msg_type()), - } - match reply.get_data("error_type") { - Some(err) => match err.to_error_type().unwrap() { - ErrorType::DocumentNotFound => {} - _ => unreachable!("got {:?}: should have been document not found'", err), - }, - None => unreachable!("should contain error type"), - } - } - - #[test] - fn root_always_exists() { - let (queue, rx) = setup_document(); - let mut msg = Message::new(MsgType::DocumentRequest); - msg.add_data("name", "root"); - queue.send(msg).unwrap(); - let reply = rx.recv_timeout(TIMEOUT).unwrap(); - match reply.get_msg_type() { - MsgType::Document => {} - _ => unreachable!( - "Got '{:?}': should have been a document", - reply.get_msg_type() - ), - } - } - - #[test] - fn add_new_document() { - let (queue, rx) = setup_document(); - let name = format!("name-{}", Uuid::new_v4()); - let content = format!("content-{}", Uuid::new_v4()); - let input = json!({ - "template": content.clone() - }); - let mut msg1 = Message::new(MsgType::DocumentRequest); - msg1.add_data("name", name.clone()); - msg1.add_data("action", ActionType::Add); - msg1.add_data("doc", input.to_string()); - queue.send(msg1.clone()).unwrap(); - let reply1 = rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(reply1.get_id(), msg1.get_id()); - match reply1.get_msg_type() { - MsgType::ActionOk => {} - _ => unreachable!( - "got {:?}: should have received action ok", - reply1.get_msg_type() - ), - } - let mut msg2 = Message::new(MsgType::DocumentRequest); - msg2.add_data("name", name.clone()); - msg2.add_data("action", ActionType::Get); - queue.send(msg2.clone()).unwrap(); - let reply2 = rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(reply2.get_id(), msg2.get_id()); - match reply2.get_msg_type() { - MsgType::Document => {} - _ => unreachable!( - "got {:?}: should have received document", - reply2.get_msg_type() - ), - } - assert_eq!(reply2.get_data("doc").unwrap().to_string(), content); - } - - #[test] - fn add_does_not_overwrite_existing() { - let (queue, rx) = setup_document(); - let mut holder = Message::new(MsgType::DocumentRequest); - holder.add_data("name", "root"); - holder.add_data("action", ActionType::Get); - queue.send(holder.clone()).unwrap(); - let binding = rx.recv_timeout(TIMEOUT).unwrap(); - let expected = binding.get_data("doc").unwrap(); - let input = json!({ - "template": format!("content-{}", Uuid::new_v4()) - }); - let mut msg = Message::new(MsgType::DocumentRequest); - msg.add_data("name", "root"); - msg.add_data("action", ActionType::Add); - msg.add_data("doc", input.to_string()); - queue.send(msg.clone()).unwrap(); - let reply = rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(reply.get_id(), msg.get_id()); - match reply.get_msg_type() { - MsgType::Error => {} - _ => unreachable!( - "got '{:?}': should have received document", - reply.get_msg_type() - ), - } - match reply.get_data("error_type") { - Some(err) => match err.to_error_type().unwrap() { - ErrorType::DocumentAlreadyExists => {} - _ => unreachable!("got {:?}: should have been document not found'", err), - }, - None => unreachable!("should contain error type"), - } - queue.send(holder).unwrap(); - let binding = rx.recv_timeout(TIMEOUT).unwrap(); - let result = binding.get_data("doc").unwrap(); - assert_eq!(result.to_string(), expected.to_string()); - } - - #[test] - fn invalid_json() { - let inputs = ["Invalid json request.", "{}"]; - let (queue, rx) = setup_document(); - for input in inputs.into_iter() { - let mut msg = Message::new(MsgType::DocumentRequest); - msg.add_data("action", ActionType::Add); - msg.add_data("name", "doc"); - msg.add_data("doc", input); - queue.send(msg.clone()).unwrap(); - let reply = match rx.recv_timeout(TIMEOUT) { - Ok(data) => data, - Err(err) => { - assert!(false, "got '{}' with the following json: '{}'", err, input); - Message::new(MsgType::Error) - } - }; - assert_eq!(reply.get_id(), msg.get_id()); - match reply.get_msg_type() { - MsgType::Error => {} - _ => unreachable!( - "got '{:?}': should have received document", - reply.get_msg_type() - ), - } - match reply.get_data("error_type") { - Some(err) => match err.to_error_type().unwrap() { - ErrorType::DocumentInvalidRequest => {} - _ => unreachable!("got {:?}: should have been bad request'", err), - }, - None => unreachable!("should contain error type"), - } - } - } - - #[test] - fn patch_nonexistant_page() { - let (queue, rx) = setup_document(); - let input = json!({ - "template": "Sothing here" - }); - let mut msg = Message::new(MsgType::DocumentRequest); - msg.add_data("action", ActionType::Update); - msg.add_data("name", "something"); - msg.add_data("doc", input.to_string()); - queue.send(msg.clone()).unwrap(); - let reply = rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(reply.get_id(), msg.get_id()); - match reply.get_msg_type() { - MsgType::Error => {} - _ => unreachable!("got {:?}: shoud have been error", reply.get_msg_type()), - } - match reply.get_data("error_type") { - Some(err) => match err.to_error_type().unwrap() { - ErrorType::DocumentNotFound => {} - _ => unreachable!("got {:?}: should have been document not found'", err), - }, - None => unreachable!("should contain error type"), - } - } -} diff --git a/src/field.rs b/src/field.rs deleted file mode 100644 index 90f44fe..0000000 --- a/src/field.rs +++ /dev/null @@ -1,350 +0,0 @@ -use crate::{ActionType, ErrorType}; -use chrono::prelude::*; -use isolang::Language; -use std::fmt; -use uuid::Uuid; - -#[derive(Clone, Debug, PartialEq)] -enum FieldType { - Action, - DateTime, - Error, - StaticString, - Uuid, -} - -#[derive(Clone, Debug)] -pub enum Field { - Action(ActionType), - DateTime(DateTime), - ErrorType(ErrorType), - Lang(Language), - Static(String), - Uuid(Uuid), -} - -impl Field { - pub fn to_action(&self) -> Result { - match self { - Field::Action(data) => Ok(data.clone()), - _ => Err("not an action".to_string()), - } - } - - pub fn to_uuid(&self) -> Result { - match self { - Field::Uuid(data) => Ok(data.clone()), - _ => Err("not a uuid".to_string()), - } - } - - pub fn to_datetime(&self) -> Result, String> { - match self { - Field::DateTime(data) => Ok(data.clone()), - _ => Err("not a datetime".to_string()), - } - } - - pub fn to_error_type(&self) -> Result { - match self { - Field::ErrorType(data) => Ok(data.clone()), - _ => Err("not an error type".to_string()), - } - } - - pub fn to_language(&self) -> Result { - match self { - Field::Lang(data) => Ok(data.clone()), - _ => Err("not an error type".to_string()), - } - } -} - -impl From for Field { - fn from(value: String) -> Self { - match Uuid::try_from(value.as_str()) { - Ok(data) => return Field::Uuid(data), - Err(_) => {} - } - Field::Static(value) - } -} - -impl From<&str> for Field { - fn from(value: &str) -> Self { - match Uuid::try_from(value) { - Ok(data) => return Field::Uuid(data), - Err(_) => {} - } - Field::Static(value.into()) - } -} - -impl From for Field { - fn from(value: ActionType) -> Self { - Field::Action(value) - } -} - -impl From for Field { - fn from(value: Uuid) -> Self { - Field::Uuid(value) - } -} - -impl From> for Field { - fn from(value: DateTime) -> Self { - Field::DateTime(value) - } -} - -impl From for Field { - fn from(value: ErrorType) -> Self { - Field::ErrorType(value) - } -} - -impl From for Field { - fn from(value: Language) -> Self { - Field::Lang(value) - } -} - -impl fmt::Display for Field { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Field::DateTime(data) => write!(f, "{}", data), - Field::Static(data) => write!(f, "{}", data), - Field::Uuid(data) => write!(f, "{}", data), - _ => write!(f, ""), - } - } -} - -#[cfg(test)] -mod fields { - use super::*; - - #[test] - fn string_to_field() { - let entries = ["test1".to_string(), "test2".to_string()]; - for data in entries { - match data.clone().into() { - Field::Static(result) => assert_eq!(result, data), - _ => unreachable!("shouuld have been a static field"), - } - } - } - - #[test] - fn str_to_field() { - let entries = ["test1", "test2"]; - for data in entries { - match data.into() { - Field::Static(result) => assert_eq!(result, data), - _ => unreachable!("shouuld have been a static field"), - } - } - } - - #[test] - fn uuid_to_field() { - let id = Uuid::new_v4(); - match id.into() { - Field::Uuid(result) => assert_eq!(result, id), - _ => unreachable!("should have been a uuid field"), - } - } - - #[test] - fn uuid_string_to_field() { - let id = Uuid::new_v4(); - let id_string = id.to_string(); - match id_string.into() { - Field::Uuid(result) => assert_eq!(result, id), - _ => unreachable!("should have been a uuid field"), - } - } - - #[test] - fn uuid_str_to_field() { - let id = Uuid::new_v4(); - let id_string = id.to_string(); - let id_str = id_string.as_str(); - match id_str.into() { - Field::Uuid(result) => assert_eq!(result, id), - _ => unreachable!("should have been a uuid field"), - } - } - - #[test] - fn uuid_field_to_string() { - let id = Uuid::new_v4(); - let result = id.to_string(); - let input = Field::Uuid(id); - assert_eq!(input.to_string(), result); - } - - #[test] - fn str_field_to_string() { - let result = "Something goes here"; - let input: Field = result.into(); - assert_eq!(input.to_string(), result); - } - - #[test] - fn string_field_to_string() { - let result = "Another string".to_string(); - let input: Field = result.clone().into(); - assert_eq!(input.to_string(), result); - } - - #[test] - fn field_to_uuid() { - let id = Uuid::new_v4(); - let field: Field = id.into(); - match field.to_uuid() { - Ok(result) => assert_eq!(result, id), - Err(_) => unreachable!("did not convert to uuid"), - } - } - - #[test] - fn not_uuid_field_to_uuid() { - let text = "Not a uuid."; - let field: Field = text.into(); - match field.to_uuid() { - Ok(_) => unreachable!("should return an error"), - Err(_) => {} - } - } - - #[test] - fn use_date_to_field() { - let expected = Utc::now(); - let field: Field = expected.into(); - match field { - Field::DateTime(result) => assert_eq!(result, expected), - _ => unreachable!("should have been date time"), - } - } - - #[test] - fn from_datetime_field_to_string() { - let now = Utc::now(); - let expected = now.to_string(); - let field: Field = now.into(); - assert_eq!(field.to_string(), expected); - } - - #[test] - fn from_field_to_datetime() { - let now = Utc::now(); - let field: Field = now.into(); - assert_eq!(field.to_datetime().unwrap(), now); - } - - #[test] - fn from_static_field_to_datatime() { - let txt = "Not gonna work."; - let field: Field = txt.into(); - assert!(field.to_datetime().is_err(), "should not return a value"); - } - - #[test] - fn from_error_to_field() { - let err = ErrorType::DocumentNotFound; - let field: Field = err.into(); - match field { - Field::ErrorType(data) => match data { - ErrorType::DocumentNotFound => {} - _ => unreachable!("got {:?}: should have been Document not found", data), - }, - _ => unreachable!("should have been an error type"), - } - } - - #[test] - fn from_field_to_error_type_error() { - let field: Field = Uuid::new_v4().into(); - assert!(field.to_error_type().is_err(), "should generate an error"); - } - - #[test] - fn from_field_to_error_type() { - let err = ErrorType::DocumentNotFound; - let field: Field = err.into(); - let result = field.to_error_type().unwrap(); - match result { - ErrorType::DocumentNotFound => {} - _ => unreachable!("got {:?}: should have been document not found", result), - } - } - - #[test] - fn from_action_to_field() { - let actions = [ActionType::Add, ActionType::Get, ActionType::Update]; - for action in actions.into_iter() { - let result: Field = action.clone().into(); - match result { - Field::Action(data) => assert_eq!(format!("{:?}", data), format!("{:?}", action)), - _ => unreachable!("should have been an action"), - } - } - } - - #[test] - fn from_field_to_action() { - let actions = [ActionType::Add, ActionType::Get, ActionType::Update]; - for action in actions.into_iter() { - let field: Field = action.clone().into(); - let result = field.to_action().unwrap(); - assert_eq!(format!("{:?}", result), format!("{:?}", action)); - } - } - - #[test] - fn from_uuid_to_action() { - let field: Field = Uuid::new_v4().into(); - match field.to_action() { - Ok(_) => unreachable!("should have returned an error"), - Err(_) => {} - } - } - - #[test] - fn from_lang_to_field() { - let langs = [ - Language::from_639_1("en").unwrap(), - Language::from_639_1("ja").unwrap(), - ]; - for lang in langs.into_iter() { - let field: Field = lang.into(); - match field { - Field::Lang(data) => assert_eq!(data, lang), - _ => unreachable!("should identify language"), - } - } - } - - #[test] - fn from_field_to_lang() { - let langs = [ - Language::from_639_1("en").unwrap(), - Language::from_639_1("ja").unwrap(), - ]; - for lang in langs.into_iter() { - let field: Field = lang.into(); - assert_eq!(field.to_language().unwrap(), lang); - } - } - - #[test] - fn wrong_field_to_lang() { - let field: Field = Uuid::nil().into(); - match field.to_language() { - Ok(_) => unreachable!("should have produced an error"), - Err(_) => {} - } - } -} diff --git a/src/lib.rs-old b/src/lib.rs-old deleted file mode 100644 index 2eff26f..0000000 --- a/src/lib.rs-old +++ /dev/null @@ -1,202 +0,0 @@ -mod client; -mod clock; -mod doctype; -mod document; -mod field; -mod message; -mod queue; -mod session; - -use client::{Client, ClientChannel}; -use clock::Clock; -use document::Document; -use field::Field; -use queue::{Message, MsgType, Queue}; -use session::Session; -use uuid::Uuid; - -#[derive(Clone, Debug, PartialEq)] -pub enum ActionType { - Get, - Add, - Update, -} - -#[derive(Clone, Debug, PartialEq)] -pub enum ErrorType { - DocumentAlreadyExists, - DocumentInvalidRequest, - DocumentNotFound, -} - -pub struct MTTReply { - document: String, - error_type: Option, -} - -impl MTTReply { - fn new(msg: Message) -> Self { - Self { - document: match msg.get_data("doc") { - Some(doc) => doc.to_string(), - None => "".to_string(), - }, - error_type: match msg.get_data("error_type") { - Some(err) => Some(err.to_error_type().unwrap()), - None => None, - }, - } - } - - pub fn get_document(&self) -> String { - self.document.clone() - } - - pub fn get_error(&self) -> Option { - self.error_type.clone() - } -} - -#[cfg(test)] -mod mtt_replies { - use super::*; - - #[test] - fn create_reply_with_no_error() { - let mut msg = Message::new(MsgType::Document); - let content = format!("content-{}", Uuid::new_v4()); - msg.add_data("doc", content.to_string()); - let reply = MTTReply::new(msg); - assert!(reply.get_error().is_none()); - assert_eq!(reply.get_document(), content); - } - - #[test] - fn create_reply_with_error() { - let mut msg = Message::new(MsgType::Error); - msg.add_data("error_type", ErrorType::DocumentNotFound); - let reply = MTTReply::new(msg); - match reply.get_error() { - Some(err) => match err { - ErrorType::DocumentNotFound => {} - _ => unreachable!("got {:?}: should have been document not found", err), - }, - None => unreachable!("should return an error type"), - } - assert_eq!(reply.get_document(), ""); - } - - #[test] - fn no_error() { - let msg = Message::new(MsgType::Document); - let reply = MTTReply::new(msg); - assert!(reply.get_error().is_none()); - } - - #[test] - fn some_error() { - let mut msg = Message::new(MsgType::Error); - msg.add_data("error_type", ErrorType::DocumentNotFound); - let reply = MTTReply::new(msg); - match reply.get_error() { - Some(err) => match err { - ErrorType::DocumentNotFound => {} - _ => unreachable!("got {:?}: should have been document not found", err), - }, - None => unreachable!("should return an error type"), - } - } -} - -#[derive(Clone)] -pub struct MoreThanText { - client_channel: ClientChannel, -} - -impl MoreThanText { - pub fn new() -> Self { - let queue = Queue::new(); - Clock::start(queue.clone()); - Document::start(queue.clone()); - Session::start(queue.clone()); - Self { - client_channel: Client::start(queue.clone()), - } - } - - pub fn validate_session(&mut self, session: Option) -> Uuid - where - F: Into, - { - let mut msg = Message::new(MsgType::SessionValidate); - match session { - Some(id) => msg.add_data("sess_id", id.into()), - None => {} - } - let rx = self.client_channel.send(msg); - let reply = rx.recv().unwrap(); - reply.get_data("sess_id").unwrap().to_uuid().unwrap() - } - - pub fn get_document( - &self, - sess_id: Uuid, - action: ActionType, - doc_name: S, - data: String, - ) -> MTTReply - where - S: Into, - { - let mut msg = Message::new(MsgType::DocumentRequest); - msg.add_data("sess_id", sess_id); - msg.add_data("action", action); - msg.add_data("name", doc_name.into()); - msg.add_data("doc", data); - let rx = self.client_channel.send(msg); - let reply = rx.recv().unwrap(); - MTTReply::new(reply) - } -} - -#[cfg(test)] -mod mtt { - use super::*; - - #[test] - fn session_id_is_unique() { - let mut mtt = MoreThanText::new(); - let input: Option = None; - let mut ids: Vec = Vec::new(); - for _ in 0..10 { - let id = mtt.validate_session(input.clone()); - assert!(!ids.contains(&id)); - ids.push(id); - } - } - - #[test] - fn reuse_existing_session() { - let mut mtt = MoreThanText::new(); - let initial: Option = None; - let id = mtt.validate_session(initial); - let output = mtt.validate_session(Some(id.clone())); - assert_eq!(output, id); - } - - #[test] - fn get_root_document_with_str() { - let mut mtt = MoreThanText::new(); - let id = mtt.validate_session(Some(Uuid::new_v4())); - let output = mtt.get_document(id, ActionType::Get, "root", "".to_string()); - assert!(output.get_error().is_none()); - } - - #[test] - fn get_root_document_with_string() { - let mut mtt = MoreThanText::new(); - let id = mtt.validate_session(Some(Uuid::new_v4())); - let output = mtt.get_document(id, ActionType::Get, "root".to_string(), "".to_string()); - assert!(output.get_error().is_none()); - } -} diff --git a/src/queue.rs b/src/queue.rs deleted file mode 100644 index efbed7a..0000000 --- a/src/queue.rs +++ /dev/null @@ -1,346 +0,0 @@ -use crate::{field::Field, ErrorType}; -use std::{ - collections::HashMap, - sync::{mpsc::Sender, Arc, RwLock}, -}; -use uuid::Uuid; - -#[derive(Clone, Debug, Eq, Hash, PartialEq)] -pub enum MsgType { - ActionOk, - Document, - DocumentRequest, - Error, - Session, - SessionGet, - SessionValidate, - SessionValidated, - Time, -} - -#[derive(Clone)] -pub struct Message { - id: Uuid, - msg_type: MsgType, - data: HashMap, -} - -impl Message { - pub fn new(msg_type: MsgType) -> Self { - Self { - id: Uuid::new_v4(), - msg_type: msg_type, - data: HashMap::new(), - } - } - - pub fn reply(&self, data: MsgType) -> Message { - Self { - id: self.id.clone(), - msg_type: data, - data: HashMap::new(), - } - } - - pub fn reply_with_data(&self, msg_type: MsgType) -> Message { - Self { - id: self.id.clone(), - msg_type: msg_type, - data: self.data.clone(), - } - } - - pub fn reply_with_error(&self, error: ErrorType) -> Self { - let mut reply = self.reply(MsgType::Error); - reply.add_data("error_type", error); - reply - } - - pub fn get_msg_type(&self) -> &MsgType { - &self.msg_type - } - - pub fn add_data(&mut self, name: S, data: F) - where - S: Into, - F: Into, - { - self.data.insert(name.into(), data.into()); - } - - pub fn get_data(&self, name: S) -> Option<&Field> - where - S: Into, - { - let field_name = name.into(); - self.data.get(&field_name) - } - - pub fn get_id(&self) -> Uuid { - self.id.clone() - } - - pub fn reset_id(&mut self) { - self.id = Uuid::new_v4(); - } -} - -#[cfg(test)] -mod messages { - use super::*; - - #[test] - fn new_message() { - let msg = Message::new(MsgType::SessionValidate); - match msg.msg_type { - MsgType::SessionValidate => (), - _ => unreachable!("new defaults to noop"), - } - assert!(msg.data.is_empty()); - } - - #[test] - fn message_ids_are_random() { - let mut ids: Vec = Vec::new(); - for _ in 0..10 { - let msg = Message::new(MsgType::SessionValidate); - let id = msg.id.clone(); - assert!(!ids.contains(&id), "{} is a duplicate", id); - ids.push(id); - } - } - - #[test] - fn create_reply() { - let id = Uuid::new_v4(); - let mut msg = Message::new(MsgType::SessionValidate); - msg.id = id.clone(); - msg.add_data("test", "test"); - let data = MsgType::SessionValidate; - let result = msg.reply(data); - assert_eq!(result.id, id); - match result.msg_type { - MsgType::SessionValidate => {} - _ => unreachable!("should have been a registration request"), - } - assert!(result.data.is_empty()); - } - - #[test] - fn get_message_type() { - let msg = Message::new(MsgType::SessionValidate); - match msg.get_msg_type() { - MsgType::SessionValidate => {} - _ => unreachable!("should have bneen noopn"), - } - } - - #[test] - fn add_data() { - let mut msg = Message::new(MsgType::SessionValidate); - let one = "one"; - let two = "two".to_string(); - msg.add_data(one, one); - msg.add_data(two.clone(), two.clone()); - assert_eq!(msg.get_data(one).unwrap().to_string(), one); - assert_eq!(msg.get_data(&two).unwrap().to_string(), two); - } - - #[test] - fn get_data_into_string() { - let id = Uuid::new_v4(); - let mut msg = Message::new(MsgType::SessionValidate); - msg.add_data(id, id); - assert_eq!(msg.get_data(id).unwrap().to_uuid().unwrap(), id); - } - - #[test] - fn copy_data_with_reply() { - let id = Uuid::new_v4(); - let reply_type = MsgType::SessionValidated; - let mut msg = Message::new(MsgType::SessionValidate); - msg.add_data(id, id); - let reply = msg.reply_with_data(reply_type.clone()); - assert_eq!(reply.id, msg.id); - match reply.get_msg_type() { - MsgType::SessionValidated => {} - _ => unreachable!( - "Got {:?} should have been {:?}", - msg.get_msg_type(), - reply_type - ), - } - assert_eq!(reply.data.len(), msg.data.len()); - let output = reply.get_data(&id.to_string()).unwrap().to_uuid().unwrap(); - let expected = msg.get_data(&id.to_string()).unwrap().to_uuid().unwrap(); - assert_eq!(output, expected); - } - - #[test] - fn get_message_id() { - let msg = Message::new(MsgType::SessionValidated); - assert_eq!(msg.get_id(), msg.id); - } - - #[test] - fn reset_msg_id() { - let mut msg = Message::new(MsgType::Time); - let id = msg.get_id(); - msg.reset_id(); - assert_ne!(msg.get_id(), id); - } - - #[test] - fn error_reply() { - let msg = Message::new(MsgType::Time); - let errors = [ - ErrorType::DocumentAlreadyExists, - ErrorType::DocumentInvalidRequest, - ]; - for error in errors.into_iter() { - let reply = msg.reply_with_error(error.clone()); - assert_eq!(reply.get_id(), msg.get_id()); - assert_eq!( - format!("{:?}", reply.get_msg_type()), - format!("{:?}", MsgType::Error) - ); - assert_eq!( - format!( - "{:?}", - reply - .get_data("error_type") - .unwrap() - .to_error_type() - .unwrap() - ), - format!("{:?}", error) - ); - } - } -} - -#[derive(Clone)] -pub struct Queue { - store: Arc>>>>, -} - -impl Queue { - pub fn new() -> Self { - Self { - store: Arc::new(RwLock::new(HashMap::new())), - } - } - - pub fn add(&self, tx: Sender, msg_types: Vec) { - let mut store = self.store.write().unwrap(); - for msg_type in msg_types.into_iter() { - if !store.contains_key(&msg_type) { - store.insert(msg_type.clone(), Vec::new()); - } - let senders = store.get_mut(&msg_type).unwrap(); - senders.push(tx.clone()); - } - } - - pub fn send(&self, msg: Message) -> Result<(), String> { - let store = self.store.read().unwrap(); - match store.get(&msg.get_msg_type()) { - Some(senders) => { - for sender in senders.into_iter() { - sender.send(msg.clone()).unwrap(); - } - Ok(()) - } - None => Err(format!("no listeners for {:?}", msg.get_msg_type())), - } - } -} - -#[cfg(test)] -mod queues { - use super::*; - use std::{ - sync::mpsc::{channel, RecvTimeoutError}, - time::Duration, - }; - - static TIMEOUT: Duration = Duration::from_millis(500); - - #[test] - fn create_queue() { - let queue = Queue::new(); - let (tx1, rx1) = channel(); - let (tx2, rx2) = channel(); - queue.add(tx1, [MsgType::SessionValidate].to_vec()); - queue.add(tx2, [MsgType::SessionValidate].to_vec()); - queue.send(Message::new(MsgType::SessionValidate)).unwrap(); - rx1.recv().unwrap(); - rx2.recv().unwrap(); - } - - #[test] - fn messages_are_routed() { - let queue = Queue::new(); - let (tx1, rx1) = channel(); - let (tx2, rx2) = channel(); - queue.add(tx1, [MsgType::SessionValidate].to_vec()); - queue.add(tx2, [MsgType::SessionValidated].to_vec()); - queue.send(Message::new(MsgType::SessionValidate)).unwrap(); - let result = rx1.recv().unwrap(); - match result.get_msg_type() { - MsgType::SessionValidate => {} - _ => unreachable!( - "received {:?}, should have been session vvalidate", - result.get_msg_type() - ), - } - match rx2.recv_timeout(TIMEOUT) { - Ok(_) => unreachable!("should not have received anything"), - Err(err) => match err { - RecvTimeoutError::Timeout => {} - _ => unreachable!("{:?}", err), - }, - } - queue.send(Message::new(MsgType::SessionValidated)).unwrap(); - let result = rx2.recv().unwrap(); - match result.get_msg_type() { - MsgType::SessionValidated => {} - _ => unreachable!( - "received {:?}, should have been session vvalidate", - result.get_msg_type() - ), - } - match rx1.recv_timeout(TIMEOUT) { - Ok(_) => unreachable!("should not have received anything"), - Err(err) => match err { - RecvTimeoutError::Timeout => {} - _ => unreachable!("{:?}", err), - }, - } - } - - #[test] - fn assign_sender_multiple_message_types() { - let queue = Queue::new(); - let (tx, rx) = channel(); - queue.add( - tx, - [MsgType::SessionValidated, MsgType::SessionValidate].to_vec(), - ); - queue.send(Message::new(MsgType::SessionValidate)).unwrap(); - let msg = rx.recv().unwrap(); - assert_eq!(msg.get_msg_type(), &MsgType::SessionValidate); - queue.send(Message::new(MsgType::SessionValidated)).unwrap(); - let msg = rx.recv().unwrap(); - assert_eq!(msg.get_msg_type(), &MsgType::SessionValidated); - } - - #[test] - fn unassigned_message_should_return_error() { - let queue = Queue::new(); - match queue.send(Message::new(MsgType::SessionValidated)) { - Ok(_) => unreachable!("should return error"), - Err(_) => {} - } - } -} diff --git a/src/session.rs b/src/session.rs deleted file mode 100644 index 22b371b..0000000 --- a/src/session.rs +++ /dev/null @@ -1,384 +0,0 @@ -use crate::{ - field::Field, - queue::{Message, MsgType, Queue}, -}; -use chrono::prelude::*; -use isolang::Language; -use std::{ - collections::HashMap, - sync::mpsc::{channel, Receiver}, - thread::spawn, - time::Duration, -}; -use uuid::Uuid; - -const EXPIRE_IN: Duration = Duration::from_secs(60 * 60); -const RESPONDS_TO: [MsgType; 3] = [MsgType::SessionGet, MsgType::SessionValidate, MsgType::Time]; -const DEFAULT_LANG: Language = Language::Eng; - -struct SessionData { - expire_on: DateTime, - language: Language, -} - -impl SessionData { - fn new(lang: Option) -> Self { - let session_lang = match lang { - Some(data) => data.clone(), - None => DEFAULT_LANG, - }; - Self { - expire_on: Utc::now() + EXPIRE_IN, - language: session_lang, - } - } - - fn extend(&mut self) { - self.expire_on = Utc::now() + EXPIRE_IN; - } - - fn is_expired(&self, now: &DateTime) -> bool { - now > &self.expire_on - } -} - -#[cfg(test)] -mod sessiondatas { - use super::*; - - #[test] - fn create_session_data() { - let expire = Utc::now() + EXPIRE_IN; - let data = SessionData::new(None); - assert!( - data.expire_on > expire, - "{:?} should be greater than {:?}", - data.expire_on, - expire - ); - } - - #[test] - fn extend_usage_time() { - let mut data = SessionData::new(None); - let expire = Utc::now() + EXPIRE_IN; - data.extend(); - assert!( - data.expire_on > expire, - "{:?} should be greater than {:?}", - data.expire_on, - expire - ); - } - - #[test] - fn is_expired() { - let data = SessionData::new(None); - let expire = Utc::now() + EXPIRE_IN; - assert!(data.is_expired(&expire), "should be expired"); - } - - #[test] - fn is_not_expired() { - let expire = Utc::now() + EXPIRE_IN; - let data = SessionData::new(None); - assert!(!data.is_expired(&expire), "should be not expired"); - } - - #[test] - fn english_is_the_default_language() { - let data = SessionData::new(None); - assert_eq!(data.language, DEFAULT_LANG); - } - - #[test] - fn assign_language() { - let langs = [Language::Jpn, Language::Deu]; - for lang in langs.into_iter() { - let data = SessionData::new(Some(lang.clone())); - assert_eq!(data.language, lang); - } - } -} - -pub struct Session { - data: HashMap, - queue: Queue, - rx: Receiver, -} - -impl Session { - fn new(queue: Queue, rx: Receiver) -> Self { - Self { - data: HashMap::new(), - queue: queue, - rx: rx, - } - } - - pub fn start(queue: Queue) { - let (tx, rx) = channel(); - let mut session = Session::new(queue, rx); - session.queue.add(tx, RESPONDS_TO.to_vec()); - spawn(move || { - session.listen(); - }); - } - - fn listen(&mut self) { - loop { - let msg = self.rx.recv().unwrap(); - match msg.get_msg_type() { - MsgType::SessionGet => self.get(msg), - MsgType::SessionValidate => self.validate(msg), - MsgType::Time => self.expire(msg), - _ => unreachable!("received unknown message"), - }; - } - } - - fn validate(&mut self, msg: Message) { - match msg.get_data("sess_id") { - Some(sid) => match sid { - Field::Uuid(sess_id) => match self.data.get_mut(&sess_id) { - Some(sess_data) => { - sess_data.extend(); - let reply = msg.reply_with_data(MsgType::SessionValidated); - self.queue.send(reply).unwrap(); - } - None => self.new_session(msg), - }, - _ => self.new_session(msg), - }, - None => self.new_session(msg), - } - } - - fn new_session(&mut self, msg: Message) { - let mut id = Uuid::new_v4(); - while self.data.contains_key(&id) { - id = Uuid::new_v4(); - } - let req_lang = match msg.get_data("language") { - Some(data) => Some(data.to_language().unwrap().clone()), - None => None, - }; - self.data.insert(id.clone(), SessionData::new(req_lang)); - let mut reply = msg.reply_with_data(MsgType::SessionValidated); - reply.add_data("sess_id", id); - self.queue.send(reply).unwrap(); - } - - fn expire(&mut self, msg: Message) { - let now = msg.get_data("time").unwrap().to_datetime().unwrap(); - let mut expired: Vec = Vec::new(); - for (id, data) in self.data.iter() { - if data.is_expired(&now) { - expired.push(id.clone()); - } - } - for id in expired.iter() { - self.data.remove(id); - } - } - - fn get(&self, msg: Message) { - let sess_id = msg.get_data("sess_id").unwrap().to_uuid().unwrap(); - let sess_data = self.data.get(&sess_id).unwrap(); - let mut reply = msg.reply(MsgType::Session); - reply.add_data("language", sess_data.language.clone()); - self.queue.send(reply); - } -} - -#[cfg(test)] -pub mod sessions { - use super::*; - use crate::queue::{Message, MsgType}; - use std::{sync::mpsc::channel, time::Duration}; - - static TIMEOUT: Duration = Duration::from_millis(500); - - pub fn create_validated_reply(msg: Message) -> Message { - let mut reply = msg.reply(MsgType::SessionValidated); - reply.add_data("sess_id", Uuid::new_v4()); - reply - } - - fn setup_session() -> (Queue, Receiver) { - let queue = Queue::new(); - let (tx, rx) = channel(); - let listen_for = [MsgType::Session, MsgType::SessionValidated].to_vec(); - queue.add(tx, listen_for); - Session::start(queue.clone()); - (queue, rx) - } - - fn create_session(queue: &Queue, rx: &Receiver, lang: Option) -> Uuid { - let mut msg = Message::new(MsgType::SessionValidate); - match lang { - Some(data) => msg.add_data("language", data.clone()), - None => {} - } - queue.send(msg.clone()).unwrap(); - let holder = rx.recv_timeout(TIMEOUT).unwrap(); - holder.get_data("sess_id").unwrap().to_uuid().unwrap() - } - - #[test] - fn get_new_session() { - let id = Uuid::new_v4(); - let (queue, rx) = setup_session(); - let mut msg = Message::new(MsgType::SessionValidate); - msg.add_data(id, id); - queue.send(msg.clone()).unwrap(); - let result = rx.recv_timeout(TIMEOUT).unwrap(); - match result.get_msg_type() { - MsgType::SessionValidated => {} - _ => unreachable!( - "received {:?}, should have been a session", - result.get_msg_type() - ), - } - assert_eq!(result.get_id(), msg.get_id()); - assert_eq!(result.get_data(id).unwrap().to_uuid().unwrap(), id); - } - - #[test] - fn session_id_is_unique() { - let (queue, rx) = setup_session(); - let msg = Message::new(MsgType::SessionValidate); - let mut ids: Vec = Vec::new(); - for _ in 0..10 { - queue.send(msg.clone()).unwrap(); - let result = rx.recv_timeout(TIMEOUT).unwrap(); - let id = result.get_data("sess_id").unwrap().to_uuid().unwrap(); - assert!(!ids.contains(&id), "{} is a duplicate id", id); - ids.push(id); - } - } - - #[test] - fn existing_id_is_returned() { - let add_data = Uuid::new_v4(); - let (queue, rx) = setup_session(); - let id = create_session(&queue, &rx, None); - let mut msg = Message::new(MsgType::SessionValidate); - msg.add_data("sess_id", id.clone()); - msg.add_data(add_data, add_data); - queue.send(msg).unwrap(); - let result = rx.recv_timeout(TIMEOUT).unwrap(); - let output = result.get_data("sess_id").unwrap().to_uuid().unwrap(); - assert_eq!(output, id); - assert_eq!( - result.get_data(add_data).unwrap().to_uuid().unwrap(), - add_data - ); - } - - #[test] - fn issue_new_if_validated_doe_not_exist() { - let id = Uuid::new_v4(); - let (queue, rx) = setup_session(); - let mut msg = Message::new(MsgType::SessionValidate); - msg.add_data("sess_id", id.clone()); - queue.send(msg).unwrap(); - let result = rx.recv_timeout(TIMEOUT).unwrap(); - let output = result.get_data("sess_id").unwrap().to_uuid().unwrap(); - assert_ne!(output, id); - } - - #[test] - fn new_for_bad_uuid() { - let id = "bad uuid"; - let (queue, rx) = setup_session(); - let mut msg = Message::new(MsgType::SessionValidate); - msg.add_data("sess_id", id); - queue.send(msg).unwrap(); - let result = rx.recv_timeout(TIMEOUT).unwrap(); - let output = result.get_data("sess_id").unwrap().to_string(); - assert_ne!(output, id); - } - - #[test] - fn timer_does_nothing_to_unexpired() { - let expire = Utc::now() + EXPIRE_IN; - let (queue, rx) = setup_session(); - let id = create_session(&queue, &rx, None); - let mut time_msg = Message::new(MsgType::Time); - time_msg.add_data("time", expire); - queue.send(time_msg).unwrap(); - let mut validate_msg = Message::new(MsgType::SessionValidate); - validate_msg.add_data("sess_id", id.clone()); - queue.send(validate_msg).unwrap(); - let result = rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(result.get_data("sess_id").unwrap().to_uuid().unwrap(), id); - } - - #[test] - fn timer_removes_expired() { - let (queue, rx) = setup_session(); - let id = create_session(&queue, &rx, None); - let expire = Utc::now() + EXPIRE_IN; - let mut time_msg = Message::new(MsgType::Time); - time_msg.add_data("time", expire); - queue.send(time_msg).unwrap(); - let mut validate_msg = Message::new(MsgType::SessionValidate); - validate_msg.add_data("sess_id", id.clone()); - queue.send(validate_msg).unwrap(); - let result = rx.recv_timeout(TIMEOUT).unwrap(); - assert_ne!(result.get_data("sess_id").unwrap().to_uuid().unwrap(), id); - } - - #[test] - fn validate_extends_session() { - let (queue, rx) = setup_session(); - let id = create_session(&queue, &rx, None); - let mut validate_msg = Message::new(MsgType::SessionValidate); - validate_msg.add_data("sess_id", id.clone()); - let expire = Utc::now() + EXPIRE_IN; - let mut time_msg = Message::new(MsgType::Time); - time_msg.add_data("time", expire); - queue.send(validate_msg.clone()).unwrap(); - queue.send(time_msg).unwrap(); - queue.send(validate_msg).unwrap(); - rx.recv_timeout(TIMEOUT).unwrap(); - let result = rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(result.get_data("sess_id").unwrap().to_uuid().unwrap(), id); - } - - #[test] - fn get_session_information() { - let (queue, rx) = setup_session(); - let id = create_session(&queue, &rx, None); - let mut msg = Message::new(MsgType::SessionGet); - msg.add_data("sess_id", id.clone()); - queue.send(msg.clone()); - let reply = rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(reply.get_id(), msg.get_id()); - assert_eq!(reply.get_msg_type(), &MsgType::Session); - assert_eq!( - reply.get_data("language").unwrap().to_language().unwrap(), - DEFAULT_LANG - ); - } - - #[test] - fn get_requested_langaages() { - let langs = [Language::Jpn, Language::Deu]; - let (queue, rx) = setup_session(); - for lang in langs.into_iter() { - let id = create_session(&queue, &rx, Some(lang.clone())); - let mut msg = Message::new(MsgType::SessionGet); - msg.add_data("sess_id", id.clone()); - queue.send(msg.clone()); - let reply = rx.recv_timeout(TIMEOUT).unwrap(); - assert_eq!(reply.get_id(), msg.get_id()); - assert_eq!(reply.get_msg_type(), &MsgType::Session); - assert_eq!( - reply.get_data("language").unwrap().to_language().unwrap(), - lang - ); - } - } -}