facebook_access_token_api/endpoints/
debug_token.rs1use http_api_client_endpoint::{
5 http::{
6 header::{ACCEPT, USER_AGENT},
7 Method, StatusCode,
8 },
9 Body, Endpoint, Request, Response, MIME_APPLICATION_JSON,
10};
11use serde::{Deserialize, Serialize};
12use url::Url;
13
14use crate::{
15 endpoints::{
16 common::{EndpointError, EndpointRet},
17 URL_BASE, VERSION,
18 },
19 objects::{DebugTokenResult, ResponseBodyErrJson},
20};
21
22#[derive(Debug, Clone)]
24pub struct DebugTokenEndpoint {
25 pub input_token: Box<str>,
26 pub access_token: Box<str>,
27 pub version: Option<Box<str>>,
29}
30
31impl DebugTokenEndpoint {
32 pub fn new(
33 input_token: impl AsRef<str>,
34 access_token: impl AsRef<str>,
35 version: impl Into<Option<Box<str>>>,
36 ) -> Self {
37 Self {
38 input_token: input_token.as_ref().into(),
39 access_token: access_token.as_ref().into(),
40 version: version.into(),
41 }
42 }
43}
44
45impl Endpoint for DebugTokenEndpoint {
46 type RenderRequestError = EndpointError;
47
48 type ParseResponseOutput = EndpointRet<DebugTokenResponseBodyOkJson>;
49 type ParseResponseError = EndpointError;
50
51 fn render_request(&self) -> Result<Request<Body>, Self::RenderRequestError> {
52 let url = format!(
53 "{}/{}/debug_token",
54 URL_BASE,
55 self.version.as_deref().unwrap_or(VERSION),
56 );
57 let mut url = Url::parse(&url).map_err(EndpointError::MakeRequestUrlFailed)?;
58
59 url.query_pairs_mut()
60 .append_pair("input_token", &self.input_token)
61 .append_pair("access_token", &self.access_token);
62
63 let request = Request::builder()
64 .method(Method::GET)
65 .uri(url.as_str())
66 .header(USER_AGENT, "facebook-access-token-api")
67 .header(ACCEPT, MIME_APPLICATION_JSON)
68 .body(vec![])
69 .map_err(EndpointError::MakeRequestFailed)?;
70
71 Ok(request)
72 }
73
74 fn parse_response(
75 &self,
76 response: Response<Body>,
77 ) -> Result<Self::ParseResponseOutput, Self::ParseResponseError> {
78 let status = response.status();
79 match status {
80 StatusCode::OK => Ok(EndpointRet::Ok(
81 serde_json::from_slice(response.body())
82 .map_err(EndpointError::DeResponseBodyOkJsonFailed)?,
83 )),
84 status => match serde_json::from_slice::<ResponseBodyErrJson>(response.body()) {
85 Ok(ok_json) => Ok(EndpointRet::Other((status, Ok(ok_json)))),
86 Err(_) => Ok(EndpointRet::Other((
87 status,
88 Err(response.body().to_owned()),
89 ))),
90 },
91 }
92 }
93}
94
95#[derive(Deserialize, Serialize, Debug, Clone)]
99pub struct DebugTokenResponseBodyOkJson {
100 pub data: DebugTokenResult,
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 use crate::objects::debug_token::DebugTokenResultTypeExtra;
108
109 #[test]
110 fn test_de_response_body_ok_json() {
111 let content =
116 include_str!("../../tests/response_body_json_files/debug_token__app_access_token.json");
117 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
118 Ok(ok_json) => {
119 assert!(ok_json.data.error.is_none(),);
121 match ok_json.data.type_extra.unwrap() {
122 DebugTokenResultTypeExtra::App(info) => {
123 assert_eq!(info.app_id, 257422819769992);
124 assert_eq!(info.application, "oauth2-rs-f-b-web-app-demo");
125 }
126 DebugTokenResultTypeExtra::User(x) => panic!("{x:?}"),
127 DebugTokenResultTypeExtra::Page(x) => panic!("{x:?}"),
128 }
129 }
130 Err(err) => panic!("{}", err),
131 }
132
133 let content = include_str!(
138 "../../tests/response_body_json_files/debug_token__user_access_token_1.json"
139 );
140 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
141 Ok(ok_json) => {
142 assert!(ok_json.data.error.is_none(),);
144 match ok_json.data.type_extra.unwrap() {
145 DebugTokenResultTypeExtra::App(x) => panic!("{x:?}"),
146 DebugTokenResultTypeExtra::User(info) => {
147 assert_eq!(info.app_id, 257422819769992);
148 assert_eq!(info.user_id, 123);
149 assert!(info.metadata.is_some());
150 }
151 DebugTokenResultTypeExtra::Page(x) => panic!("{x:?}"),
152 }
153 }
154 Err(err) => panic!("{}", err),
155 }
156
157 let content = include_str!(
159 "../../tests/response_body_json_files/debug_token__user_access_token_2.json"
160 );
161 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
162 Ok(ok_json) => {
163 assert!(ok_json.data.error.is_none(),);
165 match ok_json.data.type_extra.unwrap() {
166 DebugTokenResultTypeExtra::App(x) => panic!("{x:?}"),
167 DebugTokenResultTypeExtra::User(info) => {
168 assert_eq!(info.app_id, 257422819769992);
169 assert_eq!(info.user_id, 123);
170 assert!(info.metadata.is_none());
171 }
172 DebugTokenResultTypeExtra::Page(x) => panic!("{x:?}"),
173 }
174 }
175 Err(err) => panic!("{}", err),
176 }
177
178 let content = include_str!(
180 "../../tests/response_body_json_files/debug_token__user_access_token_3.json"
181 );
182 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
183 Ok(ok_json) => {
184 assert!(ok_json.data.error.unwrap().message.contains("has expired"));
186 match ok_json.data.type_extra.unwrap() {
187 DebugTokenResultTypeExtra::App(x) => panic!("{x:?}"),
188 DebugTokenResultTypeExtra::User(info) => {
189 assert_eq!(info.app_id, 257422819769992);
190 assert_eq!(info.user_id, 123);
191 }
192 DebugTokenResultTypeExtra::Page(x) => panic!("{x:?}"),
193 }
194 }
195 Err(err) => panic!("{}", err),
196 }
197
198 let content = include_str!(
200 "../../tests/response_body_json_files/debug_token__user_access_token_4.json"
201 );
202 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
203 Ok(ok_json) => {
204 assert!(ok_json
206 .data
207 .error
208 .unwrap()
209 .message
210 .contains("has been invalidated"));
211 match ok_json.data.type_extra.unwrap() {
212 DebugTokenResultTypeExtra::App(x) => panic!("{x:?}"),
213 DebugTokenResultTypeExtra::User(info) => {
214 assert_eq!(info.app_id, 257422819769992);
215 assert_eq!(info.user_id, 123);
216 assert!(info.granular_scopes.is_some());
217 }
218 DebugTokenResultTypeExtra::Page(x) => panic!("{x:?}"),
219 }
220 }
221 Err(err) => panic!("{}", err),
222 }
223
224 let content = include_str!(
229 "../../tests/response_body_json_files/debug_token__user_access_token_example_1.json"
230 );
231 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
232 Ok(_ok_json) => {
233 }
235 Err(err) => panic!("{}", err),
236 }
237
238 let content = include_str!(
240 "../../tests/response_body_json_files/debug_token__user_access_token_example_2.json"
241 );
242 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
243 Ok(_ok_json) => {
244 }
246 Err(err) => panic!("{}", err),
247 }
248
249 let content =
251 include_str!("../../tests/response_body_json_files/debug_token__200__example_1.json");
252 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
253 Ok(_ok_json) => {
254 }
256 Err(err) => panic!("{}", err),
257 }
258
259 let content =
261 include_str!("../../tests/response_body_json_files/debug_token__200__example_2.json");
262 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
263 Ok(ok_json) => {
264 assert!(ok_json.data.is_valid);
266 }
267 Err(err) => panic!("{}", err),
268 }
269
270 let content = include_str!(
275 "../../tests/response_body_json_files/debug_token__page_access_token.json"
276 );
277 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
278 Ok(ok_json) => {
279 assert!(ok_json.data.error.is_none(),);
281 match ok_json.data.type_extra.unwrap() {
282 DebugTokenResultTypeExtra::App(x) => panic!("{x:?}"),
283 DebugTokenResultTypeExtra::User(x) => panic!("{x:?}"),
284 DebugTokenResultTypeExtra::Page(info) => {
285 assert_eq!(info.app_id, 257422819769992);
286 assert_eq!(info.user_id, 123);
287 assert_eq!(info.profile_id, 103455271248220);
288 assert!(info.granular_scopes.is_some());
289 assert_eq!(
290 info.granular_scopes
291 .unwrap()
292 .first()
293 .cloned()
294 .unwrap()
295 .target_ids
296 .unwrap()
297 .first()
298 .cloned()
299 .unwrap(),
300 103455271248220
301 );
302 }
303 }
304 }
305 Err(err) => panic!("{}", err),
306 }
307
308 let content = include_str!(
313 "../../tests/response_body_json_files/debug_token__200__access_token_could_not_be_decrypted.json"
314 );
315 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
316 Ok(ok_json) => {
317 assert!(ok_json.data.error.is_some(),);
319 }
320 Err(err) => panic!("{}", err),
321 }
322
323 let content = include_str!(
325 "../../tests/response_body_json_files/debug_token__200__cannot_get_application_info.json"
326 );
327 match serde_json::from_str::<DebugTokenResponseBodyOkJson>(content) {
328 Ok(ok_json) => {
329 assert!(ok_json.data.error.is_some(),);
331 }
332 Err(err) => panic!("{}", err),
333 }
334 }
335}