use std::net::TcpListener;
use std::path::Path;
use super::{LysSignIn, read_secret};
use crate::door::config::Lys;
type TestResult = Result<(), Box<dyn std::error::Error>>;
const CREDENTIAL: &str = "issued-credential-never-shown";
fn lys(issuer: &str, secret_file: &Path) -> Lys {
Lys {
issuer: issuer.to_owned(),
client_id: "lys-client.haematite".to_owned(),
secret_file: secret_file.to_path_buf(),
redirect: "https://studio.example/callback".to_owned(),
}
}
#[test]
fn a_credential_file_is_read_as_its_one_line() -> TestResult {
let directory = tempfile::tempdir()?;
let path = directory.path().join("secret");
std::fs::write(&path, format!("{CREDENTIAL}\n"))?;
read_secret(&path)?;
std::fs::write(&path, format!("{CREDENTIAL}\nsecond\n"))?;
let refused = read_secret(&path)
.err()
.ok_or("a two-line credential was taken")?;
assert!(refused.contains("not one line"), "{refused}");
assert!(
!refused.contains(CREDENTIAL),
"the credential was shown: {refused}"
);
std::fs::write(&path, "x".repeat(5000))?;
assert!(
read_secret(&path).is_err(),
"an over-long credential was taken"
);
Ok(())
}
#[test]
fn a_missing_credential_file_is_named() -> TestResult {
let directory = tempfile::tempdir()?;
let path = directory.path().join("absent");
let refused = read_secret(&path).err().ok_or("an absent file was read")?;
assert!(refused.contains(&path.display().to_string()), "{refused}");
Ok(())
}
#[test]
fn an_unreachable_issuer_is_lys_could_not_be_asked() -> TestResult {
let directory = tempfile::tempdir()?;
let path = directory.path().join("secret");
std::fs::write(&path, CREDENTIAL)?;
let listener = TcpListener::bind("127.0.0.1:0")?;
let port = listener.local_addr()?.port();
drop(listener);
let refused = LysSignIn::connect(&lys(&format!("http://127.0.0.1:{port}/"), &path))
.err()
.ok_or("an unreachable Lys was connected")?;
assert!(refused.starts_with("lys_could_not_be_asked"), "{refused}");
assert!(
!refused.contains(CREDENTIAL),
"the credential was shown: {refused}"
);
Ok(())
}