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}