tmdb_api/tvshow/episode/
details.rs1use std::borrow::Cow;
2
3#[derive(Clone, Debug, Default)]
23pub struct TVShowEpisodeDetails {
24 pub tv_id: u64,
26 pub season_number: u64,
28 pub episode_number: u64,
30 pub language: Option<String>,
32}
33
34impl TVShowEpisodeDetails {
35 pub fn new(tv_id: u64, season_number: u64, episode_number: u64) -> Self {
36 Self {
37 tv_id,
38 season_number,
39 episode_number,
40 language: None,
41 }
42 }
43
44 pub fn with_language(mut self, value: Option<String>) -> Self {
45 self.language = value;
46 self
47 }
48}
49
50impl crate::prelude::Command for TVShowEpisodeDetails {
51 type Output = crate::tvshow::Episode;
52
53 fn path(&self) -> Cow<'static, str> {
54 Cow::Owned(format!(
55 "/tv/{}/season/{}/episode/{}",
56 self.tv_id, self.season_number, self.episode_number
57 ))
58 }
59
60 fn params(&self) -> Vec<(&'static str, Cow<'_, str>)> {
61 if let Some(language) = self.language.as_ref() {
62 vec![("language", Cow::Borrowed(language.as_str()))]
63 } else {
64 Vec::new()
65 }
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::TVShowEpisodeDetails;
72 use crate::client::Client;
73 use crate::client::reqwest::ReqwestExecutor;
74 use crate::prelude::Command;
75 use mockito::Matcher;
76
77 #[tokio::test]
78 async fn it_works() {
79 let mut server = mockito::Server::new_async().await;
80 let client = Client::<ReqwestExecutor>::builder()
81 .with_api_key("secret".into())
82 .with_base_url(server.url())
83 .build()
84 .unwrap();
85
86 let _m = server
87 .mock("GET", "/tv/1399/season/1/episode/1")
88 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
89 .with_status(200)
90 .with_header("content-type", "application/json")
91 .with_body(include_str!("../../../assets/tv-episode-details.json"))
92 .create_async()
93 .await;
94
95 let result = TVShowEpisodeDetails::new(1399, 1, 1)
96 .execute(&client)
97 .await
98 .unwrap();
99 assert_eq!(result.inner.id, 63056);
100 }
101
102 #[tokio::test]
103 async fn invalid_api_key() {
104 let mut server = mockito::Server::new_async().await;
105 let client = Client::<ReqwestExecutor>::builder()
106 .with_api_key("secret".into())
107 .with_base_url(server.url())
108 .build()
109 .unwrap();
110
111 let _m = server
112 .mock("GET", "/tv/1399/season/1/episode/1")
113 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
114 .with_status(401)
115 .with_header("content-type", "application/json")
116 .with_body(include_str!("../../../assets/invalid-api-key.json"))
117 .create_async()
118 .await;
119
120 let err = TVShowEpisodeDetails::new(1399, 1, 1)
121 .execute(&client)
122 .await
123 .unwrap_err();
124 let server_err = err.as_server_error().unwrap();
125 assert_eq!(server_err.status_code, 7);
126 }
127
128 #[tokio::test]
129 async fn resource_not_found() {
130 let mut server = mockito::Server::new_async().await;
131 let client = Client::<ReqwestExecutor>::builder()
132 .with_api_key("secret".into())
133 .with_base_url(server.url())
134 .build()
135 .unwrap();
136
137 let _m = server
138 .mock("GET", "/tv/1399/season/1/episode/1")
139 .match_query(Matcher::UrlEncoded("api_key".into(), "secret".into()))
140 .with_status(404)
141 .with_header("content-type", "application/json")
142 .with_body(include_str!("../../../assets/resource-not-found.json"))
143 .create_async()
144 .await;
145
146 let err = TVShowEpisodeDetails::new(1399, 1, 1)
147 .execute(&client)
148 .await
149 .unwrap_err();
150 let server_err = err.as_server_error().unwrap();
151 assert_eq!(server_err.status_code, 34);
152 }
153}
154
155#[cfg(all(test, feature = "integration"))]
156mod integration_tests {
157 use super::TVShowEpisodeDetails;
158 use crate::client::Client;
159 use crate::client::reqwest::ReqwestExecutor;
160 use crate::prelude::Command;
161
162 #[tokio::test]
163 async fn execute() {
164 let secret = std::env::var("TMDB_TOKEN_V3").unwrap();
165 let client = Client::<ReqwestExecutor>::new(secret);
166
167 for (tv_id, season_id) in [(1, 1130462u64)] {
168 let result = TVShowEpisodeDetails::new(tv_id, 1, 1)
169 .execute(&client)
170 .await
171 .unwrap();
172 assert_eq!(result.inner.id, season_id);
173 }
174 }
175}