tmdb_api/collection/
details.rs

1use crate::client::Executor;
2
3#[derive(Debug, Clone, Deserialize, Serialize)]
4#[serde(rename_all = "lowercase")]
5pub enum MediaType {
6    Movie,
7    Tv,
8    Collection,
9}
10
11#[derive(Debug, Deserialize, Serialize)]
12pub struct CollectionDetails {
13    #[serde(flatten)]
14    pub inner: super::CollectionBase,
15    pub parts: Vec<Media>,
16}
17
18#[derive(Debug, Deserialize, Serialize)]
19pub struct Media {
20    pub id: u64,
21    pub media_type: MediaType,
22    pub title: String,
23    pub original_language: String,
24    pub original_title: String,
25    pub overview: String,
26    pub poster_path: Option<String>,
27    pub backdrop_path: Option<String>,
28    #[serde(default)]
29    pub genre_ids: Vec<u64>,
30    #[serde(default)]
31    pub popularity: f64,
32    #[serde(default)]
33    pub adult: bool,
34    #[serde(default)]
35    pub video: bool,
36    #[serde(default)]
37    pub vote_average: f64,
38    #[serde(default)]
39    pub vote_count: u64,
40    #[serde(default, deserialize_with = "crate::util::empty_string::deserialize")]
41    pub release_date: Option<chrono::NaiveDate>,
42}
43
44pub type Params<'a> = crate::common::LanguageParams<'a>;
45
46impl<E: Executor> crate::Client<E> {
47    pub async fn get_collection_details(
48        &self,
49        collection_id: u64,
50        params: &Params<'_>,
51    ) -> crate::Result<CollectionDetails> {
52        self.execute(&format!("/collection/{collection_id}"), params)
53            .await
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use mockito::Matcher;
60
61    use crate::client::Client;
62    use crate::client::reqwest::Client as ReqwestClient;
63
64    #[tokio::test]
65    async fn it_works() {
66        let mut server = mockito::Server::new_async().await;
67        let _m = server
68            .mock("GET", "/collection/10")
69            .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
70            .with_status(200)
71            .with_header("content-type", "application/json")
72            .with_body(include_str!("../../assets/collection-details.json"))
73            .create_async()
74            .await;
75
76        let client = Client::<ReqwestClient>::builder()
77            .with_api_key("secret".into())
78            .with_base_url(server.url())
79            .build()
80            .unwrap();
81        let result = client
82            .get_collection_details(10, &Default::default())
83            .await
84            .unwrap();
85
86        assert_eq!(result.inner.id, 10);
87    }
88
89    #[tokio::test]
90    async fn invalid_api_key() {
91        let mut server = mockito::Server::new_async().await;
92        let _m = server
93            .mock("GET", "/collection/0")
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 client = Client::<ReqwestClient>::builder()
102            .with_api_key("secret".into())
103            .with_base_url(server.url())
104            .build()
105            .unwrap();
106        let err = client
107            .get_collection_details(0, &Default::default())
108            .await
109            .unwrap_err();
110        let server_err = err.as_server_error().unwrap();
111        assert_eq!(server_err.status_code, 7);
112    }
113
114    #[tokio::test]
115    async fn resource_not_found() {
116        let mut server = mockito::Server::new_async().await;
117        let _m = server
118            .mock("GET", "/collection/0")
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 client = Client::<ReqwestClient>::builder()
127            .with_api_key("secret".into())
128            .with_base_url(server.url())
129            .build()
130            .unwrap();
131        let err = client
132            .get_collection_details(0, &Default::default())
133            .await
134            .unwrap_err();
135        let server_err = err.as_server_error().unwrap();
136        assert_eq!(server_err.status_code, 34);
137    }
138}
139
140#[cfg(all(test, feature = "integration"))]
141mod integration_tests {
142    use crate::client::Client;
143    use crate::client::reqwest::Client as ReqwestClient;
144
145    #[tokio::test]
146    async fn execute() {
147        let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
148        let client = Client::<ReqwestClient>::new(secret);
149
150        for i in [10, 1196769] {
151            let result = client
152                .get_collection_details(0, &Default::default())
153                .await
154                .unwrap();
155            assert_eq!(result.inner.id, i);
156        }
157    }
158}