tmdb_api/tvshow/season/
details.rs

1use std::borrow::Cow;
2
3/// Command to get the details of a tvshow season
4///
5/// ```rust
6/// use tmdb_api::prelude::Command;
7/// use tmdb_api::client::Client;
8/// use tmdb_api::client::reqwest::ReqwestExecutor;
9/// use tmdb_api::tvshow::season::details::TVShowSeasonDetails;
10///
11/// #[tokio::main]
12/// async fn main() {
13///     let client = Client::<ReqwestExecutor>::new("this-is-my-secret-token".into());
14///     let cmd = TVShowSeasonDetails::new(1, 1);
15///     let result = cmd.execute(&client).await;
16///     match result {
17///         Ok(res) => println!("found: {:#?}", res),
18///         Err(err) => eprintln!("error: {:?}", err),
19///     };
20/// }
21/// ```
22#[derive(Clone, Debug, Default)]
23pub struct TVShowSeasonDetails {
24    /// ID of the TV Show
25    pub tv_id: u64,
26    /// Number of the season
27    pub season_number: u64,
28    /// ISO 639-1 value to display translated data for the fields that support it.
29    pub language: Option<String>,
30}
31
32impl TVShowSeasonDetails {
33    pub fn new(tv_id: u64, season_number: u64) -> Self {
34        Self {
35            tv_id,
36            season_number,
37            language: None,
38        }
39    }
40
41    pub fn with_language(mut self, value: Option<String>) -> Self {
42        self.language = value;
43        self
44    }
45}
46
47impl crate::prelude::Command for TVShowSeasonDetails {
48    type Output = crate::tvshow::Season;
49
50    fn path(&self) -> Cow<'static, str> {
51        Cow::Owned(format!("/tv/{}/season/{}", self.tv_id, self.season_number))
52    }
53
54    fn params(&self) -> Vec<(&'static str, Cow<'_, str>)> {
55        if let Some(language) = self.language.as_ref() {
56            vec![("language", Cow::Borrowed(language.as_str()))]
57        } else {
58            Vec::new()
59        }
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use mockito::Matcher;
66
67    use crate::client::Client;
68    use crate::client::reqwest::ReqwestExecutor;
69    use crate::prelude::Command;
70
71    use super::TVShowSeasonDetails;
72
73    #[tokio::test]
74    async fn it_works() {
75        let mut server = mockito::Server::new_async().await;
76        let client = Client::<ReqwestExecutor>::builder()
77            .with_api_key("secret".into())
78            .with_base_url(server.url())
79            .build()
80            .unwrap();
81
82        let _m = server
83            .mock("GET", "/tv/1399/season/1")
84            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
85            .with_status(200)
86            .with_header("content-type", "application/json")
87            .with_body(include_str!("../../../assets/tv-season-details.json"))
88            .create_async()
89            .await;
90
91        let result = TVShowSeasonDetails::new(1399, 1)
92            .execute(&client)
93            .await
94            .unwrap();
95        assert_eq!(result.inner.id, 3624);
96    }
97
98    #[tokio::test]
99    async fn invalid_api_key() {
100        let mut server = mockito::Server::new_async().await;
101        let client = Client::<ReqwestExecutor>::builder()
102            .with_api_key("secret".into())
103            .with_base_url(server.url())
104            .build()
105            .unwrap();
106
107        let _m = server
108            .mock("GET", "/tv/1399/season/1")
109            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
110            .with_status(401)
111            .with_header("content-type", "application/json")
112            .with_body(include_str!("../../../assets/invalid-api-key.json"))
113            .create_async()
114            .await;
115
116        let err = TVShowSeasonDetails::new(1399, 1)
117            .execute(&client)
118            .await
119            .unwrap_err();
120        let server_err = err.as_server_error().unwrap();
121        assert_eq!(server_err.status_code, 7);
122    }
123
124    #[tokio::test]
125    async fn resource_not_found() {
126        let mut server = mockito::Server::new_async().await;
127        let client = Client::<ReqwestExecutor>::builder()
128            .with_api_key("secret".into())
129            .with_base_url(server.url())
130            .build()
131            .unwrap();
132
133        let _m = server
134            .mock("GET", "/tv/1399/season/1")
135            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
136            .with_status(404)
137            .with_header("content-type", "application/json")
138            .with_body(include_str!("../../../assets/resource-not-found.json"))
139            .create_async()
140            .await;
141
142        let err = TVShowSeasonDetails::new(1399, 1)
143            .execute(&client)
144            .await
145            .unwrap_err();
146        let server_err = err.as_server_error().unwrap();
147        assert_eq!(server_err.status_code, 34);
148    }
149}
150
151#[cfg(all(test, feature = "integration"))]
152mod integration_tests {
153    use crate::client::Client;
154    use crate::client::reqwest::ReqwestExecutor;
155    use crate::prelude::Command;
156
157    use super::TVShowSeasonDetails;
158
159    #[tokio::test]
160    async fn execute() {
161        let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
162        let client = Client::<ReqwestExecutor>::new(secret);
163
164        for (tv_id, season_id) in [(1, 2328126u64)] {
165            let result = TVShowSeasonDetails::new(tv_id, 1)
166                .execute(&client)
167                .await
168                .unwrap();
169            assert_eq!(result.inner.id, season_id);
170        }
171    }
172}