tmdb_api/movie/
reviews.rs

1use 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    /// Get the release date along with the certification for a movie.
26    ///
27    /// ```rust
28    /// use tmdb_api::client::Client;
29    /// use tmdb_api::client::reqwest::Client as ReqwestClient;
30    ///
31    /// #[tokio::main]
32    /// async fn main() {
33    ///     let client = Client::<ReqwestClient>::new("this-is-my-secret-token".into());
34    ///     match client.get_movie_reviews(1, &Default::default()).await {
35    ///         Ok(res) => println!("found: {:#?}", res),
36    ///         Err(err) => eprintln!("error: {:?}", err),
37    ///     };
38    /// }
39    /// ```
40    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 mockito::Matcher;
53
54    use crate::client::Client;
55    use crate::client::reqwest::Client as ReqwestClient;
56
57    #[tokio::test]
58    async fn it_works() {
59        let mut server = mockito::Server::new_async().await;
60        let client = Client::<ReqwestClient>::builder()
61            .with_api_key("secret".into())
62            .with_base_url(server.url())
63            .build()
64            .unwrap();
65
66        let _m = server
67            .mock("GET", "/movie/550/reviews")
68            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
69            .with_status(200)
70            .with_header("content-type", "application/json")
71            .with_body(include_str!("../../assets/movie-reviews.json"))
72            .create_async()
73            .await;
74
75        let result = client
76            .get_movie_reviews(550, &Default::default())
77            .await
78            .unwrap();
79        assert_eq!(result.page, 1);
80        assert!(!result.results.is_empty());
81    }
82
83    #[tokio::test]
84    async fn invalid_api_key() {
85        let mut server = mockito::Server::new_async().await;
86        let client = Client::<ReqwestClient>::builder()
87            .with_api_key("secret".into())
88            .with_base_url(server.url())
89            .build()
90            .unwrap();
91
92        let _m = server
93            .mock("GET", "/movie/550/reviews")
94            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
95            .with_status(401)
96            .with_header("content-type", "application/json")
97            .with_body(include_str!("../../assets/invalid-api-key.json"))
98            .create_async()
99            .await;
100
101        let err = client
102            .get_movie_reviews(550, &Default::default())
103            .await
104            .unwrap_err();
105        let server_err = err.as_server_error().unwrap();
106        assert_eq!(server_err.status_code, 7);
107    }
108
109    #[tokio::test]
110    async fn resource_not_found() {
111        let mut server = mockito::Server::new_async().await;
112        let client = Client::<ReqwestClient>::builder()
113            .with_api_key("secret".into())
114            .with_base_url(server.url())
115            .build()
116            .unwrap();
117
118        let _m = server
119            .mock("GET", "/movie/550/reviews")
120            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
121            .with_status(404)
122            .with_header("content-type", "application/json")
123            .with_body(include_str!("../../assets/resource-not-found.json"))
124            .create_async()
125            .await;
126
127        let err = client
128            .get_movie_reviews(550, &Default::default())
129            .await
130            .unwrap_err();
131        let server_err = err.as_server_error().unwrap();
132        assert_eq!(server_err.status_code, 34);
133    }
134}
135
136#[cfg(all(test, feature = "integration"))]
137mod integration_tests {
138    use crate::client::Client;
139    use crate::client::reqwest::Client as ReqwestClient;
140
141    #[tokio::test]
142    async fn execute() {
143        let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
144        let client = Client::<ReqwestClient>::new(secret);
145        let result = client
146            .get_movie_reviews(550, &Default::default())
147            .await
148            .unwrap();
149        assert_eq!(result.page, 1);
150    }
151}