use referer_parser_rs::Parser;
use serde::Deserialize;
use url::Url;
#[derive(Deserialize)]
struct TestCase {
spec: String,
uri: String,
medium: String,
source: String,
term: Option<String>,
known: bool,
}
fn load_parser_and_cases() -> (Parser, Vec<TestCase>) {
let parser = Parser::new("tests/referers.yml").expect("failed to load referers.yml");
let data =
std::fs::read_to_string("tests/referer-tests.json").expect("failed to read test file");
let cases: Vec<TestCase> = serde_json::from_str(&data).expect("failed to parse test JSON");
(parser, cases)
}
#[test]
fn all_known_referers_are_found() {
let (parser, cases) = load_parser_and_cases();
for case in cases.iter().filter(|c| c.known) {
let url =
Url::parse(&case.uri).unwrap_or_else(|e| panic!("[{}]: invalid URL: {e}", case.spec));
let entry = parser
.lookup(&url)
.unwrap_or_else(|| panic!("[{}]: expected known referer, got None", case.spec));
assert_eq!(entry.medium, case.medium, "[{}]: wrong medium", case.spec);
assert_eq!(entry.source, case.source, "[{}]: wrong source", case.spec);
assert_eq!(
entry.search_term.as_deref(),
case.term.as_deref(),
"[{}]: wrong term",
case.spec
);
}
}
#[test]
fn unknown_referers_return_none() {
let (parser, cases) = load_parser_and_cases();
for case in cases.iter().filter(|c| !c.known) {
let url =
Url::parse(&case.uri).unwrap_or_else(|e| panic!("[{}]: invalid URL: {e}", case.spec));
assert!(
parser.lookup(&url).is_none(),
"[{}]: expected None for unknown referer",
case.spec
);
}
}