#![cfg(feature = "github")]
use std::sync::{Arc, Mutex};
use std::time::Duration;
use self_update::backends::github;
use self_update::http_client::{HeaderMap, HttpClient, HttpResponse};
struct CannedResponse;
impl HttpResponse for CannedResponse {
fn headers(&self) -> &HeaderMap {
static EMPTY: std::sync::OnceLock<HeaderMap> = std::sync::OnceLock::new();
EMPTY.get_or_init(HeaderMap::new)
}
fn body(self: Box<Self>) -> Box<dyn std::io::Read> {
Box::new(std::io::Cursor::new(b"[]".to_vec()))
}
}
struct AuthRecorder(Arc<Mutex<Vec<Option<String>>>>);
impl HttpClient for AuthRecorder {
fn get(
&self,
_url: &str,
headers: &HeaderMap,
_timeout: Option<Duration>,
) -> self_update::Result<Box<dyn HttpResponse>> {
self.0.lock().unwrap().push(
headers
.get(self_update::http::header::AUTHORIZATION)
.map(|v| v.to_str().expect("a header value is ASCII").to_string()),
);
Ok(Box::new(CannedResponse))
}
}
fn auth_header_of(f: impl FnOnce(Arc<dyn HttpClient>)) -> Option<String> {
let seen = Arc::new(Mutex::new(Vec::new()));
f(Arc::new(AuthRecorder(seen.clone())));
let seen = seen.lock().unwrap();
assert_eq!(
seen.len(),
1,
"exactly one request must have gone through the transport, got {seen:?}"
);
seen[0].clone()
}
#[test]
fn nothing_set_leaves_the_request_unauthenticated() {
unsafe {
std::env::remove_var("GH_TOKEN");
std::env::remove_var("GITHUB_TOKEN");
}
let mut list = github::ReleaseList::configure();
list.repo_owner("o").repo_name("r");
assert!(!list.has_auth_token());
list.auth_token_from_env();
assert!(
!list.has_auth_token(),
"with neither GH_TOKEN nor GITHUB_TOKEN set, auth_token_from_env() must leave no token \
configured"
);
let header = auth_header_of(|client| {
let _ = list.http_client(client).build().unwrap().fetch();
});
assert_eq!(
header, None,
"the request must go out with no Authorization header when nothing was set"
);
let mut upd = github::Update::configure();
upd.repo_owner("o")
.repo_name("r")
.bin_name("app")
.current_version("0.1.0");
assert!(!upd.has_auth_token());
upd.auth_token_from_env();
assert!(
!upd.has_auth_token(),
"with neither GH_TOKEN nor GITHUB_TOKEN set, auth_token_from_env() must leave no token \
configured"
);
let header = auth_header_of(|client| {
let _ = upd
.http_client(client)
.build()
.unwrap()
.get_latest_release();
});
assert_eq!(
header, None,
"the request must go out with no Authorization header when nothing was set"
);
}