tmdb_api/movie/
changes.rs1use crate::client::Executor;
2
3pub use crate::changes::list::Params;
4
5#[derive(Clone, Debug, Deserialize, Serialize)]
6pub struct MovieChange {
7 pub key: String,
8 pub items: Vec<MovieChangeItem>,
9}
10
11#[derive(Clone, Debug, Deserialize, Serialize)]
12pub struct MovieChangeItem {
13 pub id: String,
14 pub action: String,
15 pub time: chrono::DateTime<chrono::Utc>,
16 pub iso_639_1: String,
17 pub iso_3166_1: String,
18 }
22
23#[derive(Clone, Debug, Deserialize)]
24pub struct Response {
25 pub changes: Vec<MovieChange>,
26}
27
28impl<E: Executor> crate::Client<E> {
29 pub async fn get_movie_changes(
45 &self,
46 movie_id: u64,
47 params: &Params,
48 ) -> crate::Result<Response> {
49 let url = format!("/movie/{movie_id}/changes");
50 self.execute(&url, params).await
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use crate::client::Client;
57 use crate::client::reqwest::Client as ReqwestClient;
58 use mockito::Matcher;
59
60 #[tokio::test]
61 async fn it_works() {
62 let mut server = mockito::Server::new_async().await;
63 let m = server
64 .mock("GET", "/movie/3/changes")
65 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
66 .with_status(200)
67 .with_header("content-type", "application/json")
68 .with_body(include_str!("../../assets/movie-single-changes.json"))
69 .create_async()
70 .await;
71
72 let client = Client::<ReqwestClient>::builder()
73 .with_api_key("secret".into())
74 .with_base_url(server.url())
75 .build()
76 .unwrap();
77 let result = client
78 .get_movie_changes(3, &Default::default())
79 .await
80 .unwrap();
81 assert_eq!(result.changes.len(), 1);
82
83 m.assert_async().await;
84 }
85
86 #[tokio::test]
87 async fn invalid_api_key() {
88 let mut server = mockito::Server::new_async().await;
89 let m = server
90 .mock("GET", "/movie/1/changes")
91 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
92 .with_status(401)
93 .with_header("content-type", "application/json")
94 .with_body(include_str!("../../assets/invalid-api-key.json"))
95 .create_async()
96 .await;
97
98 let client = Client::<ReqwestClient>::builder()
99 .with_api_key("secret".into())
100 .with_base_url(server.url())
101 .build()
102 .unwrap();
103 let err = client
104 .get_movie_changes(1, &Default::default())
105 .await
106 .unwrap_err();
107 let server_err = err.as_server_error().unwrap();
108 assert_eq!(server_err.status_code, 7);
109
110 m.assert_async().await;
111 }
112
113 #[tokio::test]
114 async fn resource_not_found() {
115 let mut server = mockito::Server::new_async().await;
116 let m = server
117 .mock("GET", "/movie/1/changes")
118 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
119 .with_status(404)
120 .with_header("content-type", "application/json")
121 .with_body(include_str!("../../assets/resource-not-found.json"))
122 .create_async()
123 .await;
124
125 let client = Client::<ReqwestClient>::builder()
126 .with_api_key("secret".into())
127 .with_base_url(server.url())
128 .build()
129 .unwrap();
130 let err = client
131 .get_movie_changes(1, &Default::default())
132 .await
133 .unwrap_err();
134 let server_err = err.as_server_error().unwrap();
135 assert_eq!(server_err.status_code, 34);
136
137 m.assert_async().await;
138 }
139}
140
141#[cfg(all(test, feature = "integration"))]
142mod integration_tests {
143 use super::Params;
144 use crate::client::Client;
145 use crate::client::reqwest::Client as ReqwestClient;
146
147 #[tokio::test]
148 async fn execute() {
149 let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
150 let client = Client::<ReqwestClient>::new(secret);
151 let params = Params::default()
152 .with_start_date(chrono::NaiveDate::from_ymd_opt(2015, 3, 14).unwrap())
153 .with_end_date(chrono::NaiveDate::from_ymd_opt(2019, 3, 14).unwrap());
154 let result = client.get_movie_changes(1, ¶ms).await.unwrap();
155 assert!(result.changes.is_empty());
156 }
157}