Skip to main content

bpi_rs/opus/
client.rs

1use crate::opus::{OpusSpaceFeedParams, SpaceData};
2use crate::{BilibiliRequest, BpiClient, BpiResult};
3
4const SPACE_FEED_ENDPOINT: &str =
5    "https://api.bilibili.com/x/polymer/web-dynamic/v1/opus/feed/space";
6
7/// Opus API client.
8#[derive(Clone, Copy)]
9pub struct OpusClient<'a> {
10    pub(crate) client: &'a BpiClient,
11}
12
13impl<'a> OpusClient<'a> {
14    pub(crate) fn new(client: &'a BpiClient) -> Self {
15        Self { client }
16    }
17
18    #[cfg(test)]
19    pub(crate) fn space_feed_endpoint(&self) -> &'static str {
20        SPACE_FEED_ENDPOINT
21    }
22
23    /// Gets opus items from a user's space feed.
24    pub async fn space_feed(&self, params: OpusSpaceFeedParams) -> BpiResult<SpaceData> {
25        self.client
26            .get(SPACE_FEED_ENDPOINT)
27            .query(&params.query_pairs())
28            .send_bpi_payload("opus.space_feed")
29            .await
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use std::future::Future;
36
37    use crate::ids::Mid;
38    use crate::opus::{OpusSpaceFeedParams, SpaceData};
39    use crate::probe::contract::HttpMethod;
40    use crate::probe::endpoint_contract::EndpointContract;
41    use crate::{BpiClient, BpiResult};
42
43    fn assert_space_feed_future<F>(_future: F)
44    where
45        F: Future<Output = BpiResult<SpaceData>>,
46    {
47    }
48
49    fn contract() -> BpiResult<EndpointContract> {
50        EndpointContract::from_slice(include_bytes!(
51            "../../tests/contracts/opus/space-read/space-feed/contract.json"
52        ))
53    }
54
55    #[test]
56    fn opus_client_exposes_promoted_endpoint_url() -> BpiResult<()> {
57        let client = BpiClient::new()?;
58        let opus = client.opus();
59
60        assert_eq!(
61            opus.space_feed_endpoint(),
62            "https://api.bilibili.com/x/polymer/web-dynamic/v1/opus/feed/space"
63        );
64        Ok(())
65    }
66
67    #[test]
68    fn opus_space_feed_returns_payload_future() -> BpiResult<()> {
69        let client = BpiClient::new()?;
70        let opus = client.opus();
71
72        assert_space_feed_future(opus.space_feed(OpusSpaceFeedParams::new(Mid::new(4_279_370)?)));
73        Ok(())
74    }
75
76    #[test]
77    fn opus_contract_matches_module_client_endpoint() -> BpiResult<()> {
78        let client = BpiClient::new()?;
79        let opus = client.opus();
80        let contract = contract()?;
81
82        assert_eq!(contract.name, "opus.space_feed");
83        assert_eq!(contract.request.method, HttpMethod::Get);
84        assert_eq!(contract.request.url.as_str(), opus.space_feed_endpoint());
85        assert_eq!(
86            contract.request.query.get("host_mid").map(String::as_str),
87            Some("4279370")
88        );
89        assert_eq!(
90            contract.request.query.get("page").map(String::as_str),
91            Some("0")
92        );
93        assert_eq!(
94            contract.request.query.get("type").map(String::as_str),
95            Some("all")
96        );
97        assert_eq!(
98            contract
99                .request
100                .query
101                .get("web_location")
102                .map(String::as_str),
103            Some("333.1387")
104        );
105        Ok(())
106    }
107}