use uselesskey_core::{Factory, Seed};
use uselesskey_hmac::{DOMAIN_HMAC_SECRET, HmacFactoryExt, HmacSpec};
use uselesskey_test_support::{TestResult, require_ok, require_some};
fn det_fx(seed_label: &str) -> TestResult<Factory> {
Ok(Factory::deterministic(require_ok(
Seed::from_env_value(seed_label),
"valid deterministic seed",
)?))
}
#[test]
fn domain_constant_is_stable() {
assert_eq!(DOMAIN_HMAC_SECRET, "uselesskey:hmac:secret");
}
#[test]
fn clone_preserves_secret_and_identity() -> TestResult<()> {
let fx = det_fx("hmac-clone")?;
let original = fx.hmac("issuer", HmacSpec::hs256());
let cloned = original.clone();
assert_eq!(original.secret_bytes(), cloned.secret_bytes());
assert_eq!(original.label(), cloned.label());
assert_eq!(original.spec(), cloned.spec());
Ok(())
}
#[test]
fn clone_chain_preserves_secret() -> TestResult<()> {
let fx = det_fx("hmac-clone-chain")?;
let original = fx.hmac("issuer", HmacSpec::hs384());
let chained = original.clone().clone().clone();
assert_eq!(original.secret_bytes(), chained.secret_bytes());
Ok(())
}
#[test]
fn debug_omits_raw_secret_bytes() -> TestResult<()> {
let fx = det_fx("hmac-debug-secret")?;
let secret = fx.hmac("issuer", HmacSpec::hs256());
let bytes_hex = secret
.secret_bytes()
.iter()
.map(|b| format!("{b:02x}"))
.collect::<String>();
let dbg = format!("{secret:?}");
assert!(!dbg.contains(&bytes_hex));
let bytes_dbg = format!("{:?}", secret.secret_bytes());
assert!(!dbg.contains(&bytes_dbg));
Ok(())
}
#[cfg(feature = "jwk")]
#[test]
fn jwk_use_field_is_sig() -> TestResult<()> {
let fx = det_fx("hmac-jwk-use")?;
for spec in [HmacSpec::hs256(), HmacSpec::hs384(), HmacSpec::hs512()] {
let secret = fx.hmac("issuer", spec);
let val = secret.jwk().to_value();
assert_eq!(val["use"], "sig", "use field for {spec:?}");
assert_eq!(val["kty"], "oct", "kty field for {spec:?}");
}
Ok(())
}
#[cfg(feature = "jwk")]
#[test]
fn jwks_keys_array_has_exactly_one_entry() -> TestResult<()> {
let fx = det_fx("hmac-jwks-cardinality")?;
let secret = fx.hmac("issuer", HmacSpec::hs256());
let val = secret.jwks().to_value();
let keys = require_some(val["keys"].as_array(), "keys array")?;
assert_eq!(keys.len(), 1);
Ok(())
}