mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-15 23:32:46 +00:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
41f0f367b3
12 changed files with 143 additions and 90 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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(""),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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-----
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12139,8 +12139,8 @@ async fn e2e_stall_watchdog_triggers_from_dot_parsed_pipeline() {
|
|||
// Verify the canonical watchdog timeout envelope was emitted.
|
||||
let collected = events.lock().unwrap();
|
||||
assert!(
|
||||
collected.iter().any(|e| e.contains("watchdog.timeout")),
|
||||
"expected watchdog.timeout event in: {collected:?}"
|
||||
collected.iter().any(|e| e.contains("StallWatchdogTimeout")),
|
||||
"expected StallWatchdogTimeout event in: {collected:?}"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue