aboutsummaryrefslogtreecommitdiff
path: root/trakt-rs/src/test.rs
blob: c00a38d1cb365173b843325980d22e53806bd088 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use std::sync::OnceLock;

use bytes::Bytes;
use reqwest::blocking::Client;
use trakt_core::{
    error::{FromHttpError, IntoHttpError},
    Context, Request, Response,
};

static CLIENT: OnceLock<Client> = OnceLock::new();

pub fn assert_request<R, T>(ctx: Context, req: R, exp_url: &str, exp_body: &T)
where
    R: Request,
    T: ToString + ?Sized,
{
    let http_req = req.try_into_http_request::<Vec<u8>>(ctx).unwrap();

    assert_eq!(http_req.method(), R::METADATA.method);
    assert_eq!(http_req.uri(), exp_url);
    assert_eq!(
        http_req.headers().get("Content-Type").unwrap(),
        "application/json"
    );
    assert_eq!(http_req.headers().get("trakt-api-version").unwrap(), "2");
    assert_eq!(
        http_req.headers().get("trakt-api-key").unwrap(),
        ctx.client_id
    );
    if let Some(token) = ctx.oauth_token {
        assert_eq!(
            *http_req.headers().get("Authorization").unwrap(),
            format!("Bearer {token}")
        );
    }

    assert_eq!(
        String::from_utf8_lossy(http_req.body()),
        exp_body.to_string()
    );
}

pub fn execute<R: Request>(ctx: Context, req: R) -> Result<R::Response, Error> {
    let client = CLIENT.get_or_init(Client::new);

    let request: http::Request<Vec<u8>> = req.try_into_http_request(ctx)?;

    let reqwest_res = client.execute(request.try_into()?)?;
    let http_res = reqwest_to_http(reqwest_res)?;

    Ok(Response::try_from_http_response(http_res)?)
}

fn reqwest_to_http(
    mut response: reqwest::blocking::Response,
) -> Result<http::Response<Bytes>, Error> {
    let mut builder = http::Response::builder()
        .status(response.status())
        .version(response.version());

    std::mem::swap(
        builder.headers_mut().expect("response should be valid"),
        response.headers_mut(),
    );

    Ok(builder
        .body(response.bytes()?)
        .expect("response should be valid"))
}

#[derive(Debug)]
pub enum Error {
    Reqwest(reqwest::Error),
    IntoHttp(IntoHttpError),
    FromHttp(FromHttpError),
}

impl From<reqwest::Error> for Error {
    fn from(e: reqwest::Error) -> Self {
        Self::Reqwest(e)
    }
}

impl From<IntoHttpError> for Error {
    fn from(e: IntoHttpError) -> Self {
        Self::IntoHttp(e)
    }
}

impl From<FromHttpError> for Error {
    fn from(e: FromHttpError) -> Self {
        Self::FromHttp(e)
    }
}