From d358c5884433a8732034c180fb920771d4f27cf1 Mon Sep 17 00:00:00 2001 From: Miguel Palhas Date: Tue, 25 Aug 2026 08:28:56 +0100 Subject: [PATCH] test(arr): a forced candidate writes no sidecar Ranking already rejects one (#185); this holds the loop to it at the end of the pipeline, where the row would appear. --- crates/arr-daemon/src/subtitles.rs | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/crates/arr-daemon/src/subtitles.rs b/crates/arr-daemon/src/subtitles.rs index 630e0f6..ac46b6e 100644 --- a/crates/arr-daemon/src/subtitles.rs +++ b/crates/arr-daemon/src/subtitles.rs @@ -1494,6 +1494,45 @@ mod tests { .contains("no text source to translate from")); } + /// ยง15 gives a language exactly one sidecar and forced gets no segment + /// of its own, so nothing in the loop may ever write one. Ranking already + /// rejects a forced candidate (#185); this holds it to that at the end of + /// the pipeline, where the row would actually appear (#222). + #[tokio::test] + async fn a_forced_candidate_never_becomes_a_sidecar() { + let fixture = Fixture::new(&no_tracks()).await; + fixture.configure(r#"["pt-PT"]"#, Some("openai")).await; + let forced = Candidate { + forced: true, + hash_match: true, + download_count: Some(1_000_000), + ..candidate("opensubtitles", "forced", Language::PortuguesePortugal) + }; + let action = action( + vec![Arc::new(StubProvider::new("opensubtitles", vec![forced]))], + vec![Arc::new(StubBackend)], + ); + + action.run(&fixture.database).await.unwrap(); + + assert!( + fixture.files().await.is_empty(), + "a forced candidate is not a subtitle arr has" + ); + assert!( + !fixture + .directory + .path() + .join("Movie (2024) - [1080p].pt-PT.srt") + .exists(), + "and nothing was written for it" + ); + // The best candidate on offer being unusable is the same position as + // no candidate at all: nothing to fetch and nothing to translate from. + let attempt = fixture.attempt("pt-PT").await.unwrap(); + assert_eq!(attempt.state, SubtitleState::Unavailable); + } + #[tokio::test] async fn the_ranked_winner_is_fetched_synced_and_recorded() { let fixture = Fixture::new(&no_tracks()).await;