tmdb_api/genre/
list.rs

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