tmdb_api/tvshow/
aggregate_credits.rs

1//! https://developer.themoviedb.org/reference/tv-series-aggregate-credits
2
3#[derive(Debug, Deserialize)]
4pub struct TVShowAggregateCredits {
5    pub id: u64,
6    pub cast: Vec<CastPerson>,
7    pub crew: Vec<CrewPerson>,
8}
9
10#[derive(Debug, Deserialize)]
11pub struct CastPerson {
12    #[serde(flatten)]
13    pub inner: Person,
14    pub roles: Vec<Role>,
15    pub order: u64,
16}
17
18#[derive(Debug, Deserialize)]
19pub struct CrewPerson {
20    #[serde(flatten)]
21    pub inner: Person,
22    pub jobs: Vec<Job>,
23    pub department: String,
24}
25
26#[derive(Debug, Deserialize)]
27pub struct Person {
28    pub id: u64,
29    pub adult: bool,
30    pub gender: u64,
31    pub known_for_department: String,
32    pub name: String,
33    pub original_name: String,
34    pub popularity: f64,
35    pub profile_path: Option<String>,
36    pub total_episode_count: u64,
37}
38
39#[derive(Debug, Deserialize)]
40pub struct Role {
41    pub credit_id: String,
42    pub character: String,
43    pub episode_count: u64,
44}
45
46#[derive(Debug, Deserialize)]
47pub struct Job {
48    pub credit_id: String,
49    pub job: String,
50    pub episode_count: u64,
51}
52
53pub type Params<'a> = crate::common::LanguageParams<'a>;
54
55impl<E: crate::client::Executor> crate::Client<E> {
56    /// Get tvshow aggregate credits
57    ///
58    /// ```rust
59    /// use tmdb_api::client::Client;
60    /// use tmdb_api::client::reqwest::ReqwestExecutor;
61    ///
62    /// #[tokio::main]
63    /// async fn main() {
64    ///     let client = Client::<ReqwestExecutor>::new("this-is-my-secret-token".into());
65    ///     match client.get_tvshow_aggregate_credits(42, &Default::default()).await {
66    ///         Ok(res) => println!("found: {:#?}", res),
67    ///         Err(err) => eprintln!("error: {:?}", err),
68    ///     };
69    /// }
70    /// ```
71    pub async fn get_tvshow_aggregate_credits(
72        &self,
73        tvshow_id: u64,
74        params: &Params<'_>,
75    ) -> crate::Result<TVShowAggregateCredits> {
76        let url = format!("/tv/{tvshow_id}/aggregate_credits");
77        self.execute(&url, params).await
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use mockito::Matcher;
84
85    use crate::Client;
86    use crate::client::reqwest::ReqwestExecutor;
87
88    #[tokio::test]
89    async fn it_works() {
90        let mut server = mockito::Server::new_async().await;
91        let client = Client::<ReqwestExecutor>::builder()
92            .with_api_key("secret".into())
93            .with_base_url(server.url())
94            .build()
95            .unwrap();
96
97        let _m = server
98            .mock("GET", "/tv/1399/aggregate_credits")
99            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
100            .with_status(200)
101            .with_header("content-type", "application/json")
102            .with_body(include_str!("../../assets/tv-aggregate-credits.json"))
103            .create_async()
104            .await;
105
106        let result = client
107            .get_tvshow_aggregate_credits(1399, &Default::default())
108            .await
109            .unwrap();
110        assert_eq!(result.id, 1399);
111        assert!(!result.cast.is_empty());
112        assert!(!result.crew.is_empty());
113    }
114
115    #[tokio::test]
116    async fn invalid_api_key() {
117        let mut server = mockito::Server::new_async().await;
118        let client = Client::<ReqwestExecutor>::builder()
119            .with_api_key("secret".into())
120            .with_base_url(server.url())
121            .build()
122            .unwrap();
123
124        let _m = server
125            .mock("GET", "/tv/1399/aggregate_credits")
126            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
127            .with_status(401)
128            .with_header("content-type", "application/json")
129            .with_body(include_str!("../../assets/invalid-api-key.json"))
130            .create_async()
131            .await;
132
133        let err = client
134            .get_tvshow_aggregate_credits(1399, &Default::default())
135            .await
136            .unwrap_err();
137        let server_err = err.as_server_error().unwrap();
138        assert_eq!(server_err.status_code, 7);
139    }
140
141    #[tokio::test]
142    async fn resource_not_found() {
143        let mut server = mockito::Server::new_async().await;
144        let client = Client::<ReqwestExecutor>::builder()
145            .with_api_key("secret".into())
146            .with_base_url(server.url())
147            .build()
148            .unwrap();
149
150        let _m = server
151            .mock("GET", "/tv/1399/aggregate_credits")
152            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
153            .with_status(404)
154            .with_header("content-type", "application/json")
155            .with_body(include_str!("../../assets/resource-not-found.json"))
156            .create_async()
157            .await;
158
159        let err = client
160            .get_tvshow_aggregate_credits(1399, &Default::default())
161            .await
162            .unwrap_err();
163        let server_err = err.as_server_error().unwrap();
164        assert_eq!(server_err.status_code, 34);
165    }
166}
167
168#[cfg(all(test, feature = "integration"))]
169mod integration_tests {
170    use crate::Client;
171    use crate::client::reqwest::ReqwestExecutor;
172
173    #[tokio::test]
174    async fn execute() {
175        let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
176        let client = Client::<ReqwestExecutor>::new(secret);
177
178        let result = client
179            .get_tvshow_aggregate_credits(1399, &Default::default())
180            .await
181            .unwrap();
182        assert_eq!(result.id, 1399);
183        assert!(!result.cast.is_empty());
184        assert!(!result.crew.is_empty());
185    }
186}