Set up automated tests for the application Core #266

Merged
savanni merged 6 commits from visions-core-test into main 2024-11-24 14:53:18 +00:00
3 changed files with 39 additions and 33 deletions
Showing only changes of commit 5535632466 - Show all commits

View File

@ -1,5 +1,5 @@
use std::{ use std::{
collections::HashMap, collections::{hash_map::Iter, HashMap},
fmt::{self, Display}, fmt::{self, Display},
}; };
@ -16,7 +16,7 @@ pub struct AssetId(String);
impl Display for AssetId { impl Display for AssetId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "AssetId({}", self.0) write!(f, "AssetId({})", self.0)
} }
} }
@ -26,8 +26,24 @@ impl From<&str> for AssetId {
} }
} }
impl From<String> for AssetId {
fn from(s: String) -> Self {
AssetId(s)
}
}
pub struct AssetIter<'a>(Iter<'a, AssetId, String>);
impl <'a> Iterator for AssetIter<'a> {
type Item = (&'a AssetId, &'a String);
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
pub trait Assets { pub trait Assets {
fn assets(&self) -> Vec<AssetId>; fn assets<'a>(&'a self) -> AssetIter<'a>;
fn get(&self, asset_id: AssetId) -> Result<Vec<u8>, Error>; fn get(&self, asset_id: AssetId) -> Result<Vec<u8>, Error>;
} }
@ -49,8 +65,8 @@ impl FsAssets {
} }
impl Assets for FsAssets { impl Assets for FsAssets {
fn assets(&self) -> Vec<AssetId> { fn assets<'a>(&'a self) -> AssetIter<'a> {
self.assets.keys().cloned().collect() AssetIter(self.assets.iter())
} }
fn get(&self, asset_id: AssetId) -> Result<Vec<u8>, Error> { fn get(&self, asset_id: AssetId) -> Result<Vec<u8>, Error> {
@ -79,8 +95,8 @@ pub mod mocks {
} }
impl Assets for MemoryAssets { impl Assets for MemoryAssets {
fn assets(&self) -> Vec<AssetId> { fn assets<'a>(&'a self) -> AssetIter<'a> {
self.assets.keys().cloned().collect() AssetIter(self.assets.iter())
} }
fn get(&self, asset_id: AssetId) -> Result<Vec<u8>, Error> { fn get(&self, asset_id: AssetId) -> Result<Vec<u8>, Error> {

View File

@ -20,7 +20,7 @@ struct WebsocketClient {
} }
pub struct AppState { pub struct AppState {
pub assets: Box<dyn Assets + Sync + Send + 'static>, pub asset_db: Box<dyn Assets + Sync + Send + 'static>,
pub clients: HashMap<String, WebsocketClient>, pub clients: HashMap<String, WebsocketClient>,
pub tabletop: Tabletop, pub tabletop: Tabletop,
@ -35,7 +35,7 @@ impl Core {
A: Assets + Sync + Send + 'static, A: Assets + Sync + Send + 'static,
{ {
Self(Arc::new(RwLock::new(AppState { Self(Arc::new(RwLock::new(AppState {
assets: Box::new(assetdb), asset_db: Box::new(assetdb),
clients: HashMap::new(), clients: HashMap::new(),
tabletop: Tabletop { tabletop: Tabletop {
background_color: RGB { background_color: RGB {
@ -98,26 +98,19 @@ impl Core {
} }
pub fn available_images(&self) -> Vec<AssetId> { pub fn available_images(&self) -> Vec<AssetId> {
self.0.read().unwrap().assets.assets() self.0
/* .read()
Ok(std::fs::read_dir(&self.0.read().unwrap().image_base)
.unwrap() .unwrap()
.filter_map(|entry| match entry { .asset_db
Ok(entry_) => match mime_guess::from_path(entry_.path()).first() { .assets()
Some(mime) if mime.type_() == mime::IMAGE => Some( .filter_map(|(asset_id, value)| {
entry_ println!("[{:?}] {}", mime_guess::from_path(&value).first(), value);
.path() match mime_guess::from_path(&value).first() {
.file_name() Some(mime) if mime.type_() == mime::IMAGE => Some(asset_id.clone()),
.and_then(|filename| filename.to_str())
.and_then(|filename| Some(filename.to_owned()))
.unwrap(),
),
_ => None, _ => None,
}, }
Err(_) => None,
}) })
.collect()) .collect()
*/
} }
pub fn set_background_image(&self, path: String) -> Result<(), AppError> { pub fn set_background_image(&self, path: String) -> Result<(), AppError> {
@ -149,8 +142,8 @@ mod test {
#[tokio::test] #[tokio::test]
async fn it_lists_available_images() { async fn it_lists_available_images() {
let assets = MemoryAssets::new(vec![ let assets = MemoryAssets::new(vec![
(AssetId::from("asset_1"), "asset_1".to_owned()), (AssetId::from("asset_1"), "asset_1.png".to_owned()),
(AssetId::from("asset_2"), "asset_2".to_owned()), (AssetId::from("asset_2"), "asset_2.jpg".to_owned()),
(AssetId::from("asset_3"), "asset_3".to_owned()), (AssetId::from("asset_3"), "asset_3".to_owned()),
(AssetId::from("asset_4"), "asset_4".to_owned()), (AssetId::from("asset_4"), "asset_4".to_owned()),
(AssetId::from("asset_5"), "asset_5".to_owned()), (AssetId::from("asset_5"), "asset_5".to_owned()),
@ -158,6 +151,6 @@ mod test {
let core = Core::new(assets); let core = Core::new(assets);
let image_paths = core.available_images(); let image_paths = core.available_images();
assert_eq!(image_paths.len(), 5); assert_eq!(image_paths.len(), 2);
} }
} }

View File

@ -1,8 +1,5 @@
use std::{pin::Pin, time::Duration};
use futures::{SinkExt, StreamExt}; use futures::{SinkExt, StreamExt};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio_stream::wrappers::UnboundedReceiverStream;
use warp::{http::Response, reply::Reply, ws::Message}; use warp::{http::Response, reply::Reply, ws::Message};
use crate::core::Core; use crate::core::Core;
@ -59,7 +56,7 @@ pub struct RegisterResponse {
url: String, url: String,
} }
pub async fn handle_register_client(core: Core, request: RegisterRequest) -> impl Reply { pub async fn handle_register_client(core: Core, _request: RegisterRequest) -> impl Reply {
let client_id = core.register_client(); let client_id = core.register_client();
Response::builder() Response::builder()