Skip to main content

bpi_rs/user/
batch.rs

1//! B站用户批量信息相关接口
2//!
3//! [查看 API 文档](https://github.com/SocialSisterYi/bilibili-API-collect/tree/master/docs/user)
4use serde::{Deserialize, Serialize};
5
6/// UID 查询返回的单个条目
7#[derive(Debug, Clone, Deserialize, Serialize)]
8pub struct NameUidItem {
9    /// 用户名
10    pub name: String,
11    /// 用户 mid
12    pub uid: String,
13}
14
15/// 批量用户名查 UID 的数据本体
16#[derive(Debug, Clone, Deserialize, Serialize)]
17pub struct NameToUidData {
18    pub uid_list: Vec<NameUidItem>,
19}
20
21#[cfg(test)]
22mod tests {
23    use super::*;
24    use crate::probe::contract::HttpMethod;
25    use crate::probe::endpoint_contract::EndpointContract;
26    use crate::user::params::UserNameToUidParams;
27    use crate::{ApiEnvelope, BpiClient, BpiError, BpiResult};
28    use tracing::info;
29
30    #[ignore = "legacy live API test; requires explicit BPI_LIVE_TEST review"]
31    #[tokio::test]
32    async fn test_user_name_to_uid() -> Result<(), BpiError> {
33        if std::env::var_os("BPI_LIVE_TEST").is_none() {
34            return Ok(());
35        }
36
37        let bpi = BpiClient::new().expect("client should build");
38        let data = bpi
39            .user()
40            .name_to_uid(UserNameToUidParams::new(["LexBurner", "某科学"])?)
41            .await?;
42
43        info!("用户名查 UID 返回: {:?}", data);
44        assert!(!data.uid_list.is_empty());
45
46        Ok(())
47    }
48
49    fn name_to_uid_contract() -> BpiResult<EndpointContract> {
50        EndpointContract::from_slice(include_bytes!(
51            "../../tests/contracts/user/public-read/name-to-uid/contract.json"
52        ))
53    }
54
55    #[test]
56    fn legacy_user_name_to_uid_contract_matches_endpoint_request() -> BpiResult<()> {
57        let contract = name_to_uid_contract()?;
58
59        assert_eq!(contract.name, "user.name_to_uid");
60        assert_eq!(contract.request.method, HttpMethod::Get);
61        assert_eq!(
62            contract.request.url.as_str(),
63            "https://api.bilibili.com/x/polymer/web-dynamic/v1/name-to-uid"
64        );
65        assert_eq!(
66            contract.request.query.get("names").map(String::as_str),
67            Some("LexBurner,某科学")
68        );
69        assert_eq!(
70            contract.cases[0].response.error.as_deref(),
71            Some("requires_login")
72        );
73        Ok(())
74    }
75
76    #[test]
77    fn legacy_user_name_to_uid_fixture_parses_promoted_contract_model() -> BpiResult<()> {
78        let err = ApiEnvelope::<serde_json::Value>::from_slice(include_bytes!(
79            "../../tests/contracts/user/public-read/name-to-uid/responses/anonymous.error.json"
80        ))?
81        .ensure_success()
82        .unwrap_err();
83        assert!(err.requires_login());
84
85        let data = ApiEnvelope::<NameToUidData>::from_slice(include_bytes!(
86            "../../tests/contracts/user/public-read/name-to-uid/responses/success.json"
87        ))?
88        .into_payload()?;
89        assert!(!data.uid_list.is_empty());
90        Ok(())
91    }
92}