use parlov_elicit::ProbeSpec;
pub(crate) fn spec_strategy_id(spec: &ProbeSpec) -> &str {
match spec {
ProbeSpec::Pair(p) | ProbeSpec::HeaderDiff(p) => p.metadata.strategy_id,
ProbeSpec::Burst(b) => b.metadata.strategy_id,
}
}
pub(crate) fn apply_strategy_filters(plan: Vec<ProbeSpec>, ids: &[String]) -> Vec<ProbeSpec> {
plan.into_iter()
.filter(|spec| ids.iter().any(|id| id == spec_strategy_id(spec)))
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
use http::{HeaderMap, Method};
use parlov_core::{
always_applicable, NormativeStrength, OracleClass, ProbeDefinition, SignalSurface,
Technique, Vector,
};
use parlov_elicit::{ProbePair, RiskLevel, StrategyMetadata};
fn make_def() -> ProbeDefinition {
ProbeDefinition {
url: "https://example.com/1".to_owned(),
method: Method::GET,
headers: HeaderMap::new(),
body: None,
}
}
fn make_spec(strategy_id: &'static str) -> ProbeSpec {
ProbeSpec::Pair(ProbePair {
baseline: make_def(),
probe: make_def(),
canonical_baseline: None,
metadata: StrategyMetadata {
strategy_id,
strategy_name: "Test",
risk: RiskLevel::Safe,
},
technique: Technique {
id: "test",
name: "Test",
oracle_class: OracleClass::Existence,
vector: Vector::StatusCodeDiff,
strength: NormativeStrength::Should,
normalization_weight: Some(0.2),
inverted_signal_weight: None,
method_relevant: false,
parser_relevant: false,
applicability: always_applicable,
contradiction_surface: SignalSurface::Status,
},
chain_provenance: None,
})
}
#[test]
fn filter_keeps_matching_spec() {
let plan = vec![
make_spec("rd-percent-encoding"),
make_spec("rd-double-slash"),
];
let result = apply_strategy_filters(plan, &["rd-percent-encoding".to_owned()]);
assert_eq!(result.len(), 1);
assert_eq!(spec_strategy_id(&result[0]), "rd-percent-encoding");
}
#[test]
fn filter_unknown_id_yields_empty() {
let plan = vec![make_spec("rd-percent-encoding")];
let result = apply_strategy_filters(plan, &["nonexistent-id".to_owned()]);
assert!(result.is_empty());
}
#[test]
fn filter_multiple_ids_yields_union() {
let plan = vec![
make_spec("rd-percent-encoding"),
make_spec("rd-double-slash"),
make_spec("cp-if-none-match"),
];
let ids = vec![
"rd-percent-encoding".to_owned(),
"rd-double-slash".to_owned(),
];
let result = apply_strategy_filters(plan, &ids);
assert_eq!(result.len(), 2);
}
#[test]
fn filter_empty_ids_yields_empty() {
let plan = vec![make_spec("rd-percent-encoding")];
let result = apply_strategy_filters(plan, &[]);
assert!(result.is_empty());
}
#[test]
fn filter_empty_plan_yields_empty() {
let result = apply_strategy_filters(vec![], &["rd-percent-encoding".to_owned()]);
assert!(result.is_empty());
}
}