From 9123067651ed0c3a21f52f2a884136f2ee7d70e3 Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Sat, 25 Nov 2023 17:50:23 -0700 Subject: [PATCH] Fixed a race condition bug with the MovieDetailsModal --- src/network/radarr_network.rs | 68 +++++++++++++------- src/network/radarr_network_tests.rs | 98 +++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 21 deletions(-) diff --git a/src/network/radarr_network.rs b/src/network/radarr_network.rs index a3b64a5..26c0786 100644 --- a/src/network/radarr_network.rs +++ b/src/network/radarr_network.rs @@ -660,24 +660,40 @@ impl<'a, 'b> Network<'a, 'b> { .await; self - .handle_request::<(), Vec>(request_props, |credit_vec, mut app| { - let cast_vec: Vec = credit_vec - .iter() - .cloned() - .filter(|credit| credit.credit_type == CreditType::Cast) - .collect(); - let crew_vec: Vec = credit_vec - .iter() - .cloned() - .filter(|credit| credit.credit_type == CreditType::Crew) - .collect(); + .handle_request::<(), Vec>(request_props, |credit_vec, mut app| { + let cast_vec: Vec = credit_vec + .iter() + .cloned() + .filter(|credit| credit.credit_type == CreditType::Cast) + .collect(); + let crew_vec: Vec = credit_vec + .iter() + .cloned() + .filter(|credit| credit.credit_type == CreditType::Crew) + .collect(); - debug!("Assuming the movie_details_modal is already a Some and was created by the get_movie_details request"); + if app.data.radarr_data.movie_details_modal.is_none() { + app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal::default()); + } - app.data.radarr_data.movie_details_modal.as_mut().unwrap().movie_cast.set_items(cast_vec); - app.data.radarr_data.movie_details_modal.as_mut().unwrap().movie_crew.set_items(crew_vec); - }) - .await; + app + .data + .radarr_data + .movie_details_modal + .as_mut() + .unwrap() + .movie_cast + .set_items(cast_vec); + app + .data + .radarr_data + .movie_details_modal + .as_mut() + .unwrap() + .movie_crew + .set_items(crew_vec); + }) + .await; } async fn get_diskspace(&mut self) { @@ -1076,11 +1092,21 @@ impl<'a, 'b> Network<'a, 'b> { .await; self - .handle_request::<(), Vec>(request_props, |release_vec, mut app| { - debug!("Assuming the movie_details_modal is already a Some and was created by the get_movie_details request"); - app.data.radarr_data.movie_details_modal.as_mut().unwrap().movie_releases.set_items(release_vec); - }) - .await; + .handle_request::<(), Vec>(request_props, |release_vec, mut app| { + if app.data.radarr_data.movie_details_modal.is_none() { + app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal::default()); + } + + app + .data + .radarr_data + .movie_details_modal + .as_mut() + .unwrap() + .movie_releases + .set_items(release_vec); + }) + .await; } async fn get_root_folders(&mut self) { diff --git a/src/network/radarr_network_tests.rs b/src/network/radarr_network_tests.rs index 8614c06..193f423 100644 --- a/src/network/radarr_network_tests.rs +++ b/src/network/radarr_network_tests.rs @@ -366,6 +366,59 @@ mod test { ); } + #[tokio::test] + async fn test_handle_get_releases_event_empty_movie_details_modal() { + let release_json = json!([{ + "guid": "1234", + "protocol": "torrent", + "age": 1, + "title": "Test Release", + "indexer": "kickass torrents", + "indexerId": 2, + "size": 1234, + "rejected": true, + "rejections": [ "Unknown quality profile", "Release is already mapped" ], + "seeders": 2, + "leechers": 1, + "languages": [ { "name": "English" } ], + "quality": { "quality": { "name": "HD - 1080p" }} + }]); + let resource = format!("{}?movieId=1", RadarrEvent::GetReleases.resource()); + let (async_server, app_arc, _server) = mock_radarr_api( + RequestMethod::Get, + None, + Some(release_json), + None, + &resource, + ) + .await; + app_arc + .lock() + .await + .data + .radarr_data + .movies + .set_items(vec![movie()]); + let mut network = Network::new(&app_arc, CancellationToken::new()); + + network.handle_radarr_event(RadarrEvent::GetReleases).await; + + async_server.assert_async().await; + assert_eq!( + app_arc + .lock() + .await + .data + .radarr_data + .movie_details_modal + .as_ref() + .unwrap() + .movie_releases + .items, + vec![release()] + ); + } + #[tokio::test] async fn test_handle_search_new_movie_event() { let add_movie_search_result_json = json!([{ @@ -1684,6 +1737,51 @@ mod test { assert_eq!(movie_details_modal.movie_crew.items, vec![crew_credit()]); } + #[tokio::test] + async fn test_handle_get_movie_credits_event_empty_movie_details_modal() { + let credits_json = json!([ + { + "personName": "Madison Clarke", + "character": "Johnny Blaze", + "type": "cast", + }, + { + "personName": "Alex Clarke", + "department": "Music", + "job": "Composition", + "type": "crew", + } + ]); + let resource = format!("{}?movieId=1", RadarrEvent::GetMovieCredits.resource()); + let (async_server, app_arc, _server) = mock_radarr_api( + RequestMethod::Get, + None, + Some(credits_json), + None, + &resource, + ) + .await; + app_arc + .lock() + .await + .data + .radarr_data + .movies + .set_items(vec![movie()]); + let mut network = Network::new(&app_arc, CancellationToken::new()); + + network + .handle_radarr_event(RadarrEvent::GetMovieCredits) + .await; + + let app = app_arc.lock().await; + let movie_details_modal = app.data.radarr_data.movie_details_modal.as_ref().unwrap(); + + async_server.assert_async().await; + assert_eq!(movie_details_modal.movie_cast.items, vec![cast_credit()]); + assert_eq!(movie_details_modal.movie_crew.items, vec![crew_credit()]); + } + #[tokio::test] async fn test_handle_delete_movie_event() { let resource = format!(