tmdb_api/movie/
alternative_titles.rs1use std::borrow::Cow;
2
3use crate::client::Executor;
4
5#[derive(Clone, Debug, Default, serde::Serialize)]
6pub struct Params<'a> {
7 #[serde(skip_serializing_if = "Option::is_none")]
9 pub country: Option<Cow<'a, str>>,
10}
11
12impl<'a> Params<'a> {
13 pub fn set_country(&mut self, value: impl Into<Cow<'a, str>>) {
14 self.country = Some(value.into());
15 }
16
17 pub fn with_country(mut self, value: impl Into<Cow<'a, str>>) -> Self {
18 self.set_country(value);
19 self
20 }
21}
22
23#[derive(Clone, Debug, Deserialize, Serialize)]
24pub struct MovieAlternativeTitle {
25 pub iso_3166_1: String,
26 pub title: String,
27 #[serde(
28 deserialize_with = "crate::util::empty_string::deserialize",
29 rename = "type"
30 )]
31 pub kind: Option<String>,
32}
33
34#[derive(Clone, Debug, Deserialize)]
35pub struct Response {
36 pub titles: Vec<MovieAlternativeTitle>,
37}
38
39impl<E: Executor> crate::Client<E> {
40 pub async fn get_movie_alternative_titles(
56 &self,
57 movie_id: u64,
58 params: &Params<'_>,
59 ) -> crate::Result<Response> {
60 let url = format!("/movie/{movie_id}/alternative_titles");
61 self.execute(&url, params).await
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use crate::client::Client;
68 use crate::client::reqwest::Client as ReqwestClient;
69 use mockito::Matcher;
70
71 #[tokio::test]
72 async fn it_works() {
73 let mut server = mockito::Server::new_async().await;
74 let m = server
75 .mock("GET", "/movie/3/alternative_titles")
76 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
77 .with_status(200)
78 .with_header("content-type", "application/json")
79 .with_body(include_str!("../../assets/movie-alternative-titles.json"))
80 .create_async()
81 .await;
82
83 let client = Client::<ReqwestClient>::builder()
84 .with_api_key("secret".into())
85 .with_base_url(server.url())
86 .build()
87 .unwrap();
88 let result = client
89 .get_movie_alternative_titles(3, &Default::default())
90 .await
91 .unwrap();
92 assert!(!result.titles.is_empty());
93
94 m.assert_async().await;
95 }
96
97 #[tokio::test]
98 async fn invalid_api_key() {
99 let mut server = mockito::Server::new_async().await;
100 let m = server
101 .mock("GET", "/movie/1/alternative_titles")
102 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
103 .with_status(401)
104 .with_header("content-type", "application/json")
105 .with_body(include_str!("../../assets/invalid-api-key.json"))
106 .create_async()
107 .await;
108
109 let client = Client::<ReqwestClient>::builder()
110 .with_api_key("secret".into())
111 .with_base_url(server.url())
112 .build()
113 .unwrap();
114 let err = client
115 .get_movie_alternative_titles(1, &Default::default())
116 .await
117 .unwrap_err();
118 let server_err = err.as_server_error().unwrap();
119 assert_eq!(server_err.status_code, 7);
120
121 m.assert_async().await;
122 }
123
124 #[tokio::test]
125 async fn resource_not_found() {
126 let mut server = mockito::Server::new_async().await;
127 let m = server
128 .mock("GET", "/movie/1/alternative_titles")
129 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
130 .with_status(404)
131 .with_header("content-type", "application/json")
132 .with_body(include_str!("../../assets/resource-not-found.json"))
133 .create_async()
134 .await;
135
136 let client = Client::<ReqwestClient>::builder()
137 .with_api_key("secret".into())
138 .with_base_url(server.url())
139 .build()
140 .unwrap();
141 let err = client
142 .get_movie_alternative_titles(1, &Default::default())
143 .await
144 .unwrap_err();
145 let server_err = err.as_server_error().unwrap();
146 assert_eq!(server_err.status_code, 34);
147
148 m.assert_async().await;
149 }
150}
151
152#[cfg(all(test, feature = "integration"))]
153mod integration_tests {
154 use crate::client::Client;
155 use crate::client::reqwest::Client as ReqwestClient;
156
157 #[tokio::test]
158 async fn execute() {
159 let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
160 let client = Client::<ReqwestClient>::new(secret);
161 let result = client
162 .get_movie_alternative_titles(3, &Default::default())
163 .await
164 .unwrap();
165 assert!(!result.titles.is_empty());
166 }
167}