From 3af3eddf713721e1194e07b3d2c8f6cc16407efe Mon Sep 17 00:00:00 2001 From: Dark-Alex-17 Date: Tue, 8 Aug 2023 10:50:05 -0600 Subject: [PATCH] Added unit tests to the app module --- Cargo.toml | 5 + src/app/mod.rs | 161 +++++ src/app/radarr.rs | 599 +++++++++++++++++- .../radarr_handlers/add_movie_handler.rs | 6 +- src/models/radarr_models.rs | 27 +- src/utils.rs | 29 + 6 files changed, 800 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 848be26..6fc4662 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,11 @@ reqwest = { version = "0.11.13", features = ["json"] } serde_yaml = "0.9.16" serde_json = "1.0.91" serde = { version = "1.0", features = ["derive"] } +strum = {version = "0.24", features = ["derive"] } +strum_macros = "0.24" tokio = { version = "1.24.1", features = ["full"] } tui = "0.19.0" urlencoding = "2.1.2" + +[dev-dependencies] +pretty_assertions = "1.3.0" \ No newline at end of file diff --git a/src/app/mod.rs b/src/app/mod.rs index c38c450..ab2c648 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -170,3 +170,164 @@ impl Default for RadarrConfig { } } } + +#[cfg(test)] +mod tests { + use pretty_assertions::assert_eq; + use tokio::sync::mpsc; + + use crate::network::radarr_network::RadarrEvent; + + use super::*; + + #[test] + fn test_navigation_stack_methods() { + let mut app = App::default(); + + assert_eq!(app.get_current_route(), &DEFAULT_ROUTE); + + app.push_navigation_stack(ActiveRadarrBlock::Downloads.into()); + + assert_eq!( + app.get_current_route(), + &ActiveRadarrBlock::Downloads.into() + ); + assert!(app.is_routing); + + app.is_routing = false; + app.pop_and_push_navigation_stack(ActiveRadarrBlock::Collections.into()); + + assert_eq!( + app.get_current_route(), + &ActiveRadarrBlock::Collections.into() + ); + assert!(app.is_routing); + + app.is_routing = false; + app.pop_navigation_stack(); + + assert_eq!(app.get_current_route(), &DEFAULT_ROUTE); + assert!(app.is_routing); + + app.is_routing = false; + app.pop_navigation_stack(); + + assert_eq!(app.get_current_route(), &DEFAULT_ROUTE); + assert!(app.is_routing); + } + + #[test] + fn test_reset_tick_count() { + let mut app = App { + tick_count: 2, + ..App::default() + }; + + app.reset_tick_count(); + + assert_eq!(app.tick_count, 0); + } + + #[test] + fn test_reset() { + let mut app = App { + tick_count: 2, + error: String::from("Test error").into(), + data: Data { + radarr_data: RadarrData { + version: "test".to_owned(), + ..RadarrData::default() + }, + }, + ..App::default() + }; + + app.reset(); + + assert_eq!(app.tick_count, 0); + assert_eq!(app.error, HorizontallyScrollableText::default()); + assert_eq!(app.data.radarr_data.version, String::default()); + } + + #[test] + fn test_handle_error() { + let mut app = App::default(); + let test_string = "Testing"; + + app.handle_error(anyhow!(test_string)); + + assert_eq!(app.error.stationary_style(), test_string); + + app.handle_error(anyhow!("Testing a different error")); + + assert_eq!(app.error.stationary_style(), test_string); + } + + #[tokio::test] + async fn test_on_tick_first_render() { + let (sync_network_tx, mut sync_network_rx) = mpsc::channel::(500); + + let mut app = App { + tick_until_poll: 2, + network_tx: Some(sync_network_tx), + ..App::default() + }; + + assert_eq!(app.tick_count, 0); + + app.on_tick(true).await; + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetQualityProfiles.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetRootFolders.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetOverview.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetStatus.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetMovies.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetDownloads.into() + ); + assert!(!app.is_routing); + assert!(!app.should_refresh); + assert_eq!(app.tick_count, 1); + } + + #[tokio::test] + async fn test_on_tick_routing() { + let mut app = App { + tick_until_poll: 2, + tick_count: 2, + is_routing: true, + ..App::default() + }; + + app.on_tick(false).await; + assert!(!app.is_routing); + } + + #[tokio::test] + async fn test_on_tick_should_refresh() { + let mut app = App { + tick_until_poll: 2, + tick_count: 2, + should_refresh: true, + ..App::default() + }; + + app.on_tick(false).await; + assert!(!app.should_refresh); + } +} diff --git a/src/app/radarr.rs b/src/app/radarr.rs index 78df5d6..4afa58f 100644 --- a/src/app/radarr.rs +++ b/src/app/radarr.rs @@ -76,10 +76,6 @@ impl RadarrData { self.add_movie_minimum_availability_list = StatefulList::default(); self.add_movie_quality_profile_list = StatefulList::default(); } - - pub fn reset_main_tab_index(&mut self) { - self.main_tabs.index = 0; - } } impl Default for RadarrData { @@ -397,3 +393,598 @@ impl App { .set_items(collection_movies); } } + +#[cfg(test)] +mod radarr_data_tests { + use pretty_assertions::assert_eq; + + use super::*; + + #[test] + fn test_reset_movie_collection_table() { + let mut radarr_data = RadarrData::default(); + radarr_data + .collection_movies + .set_items(vec![CollectionMovie::default()]); + + radarr_data.reset_movie_collection_table(); + + assert!(radarr_data.collection_movies.items.is_empty()); + } + + #[test] + fn test_rest_search() { + let mut radarr_data = RadarrData { + is_searching: true, + search: "test search".to_owned(), + filter: "test filter".to_owned(), + ..RadarrData::default() + }; + radarr_data + .filtered_movies + .set_items(vec![Movie::default()]); + radarr_data + .filtered_collections + .set_items(vec![Collection::default()]); + radarr_data + .add_searched_movies + .set_items(vec![AddMovieSearchResult::default()]); + + radarr_data.reset_search(); + + assert!(!radarr_data.is_searching); + assert!(radarr_data.search.is_empty()); + assert!(radarr_data.filter.is_empty()); + assert!(radarr_data.filtered_movies.items.is_empty()); + assert!(radarr_data.filtered_collections.items.is_empty()); + assert!(radarr_data.add_searched_movies.items.is_empty()); + } + + #[test] + fn test_reset_movie_info_tabs() { + let mut radarr_data = RadarrData { + file_details: "test file details".to_owned(), + audio_details: "test audio details".to_owned(), + video_details: "test video details".to_owned(), + movie_details: ScrollableText::with_string("test movie details".to_owned()), + ..RadarrData::default() + }; + radarr_data + .movie_history + .set_items(vec![MovieHistoryItem::default()]); + radarr_data.movie_cast.set_items(vec![Credit::default()]); + radarr_data.movie_crew.set_items(vec![Credit::default()]); + radarr_data + .movie_releases + .set_items(vec![Release::default()]); + radarr_data.movie_info_tabs.index = 1; + + radarr_data.reset_movie_info_tabs(); + + assert!(radarr_data.file_details.is_empty()); + assert!(radarr_data.audio_details.is_empty()); + assert!(radarr_data.video_details.is_empty()); + assert!(radarr_data.movie_details.get_text().is_empty()); + assert!(radarr_data.movie_history.items.is_empty()); + assert!(radarr_data.movie_cast.items.is_empty()); + assert!(radarr_data.movie_crew.items.is_empty()); + assert!(radarr_data.movie_releases.items.is_empty()); + assert_eq!(radarr_data.movie_info_tabs.index, 0); + } + + #[test] + fn test_reset_add_movie_selections() { + let mut radarr_data = RadarrData::default(); + radarr_data + .add_movie_monitor_list + .set_items(vec![Monitor::default()]); + radarr_data + .add_movie_minimum_availability_list + .set_items(vec![MinimumAvailability::default()]); + radarr_data + .add_movie_quality_profile_list + .set_items(vec![String::default()]); + + radarr_data.reset_add_movie_selections(); + + assert!(radarr_data.add_movie_monitor_list.items.is_empty()); + assert!(radarr_data + .add_movie_minimum_availability_list + .items + .is_empty()); + assert!(radarr_data.add_movie_quality_profile_list.items.is_empty()); + } +} + +#[cfg(test)] +mod active_radarr_block_tests { + use pretty_assertions::assert_eq; + + use crate::app::radarr::ActiveRadarrBlock; + + #[test] + fn test_next_add_prompt_block() { + let active_block = ActiveRadarrBlock::AddMovieSelectMonitor.next_add_prompt_block(); + + assert_eq!( + active_block, + ActiveRadarrBlock::AddMovieSelectMinimumAvailability + ); + + let active_block = active_block.next_add_prompt_block(); + + assert_eq!( + active_block, + ActiveRadarrBlock::AddMovieSelectQualityProfile + ); + + let active_block = active_block.next_add_prompt_block(); + + assert_eq!(active_block, ActiveRadarrBlock::AddMovieConfirmPrompt); + + let active_block = active_block.next_add_prompt_block(); + + assert_eq!(active_block, ActiveRadarrBlock::AddMovieSelectMonitor); + } + + #[test] + fn test_previous_add_prompt_block() { + let active_block = ActiveRadarrBlock::AddMovieSelectMonitor.previous_add_prompt_block(); + + assert_eq!(active_block, ActiveRadarrBlock::AddMovieConfirmPrompt); + + let active_block = active_block.previous_add_prompt_block(); + + assert_eq!( + active_block, + ActiveRadarrBlock::AddMovieSelectQualityProfile + ); + + let active_block = active_block.previous_add_prompt_block(); + + assert_eq!( + active_block, + ActiveRadarrBlock::AddMovieSelectMinimumAvailability + ); + + let active_block = active_block.previous_add_prompt_block(); + + assert_eq!(active_block, ActiveRadarrBlock::AddMovieSelectMonitor); + } +} + +#[cfg(test)] +mod tests { + use pretty_assertions::assert_eq; + use tokio::sync::mpsc; + + use crate::network::NetworkEvent; + + use super::*; + + #[tokio::test] + async fn test_dispatch_by_collections_block() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + app + .dispatch_by_radarr_block(&ActiveRadarrBlock::Collections) + .await; + + assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetCollections.into() + ); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + + #[tokio::test] + async fn test_dispatch_by_collection_details_block() { + let mut app = App::default(); + + app.data.radarr_data.collections.set_items(vec![Collection { + movies: Some(vec![CollectionMovie::default()]), + ..Collection::default() + }]); + + app + .dispatch_by_radarr_block(&ActiveRadarrBlock::CollectionDetails) + .await; + + assert!(!app.is_loading); + assert!(!app.data.radarr_data.collection_movies.items.is_empty()); + assert_eq!(app.tick_count, 0); + } + + #[tokio::test] + async fn test_dispatch_by_downloads_block() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + app + .dispatch_by_radarr_block(&ActiveRadarrBlock::Downloads) + .await; + + assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetDownloads.into() + ); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + + #[tokio::test] + async fn test_dispatch_by_movies_block() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + app + .dispatch_by_radarr_block(&ActiveRadarrBlock::Movies) + .await; + + assert!(!app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetMovies.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetDownloads.into() + ); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + + #[tokio::test] + async fn test_dispatch_by_add_movie_search_results_block() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + app + .dispatch_by_radarr_block(&ActiveRadarrBlock::AddMovieSearchResults) + .await; + + assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::SearchNewMovie.into() + ); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + + #[tokio::test] + async fn test_dispatch_by_movie_details_block() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + app + .dispatch_by_radarr_block(&ActiveRadarrBlock::MovieDetails) + .await; + + assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetMovieDetails.into() + ); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + + #[tokio::test] + async fn test_dispatch_by_file_info_block() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + app + .dispatch_by_radarr_block(&ActiveRadarrBlock::FileInfo) + .await; + + assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetMovieDetails.into() + ); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + + #[tokio::test] + async fn test_dispatch_by_movie_history_block() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + app + .dispatch_by_radarr_block(&ActiveRadarrBlock::MovieHistory) + .await; + + assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetMovieHistory.into() + ); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + + #[tokio::test] + async fn test_dispatch_by_cast_crew_blocks() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + for active_radarr_block in &[ActiveRadarrBlock::Cast, ActiveRadarrBlock::Crew] { + app.data.radarr_data.movie_cast = StatefulTable::default(); + app.data.radarr_data.movie_crew = StatefulTable::default(); + + app.dispatch_by_radarr_block(active_radarr_block).await; + + assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetMovieCredits.into() + ); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + } + + #[tokio::test] + async fn test_dispatch_by_cast_crew_blocks_movie_cast_non_empty() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + for active_radarr_block in &[ActiveRadarrBlock::Cast, ActiveRadarrBlock::Crew] { + app + .data + .radarr_data + .movie_cast + .set_items(vec![Credit::default()]); + + app.dispatch_by_radarr_block(active_radarr_block).await; + + assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetMovieCredits.into() + ); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + } + + #[tokio::test] + async fn test_dispatch_by_cast_crew_blocks_movie_crew_non_empty() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + for active_radarr_block in &[ActiveRadarrBlock::Cast, ActiveRadarrBlock::Crew] { + app + .data + .radarr_data + .movie_crew + .set_items(vec![Credit::default()]); + + app.dispatch_by_radarr_block(active_radarr_block).await; + + assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetMovieCredits.into() + ); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + } + + #[tokio::test] + async fn test_dispatch_by_cast_crew_blocks_cast_and_crew_non_empty() { + let mut app = App::default(); + + for active_radarr_block in &[ActiveRadarrBlock::Cast, ActiveRadarrBlock::Crew] { + app + .data + .radarr_data + .movie_cast + .set_items(vec![Credit::default()]); + app + .data + .radarr_data + .movie_crew + .set_items(vec![Credit::default()]); + + app.dispatch_by_radarr_block(active_radarr_block).await; + + assert!(!app.is_loading); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + } + + #[tokio::test] + async fn test_dispatch_by_manual_search_block() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + app + .dispatch_by_radarr_block(&ActiveRadarrBlock::ManualSearch) + .await; + + assert!(app.is_loading); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetReleases.into() + ); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + + #[tokio::test] + async fn test_dispatch_by_manual_search_block_movie_releases_non_empty() { + let mut app = App::default(); + app + .data + .radarr_data + .movie_releases + .set_items(vec![Release::default()]); + + app + .dispatch_by_radarr_block(&ActiveRadarrBlock::ManualSearch) + .await; + + assert!(!app.is_loading); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + + #[tokio::test] + async fn test_dispatch_by_manual_search_block_is_loading() { + let mut app = App { + is_loading: true, + ..App::default() + }; + + app + .dispatch_by_radarr_block(&ActiveRadarrBlock::ManualSearch) + .await; + + assert!(app.is_loading); + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + + #[tokio::test] + async fn test_check_for_prompt_action_no_prompt_confirm() { + let mut app = App::default(); + app.data.radarr_data.prompt_confirm = false; + + app.check_for_prompt_action().await; + + assert!(!app.data.radarr_data.prompt_confirm); + assert!(!app.should_refresh); + } + + #[tokio::test] + async fn test_check_for_prompt_action() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::GetStatus); + + app.check_for_prompt_action().await; + + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetStatus.into() + ); + assert!(app.should_refresh); + assert_eq!(app.data.radarr_data.prompt_confirm_action, None); + } + + #[tokio::test] + async fn test_radarr_on_tick_first_render() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + + app.radarr_on_tick(ActiveRadarrBlock::Downloads, true).await; + + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetQualityProfiles.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetRootFolders.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetOverview.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetStatus.into() + ); + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetDownloads.into() + ); + assert!(app.is_loading); + assert!(!app.data.radarr_data.prompt_confirm); + } + + #[tokio::test] + async fn test_radarr_on_tick_not_routing() { + let mut app = App::default(); + + app + .radarr_on_tick(ActiveRadarrBlock::Downloads, false) + .await; + + assert!(!app.is_routing); + } + + #[tokio::test] + async fn test_radarr_on_tick_routing() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + app.is_routing = true; + + app + .radarr_on_tick(ActiveRadarrBlock::Downloads, false) + .await; + + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetDownloads.into() + ); + assert!(app.is_loading); + assert!(!app.data.radarr_data.prompt_confirm); + } + + #[tokio::test] + async fn test_radarr_on_tick_network_tick_frequency() { + let (mut app, mut sync_network_rx) = construct_app_unit(); + app.network_tick_frequency = Duration::from_secs(0); + + app + .radarr_on_tick(ActiveRadarrBlock::Downloads, false) + .await; + + assert_eq!( + sync_network_rx.recv().await.unwrap(), + RadarrEvent::GetDownloads.into() + ); + assert!(app.is_loading); + assert!(!app.data.radarr_data.prompt_confirm); + } + + #[tokio::test] + async fn test_populate_movie_collection_table_unfiltered() { + let mut app = App::default(); + app.data.radarr_data.collections.set_items(vec![Collection { + movies: Some(vec![CollectionMovie::default()]), + ..Collection::default() + }]); + + app.populate_movie_collection_table().await; + + assert!(!app.data.radarr_data.collection_movies.items.is_empty()); + } + + #[tokio::test] + async fn test_populate_movie_collection_table_filtered() { + let mut app = App::default(); + app + .data + .radarr_data + .filtered_collections + .set_items(vec![Collection { + movies: Some(vec![CollectionMovie::default()]), + ..Collection::default() + }]); + + app.populate_movie_collection_table().await; + + assert!(!app.data.radarr_data.collection_movies.items.is_empty()); + } + + fn construct_app_unit() -> (App, mpsc::Receiver) { + let (sync_network_tx, sync_network_rx) = mpsc::channel::(500); + let mut app = App { + network_tx: Some(sync_network_tx), + tick_count: 1, + ..App::default() + }; + app.data.radarr_data.prompt_confirm = true; + + (app, sync_network_rx) + } +} diff --git a/src/handlers/radarr_handlers/add_movie_handler.rs b/src/handlers/radarr_handlers/add_movie_handler.rs index 9774cbc..7ddcda9 100644 --- a/src/handlers/radarr_handlers/add_movie_handler.rs +++ b/src/handlers/radarr_handlers/add_movie_handler.rs @@ -1,3 +1,5 @@ +use strum::IntoEnumIterator; + use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::radarr::ActiveRadarrBlock; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; @@ -182,13 +184,13 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for AddMovieHandler<'a> { .data .radarr_data .add_movie_monitor_list - .set_items(Monitor::vec()); + .set_items(Vec::from_iter(Monitor::iter())); self .app .data .radarr_data .add_movie_minimum_availability_list - .set_items(MinimumAvailability::vec()); + .set_items(Vec::from_iter(MinimumAvailability::iter())); let mut quality_profile_names: Vec = self .app .data diff --git a/src/models/radarr_models.rs b/src/models/radarr_models.rs index b08e87f..9f0f2e2 100644 --- a/src/models/radarr_models.rs +++ b/src/models/radarr_models.rs @@ -4,6 +4,7 @@ use chrono::{DateTime, Utc}; use derivative::Derivative; use serde::{Deserialize, Serialize}; use serde_json::Number; +use strum_macros::EnumIter; use crate::models::HorizontallyScrollableText; @@ -198,14 +199,15 @@ pub struct QualityWrapper { pub quality: Quality, } -#[derive(Deserialize, PartialEq, Eq, Clone, Debug)] +#[derive(Deserialize, Default, PartialEq, Eq, Clone, Debug)] #[serde(rename_all = "lowercase")] pub enum CreditType { + #[default] Cast, Crew, } -#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] +#[derive(Deserialize, Default, Clone, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Credit { pub person_name: String, @@ -297,7 +299,7 @@ pub struct CommandBody { pub name: String, } -#[derive(Default, PartialEq, Eq, Clone, Debug)] +#[derive(Default, PartialEq, Eq, Clone, Debug, EnumIter)] pub enum MinimumAvailability { #[default] Announced, @@ -319,15 +321,6 @@ impl Display for MinimumAvailability { } impl MinimumAvailability { - pub fn vec() -> Vec { - vec![ - MinimumAvailability::Announced, - MinimumAvailability::InCinemas, - MinimumAvailability::Released, - MinimumAvailability::Tba, - ] - } - pub fn to_display_str(&self) -> &str { match self { MinimumAvailability::Announced => "Announced", @@ -338,7 +331,7 @@ impl MinimumAvailability { } } -#[derive(Default, PartialEq, Eq, Clone, Debug)] +#[derive(Default, PartialEq, Eq, Clone, Debug, EnumIter)] pub enum Monitor { #[default] MovieOnly, @@ -358,14 +351,6 @@ impl Display for Monitor { } impl Monitor { - pub fn vec() -> Vec { - vec![ - Monitor::MovieOnly, - Monitor::MovieAndCollection, - Monitor::None, - ] - } - pub fn to_display_str(&self) -> &str { match self { Monitor::MovieOnly => "Movie only", diff --git a/src/utils.rs b/src/utils.rs index a30562d..4f62d3a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -40,3 +40,32 @@ pub fn strip_non_alphanumeric_characters(input: &str) -> String { .replace_all(&input.to_lowercase(), "") .to_string() } + +#[cfg(test)] +mod tests { + use pretty_assertions::assert_eq; + + use crate::utils::{convert_runtime, convert_to_gb, strip_non_alphanumeric_characters}; + + #[test] + fn test_convert_to_gb() { + assert_eq!(convert_to_gb(2147483648), 2f64); + assert_eq!(convert_to_gb(2662879723), 2.4799999995157123); + } + + #[test] + fn test_convert_runtime() { + let (hours, minutes) = convert_runtime(154); + + assert_eq!(hours, 2); + assert_eq!(minutes, 34); + } + + #[test] + fn test_strop_non_alphanumeric_characters() { + assert_eq!( + strip_non_alphanumeric_characters("Te$t S7r!ng::'~-_}"), + String::from("tet s7rng") + ) + } +}