#![allow(dead_code)]
use std::time::Duration;
pub fn client_for(server: &wiremock::MockServer) -> linear_api::LinearClient {
linear_api::LinearClient::builder()
.api_key("test-key")
.endpoint(server.uri())
.retry(linear_api::RetryConfig {
max_attempts: 3,
base_backoff: Duration::from_millis(5),
max_rate_limit_wait: Duration::from_secs(2),
retry_mutations_on_transient: false,
})
.build()
.expect("test client builds")
}
pub fn graphql_ok(data: serde_json::Value) -> wiremock::ResponseTemplate {
wiremock::ResponseTemplate::new(200).set_body_json(serde_json::json!({ "data": data }))
}
pub fn graphql_errors(status: u16, errors: serde_json::Value) -> wiremock::ResponseTemplate {
wiremock::ResponseTemplate::new(status).set_body_json(serde_json::json!({ "errors": errors }))
}
pub fn rate_limited(reset_epoch_ms: i128) -> wiremock::ResponseTemplate {
wiremock::ResponseTemplate::new(400)
.set_body_json(serde_json::json!({
"errors": [{
"message": "rate limited",
"extensions": { "code": "RATELIMITED" }
}]
}))
.insert_header("X-RateLimit-Requests-Remaining", "0")
.insert_header(
"X-RateLimit-Requests-Reset",
reset_epoch_ms.to_string().as_str(),
)
}
pub struct Operation(pub &'static str);
impl wiremock::Match for Operation {
fn matches(&self, request: &wiremock::Request) -> bool {
let Ok(body) = serde_json::from_slice::<serde_json::Value>(&request.body) else {
return false;
};
body.get("query")
.and_then(serde_json::Value::as_str)
.is_some_and(|query| {
query.contains(&format!("query {}", self.0))
|| query.contains(&format!("mutation {}", self.0))
})
}
}