use crate::queue::{Message, MsgType, Queue}; use std::{ sync::mpsc::{channel, Receiver}, thread::spawn, }; use uuid::Uuid; const RESPONS_TO: [MsgType; 1] = [MsgType::SessionValidate]; struct Session { queue: Queue, rx: Receiver, } impl Session { fn new(queue: Queue, rx: Receiver) -> Self { Self { queue: queue, rx: rx, } } fn start(queue: Queue) { let (tx, rx) = channel(); let session = Session::new(queue, rx); session.queue.add(tx, RESPONS_TO.to_vec()); spawn(move || { session.listen(); }); } fn listen(&self) { loop { let msg = self.rx.recv().unwrap(); self.validate(msg); } } fn validate(&self, msg: Message) { let mut reply = msg.reply(MsgType::Session); reply.add_data("sess_id", Uuid::new_v4()); self.queue.send(reply); } } #[cfg(test)] mod sessions { use super::*; use crate::queue::{Message, MsgType}; use std::{sync::mpsc::channel, time::Duration}; static TIMEOUT: Duration = Duration::from_millis(500); #[test] fn get_new_session() { let queue = Queue::new(); let (tx, rx) = channel(); queue.add(tx, [MsgType::Session].to_vec()); Session::start(queue.clone()); let msg = Message::new(MsgType::SessionValidate); queue.send(msg.clone()); let result = rx.recv_timeout(TIMEOUT).unwrap(); match result.get_class() { MsgType::Session => {} _ => unreachable!( "received {:?}, should have been a session", result.get_class() ), } assert_eq!(result.get_id(), msg.get_id()); } #[test] fn session_id_is_unique() { let queue = Queue::new(); let (tx, rx) = channel(); queue.add(tx, [MsgType::Session].to_vec()); Session::start(queue.clone()); let msg = Message::new(MsgType::SessionValidate); let mut ids: Vec = Vec::new(); for _ in 0..10 { queue.send(msg.clone()); let result = rx.recv().unwrap(); let id = result.get_data().get("sess_id").unwrap().to_uuid().unwrap(); assert!(!ids.contains(&id), "{} is a duplicate id", id); ids.push(id); } } }