tmdb_api/changes/
list.rs

1use chrono::NaiveDate;
2
3use crate::client::Executor;
4
5const TV_PATH: &str = "/tv/changes";
6const MOVIE_PATH: &str = "/movie/changes";
7const PERSON_PATH: &str = "/person/changes";
8
9#[derive(Clone, Debug, Default, Serialize)]
10pub struct Params {
11    /// Filter the results with a start date.
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub start_date: Option<NaiveDate>,
14    /// Filter the results with an end date.
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub end_date: Option<NaiveDate>,
17    /// Which page to query.
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub page: Option<u32>,
20}
21
22impl Params {
23    pub fn set_start_date(&mut self, value: NaiveDate) {
24        self.start_date = Some(value);
25    }
26
27    pub fn with_start_date(mut self, value: NaiveDate) -> Self {
28        self.set_start_date(value);
29        self
30    }
31
32    pub fn set_end_date(&mut self, value: NaiveDate) {
33        self.end_date = Some(value);
34    }
35
36    pub fn with_end_date(mut self, value: NaiveDate) -> Self {
37        self.set_end_date(value);
38        self
39    }
40
41    pub fn set_page(&mut self, value: u32) {
42        self.page = Some(value);
43    }
44
45    pub fn with_page(mut self, value: u32) -> Self {
46        self.set_page(value);
47        self
48    }
49}
50
51impl<E: Executor> crate::Client<E> {
52    /// Get a list of all of the movie ids that have been changed in the past 24
53    /// hours.
54    ///
55    /// ```rust
56    /// use tmdb_api::Client;
57    /// use tmdb_api::client::reqwest::Client as ReqwestClient;
58    ///
59    /// #[tokio::main]
60    /// async fn main() {
61    ///     let client = Client::<ReqwestClient>::new("this-is-my-secret-token".into());
62    ///     match client.list_movie_changes(&Default::default()).await {
63    ///         Ok(res) => println!("found: {:#?}", res),
64    ///         Err(err) => eprintln!("error: {:?}", err),
65    ///     };
66    /// }
67    /// ```
68    pub async fn list_movie_changes(
69        &self,
70        params: &Params,
71    ) -> crate::Result<crate::common::PaginatedResult<super::Change>> {
72        self.execute(MOVIE_PATH, params).await
73    }
74
75    /// Get a list of all of the person ids that have been changed in the past
76    /// 24 hours.
77    ///
78    /// ```rust
79    /// use tmdb_api::Client;
80    /// use tmdb_api::client::reqwest::Client as ReqwestClient;
81    ///
82    /// #[tokio::main]
83    /// async fn main() {
84    ///     let client = Client::<ReqwestClient>::new("this-is-my-secret-token".into());
85    ///     match client.list_person_changes(&Default::default()).await {
86    ///         Ok(res) => println!("found: {:#?}", res),
87    ///         Err(err) => eprintln!("error: {:?}", err),
88    ///     };
89    /// }
90    /// ```
91    pub async fn list_person_changes(
92        &self,
93        params: &Params,
94    ) -> crate::Result<crate::common::PaginatedResult<super::Change>> {
95        self.execute(PERSON_PATH, params).await
96    }
97
98    /// Get a list of all of the tvshow ids that have been changed in the past
99    /// 24 hours.
100    ///
101    /// ```rust
102    /// use tmdb_api::Client;
103    /// use tmdb_api::client::reqwest::Client as ReqwestClient;
104    ///
105    /// #[tokio::main]
106    /// async fn main() {
107    ///     let client = Client::<ReqwestClient>::new("this-is-my-secret-token".into());
108    ///     match client.list_tvshow_changes(&Default::default()).await {
109    ///         Ok(res) => println!("found: {:#?}", res),
110    ///         Err(err) => eprintln!("error: {:?}", err),
111    ///     };
112    /// }
113    /// ```
114    pub async fn list_tvshow_changes(
115        &self,
116        params: &Params,
117    ) -> crate::Result<crate::common::PaginatedResult<super::Change>> {
118        self.execute(TV_PATH, params).await
119    }
120}
121
122#[cfg(test)]
123mod tests {
124    use chrono::NaiveDate;
125    use mockito::Matcher;
126
127    use crate::changes::list::Params;
128    use crate::client::Client;
129    use crate::client::reqwest::Client as ReqwestClient;
130
131    #[tokio::test]
132    async fn tv_works() {
133        let mut server = mockito::Server::new_async().await;
134        let m = server
135            .mock("GET", super::TV_PATH)
136            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
137            .with_status(200)
138            .with_header("content-type", "application/json")
139            .with_body(include_str!("../../assets/tv-all-changes.json"))
140            .create_async()
141            .await;
142
143        let client = Client::<ReqwestClient>::builder()
144            .with_api_key("secret".into())
145            .with_base_url(server.url())
146            .build()
147            .unwrap();
148        let result = client
149            .list_tvshow_changes(&Default::default())
150            .await
151            .unwrap();
152        assert_eq!(result.page, 1);
153
154        m.assert_async().await;
155    }
156
157    #[tokio::test]
158    async fn tv_works_with_args() {
159        let mut server = mockito::Server::new_async().await;
160        let m = server
161            .mock("GET", super::TV_PATH)
162            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
163            .match_query(Matcher::AllOf(vec![
164                Matcher::UrlEncoded("api_key".into(), "secret".into()),
165                Matcher::UrlEncoded("start_date".into(), "2015-03-14".into()),
166                Matcher::UrlEncoded("end_date".into(), "2019-03-14".into()),
167                Matcher::UrlEncoded("page".into(), "2".into()),
168            ]))
169            .with_status(200)
170            .with_header("content-type", "application/json")
171            .with_body(include_str!("../../assets/tv-all-changes.json"))
172            .create_async()
173            .await;
174
175        let client = Client::<ReqwestClient>::builder()
176            .with_api_key("secret".into())
177            .with_base_url(server.url())
178            .build()
179            .unwrap();
180        let result = client
181            .list_tvshow_changes(
182                &Params::default()
183                    .with_start_date(NaiveDate::from_ymd_opt(2015, 3, 14).unwrap())
184                    .with_end_date(NaiveDate::from_ymd_opt(2019, 3, 14).unwrap())
185                    .with_page(2),
186            )
187            .await
188            .unwrap();
189        assert_eq!(result.page, 1);
190        m.assert_async().await;
191    }
192
193    #[tokio::test]
194    async fn movie_works() {
195        let mut server = mockito::Server::new_async().await;
196        let m = server
197            .mock("GET", super::MOVIE_PATH)
198            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
199            .with_status(200)
200            .with_header("content-type", "application/json")
201            .with_body(include_str!("../../assets/movie-all-changes.json"))
202            .create_async()
203            .await;
204
205        let client = Client::<ReqwestClient>::builder()
206            .with_api_key("secret".into())
207            .with_base_url(server.url())
208            .build()
209            .unwrap();
210        let result = client
211            .list_movie_changes(&Default::default())
212            .await
213            .unwrap();
214        assert_eq!(result.page, 1);
215
216        m.assert_async().await;
217    }
218
219    #[tokio::test]
220    async fn person_works() {
221        let mut server = mockito::Server::new_async().await;
222        let m = server
223            .mock("GET", super::PERSON_PATH)
224            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
225            .with_status(200)
226            .with_header("content-type", "application/json")
227            .with_body(include_str!("../../assets/movie-all-changes.json"))
228            .create_async()
229            .await;
230
231        let client = Client::<ReqwestClient>::builder()
232            .with_api_key("secret".into())
233            .with_base_url(server.url())
234            .build()
235            .unwrap();
236        let result = client
237            .list_person_changes(&Default::default())
238            .await
239            .unwrap();
240        assert_eq!(result.page, 1);
241
242        m.assert_async().await;
243    }
244
245    #[tokio::test]
246    async fn invalid_api_key() {
247        let mut server = mockito::Server::new_async().await;
248        let m = server
249            .mock("GET", super::TV_PATH)
250            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
251            .with_status(401)
252            .with_header("content-type", "application/json")
253            .with_body(include_str!("../../assets/invalid-api-key.json"))
254            .create_async()
255            .await;
256
257        let client = Client::<ReqwestClient>::builder()
258            .with_api_key("secret".into())
259            .with_base_url(server.url())
260            .build()
261            .unwrap();
262        let err = client
263            .list_tvshow_changes(&Default::default())
264            .await
265            .unwrap_err();
266        let server_err = err.as_server_error().unwrap();
267        assert_eq!(server_err.status_code, 7);
268
269        m.assert_async().await;
270    }
271
272    #[tokio::test]
273    async fn resource_not_found() {
274        let mut server = mockito::Server::new_async().await;
275        let m = server
276            .mock("GET", super::TV_PATH)
277            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
278            .with_status(404)
279            .with_header("content-type", "application/json")
280            .with_body(include_str!("../../assets/resource-not-found.json"))
281            .create_async()
282            .await;
283
284        let client = Client::<ReqwestClient>::builder()
285            .with_api_key("secret".into())
286            .with_base_url(server.url())
287            .build()
288            .unwrap();
289        let err = client
290            .list_tvshow_changes(&Default::default())
291            .await
292            .unwrap_err();
293        let server_err = err.as_server_error().unwrap();
294        assert_eq!(server_err.status_code, 34);
295
296        m.assert_async().await;
297    }
298}
299
300#[cfg(all(test, feature = "integration"))]
301mod integration_tests {
302    use crate::client::Client;
303    use crate::client::reqwest::Client as ReqwestClient;
304
305    #[tokio::test]
306    async fn execute_tv() {
307        let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
308        let client = Client::<ReqwestClient>::new(secret);
309
310        let result = client
311            .list_tvshow_changes(&Default::default())
312            .await
313            .unwrap();
314        assert_eq!(result.page, 1);
315    }
316
317    #[tokio::test]
318    async fn execute_movie() {
319        let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
320        let client = Client::<ReqwestClient>::new(secret);
321
322        let result = client
323            .list_movie_changes(&Default::default())
324            .await
325            .unwrap();
326        assert_eq!(result.page, 1);
327    }
328
329    #[tokio::test]
330    async fn execute_person() {
331        let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
332        let client = Client::<ReqwestClient>::new(secret);
333
334        let result = client
335            .list_person_changes(&Default::default())
336            .await
337            .unwrap();
338        assert_eq!(result.page, 1);
339    }
340}