fix(test): remove hidden HTTP client startup overhead

Disable proxy discovery for the hot test HTTP clients so nextest no longer
pays macOS system proxy lookup on repeated reqwest client creation.

Also keep the approved OAuth loopback cleanup and replace GitHub test key
generation with a checked-in PEM fixture.
This commit is contained in:
Bryan Helmkamp 2026-04-04 21:25:51 -04:00
parent aa5047c509
commit 8a2d00591b
11 changed files with 141 additions and 88 deletions

View file

@ -394,10 +394,21 @@ impl HookExecutorImpl {
/// Build a reqwest client for the given TLS mode.
fn build_http_client(tls: TlsMode) -> reqwest::Client {
let accept_invalid = matches!(tls, TlsMode::NoVerify | TlsMode::Off);
reqwest::Client::builder()
.danger_accept_invalid_certs(accept_invalid)
.build()
.unwrap_or_default()
#[cfg(test)]
{
return reqwest::Client::builder()
.danger_accept_invalid_certs(accept_invalid)
.no_proxy()
.build()
.unwrap_or_default();
}
#[cfg(not(test))]
{
reqwest::Client::builder()
.danger_accept_invalid_certs(accept_invalid)
.build()
.unwrap_or_default()
}
}
/// Execute an HTTP hook: POST context JSON and parse the response.

View file

@ -1413,6 +1413,10 @@ async fn test_models(
mod tests {
use super::*;
fn test_http_client() -> reqwest::Client {
reqwest::Client::builder().no_proxy().build().unwrap()
}
// --- parse_option ---
#[test]
@ -1618,7 +1622,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let resp = test_model_via_server(&client, &server.url(""), "test-model")
.await
.unwrap();
@ -1646,7 +1650,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let resp = test_model_via_server(&client, &server.url(""), "test-model")
.await
.unwrap();
@ -1669,7 +1673,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let result = test_model_via_server(&client, &server.url(""), "bad-model").await;
assert!(result.is_err());
}
@ -1701,7 +1705,7 @@ mod tests {
}).to_string());
}).await;
let client = reqwest::Client::new();
let client = test_http_client();
let models = fetch_models_from_server(&client, &server.url(""), None)
.await
.unwrap();
@ -1753,7 +1757,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let models = fetch_models_from_server(&client, &server.url(""), Some("anthropic"))
.await
.unwrap();
@ -1772,7 +1776,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let result = fetch_models_from_server(&client, &server.url(""), None).await;
assert!(result.is_err());
}
@ -1801,7 +1805,7 @@ mod tests {
.await;
let server = ServerConnection {
client: reqwest::Client::new(),
client: test_http_client(),
base_url: mock_server.url(""),
};
@ -1841,7 +1845,7 @@ data: {\"type\":\"finish\",\"finish_reason\":\"stop\",\"usage\":{\"input_tokens\
.await;
let server = ServerConnection {
client: reqwest::Client::new(),
client: test_http_client(),
base_url: mock_server.url(""),
};

View file

@ -2201,7 +2201,6 @@ mod tests {
"beta header should contain fast-mode header, got: {beta}"
);
}
#[test]
fn beta_header_includes_both_cache_and_fast_mode() {
let result = build_beta_header(None, true, true, false);

View file

@ -229,6 +229,10 @@ mod tests {
use futures::StreamExt;
use httpmock::prelude::*;
fn test_http_client() -> reqwest::Client {
reqwest::Client::builder().no_proxy().build().unwrap()
}
fn make_request() -> Request {
Request {
model: "test-model".to_string(),
@ -270,7 +274,7 @@ data: {\"type\":\"text_delta\",\"delta\":\" world\",\"text_id\":null}\n\
.body(sse_body);
});
let adapter = Adapter::new(reqwest::Client::new(), server.base_url(), "test-provider");
let adapter = Adapter::new(test_http_client(), server.base_url(), "test-provider");
let mut stream = adapter.stream(&make_request()).await.unwrap();
@ -323,7 +327,7 @@ data: {\"type\":\"text_delta\",\"delta\":\" world\",\"text_id\":null}\n\
.json_body(response_json);
});
let adapter = Adapter::new(reqwest::Client::new(), server.base_url(), "test-provider");
let adapter = Adapter::new(test_http_client(), server.base_url(), "test-provider");
let response = adapter.complete(&make_request()).await.unwrap();
@ -346,7 +350,7 @@ data: {\"type\":\"text_delta\",\"delta\":\" world\",\"text_id\":null}\n\
then.status(502).body("Bad Gateway");
});
let adapter = Adapter::new(reqwest::Client::new(), server.base_url(), "test-provider");
let adapter = Adapter::new(test_http_client(), server.base_url(), "test-provider");
let err = adapter.complete(&make_request()).await.unwrap_err();
match &err {
@ -367,7 +371,7 @@ data: {\"type\":\"text_delta\",\"delta\":\" world\",\"text_id\":null}\n\
then.status(502).body("Bad Gateway");
});
let adapter = Adapter::new(reqwest::Client::new(), server.base_url(), "test-provider");
let adapter = Adapter::new(test_http_client(), server.base_url(), "test-provider");
let result = adapter.stream(&make_request()).await;
let Err(err) = result else {
@ -401,7 +405,7 @@ data: {\"type\":\"stream_start\"}\n\
.body(sse_body);
});
let adapter = Adapter::new(reqwest::Client::new(), server.base_url(), "test-provider");
let adapter = Adapter::new(test_http_client(), server.base_url(), "test-provider");
let mut stream = adapter.stream(&make_request()).await.unwrap();
@ -447,7 +451,7 @@ data: {\"type\":\"stream_start\"}\n\
#[test]
fn adapter_name() {
let adapter = Adapter::new(reqwest::Client::new(), "http://localhost", "anthropic");
let adapter = Adapter::new(test_http_client(), "http://localhost", "anthropic");
assert_eq!(adapter.name(), "anthropic");
}
}

View file

@ -18,13 +18,28 @@ pub struct HttpApi {
}
impl HttpApi {
fn build_client(timeout: AdapterTimeout) -> reqwest::Client {
#[cfg(test)]
{
return reqwest::Client::builder()
.connect_timeout(Duration::from_secs_f64(timeout.connect))
.no_proxy()
.build()
.unwrap_or_default();
}
#[cfg(not(test))]
{
reqwest::Client::builder()
.connect_timeout(Duration::from_secs_f64(timeout.connect))
.build()
.unwrap_or_default()
}
}
#[must_use]
pub fn new(api_key: impl Into<String>, base_url: impl Into<String>) -> Self {
let timeout = AdapterTimeout::default();
let client = reqwest::Client::builder()
.connect_timeout(Duration::from_secs_f64(timeout.connect))
.build()
.unwrap_or_default();
let client = Self::build_client(timeout);
Self {
api_key: api_key.into(),
base_url: base_url.into(),
@ -37,10 +52,7 @@ impl HttpApi {
#[must_use]
pub fn with_timeout(mut self, timeout: AdapterTimeout) -> Self {
self.client = reqwest::Client::builder()
.connect_timeout(Duration::from_secs_f64(timeout.connect))
.build()
.unwrap_or_default();
self.client = Self::build_client(timeout);
self.request_timeout = timeout.request.map(Duration::from_secs_f64);
self.stream_read_timeout = timeout.stream_read.map(Duration::from_secs_f64);
self

View file

@ -1223,7 +1223,6 @@ mod tests {
assert!(adapter.project_id.is_none());
assert!(adapter.http.default_headers.is_empty());
}
#[test]
fn audio_content_produces_text_fallback() {
let msg = Message {

View file

@ -224,7 +224,7 @@ fn validate_callback_path(path: &str) -> Result<(), String> {
}
fn build_redirect_uri(port: u16, path: &str) -> String {
format!("http://localhost:{port}{path}")
format!("http://127.0.0.1:{port}{path}")
}
pub async fn start_callback_server(
@ -234,7 +234,7 @@ pub async fn start_callback_server(
) -> Result<(u16, oneshot::Receiver<Result<String, String>>), String> {
validate_callback_path(path)?;
let listener = TcpListener::bind(format!("localhost:{port}"))
let listener = TcpListener::bind(("127.0.0.1", port))
.await
.map_err(|e| format!("Failed to bind callback server: {e}"))?;
let actual_port = listener
@ -414,6 +414,10 @@ pub async fn run_browser_flow(
mod tests {
use super::*;
fn test_http_client() -> reqwest::Client {
reqwest::Client::builder().no_proxy().build().unwrap()
}
// -----------------------------------------------------------------------
// Phase 1: PKCE
// -----------------------------------------------------------------------
@ -554,13 +558,13 @@ mod tests {
fn build_redirect_uri_constructs_expected_uri() {
assert_eq!(
build_redirect_uri(1455, "/auth/callback"),
"http://localhost:1455/auth/callback"
"http://127.0.0.1:1455/auth/callback"
);
assert_eq!(
build_redirect_uri(8080, "/oauth/done"),
"http://localhost:8080/oauth/done"
"http://127.0.0.1:8080/oauth/done"
);
assert_eq!(build_redirect_uri(1, "/"), "http://localhost:1/");
assert_eq!(build_redirect_uri(1, "/"), "http://127.0.0.1:1/");
}
// -----------------------------------------------------------------------
@ -595,7 +599,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let tokens = exchange_code_for_tokens(
&client,
&server.url(""),
@ -633,7 +637,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let tokens = exchange_code_for_tokens(
&client,
&server.url(""),
@ -662,7 +666,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let err = exchange_code_for_tokens(
&client,
&server.url(""),
@ -706,7 +710,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let tokens =
refresh_access_token(&client, &server.url(""), "test-client", "old-refresh-tok")
.await
@ -731,7 +735,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let err = refresh_access_token(&client, &server.url(""), "test-client", "expired-tok")
.await
.unwrap_err();
@ -752,10 +756,10 @@ mod tests {
assert_ne!(port, 0);
let client = reqwest::Client::new();
let client = test_http_client();
client
.get(format!(
"http://localhost:{port}{callback_path}?code=abc&state=test-state"
"http://127.0.0.1:{port}{callback_path}?code=abc&state=test-state"
))
.send()
.await
@ -772,10 +776,10 @@ mod tests {
.await
.unwrap();
let client = reqwest::Client::new();
let client = test_http_client();
let resp = client
.get(format!(
"http://localhost:{port}{callback_path}?code=abc&state=test-state"
"http://127.0.0.1:{port}{callback_path}?code=abc&state=test-state"
))
.send()
.await
@ -791,10 +795,10 @@ mod tests {
.await
.unwrap();
let client = reqwest::Client::new();
let client = test_http_client();
let resp = client
.get(format!(
"http://localhost:{port}{callback_path}?code=abc&state=wrong-state"
"http://127.0.0.1:{port}{callback_path}?code=abc&state=wrong-state"
))
.send()
.await
@ -810,10 +814,10 @@ mod tests {
.await
.unwrap();
let client = reqwest::Client::new();
let client = test_http_client();
let resp = client
.get(format!(
"http://localhost:{port}{callback_path}?code=abc&state=test-state"
"http://127.0.0.1:{port}{callback_path}?code=abc&state=test-state"
))
.send()
.await

View file

@ -286,6 +286,10 @@ mod tests {
use axum::http::Request;
use tower::ServiceExt;
fn test_http_client() -> reqwest::Client {
reqwest::Client::builder().no_proxy().build().unwrap()
}
// -----------------------------------------------------------------------
// verify_signature
// -----------------------------------------------------------------------
@ -407,7 +411,7 @@ mod tests {
let body = b"{}";
let sig = compute_signature(secret, body);
let client = reqwest::Client::new();
let client = test_http_client();
let resp = client
.post(format!("http://127.0.0.1:{port}/webhooks/github"))
.header("x-hub-signature-256", sig)

View file

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDLrOym7SsuLj2K
yFR9UC3jhPUDgCVC1yWa2XF7Hl2LoCGuUIyxFJwUyoWGFgkWpQKCKmNqp1AEyJI3
LEOQTBT9wqLBImuZ2J7vtDCYhMWyzMH0vLatAqcDTvPfDcdu9B27VVU1TGfiNe7t
EXP5jfjNvi7AZKdwEYnZUeE4rC4fmraQy4XY9jSm/l9hEq4/RgNg6Pnjr8EJMpxM
L8CJGLnYcJA7k4wD6VwpCQoI2vOPjfEiffkAK7Ul264/ex+hWDLycqvpeL4dJ8ZM
PGOpjuG2z9dElP50pTTycAO5wXkm+luTDVYXgtSQAs5qA4mdMMvsWUCfvV0hxer6
aaa0EVBlAgMBAAECggEAKBjFBh/OzmqgBwBlUb5FKnN0YNoLe9srNg70vk4+EEzY
FJ8a84mhKJ6uJrWT2HdnxQRfShHiOO7bii0WqAOyZjq5G9iQ4lq4/2uz3XLWENsq
m+nC9NB+3LHgZNsrlfZNHCIygimmkewYO2eiM1D12FtGjO3D4NYzEyuBcUzET8gl
k0ZbBCYee6D0cRhABlg8c35ZYQ7CGeP5eUnlPMXxh/GR3VTXs5ZXeuX2G0na6COT
t3AM0xia9FJiCw73sCb3M5xVhu+61UHXQFU2gqbUZq51B/7wiEhVmIqxoU9IUIgd
UIVGUAGfPkOmZcEhIF4Kv3tEzU+hgX9aReF7hNKXAQKBgQDq6Qy9s9HdThiu2hGV
sUF7g4uglYSPQBwddNdO+x/EgvIoij91Qh44/XF5DbHy2hUVMLJivBaO9g0xjBEL
ZAhFzYEZuKTvGEYzZw9T2K1WE0lSbk+z3kp6+nasOxrtrk63oAPTB71yiGi44S2r
eqov19s6519Qpji1W8ApW063oQKBgQDd9gDFKKa6wpYVH+6KmBeaUrGUhnoujujz
fIWX4DapGoqhpx2fTOJe8vlyPbXqfG/akzvEjd21voXHeeR9GfsOOqjtW9v89Aq3
Pfqli6VdLcRFxT81kgL87/3m6WvmT6sq0mfIuIwiVul6bCdIBWoYOGffiGu5NCS6
BSFi3yCSRQKBgQCLwWbRHcBHl4Tb0eUQV8qLfzF8sjeROiT/6VmHJaQ6t2T2dXlX
e6SbZz0xNdKeltxgJP6b+ya4mu4yghBJ5JN/Y8ng0Zden+R0BGZ8DbbiNMs0fWhx
rFhHXedohCl7Km6ulEZyMHKnRzx2cZFIKcxCdnt5SdnNE3c9fn6OnEHywQKBgQC0
RBk4Bt3yjBqsKXTopsF0mniS8ezFZ1eWeKlfQb/i8yVoSHtsZ1rqVld1Ct12BX4q
fK1r4vQPqR6pdTu2xqT5V3be3135QJJ7ZCDu1k2FMahYKew+K8m1d4w0P5tcP5P6
gUu83vUg5olU3gXBHnSeGyFxkDA9CDZTxdrpm+GuKQKBgQCHPw1CBsijUwrSOEqu
4U4DkvrchEHiix3BMv6rYrDBFYu+NbDJEEkLORjN0uIV5Iq++zwewCYq1QzIdX/a
ZRBsajgkhzM5Cw8BtsRz0NgT0wsw2gk4NnViy/pLUzXWfwVpFsMTgNpJ/ya3/giU
imhV/k13UHJZzwEx/cR3JiK1uQ==
-----END PRIVATE KEY-----

View file

@ -498,21 +498,12 @@ mod tests {
use crate::Issue;
use fabro_github::GitHubAppCredentials;
fn test_http_client() -> reqwest::Client {
reqwest::Client::builder().no_proxy().build().unwrap()
}
fn test_rsa_key() -> String {
use std::process::Command;
let output = Command::new("openssl")
.args([
"genpkey",
"-algorithm",
"RSA",
"-pkeyopt",
"rsa_keygen_bits:2048",
])
.output()
.expect("openssl should be available");
assert!(output.status.success(), "openssl keygen failed");
String::from_utf8(output.stdout).unwrap()
include_str!("fixtures/github-app-test-key.pem").to_string()
}
// -----------------------------------------------------------------------
@ -535,7 +526,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let result = execute_github_graphql(
&client,
"test-token",
@ -561,7 +552,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let err = execute_github_graphql(
&client,
"bad-token",
@ -587,7 +578,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let err = execute_github_graphql(
&client,
"token",
@ -616,7 +607,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
execute_github_graphql(
&client,
"my-token",
@ -640,7 +631,7 @@ mod tests {
app_id: "test-app".to_string(),
private_key_pem: pem,
},
reqwest::Client::new(),
test_http_client(),
"owner".to_string(),
"repo".to_string(),
1,
@ -768,7 +759,6 @@ mod tests {
then.status(201).body(r#"{"token": "ghs_test"}"#);
})
.await;
// Org query returns null → fall back to user
server
.mock_async(|when, then| {
when.method("POST")
@ -777,7 +767,6 @@ mod tests {
then.status(200).body(r#"{"data": {"organization": null}}"#);
})
.await;
// User query succeeds
server
.mock_async(|when, then| {
when.method("POST")
@ -787,7 +776,6 @@ mod tests {
.body(r#"{"data": {"user": {"projectV2": {"id": "PVT_user1"}}}}"#);
})
.await;
// Items page (empty)
server
.mock_async(|when, then| {
when.method("POST")
@ -894,7 +882,6 @@ mod tests {
then.status(201).body(r#"{"token": "ghs_test"}"#);
})
.await;
// Resolve project node ID (org path)
server
.mock_async(|when, then| {
when.method("POST")
@ -908,7 +895,6 @@ mod tests {
when.method("POST").path("/graphql").body_includes("field(name:");
then.status(200).body(r#"{"data": {"node": {"field": {"id": "FLD_1", "options": [{"id": "opt-done", "name": "Done"}, {"id": "opt-todo", "name": "Todo"}]}}}}"#);
}).await;
// Update mutation
server.mock_async(|when, then| {
when.method("POST").path("/graphql").body_includes("updateProjectV2ItemFieldValue");
then.status(200).body(r#"{"data": {"updateProjectV2ItemFieldValue": {"projectV2Item": {"id": "PVTI_item1"}}}}"#);
@ -937,7 +923,6 @@ mod tests {
then.status(201).body(r#"{"token": "ghs_test"}"#);
})
.await;
// Resolve project node ID
server
.mock_async(|when, then| {
when.method("POST")

View file

@ -355,6 +355,9 @@ impl Tracker for LinearTracker {
#[cfg(test)]
mod tests {
use super::*;
fn test_http_client() -> reqwest::Client {
reqwest::Client::builder().no_proxy().build().unwrap()
}
fn mock_config(server_url: &str) -> LinearOptions {
LinearOptions {
@ -591,7 +594,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let result = execute_graphql(
&client,
&config,
@ -617,7 +620,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let err = execute_graphql(
&client,
&config,
@ -642,7 +645,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let err = execute_graphql(
&client,
&config,
@ -668,7 +671,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
let err = execute_graphql(&client, &config, "query { bad }", serde_json::json!({}))
.await
.unwrap_err();
@ -691,7 +694,7 @@ mod tests {
})
.await;
let client = reqwest::Client::new();
let client = test_http_client();
execute_graphql(
&client,
&config,
@ -721,7 +724,7 @@ mod tests {
})
.await;
let tracker = LinearTracker::new(config, reqwest::Client::new(), "proj".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "proj".to_string());
let id = tracker.fetch_viewer_id().await.unwrap();
assert_eq!(id, "user-abc");
}
@ -738,7 +741,7 @@ mod tests {
})
.await;
let tracker = LinearTracker::new(config, reqwest::Client::new(), "proj".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "proj".to_string());
let err = tracker.fetch_viewer_id().await.unwrap_err();
assert!(err.contains("401"), "got: {err}");
}
@ -760,7 +763,7 @@ mod tests {
})
.await;
let tracker = LinearTracker::new(config, reqwest::Client::new(), "proj".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "proj".to_string());
let issue = make_test_issue();
tracker.create_comment(&issue, "Hello world").await.unwrap();
}
@ -778,7 +781,7 @@ mod tests {
})
.await;
let tracker = LinearTracker::new(config, reqwest::Client::new(), "proj".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "proj".to_string());
let issue = make_test_issue();
let err = tracker.create_comment(&issue, "Hello").await.unwrap_err();
assert!(err.contains("success: false"), "got: {err}");
@ -811,7 +814,7 @@ mod tests {
})
.await;
let tracker = LinearTracker::new(config, reqwest::Client::new(), "proj".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "proj".to_string());
let issue = make_test_issue();
tracker.update_issue_state(&issue, "Done").await.unwrap();
@ -832,7 +835,7 @@ mod tests {
})
.await;
let tracker = LinearTracker::new(config, reqwest::Client::new(), "proj".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "proj".to_string());
let issue = make_test_issue();
let err = tracker
.update_issue_state(&issue, "Nonexistent")
@ -868,7 +871,7 @@ mod tests {
})
.await;
let tracker = LinearTracker::new(config, reqwest::Client::new(), "my-project".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "my-project".to_string());
let issues = tracker
.fetch_candidate_issues(&["In Progress"])
.await
@ -929,7 +932,7 @@ mod tests {
})
.await;
let tracker = LinearTracker::new(config, reqwest::Client::new(), "proj".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "proj".to_string());
let issues = tracker.fetch_candidate_issues(&["Todo"]).await.unwrap();
assert_eq!(issues.len(), 2);
@ -958,7 +961,7 @@ mod tests {
})
.await;
let tracker = LinearTracker::new(config, reqwest::Client::new(), "proj".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "proj".to_string());
let issues = tracker.fetch_candidate_issues(&["Todo"]).await.unwrap();
assert!(issues.is_empty());
@ -1000,7 +1003,7 @@ mod tests {
})
.await;
let tracker = LinearTracker::new(config, reqwest::Client::new(), "proj".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "proj".to_string());
let issues = tracker
.fetch_issues_by_ids(&["id-a", "id-b"])
.await
@ -1060,7 +1063,7 @@ mod tests {
})
.await;
let tracker = LinearTracker::new(config, reqwest::Client::new(), "proj".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "proj".to_string());
let issues = tracker.fetch_issues_by_ids(&id_refs).await.unwrap();
assert_eq!(issues.len(), 51);
@ -1071,7 +1074,7 @@ mod tests {
#[tokio::test]
async fn fetch_issues_by_ids_empty() {
let config = LinearOptions::new("unused".to_string());
let tracker = LinearTracker::new(config, reqwest::Client::new(), "proj".to_string());
let tracker = LinearTracker::new(config, test_http_client(), "proj".to_string());
let issues = tracker.fetch_issues_by_ids(&[]).await.unwrap();
assert!(issues.is_empty());
}