use super::selection_error;
use crate::config_error::ConfigError;
use crate::policy_trigger::{Trigger, policy_runs_on};
use crate::config_schema::PolicyConfig;
use crate::policy_registry::{POLICY_REGISTRY, PolicyId, Severity, policy_descriptor};
use crate::policy_test_support::with_severity;
fn refusal(selected: &[PolicyId], config: &PolicyConfig) -> String {
return selection_error(selected, config, Trigger::DirectCheck)
.expect("a refusal")
.message;
}
#[test]
fn an_unlisted_optional_policy_is_refused_with_the_key_that_turns_it_on() {
let defaults: PolicyConfig = PolicyConfig::defaults();
let mut refused: usize = 0;
for descriptor in POLICY_REGISTRY {
if !descriptor.off_unless_listed {
continue;
}
refused += 1;
let message: String = refusal(&[descriptor.id], &defaults);
let on: &str = if descriptor.default_severity == Severity::Warn {
"warn"
} else {
"error"
};
assert!(
message.starts_with(format!("Policy {} is off,", descriptor.name).as_str()),
"{message}"
);
assert!(message.contains("does not list"), "{message}");
assert!(message.contains("cli-git.config.jsonc"), "{message}");
assert!(
message.contains(format!("\"policies\": {{ \"{}\": \"{on}\" }}", descriptor.name).as_str()),
"{message}"
);
}
assert_eq!(refused, 5, "the four plugin policies and the catalog policy are optional");
}
#[test]
fn a_policy_listed_as_off_is_refused_with_its_listed_value() {
let mut config: PolicyConfig =
with_severity(&PolicyConfig::defaults(), PolicyId::CatalogSpecifiers, Severity::Off);
for setting in &mut config.settings {
setting.explicit = setting.id == PolicyId::CatalogSpecifiers;
}
let message: String = refusal(&[PolicyId::CatalogSpecifiers], &config);
assert!(
message.contains("sets policies.\"mono/catalog-specifiers\" to \"off\""),
"{message}"
);
assert!(!message.contains("does not list"), "{message}");
}
#[test]
fn running_policies_and_an_empty_selection_are_not_refused() {
let defaults: PolicyConfig = PolicyConfig::defaults();
assert_eq!(selection_error(&[], &defaults, Trigger::DirectCheck), None);
assert_eq!(
selection_error(&[PolicyId::RequireRoot, PolicyId::FinalNewline], &defaults, Trigger::DirectCheck),
None
);
for severity in [Severity::Warn, Severity::Error] {
let on: PolicyConfig = with_severity(&defaults, PolicyId::CatalogSpecifiers, severity);
assert_eq!(
selection_error(&[PolicyId::CatalogSpecifiers], &on, Trigger::DirectCheck),
None,
"{severity:?}"
);
}
}
#[test]
fn an_on_policy_without_the_direct_trigger_is_refused_for_that_command() {
let on: PolicyConfig = with_severity(&PolicyConfig::defaults(), PolicyId::CatalogSpecifiers, Severity::Error);
for trigger in [Trigger::DirectCheck, Trigger::DirectFix] {
let runs: bool = policy_runs_on(PolicyId::CatalogSpecifiers, trigger);
let refused: Option<ConfigError> = selection_error(&[PolicyId::CatalogSpecifiers], &on, trigger);
assert_eq!(refused.is_none(), runs, "{trigger:?}");
if let Some(error) = refused {
assert!(error.message.contains("does not run for cli-git fix"), "{}", error.message);
assert!(error.message.contains("It runs for cli-git check."), "{}", error.message);
}
}
}
#[test]
fn every_off_policy_of_a_selection_is_named_once() {
let config: PolicyConfig =
with_severity(&PolicyConfig::defaults(), PolicyId::ForbiddenStrings, Severity::Error);
let message: String = refusal(
&[
PolicyId::CatalogSpecifiers,
PolicyId::ForbiddenStrings,
PolicyId::DependentVersionBump,
PolicyId::CatalogSpecifiers,
],
&config,
);
assert_eq!(
message.matches("Policy mono/catalog-specifiers is off").count(),
1,
"{message}"
);
assert_eq!(
message.matches("Policy mono/dependent-version-bump is off").count(),
1,
"{message}"
);
assert!(!message.contains("security/forbidden-strings is off"), "{message}");
let first: usize = message.find("mono/catalog-specifiers is off").expect("first");
let second: usize = message.find("mono/dependent-version-bump is off").expect("second");
assert!(first < second, "{message}");
assert_eq!(policy_descriptor(PolicyId::CatalogSpecifiers).name, "mono/catalog-specifiers");
}