use keyhog_scanner::testing::{
caesar_credential_shape_gate, caesar_shift, is_source_code_path, CaesarDecoder,
};
#[test]
fn rot13_round_trip() {
let s = "AKIA64ABDEFSEWKRUMSEK1NR";
let r13 = caesar_shift(s, 13);
assert_eq!(caesar_shift(&r13, 13), s);
}
#[test]
fn shift_preserves_non_letters() {
assert_eq!(caesar_shift("AB-CD_12", 1), "BC-DE_12");
}
#[test]
fn caesar_credential_shape_gate_requires_digit_and_run() {
assert!(caesar_credential_shape_gate("AKIA64ABDEFSEWKR"));
assert!(!caesar_credential_shape_gate("HELLOWORLDFOOBAR")); assert!(!caesar_credential_shape_gate("12-34-56-78-")); }
#[test]
fn is_source_code_path_matches_known_extensions() {
assert!(is_source_code_path(Some("src/foo.rs")));
assert!(is_source_code_path(Some("/abs/path/bar.py")));
assert!(is_source_code_path(Some("RELATIVE.GO")));
assert!(is_source_code_path(Some("docs/README.md")));
assert!(!is_source_code_path(Some("config/secrets.env")));
assert!(!is_source_code_path(Some("blob.bin")));
assert!(!is_source_code_path(None));
}
#[test]
fn source_code_path_skips_caesar_decoder() {
use keyhog_core::{Chunk, ChunkMetadata};
let chunk = Chunk {
data: "//! Source trait and chunk types: pluggable input backends.".into(),
metadata: ChunkMetadata {
base_offset: 0,
base_line: 0,
source_type: "filesystem".into(),
path: Some("crates/core/src/source.rs".into()),
..Default::default()
},
};
let decoded = CaesarDecoder
.decode_chunk(&chunk)
.expect("bounded source-path Caesar decode should succeed");
assert!(
decoded.is_empty(),
"Caesar decoder must not run on .rs source files; got {} decoded variants",
decoded.len()
);
}
#[test]
fn decode_chunk_round_trips_aws_shaped_token() {
use keyhog_core::{Chunk, ChunkMetadata};
let chunk = Chunk {
data: "k = \"BLJBRS4EFGHIJKLM2345\";".into(),
metadata: ChunkMetadata {
base_offset: 0,
base_line: 0,
source_type: "test".into(),
..Default::default()
},
};
let decoded = CaesarDecoder
.decode_chunk(&chunk)
.expect("bounded env Caesar decode should succeed");
assert!(
decoded
.iter()
.any(|c| c.data.as_ref() == concat!("AK", "IAQR4DEFGHIJKL2345")),
"Caesar decoder did not surface the round-trip plaintext among {} variants. \
Got: {:?}",
decoded.len(),
decoded.iter().map(|c| c.data.clone()).collect::<Vec<_>>(),
);
}
#[test]
fn private_key_block_body_skips_caesar_decoder() {
use keyhog_core::{Chunk, ChunkMetadata};
let shifted_google = caesar_shift("AIzaJBPI2n5UC64198Pt4qMGLqLHKvwsPonI4Lb", 1);
let chunk = Chunk {
data: format!("-----BEGIN PRIVATE KEY-----\n{shifted_google}\n-----END PRIVATE KEY-----\n")
.into(),
metadata: ChunkMetadata {
source_type: "filesystem".into(),
path: Some("key.pem".into()),
..Default::default()
},
};
let decoded = CaesarDecoder
.decode_chunk(&chunk)
.expect("bounded lowercase Caesar decode should succeed");
assert!(
decoded.is_empty(),
"Caesar decoder must not emit provider-shaped children from private-key material: {:?}",
decoded.iter().map(|c| c.data.clone()).collect::<Vec<_>>()
);
}
#[test]
fn private_key_block_does_not_disable_caesar_outside_block() {
use keyhog_core::{Chunk, ChunkMetadata};
let shifted = caesar_shift("AKIAQR4DEFGHIJKL2345", 1);
let chunk = Chunk {
data: format!(
"token = \"{shifted}\"\n-----BEGIN PRIVATE KEY-----\nopaque\n-----END PRIVATE KEY-----\n"
)
.into(),
metadata: ChunkMetadata {
source_type: "filesystem".into(),
path: Some("bundle.env".into()),
..Default::default()
},
};
let decoded = CaesarDecoder
.decode_chunk(&chunk)
.expect("bounded candidate Caesar decode should succeed");
assert!(
decoded
.iter()
.any(|c| c.data.as_ref() == concat!("AK", "IAQR4DEFGHIJKL2345")),
"Caesar token outside the private-key block must still decode: {:?}",
decoded.iter().map(|c| c.data.clone()).collect::<Vec<_>>()
);
}