1use 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 pub async fn list_movie_genres(&self, params: &Params<'_>) -> crate::Result<Response> {
35 self.execute(MOVIE_PATH, params).await
36 }
37
38 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}