#![allow(clippy::expect_used, clippy::unwrap_used)]
use wiremock::matchers::{method, path, query_param};
use wiremock::{Mock, ResponseTemplate};
mod harness;
use harness::{Harness, fixture};
async fn directory(harness: &Harness) {
Mock::given(method("GET"))
.and(path("/v3/users"))
.respond_with(
ResponseTemplate::new(200)
.set_body_json(fixture("users.json"))
.append_header("X-Total-Count", "4"),
)
.mount(&harness.server)
.await;
}
#[tokio::test]
async fn a_listing_ends_with_a_tally() {
let harness = Harness::new().await;
directory(&harness).await;
let output = harness.run(&["user", "list"]).assert().success();
let stdout = String::from_utf8(output.get_output().stdout.clone()).expect("utf-8");
assert!(stdout.contains("ilubenets"), "{stdout}");
assert!(stdout.ends_with("shown 4 of 4\n"), "{stdout}");
}
#[tokio::test]
async fn a_departed_colleague_is_listed_and_labelled() {
let harness = Harness::new().await;
directory(&harness).await;
let output = harness.run(&["user", "list"]).assert().success();
let stdout = String::from_utf8(output.get_output().stdout.clone()).expect("utf-8");
assert!(stdout.contains("departed"), "{stdout}");
assert!(stdout.contains("dismissed"), "{stdout}");
assert!(stdout.contains("external"), "{stdout}");
}
#[tokio::test]
async fn one_person_is_fetched_by_login() {
let harness = Harness::new().await;
Mock::given(method("GET"))
.and(path("/v3/users/ilubenets"))
.respond_with(ResponseTemplate::new(200).set_body_json(fixture("user.json")))
.mount(&harness.server)
.await;
let output = harness
.run(&["user", "get", "ilubenets"])
.assert()
.success();
let stdout = String::from_utf8(output.get_output().stdout.clone()).expect("utf-8");
assert!(stdout.starts_with("ilubenets Ilya Lubenets\n"), "{stdout}");
assert!(stdout.contains("state: active"), "{stdout}");
}
#[tokio::test]
async fn find_matches_login_name_and_email() {
let harness = Harness::new().await;
directory(&harness).await;
for (needle, expected) in [
("ilubenets", "ilubenets"),
("outside", "contractor"),
("elsewhere.example", "contractor"),
] {
let output = harness.run(&["user", "find", needle]).assert().success();
let stdout = String::from_utf8(output.get_output().stdout.clone()).expect("utf-8");
assert!(
stdout.contains(expected),
"{needle} did not find {expected}"
);
}
}
#[tokio::test]
async fn a_search_reports_how_many_people_it_read() {
let harness = Harness::new().await;
directory(&harness).await;
let output = harness
.run(&["user", "find", "ilubenets"])
.assert()
.success();
let stdout = String::from_utf8(output.get_output().stdout.clone()).expect("utf-8");
assert!(stdout.ends_with("shown 1 of 4\n"), "{stdout}");
}
#[tokio::test]
async fn a_search_that_hit_its_ceiling_says_so() {
let harness = Harness::new().await;
Mock::given(method("GET"))
.and(path("/v3/users"))
.respond_with(
ResponseTemplate::new(200)
.set_body_json(fixture("users.json"))
.append_header("X-Total-Count", "900"),
)
.mount(&harness.server)
.await;
let output = harness
.run(&["user", "find", "nobody", "--scan", "2"])
.assert()
.success();
let stderr = String::from_utf8(output.get_output().stderr.clone()).expect("utf-8");
assert!(stderr.contains("searched 4 of 900"), "{stderr}");
assert!(stderr.contains("--scan"), "{stderr}");
}
#[tokio::test]
async fn a_page_is_asked_for_by_number() {
let harness = Harness::new().await;
Mock::given(method("GET"))
.and(path("/v3/users"))
.and(query_param("page", "2"))
.and(query_param("perPage", "10"))
.respond_with(
ResponseTemplate::new(200)
.set_body_json(fixture("users.json"))
.append_header("X-Total-Count", "4"),
)
.mount(&harness.server)
.await;
harness
.run(&["user", "list", "--page", "2", "--limit", "10"])
.assert()
.success();
}
#[tokio::test]
async fn an_unknown_login_exits_four() {
let harness = Harness::new().await;
Mock::given(method("GET"))
.and(path("/v3/users/me"))
.respond_with(ResponseTemplate::new(404).set_body_json(serde_json::json!({
"errorMessages": ["пользователь me не существует."],
"statusCode": 404
})))
.mount(&harness.server)
.await;
harness.run(&["user", "get", "me"]).assert().code(4);
}