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::ReqwestExecutor;
30    ///
31    /// #[tokio::main]
32    /// async fn main() {
33    ///     let client = Client::<ReqwestExecutor>::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 crate::client::Client;
53    use crate::client::reqwest::ReqwestExecutor;
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::<ReqwestExecutor>::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::<ReqwestExecutor>::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::<ReqwestExecutor>::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::ReqwestExecutor;
139
140    #[tokio::test]
141    async fn execute() {
142        let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
143        let client = Client::<ReqwestExecutor>::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}