feat(api): reject empty episode titles
This commit is contained in:
@@ -721,6 +721,15 @@ pub async fn create_season(
|
|||||||
"episode number cannot be negative".into(),
|
"episode number cannot be negative".into(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
// The column rejects the empty string (#153); say so before the database
|
||||||
|
// has to.
|
||||||
|
if input
|
||||||
|
.episodes
|
||||||
|
.iter()
|
||||||
|
.any(|episode| episode.title.trim().is_empty())
|
||||||
|
{
|
||||||
|
return Err(ApiError::Invalid("episode title cannot be empty".into()));
|
||||||
|
}
|
||||||
let mut numbers: Vec<i64> = input
|
let mut numbers: Vec<i64> = input
|
||||||
.episodes
|
.episodes
|
||||||
.iter()
|
.iter()
|
||||||
@@ -1394,6 +1403,28 @@ mod tests {
|
|||||||
assert_eq!(season["episodes"][0]["wanted"], false);
|
assert_eq!(season["episodes"][0]["wanted"], false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// #153. An empty episode title is rejected up front — the column and the
|
||||||
|
/// TMDB boundary both refuse it, so the API must too.
|
||||||
|
#[tokio::test]
|
||||||
|
async fn an_empty_episode_title_is_rejected() {
|
||||||
|
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");
|
||||||
|
|
||||||
|
for title in ["", " "] {
|
||||||
|
let response = reqwest::Client::new()
|
||||||
|
.post(format!("{base}/api/series/{series_id}/seasons"))
|
||||||
|
.json(&serde_json::json!({"number": 1, "episodes": [
|
||||||
|
{"number": 1, "title": title}
|
||||||
|
]}))
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.expect("create season");
|
||||||
|
assert_eq!(response.status(), StatusCode::UNPROCESSABLE_ENTITY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn a_rejected_season_leaves_nothing_behind_to_retry_over() {
|
async fn a_rejected_season_leaves_nothing_behind_to_retry_over() {
|
||||||
let (_dir, state, base) = application().await;
|
let (_dir, state, base) = application().await;
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ mod model;
|
|||||||
pub use client::{TmdbClient, TmdbClientBuilder, DEFAULT_BASE_URL, DEFAULT_CACHE_TTL};
|
pub use client::{TmdbClient, TmdbClientBuilder, DEFAULT_BASE_URL, DEFAULT_CACHE_TTL};
|
||||||
pub use error::{Error, Result};
|
pub use error::{Error, Result};
|
||||||
pub use model::{
|
pub use model::{
|
||||||
Episode, ExternalIds, FindResults, Movie, MovieSearchResult, Season, Series, SeriesSearchResult,
|
Episode, ExternalIds, FindResults, Movie, MovieSearchResult, Season, Series,
|
||||||
UNTITLED_EPISODE,
|
SeriesSearchResult, UNTITLED_EPISODE,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user