tmdb_api/movie/
upcoming.rs1use std::borrow::Cow;
2
3use crate::common::PaginatedResult;
4
5#[derive(Clone, Debug, Default, serde::Serialize)]
6pub struct Params<'a> {
7 #[serde(skip_serializing_if = "Option::is_none")]
10 pub language: Option<Cow<'a, str>>,
11 #[serde(skip_serializing_if = "Option::is_none")]
13 pub page: Option<u32>,
14 #[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 pub async fn list_movies_upcoming(
71 &self,
72 params: &Params<'_>,
73 ) -> crate::Result<PaginatedResult<super::MovieShort>> {
74 self.execute("/movie/upcoming", params).await
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use mockito::Matcher;
81
82 use crate::client::Client;
83 use crate::client::reqwest::Client as ReqwestClient;
84
85 #[tokio::test]
86 async fn it_works() {
87 let mut server = mockito::Server::new_async().await;
88 let client = Client::<ReqwestClient>::builder()
89 .with_api_key("secret".into())
90 .with_base_url(server.url())
91 .build()
92 .unwrap();
93
94 let _m = server
95 .mock("GET", "/movie/upcoming")
96 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
97 .with_status(200)
98 .with_header("content-type", "application/json")
99 .with_body(include_str!("../../assets/movie-upcoming.json"))
100 .create_async()
101 .await;
102
103 let result = client
104 .list_movies_upcoming(&Default::default())
105 .await
106 .unwrap();
107 assert_eq!(result.page, 1);
108 }
109
110 #[tokio::test]
111 async fn invalid_api_key() {
112 let mut server = mockito::Server::new_async().await;
113 let client = Client::<ReqwestClient>::builder()
114 .with_api_key("secret".into())
115 .with_base_url(server.url())
116 .build()
117 .unwrap();
118
119 let _m = server
120 .mock("GET", "/movie/upcoming")
121 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
122 .with_status(401)
123 .with_header("content-type", "application/json")
124 .with_body(include_str!("../../assets/invalid-api-key.json"))
125 .create_async()
126 .await;
127
128 let err = client
129 .list_movies_upcoming(&Default::default())
130 .await
131 .unwrap_err();
132 let server_err = err.as_server_error().unwrap();
133 assert_eq!(server_err.status_code, 7);
134 }
135
136 #[tokio::test]
137 async fn resource_not_found() {
138 let mut server = mockito::Server::new_async().await;
139 let client = Client::<ReqwestClient>::builder()
140 .with_api_key("secret".into())
141 .with_base_url(server.url())
142 .build()
143 .unwrap();
144
145 let _m = server
146 .mock("GET", "/movie/upcoming")
147 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
148 .with_status(404)
149 .with_header("content-type", "application/json")
150 .with_body(include_str!("../../assets/resource-not-found.json"))
151 .create_async()
152 .await;
153
154 let err = client
155 .list_movies_upcoming(&Default::default())
156 .await
157 .unwrap_err();
158 let server_err = err.as_server_error().unwrap();
159 assert_eq!(server_err.status_code, 34);
160 }
161}
162
163#[cfg(all(test, feature = "integration"))]
164mod integration_tests {
165 use crate::client::Client;
166 use crate::client::reqwest::Client as ReqwestClient;
167
168 #[tokio::test]
169 async fn execute() {
170 let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
171 let client = Client::<ReqwestClient>::new(secret);
172
173 let _result = client
174 .list_movies_upcoming(&Default::default())
175 .await
176 .unwrap();
177 }
178}