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 mockito::Matcher;
68
69 use crate::client::Client;
70 use crate::client::reqwest::Client as ReqwestClient;
71
72 #[tokio::test]
73 async fn it_works() {
74 let mut server = mockito::Server::new_async().await;
75 let m = server
76 .mock("GET", "/movie/3/alternative_titles")
77 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
78 .with_status(200)
79 .with_header("content-type", "application/json")
80 .with_body(include_str!("../../assets/movie-alternative-titles.json"))
81 .create_async()
82 .await;
83
84 let client = Client::<ReqwestClient>::builder()
85 .with_api_key("secret".into())
86 .with_base_url(server.url())
87 .build()
88 .unwrap();
89 let result = client
90 .get_movie_alternative_titles(3, &Default::default())
91 .await
92 .unwrap();
93 assert!(!result.titles.is_empty());
94
95 m.assert_async().await;
96 }
97
98 #[tokio::test]
99 async fn invalid_api_key() {
100 let mut server = mockito::Server::new_async().await;
101 let m = server
102 .mock("GET", "/movie/1/alternative_titles")
103 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
104 .with_status(401)
105 .with_header("content-type", "application/json")
106 .with_body(include_str!("../../assets/invalid-api-key.json"))
107 .create_async()
108 .await;
109
110 let client = Client::<ReqwestClient>::builder()
111 .with_api_key("secret".into())
112 .with_base_url(server.url())
113 .build()
114 .unwrap();
115 let err = client
116 .get_movie_alternative_titles(1, &Default::default())
117 .await
118 .unwrap_err();
119 let server_err = err.as_server_error().unwrap();
120 assert_eq!(server_err.status_code, 7);
121
122 m.assert_async().await;
123 }
124
125 #[tokio::test]
126 async fn resource_not_found() {
127 let mut server = mockito::Server::new_async().await;
128 let m = server
129 .mock("GET", "/movie/1/alternative_titles")
130 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
131 .with_status(404)
132 .with_header("content-type", "application/json")
133 .with_body(include_str!("../../assets/resource-not-found.json"))
134 .create_async()
135 .await;
136
137 let client = Client::<ReqwestClient>::builder()
138 .with_api_key("secret".into())
139 .with_base_url(server.url())
140 .build()
141 .unwrap();
142 let err = client
143 .get_movie_alternative_titles(1, &Default::default())
144 .await
145 .unwrap_err();
146 let server_err = err.as_server_error().unwrap();
147 assert_eq!(server_err.status_code, 34);
148
149 m.assert_async().await;
150 }
151}
152
153#[cfg(all(test, feature = "integration"))]
154mod integration_tests {
155 use crate::client::Client;
156 use crate::client::reqwest::Client as ReqwestClient;
157
158 #[tokio::test]
159 async fn execute() {
160 let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
161 let client = Client::<ReqwestClient>::new(secret);
162 let result = client
163 .get_movie_alternative_titles(3, &Default::default())
164 .await
165 .unwrap();
166 assert!(!result.titles.is_empty());
167 }
168}