use super::*;
fn linux_ctx<'a>(features: &'a FeatureSet) -> RuleContext<'a> {
RuleContext {
os_name: "linux",
os_version: "6.0",
arch: "x86_64",
features,
}
}
#[test]
fn empty_rules_allow() {
let features = FeatureSet::default();
let ctx = linux_ctx(&features);
assert!(evaluate(&[], &ctx));
}
#[test]
fn single_allow_matching_os_allows() {
let rules = vec![Rule {
action: RuleAction::Allow,
os: Some(OsCondition {
name: Some("linux".into()),
arch: None,
..Default::default()
}),
features: None,
}];
let features = FeatureSet::default();
let ctx = linux_ctx(&features);
assert!(evaluate(&rules, &ctx));
}
#[test]
fn single_disallow_matching_os_disallows() {
let rules = vec![Rule {
action: RuleAction::Disallow,
os: Some(OsCondition {
name: Some("linux".into()),
arch: None,
..Default::default()
}),
features: None,
}];
let features = FeatureSet::default();
let ctx = linux_ctx(&features);
assert!(!evaluate(&rules, &ctx));
}
#[test]
fn allow_without_os_match_disallows_by_default() {
let rules = vec![Rule {
action: RuleAction::Allow,
os: Some(OsCondition {
name: Some("windows".into()),
arch: None,
..Default::default()
}),
features: None,
}];
let features = FeatureSet::default();
let ctx = linux_ctx(&features);
assert!(!evaluate(&rules, &ctx));
}
#[test]
fn last_matching_rule_wins_when_allow_then_disallow() {
let rules = vec![
Rule {
action: RuleAction::Allow,
os: None,
features: None,
},
Rule {
action: RuleAction::Disallow,
os: Some(OsCondition {
name: Some("osx".into()),
arch: None,
..Default::default()
}),
features: None,
},
];
let features = FeatureSet::default();
let osx_ctx = RuleContext {
os_name: "osx",
os_version: "6.0",
arch: "x86_64",
features: &features,
};
assert!(!evaluate(&rules, &osx_ctx));
let lin = linux_ctx(&features);
assert!(evaluate(&rules, &lin));
}
#[test]
fn last_matching_rule_wins_when_disallow_then_allow() {
let rules = vec![
Rule {
action: RuleAction::Disallow,
os: None,
features: None,
},
Rule {
action: RuleAction::Allow,
os: Some(OsCondition {
name: Some("linux".into()),
arch: None,
..Default::default()
}),
features: None,
},
];
let features = FeatureSet::default();
let ctx = linux_ctx(&features);
assert!(evaluate(&rules, &ctx));
}
#[test]
fn arch_mismatch_blocks_rule() {
let rules = vec![Rule {
action: RuleAction::Allow,
os: Some(OsCondition {
name: Some("linux".into()),
arch: Some("arm64".into()),
version: None,
}),
features: None,
}];
let features = FeatureSet::default();
let ctx = linux_ctx(&features);
assert!(!evaluate(&rules, &ctx));
}
#[test]
fn feature_required_true_matches_when_ctx_true() {
let rules = vec![Rule {
action: RuleAction::Allow,
os: None,
features: Some(FeatureSet {
is_demo_user: Some(true),
..Default::default()
}),
}];
let demo_features = FeatureSet {
is_demo_user: Some(true),
..Default::default()
};
let ctx = RuleContext {
os_name: "linux",
os_version: "6.0",
arch: "x86_64",
features: &demo_features,
};
assert!(evaluate(&rules, &ctx));
}
#[test]
fn feature_required_true_blocks_when_ctx_false() {
let rules = vec![Rule {
action: RuleAction::Allow,
os: None,
features: Some(FeatureSet {
is_demo_user: Some(true),
..Default::default()
}),
}];
let features = FeatureSet::default();
let ctx = linux_ctx(&features);
assert!(!evaluate(&rules, &ctx));
}
#[test]
fn no_os_no_features_rule_always_matches() {
let rules = vec![Rule {
action: RuleAction::Allow,
os: None,
features: None,
}];
let features = FeatureSet::default();
let ctx = linux_ctx(&features);
assert!(evaluate(&rules, &ctx));
}
#[test]
fn os_version_pattern_matches_against_host() {
let rules = vec![Rule {
action: RuleAction::Allow,
os: Some(OsCondition {
name: Some("osx".into()),
arch: None,
version: Some("^10\\.".into()),
}),
features: None,
}];
let features = FeatureSet::default();
let ctx_match = RuleContext {
os_name: "osx",
os_version: "10.15.7",
arch: "x86_64",
features: &features,
};
assert!(evaluate(&rules, &ctx_match));
let ctx_mismatch = RuleContext {
os_name: "osx",
os_version: "13.2.1",
arch: "x86_64",
features: &features,
};
assert!(!evaluate(&rules, &ctx_mismatch));
}
#[test]
fn os_version_pattern_does_not_match_when_host_unknown() {
let rules = vec![Rule {
action: RuleAction::Allow,
os: Some(OsCondition {
name: Some("windows".into()),
arch: None,
version: Some("^10\\.".into()),
}),
features: None,
}];
let features = FeatureSet::default();
let ctx = RuleContext {
os_name: "windows",
os_version: "",
arch: "x86_64",
features: &features,
};
assert!(!evaluate(&rules, &ctx));
}
#[test]
fn rule_deserializes_from_mojang_json() {
let json = r#"{
"action": "allow",
"os": { "name": "osx" }
}"#;
let rule: Rule = serde_json::from_str(json).unwrap();
assert_eq!(rule.action, RuleAction::Allow);
assert_eq!(
rule.os.as_ref().and_then(|o| o.name.as_deref()),
Some("osx")
);
assert!(rule.os.as_ref().and_then(|o| o.arch.as_ref()).is_none());
assert!(rule.features.is_none());
}
#[test]
fn rule_deserializes_with_features() {
let json = r#"{
"action": "allow",
"features": { "is_demo_user": true }
}"#;
let rule: Rule = serde_json::from_str(json).unwrap();
assert_eq!(rule.action, RuleAction::Allow);
assert!(rule.os.is_none());
assert_eq!(
rule.features.as_ref().and_then(|f| f.is_demo_user),
Some(true)
);
}