tmdb_api/movie/
popular.rs

1use std::borrow::Cow;
2
3use crate::common::PaginatedResult;
4
5#[derive(Clone, Debug, Default, serde::Serialize)]
6pub struct Params<'a> {
7    /// ISO 639-1 value to display translated data for the fields that support
8    /// it.
9    #[serde(skip_serializing_if = "Option::is_none")]
10    pub language: Option<Cow<'a, str>>,
11    /// Specify which page to query.
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub page: Option<u32>,
14    /// Specify a ISO 3166-1 code to filter release dates. Must be uppercase.
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub region: Option<Cow<'a, str>>,
17}
18
19impl<'a> Params<'a> {
20    pub fn set_page(&mut self, value: u32) {
21        self.page = Some(value);
22    }
23
24    pub fn with_page(mut self, value: u32) -> Self {
25        self.set_page(value);
26        self
27    }
28
29    pub fn set_language(&mut self, value: impl Into<Cow<'a, str>>) {
30        self.language = Some(value.into());
31    }
32
33    pub fn with_language(mut self, value: impl Into<Cow<'a, str>>) -> Self {
34        self.set_language(value);
35        self
36    }
37
38    pub fn set_region(&mut self, value: impl Into<Cow<'a, str>>) {
39        self.region = Some(value.into());
40    }
41
42    pub fn with_region(mut self, value: impl Into<Cow<'a, str>>) -> Self {
43        self.set_region(value);
44        self
45    }
46}
47
48impl<E: crate::client::Executor> crate::Client<E> {
49    /// Get a list of the current popular movies on TMDB. This list updates
50    /// daily.
51    ///
52    /// ```rust
53    /// use tmdb_api::client::Client;
54    /// use tmdb_api::client::reqwest::Client as ReqwestClient;
55    ///
56    /// #[tokio::main]
57    /// async fn main() {
58    ///     let client = Client::<ReqwestClient>::new("this-is-my-secret-token".into());
59    ///     match client.list_popular_movies(&Default::default()).await {
60    ///         Ok(res) => println!("found: {:#?}", res),
61    ///         Err(err) => eprintln!("error: {:?}", err),
62    ///     };
63    /// }
64    /// ```
65    pub async fn list_popular_movies(
66        &self,
67        params: &Params<'_>,
68    ) -> crate::Result<PaginatedResult<super::MovieShort>> {
69        self.execute("/movie/popular", params).await
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use mockito::Matcher;
76
77    use crate::client::Client;
78    use crate::client::reqwest::Client as ReqwestClient;
79
80    #[tokio::test]
81    async fn it_works() {
82        let mut server = mockito::Server::new_async().await;
83        let _m = server
84            .mock("GET", "/movie/popular")
85            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
86            .with_status(200)
87            .with_header("content-type", "application/json")
88            .with_body(include_str!("../../assets/movie-popular.json"))
89            .create_async()
90            .await;
91
92        let client = Client::<ReqwestClient>::builder()
93            .with_api_key("secret".into())
94            .with_base_url(server.url())
95            .build()
96            .unwrap();
97        let result = client
98            .list_popular_movies(&Default::default())
99            .await
100            .unwrap();
101        assert_eq!(result.page, 1);
102    }
103
104    #[tokio::test]
105    async fn invalid_api_key() {
106        let mut server = mockito::Server::new_async().await;
107        let client = Client::<ReqwestClient>::builder()
108            .with_api_key("secret".into())
109            .with_base_url(server.url())
110            .build()
111            .unwrap();
112
113        let _m = server
114            .mock("GET", "/movie/popular")
115            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
116            .with_status(401)
117            .with_header("content-type", "application/json")
118            .with_body(include_str!("../../assets/invalid-api-key.json"))
119            .create_async()
120            .await;
121
122        let err = client
123            .list_popular_movies(&Default::default())
124            .await
125            .unwrap_err();
126        let server_err = err.as_server_error().unwrap();
127        assert_eq!(server_err.status_code, 7);
128    }
129
130    #[tokio::test]
131    async fn resource_not_found() {
132        let mut server = mockito::Server::new_async().await;
133        let client = Client::<ReqwestClient>::builder()
134            .with_api_key("secret".into())
135            .with_base_url(server.url())
136            .build()
137            .unwrap();
138
139        let _m = server
140            .mock("GET", "/movie/popular")
141            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
142            .with_status(404)
143            .with_header("content-type", "application/json")
144            .with_body(include_str!("../../assets/resource-not-found.json"))
145            .create_async()
146            .await;
147
148        let err = client
149            .list_popular_movies(&Default::default())
150            .await
151            .unwrap_err();
152        let server_err = err.as_server_error().unwrap();
153        assert_eq!(server_err.status_code, 34);
154    }
155}
156
157#[cfg(all(test, feature = "integration"))]
158mod integration_tests {
159    use crate::client::Client;
160    use crate::client::reqwest::Client as ReqwestClient;
161
162    #[tokio::test]
163    async fn execute() {
164        let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
165        let client = Client::<ReqwestClient>::new(secret);
166        let _result = client
167            .list_popular_movies(&Default::default())
168            .await
169            .unwrap();
170    }
171}