use crate::{ queue::{Message, MsgType, Queue}, ErrorType, }; use std::{ sync::mpsc::{channel, Receiver}, thread::spawn, }; const RESPONDS_TO: [MsgType; 1] = [MsgType::DocumentRequest]; pub struct Document { queue: Queue, rx: Receiver, } impl Document { fn new(queue: Queue, rx: Receiver) -> Self { Self { 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(); let mut reply = match msg.get_data("name") { Some(name) => { if name.to_string() == "root" { msg.reply(MsgType::Document) } else { let mut output = msg.reply(MsgType::Error); output.add_data("error_type", ErrorType::DocumentNotFound); output } } None => msg.reply(MsgType::Document), }; reply.add_data("doc", "Something goes hwew"); self.queue.send(reply).unwrap(); } } } #[cfg(test)] pub mod documents { use super::*; 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::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 name = format!("name-{}", Uuid::new_v4()); let mut msg = Message::new(MsgType::DocumentRequest); msg.add_data("name", "root"); queue.send(msg); let reply = rx.recv().unwrap(); match reply.get_msg_type() { MsgType::Document => {} _ => unreachable!( "Got '{:?}': should have been a document", reply.get_msg_type() ), } } }