Skip to main content

yt/api/
mod.rs

1pub mod agiles;
2pub mod articles;
3pub mod attachments;
4pub mod client;
5pub mod commands;
6pub mod comments;
7pub mod custom_fields;
8pub mod error;
9pub mod issues;
10pub mod links;
11pub mod parent;
12pub mod projection;
13pub mod projects;
14pub mod tags;
15pub mod users;
16pub mod work_items;
17
18pub use client::{Client, TokenSource};
19pub use parent::Parent;
20pub use projection::Projection;
21
22#[cfg(test)]
23pub(crate) fn test_client(uri: &str) -> Client {
24    let http = crate::http::client(&crate::http::HttpConfig {
25        timeout: std::time::Duration::from_secs(5),
26        retries: 0,
27        ca_file: None,
28    })
29    .unwrap();
30    let token = std::sync::Arc::new(crate::auth::token_source::StaticToken::new(
31        secrecy::SecretString::from("perm-dGVzdA==.dGVzdA==.secret123456".to_string()),
32        "acme",
33    ));
34    Client::new(
35        http,
36        crate::instance::InstanceUrl::parse(uri).unwrap(),
37        token,
38        0,
39    )
40}
41
42#[cfg(test)]
43mod tests {
44    use serde_json::{Value, json};
45    use wiremock::matchers::{method, path, query_param};
46    use wiremock::{Mock, MockServer, ResponseTemplate};
47
48    use super::*;
49    use crate::api::client::LIST_PAGE;
50
51    async fn two_pages(server: &MockServer, endpoint: &str, item: Value) {
52        Mock::given(method("GET"))
53            .and(path(endpoint))
54            .and(query_param("$skip", "0"))
55            .respond_with(ResponseTemplate::new(200).set_body_json(vec![item.clone(); LIST_PAGE]))
56            .mount(server)
57            .await;
58        Mock::given(method("GET"))
59            .and(path(endpoint))
60            .and(query_param("$skip", LIST_PAGE.to_string()))
61            .respond_with(ResponseTemplate::new(200).set_body_json(json!([item])))
62            .mount(server)
63            .await;
64    }
65
66    #[tokio::test]
67    async fn lists_read_every_page() {
68        let server = MockServer::start().await;
69        let issue = "/api/issues/WEB-1";
70        two_pages(&server, &format!("{issue}/comments"), json!({"id": "4-1"})).await;
71        two_pages(
72            &server,
73            &format!("{issue}/attachments"),
74            json!({"id": "8-1", "name": "a.txt"}),
75        )
76        .await;
77        two_pages(
78            &server,
79            &format!("{issue}/links"),
80            json!({"direction": "OUTWARD", "linkType": {"name": "Relates"}}),
81        )
82        .await;
83        two_pages(&server, "/api/tags", json!({"name": "ui"})).await;
84        two_pages(&server, "/api/admin/projects", json!({"shortName": "WEB"})).await;
85        let client = test_client(&server.uri());
86        let all = LIST_PAGE + 1;
87        assert_eq!(
88            comments::list(&client, &Parent::Issue("WEB-1".into()))
89                .await
90                .unwrap()
91                .len(),
92            all
93        );
94        assert_eq!(
95            attachments::list(&client, &Parent::Issue("WEB-1".into()))
96                .await
97                .unwrap()
98                .len(),
99            all
100        );
101        assert_eq!(links::list(&client, "WEB-1").await.unwrap().len(), all);
102        assert_eq!(tags::visible(&client).await.unwrap().len(), all);
103        assert_eq!(projects::short_names(&client).await.unwrap().len(), all);
104    }
105}