fix(sonarr): Pass the series ID and season number alongside all TriggerAutomaticSeasonSearch events when publishing to the networking channel

This commit is contained in:
2024-12-18 01:34:45 -07:00
parent b12c635c27
commit ed645dd0d5
6 changed files with 46 additions and 128 deletions
@@ -94,7 +94,7 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, SonarrTriggerAutomaticSearchCommand>
let resp = self let resp = self
.network .network
.handle_network_event( .handle_network_event(
SonarrEvent::TriggerAutomaticSeasonSearch(Some((series_id, season_number))).into(), SonarrEvent::TriggerAutomaticSeasonSearch((series_id, season_number)).into(),
) )
.await?; .await?;
serde_json::to_string_pretty(&resp)? serde_json::to_string_pretty(&resp)?
@@ -197,11 +197,8 @@ mod tests {
mock_network mock_network
.expect_handle_network_event() .expect_handle_network_event()
.with(eq::<NetworkEvent>( .with(eq::<NetworkEvent>(
SonarrEvent::TriggerAutomaticSeasonSearch(Some(( SonarrEvent::TriggerAutomaticSeasonSearch((expected_series_id, expected_season_number))
expected_series_id, .into(),
expected_season_number,
)))
.into(),
)) ))
.times(1) .times(1)
.returning(|_| { .returning(|_| {
@@ -91,6 +91,18 @@ impl<'a, 'b> SeasonDetailsHandler<'a, 'b> {
.current_selection() .current_selection()
.id .id
} }
fn extract_series_id_season_number_tuple(&self) -> (i64, i64) {
let series_id = self.app.data.sonarr_data.series.current_selection().id;
let season_number = self
.app
.data
.sonarr_data
.seasons
.current_selection()
.season_number;
(series_id, season_number)
}
} }
impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SeasonDetailsHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SeasonDetailsHandler<'a, 'b> {
@@ -268,8 +280,9 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SeasonDetailsHandler
} }
ActiveSonarrBlock::AutomaticallySearchSeasonPrompt => { ActiveSonarrBlock::AutomaticallySearchSeasonPrompt => {
if self.app.data.sonarr_data.prompt_confirm { if self.app.data.sonarr_data.prompt_confirm {
self.app.data.sonarr_data.prompt_confirm_action = self.app.data.sonarr_data.prompt_confirm_action = Some(
Some(SonarrEvent::TriggerAutomaticSeasonSearch(None)); SonarrEvent::TriggerAutomaticSeasonSearch(self.extract_series_id_season_number_tuple()),
);
} }
self.app.pop_navigation_stack(); self.app.pop_navigation_stack();
@@ -394,8 +407,9 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SeasonDetailsHandler
if key == DEFAULT_KEYBINDINGS.confirm.key => if key == DEFAULT_KEYBINDINGS.confirm.key =>
{ {
self.app.data.sonarr_data.prompt_confirm = true; self.app.data.sonarr_data.prompt_confirm = true;
self.app.data.sonarr_data.prompt_confirm_action = self.app.data.sonarr_data.prompt_confirm_action = Some(
Some(SonarrEvent::TriggerAutomaticSeasonSearch(None)); SonarrEvent::TriggerAutomaticSeasonSearch(self.extract_series_id_season_number_tuple()),
);
self.app.pop_navigation_stack(); self.app.pop_navigation_stack();
} }
@@ -276,7 +276,7 @@ mod tests {
#[rstest] #[rstest]
#[case( #[case(
ActiveSonarrBlock::AutomaticallySearchSeasonPrompt, ActiveSonarrBlock::AutomaticallySearchSeasonPrompt,
SonarrEvent::TriggerAutomaticSeasonSearch(None) SonarrEvent::TriggerAutomaticSeasonSearch((0, 0))
)] )]
#[case( #[case(
ActiveSonarrBlock::DeleteEpisodeFilePrompt, ActiveSonarrBlock::DeleteEpisodeFilePrompt,
@@ -713,7 +713,7 @@ mod tests {
#[rstest] #[rstest]
#[case( #[case(
ActiveSonarrBlock::AutomaticallySearchSeasonPrompt, ActiveSonarrBlock::AutomaticallySearchSeasonPrompt,
SonarrEvent::TriggerAutomaticSeasonSearch(None) SonarrEvent::TriggerAutomaticSeasonSearch((0, 0))
)] )]
#[case( #[case(
ActiveSonarrBlock::DeleteEpisodeFilePrompt, ActiveSonarrBlock::DeleteEpisodeFilePrompt,
@@ -854,6 +854,23 @@ mod tests {
.extract_episode_id(); .extract_episode_id();
} }
#[test]
fn test_extract_series_id_season_number_tuple() {
let mut app = App::default();
app.data.sonarr_data = create_test_sonarr_data();
let (series_id, season_number) = SeasonDetailsHandler::with(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveSonarrBlock::SeasonDetails,
None,
)
.extract_series_id_season_number_tuple();
assert_eq!(series_id, 0);
assert_eq!(season_number, 0);
}
#[test] #[test]
fn test_season_details_handler_is_not_ready_when_loading() { fn test_season_details_handler_is_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::default();
+3 -11
View File
@@ -89,7 +89,7 @@ pub enum SonarrEvent {
ToggleSeasonMonitoring((i64, i64)), ToggleSeasonMonitoring((i64, i64)),
ToggleEpisodeMonitoring(i64), ToggleEpisodeMonitoring(i64),
TriggerAutomaticEpisodeSearch(i64), TriggerAutomaticEpisodeSearch(i64),
TriggerAutomaticSeasonSearch(Option<(i64, i64)>), TriggerAutomaticSeasonSearch((i64, i64)),
TriggerAutomaticSeriesSearch(Option<i64>), TriggerAutomaticSeriesSearch(Option<i64>),
UpdateAllSeries, UpdateAllSeries,
UpdateAndScanSeries(Option<i64>), UpdateAndScanSeries(Option<i64>),
@@ -2200,18 +2200,10 @@ impl<'a, 'b> Network<'a, 'b> {
async fn trigger_automatic_season_search( async fn trigger_automatic_season_search(
&mut self, &mut self,
series_season_id_tuple: Option<(i64, i64)>, series_season_id_tuple: (i64, i64),
) -> Result<Value> { ) -> Result<Value> {
let event = SonarrEvent::TriggerAutomaticSeasonSearch(series_season_id_tuple); let event = SonarrEvent::TriggerAutomaticSeasonSearch(series_season_id_tuple);
let (series_id, season_number) = let (series_id, season_number) = series_season_id_tuple;
if let Some((series_id, season_number)) = series_season_id_tuple {
(Some(series_id), Some(season_number))
} else {
(None, None)
};
let (series_id, _) = self.extract_series_id(series_id).await;
let (season_number, _) = self.extract_season_number(season_number).await?;
info!("Searching indexers for series with ID: {series_id} and season number: {season_number}"); info!("Searching indexers for series with ID: {series_id} and season number: {season_number}");
let body = SonarrCommandBody { let body = SonarrCommandBody {
+3 -105
View File
@@ -194,7 +194,7 @@ mod test {
SonarrEvent::GetQueuedEvents, SonarrEvent::GetQueuedEvents,
SonarrEvent::StartTask(SonarrTaskName::default()), SonarrEvent::StartTask(SonarrTaskName::default()),
SonarrEvent::TriggerAutomaticEpisodeSearch(0), SonarrEvent::TriggerAutomaticEpisodeSearch(0),
SonarrEvent::TriggerAutomaticSeasonSearch(None), SonarrEvent::TriggerAutomaticSeasonSearch((0, 0)),
SonarrEvent::TriggerAutomaticSeriesSearch(None), SonarrEvent::TriggerAutomaticSeriesSearch(None),
SonarrEvent::UpdateAllSeries, SonarrEvent::UpdateAllSeries,
SonarrEvent::UpdateAndScanSeries(None), SonarrEvent::UpdateAndScanSeries(None),
@@ -5167,117 +5167,15 @@ mod test {
})), })),
Some(json!({})), Some(json!({})),
None, None,
SonarrEvent::TriggerAutomaticSeasonSearch(None), SonarrEvent::TriggerAutomaticSeasonSearch((1, 1)),
None, None,
None, None,
) )
.await; .await;
app_arc
.lock()
.await
.data
.sonarr_data
.series
.set_items(vec![series()]);
app_arc
.lock()
.await
.data
.sonarr_data
.seasons
.set_items(vec![season()]);
app_arc.lock().await.data.sonarr_data.season_details_modal =
Some(SeasonDetailsModal::default());
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_sonarr_event(SonarrEvent::TriggerAutomaticSeasonSearch(None)) .handle_sonarr_event(SonarrEvent::TriggerAutomaticSeasonSearch((1, 1)))
.await
.is_ok());
async_server.assert_async().await;
}
#[tokio::test]
async fn test_handle_trigger_automatic_season_search_event_uses_provided_series_id_and_season_number(
) {
let (async_server, app_arc, _server) = mock_servarr_api(
RequestMethod::Post,
Some(json!({
"name": "SeasonSearch",
"seriesId": 2,
"seasonNumber": 2
})),
Some(json!({})),
None,
SonarrEvent::TriggerAutomaticSeasonSearch(None),
None,
None,
)
.await;
app_arc
.lock()
.await
.data
.sonarr_data
.series
.set_items(vec![series()]);
app_arc
.lock()
.await
.data
.sonarr_data
.seasons
.set_items(vec![season()]);
app_arc.lock().await.data.sonarr_data.season_details_modal =
Some(SeasonDetailsModal::default());
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network
.handle_sonarr_event(SonarrEvent::TriggerAutomaticSeasonSearch(Some((2, 2))))
.await
.is_ok());
async_server.assert_async().await;
}
#[tokio::test]
async fn test_handle_trigger_automatic_season_search_event_filtered_series_and_filtered_seasons()
{
let (async_server, app_arc, _server) = mock_servarr_api(
RequestMethod::Post,
Some(json!({
"name": "SeasonSearch",
"seriesId": 1,
"seasonNumber": 1
})),
Some(json!({})),
None,
SonarrEvent::TriggerAutomaticSeasonSearch(None),
None,
None,
)
.await;
let mut filtered_series = StatefulTable::default();
filtered_series.set_items(vec![Series::default()]);
filtered_series.set_filtered_items(vec![Series {
id: 1,
..Series::default()
}]);
app_arc.lock().await.data.sonarr_data.series = filtered_series;
let mut filtered_seasons = StatefulTable::default();
filtered_seasons.set_items(vec![Season::default()]);
filtered_seasons.set_filtered_items(vec![Season {
season_number: 1,
..Season::default()
}]);
app_arc.lock().await.data.sonarr_data.seasons = filtered_seasons;
app_arc.lock().await.data.sonarr_data.season_details_modal =
Some(SeasonDetailsModal::default());
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network
.handle_sonarr_event(SonarrEvent::TriggerAutomaticSeasonSearch(None))
.await .await
.is_ok()); .is_ok());