use hackerone_api::{Client, HacktivityQuery, PageQuery};
fn live_client() -> Option<Client> {
let identifier = std::env::var("HACKERONE_API_IDENTIFIER").ok()?;
let token = std::env::var("HACKERONE_API_TOKEN").ok()?;
if identifier.is_empty() || token.is_empty() {
return None;
}
Some(Client::new(identifier, token))
}
#[test]
#[ignore = "hits the live HackerOne API; run with --ignored and credentials"]
fn my_reports_round_trips() {
let Some(client) = live_client() else {
eprintln!("skipping: HACKERONE_API_IDENTIFIER / HACKERONE_API_TOKEN not set");
return;
};
let page = client
.my_reports(&PageQuery::new().page(1, 25))
.expect("my_reports() against the live API");
eprintln!("{} report(s) on page 1", page.len());
for (id, report) in page.ids().zip(page.items()) {
eprintln!(
" {} {:<12} {:?}",
id.unwrap_or("?"),
report.state.as_deref().unwrap_or("?"),
report.title.as_deref().unwrap_or("(untitled)")
);
}
}
#[test]
#[ignore = "hits the live HackerOne API; run with --ignored and credentials"]
fn my_report_fetches_a_specific_report() {
let Some(client) = live_client() else {
eprintln!("skipping: credentials not set");
return;
};
let id = match std::env::var("H1_REPORT_ID") {
Ok(id) if !id.is_empty() => id,
_ => {
let page = client
.my_reports(&PageQuery::new().page(1, 1))
.expect("my_reports()");
let first = page.ids().next().flatten().map(str::to_string);
match first {
Some(id) => id,
None => {
eprintln!("no reports on the account — nothing to fetch");
return;
}
}
}
};
let report = client
.my_report(&id)
.unwrap_or_else(|e| panic!("my_report({id}) failed: {e}"));
eprintln!(
"report {}: state={:?} title={:?}",
id,
report.state.as_deref().unwrap_or("?"),
report.title.as_deref().unwrap_or("(untitled)")
);
assert!(
report.title.as_deref().is_some_and(|t| !t.is_empty()),
"report {id} had no title: {report:?}"
);
}
#[test]
#[ignore = "hits the live HackerOne API; run with --ignored and credentials"]
fn balance_round_trips() {
let Some(client) = live_client() else {
eprintln!("skipping: credentials not set");
return;
};
let balance = client.balance().expect("balance() against the live API");
eprintln!("balance = {:?}", balance.balance);
assert!(balance.balance.is_some(), "no balance returned");
}
#[test]
#[ignore = "hits the live HackerOne API; run with --ignored and credentials"]
fn earnings_round_trips() {
let Some(client) = live_client() else {
eprintln!("skipping: credentials not set");
return;
};
let page = client
.earnings(&PageQuery::new().page(1, 25))
.expect("earnings() against the live API");
eprintln!("{} earning(s)", page.len());
}
#[test]
#[ignore = "hits the live HackerOne API; run with --ignored and credentials"]
fn hacktivity_is_publicly_readable() {
let client = live_client().unwrap_or_else(Client::anonymous);
let page = client
.hacktivity(&HacktivityQuery::new().page(1, 3))
.expect("hacktivity() against the live API");
eprintln!("{} hacktivity item(s)", page.len());
assert!(!page.is_empty(), "expected at least one hacktivity item");
}