tmdb_api/movie/
reviews.rs1use crate::common::PaginatedResult;
2
3pub type Params<'a> = crate::common::LanguagePageParams<'a>;
4
5#[derive(Debug, Deserialize, Serialize)]
6pub struct AuthorDetails {
7 pub name: String,
8 pub username: String,
9 pub avatar_path: Option<String>,
10 pub rating: Option<f32>,
11}
12
13#[derive(Debug, Deserialize, Serialize)]
14pub struct MovieReview {
15 pub id: String,
16 pub author: String,
17 pub author_details: AuthorDetails,
18 pub content: String,
19 pub url: String,
20 pub created_at: chrono::DateTime<chrono::Utc>,
21 pub updated_at: chrono::DateTime<chrono::Utc>,
22}
23
24impl<E: crate::client::Executor> crate::Client<E> {
25 pub async fn get_movie_reviews(
41 &self,
42 movie_id: u64,
43 params: &Params<'_>,
44 ) -> crate::Result<PaginatedResult<MovieReview>> {
45 let url = format!("/movie/{movie_id}/reviews");
46 self.execute(&url, params).await
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use crate::client::Client;
53 use crate::client::reqwest::Client as ReqwestClient;
54 use mockito::Matcher;
55
56 #[tokio::test]
57 async fn it_works() {
58 let mut server = mockito::Server::new_async().await;
59 let client = Client::<ReqwestClient>::builder()
60 .with_api_key("secret".into())
61 .with_base_url(server.url())
62 .build()
63 .unwrap();
64
65 let _m = server
66 .mock("GET", "/movie/550/reviews")
67 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
68 .with_status(200)
69 .with_header("content-type", "application/json")
70 .with_body(include_str!("../../assets/movie-reviews.json"))
71 .create_async()
72 .await;
73
74 let result = client
75 .get_movie_reviews(550, &Default::default())
76 .await
77 .unwrap();
78 assert_eq!(result.page, 1);
79 assert!(!result.results.is_empty());
80 }
81
82 #[tokio::test]
83 async fn invalid_api_key() {
84 let mut server = mockito::Server::new_async().await;
85 let client = Client::<ReqwestClient>::builder()
86 .with_api_key("secret".into())
87 .with_base_url(server.url())
88 .build()
89 .unwrap();
90
91 let _m = server
92 .mock("GET", "/movie/550/reviews")
93 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
94 .with_status(401)
95 .with_header("content-type", "application/json")
96 .with_body(include_str!("../../assets/invalid-api-key.json"))
97 .create_async()
98 .await;
99
100 let err = client
101 .get_movie_reviews(550, &Default::default())
102 .await
103 .unwrap_err();
104 let server_err = err.as_server_error().unwrap();
105 assert_eq!(server_err.status_code, 7);
106 }
107
108 #[tokio::test]
109 async fn resource_not_found() {
110 let mut server = mockito::Server::new_async().await;
111 let client = Client::<ReqwestClient>::builder()
112 .with_api_key("secret".into())
113 .with_base_url(server.url())
114 .build()
115 .unwrap();
116
117 let _m = server
118 .mock("GET", "/movie/550/reviews")
119 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
120 .with_status(404)
121 .with_header("content-type", "application/json")
122 .with_body(include_str!("../../assets/resource-not-found.json"))
123 .create_async()
124 .await;
125
126 let err = client
127 .get_movie_reviews(550, &Default::default())
128 .await
129 .unwrap_err();
130 let server_err = err.as_server_error().unwrap();
131 assert_eq!(server_err.status_code, 34);
132 }
133}
134
135#[cfg(all(test, feature = "integration"))]
136mod integration_tests {
137 use crate::client::Client;
138 use crate::client::reqwest::Client as ReqwestClient;
139
140 #[tokio::test]
141 async fn execute() {
142 let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
143 let client = Client::<ReqwestClient>::new(secret);
144 let result = client
145 .get_movie_reviews(550, &Default::default())
146 .await
147 .unwrap();
148 assert_eq!(result.page, 1);
149 }
150}