feat(api): expose seasons.vanished (#141)

Season objects from the series endpoints now carry the conflict flag
#137 writes, the way episodes already do.
This commit is contained in:
Miguel Palhas
2026-08-23 20:27:34 +01:00
parent 4efc7b1833
commit 571ec42e92
2 changed files with 58 additions and 3 deletions
+50 -1
View File
@@ -97,6 +97,10 @@ pub struct Season {
pub number: i64,
/// §4.1. Whether new episodes of this season arrive wanted.
pub tracked: bool,
/// #141. The season vanished upstream while files remained under it,
/// which is why the row still exists. A conflict for the operator to
/// resolve; nothing was deleted from disk.
pub vanished: bool,
pub episodes: Vec<Episode>,
}
@@ -629,7 +633,7 @@ async fn remove_library_files(state: &AppState, id: i64) -> Result<(), ApiError>
async fn load_seasons(state: &AppState, series_id: i64) -> Result<Vec<Season>, ApiError> {
let seasons = sqlx::query!(
r#"SELECT id AS "id!: i64", series_id AS "series_id!: i64", number AS "number!: i64", tracked AS "tracked!: bool" FROM seasons WHERE series_id = ? ORDER BY number"#,
r#"SELECT id AS "id!: i64", series_id AS "series_id!: i64", number AS "number!: i64", tracked AS "tracked!: bool", vanished AS "vanished!: bool" FROM seasons WHERE series_id = ? ORDER BY number"#,
series_id
)
.fetch_all(pool(state)?)
@@ -650,6 +654,7 @@ async fn load_seasons(state: &AppState, series_id: i64) -> Result<Vec<Season>, A
series_id: season.series_id,
number: season.number,
tracked: season.tracked,
vanished: season.vanished,
episodes: episodes
.iter()
.filter(|episode| episode.season_id == season.id)
@@ -1390,6 +1395,50 @@ mod tests {
assert_eq!(season["number"], 1);
}
#[tokio::test]
async fn a_vanished_season_reaches_the_seasons_endpoint() {
let (_dir, state, base) = application().await;
let root_id = tv_root(&state, "main").await;
let series = add_series(&base, root_id, false).await;
let series_id = series["id"].as_i64().expect("id");
let clean = add_season(
&base,
series_id,
1,
serde_json::json!([{"number": 1, "title": "One"}]),
)
.await;
assert_eq!(clean["vanished"], false);
add_season(
&base,
series_id,
2,
serde_json::json!([{"number": 1, "title": "One"}]),
)
.await;
sqlx::query("UPDATE seasons SET vanished = 1 WHERE series_id = ? AND number = 2")
.bind(series_id)
.execute(state.database().expect("database").pool())
.await
.expect("flag season vanished");
let seasons: serde_json::Value = reqwest::Client::new()
.get(format!("{base}/api/series/{series_id}/seasons"))
.send()
.await
.expect("list seasons")
.json()
.await
.expect("seasons json");
let seasons = seasons.as_array().expect("seasons array");
assert_eq!(seasons[0]["vanished"], false);
assert_eq!(
seasons[1]["vanished"], true,
"#141: the conflict flag is not stopped at the database"
);
}
#[tokio::test]
async fn intent_is_set_on_seasons_and_on_single_episodes() {
let (_dir, state, base) = application().await;