test: add approval requirements fallback regression coverage

This commit is contained in:
daniel-oai
2026-02-13 14:37:08 -08:00
parent 6c0a924203
commit d3abfcf116
3 changed files with 204 additions and 0 deletions
@@ -885,6 +885,22 @@ mod tests {
Ok(())
}
#[test]
fn empty_allowed_approval_policies_is_rejected() -> Result<()> {
let toml_str = r#"
allowed_approval_policies = []
"#;
let config: ConfigRequirementsToml = from_str(toml_str)?;
let err = ConfigRequirements::try_from(with_unknown_source(config))
.expect_err("empty allowlist should be rejected");
assert_eq!(
err,
ConstraintError::empty_field("allowed_approval_policies")
);
Ok(())
}
#[test]
fn deserialize_allowed_sandbox_modes() -> Result<()> {
let toml_str = r#"
+28
View File
@@ -8034,4 +8034,32 @@ mod tests {
pretty_assertions::assert_eq!(output, expected);
}
#[tokio::test]
async fn session_configuration_apply_rejects_disallowed_approval_policy_update() {
let mut session_configuration = make_session_configuration_for_tests().await;
session_configuration.approval_policy =
Constrained::allow_only(AskForApproval::UnlessTrusted);
let err = match session_configuration.apply(&SessionSettingsUpdate {
approval_policy: Some(AskForApproval::OnRequest),
..Default::default()
}) {
Ok(_) => panic!("disallowed approval policy update should be rejected"),
Err(err) => err,
};
assert!(matches!(
err,
crate::config::ConstraintError::InvalidValue {
candidate,
allowed,
..
} if candidate == "OnRequest" && allowed == "[UnlessTrusted]"
));
assert_eq!(
session_configuration.approval_policy.value(),
AskForApproval::UnlessTrusted
);
}
}
+160
View File
@@ -5159,6 +5159,166 @@ trust_level = "untrusted"
);
Ok(())
}
#[tokio::test]
async fn explicit_on_request_approval_falls_back_to_untrusted_when_disallowed_by_requirements()
-> std::io::Result<()> {
let codex_home = TempDir::new()?;
std::fs::write(
codex_home.path().join(CONFIG_TOML_FILE),
r#"approval_policy = "on-request"
"#,
)?;
let config = ConfigBuilder::default()
.codex_home(codex_home.path().to_path_buf())
.fallback_cwd(Some(codex_home.path().to_path_buf()))
.cloud_requirements(CloudRequirementsLoader::new(async {
Some(crate::config_loader::ConfigRequirementsToml {
allowed_approval_policies: Some(vec![AskForApproval::UnlessTrusted]),
..Default::default()
})
}))
.build()
.await?;
assert_eq!(
config.permissions.approval_policy.value(),
AskForApproval::UnlessTrusted
);
Ok(())
}
#[tokio::test]
async fn cli_on_request_approval_falls_back_to_untrusted_when_disallowed_by_requirements()
-> std::io::Result<()> {
let codex_home = TempDir::new()?;
let config = ConfigBuilder::default()
.codex_home(codex_home.path().to_path_buf())
.fallback_cwd(Some(codex_home.path().to_path_buf()))
.cli_overrides(vec![(
"approval_policy".to_string(),
TomlValue::String("on-request".to_string()),
)])
.cloud_requirements(CloudRequirementsLoader::new(async {
Some(crate::config_loader::ConfigRequirementsToml {
allowed_approval_policies: Some(vec![AskForApproval::UnlessTrusted]),
..Default::default()
})
}))
.build()
.await?;
assert_eq!(
config.permissions.approval_policy.value(),
AskForApproval::UnlessTrusted
);
Ok(())
}
#[tokio::test]
async fn disallowed_approval_policy_adds_startup_warning() -> std::io::Result<()> {
let codex_home = TempDir::new()?;
std::fs::write(
codex_home.path().join(CONFIG_TOML_FILE),
r#"approval_policy = "on-request"
"#,
)?;
let config = ConfigBuilder::default()
.codex_home(codex_home.path().to_path_buf())
.fallback_cwd(Some(codex_home.path().to_path_buf()))
.cloud_requirements(CloudRequirementsLoader::new(async {
Some(crate::config_loader::ConfigRequirementsToml {
allowed_approval_policies: Some(vec![AskForApproval::UnlessTrusted]),
..Default::default()
})
}))
.build()
.await?;
assert!(
config.startup_warnings.iter().any(|warning| {
warning.contains("Configured value for `approval_policy`")
&& warning.contains("falling back to required value")
&& warning.contains("UnlessTrusted")
}),
"{:?}",
config.startup_warnings
);
Ok(())
}
#[cfg(target_os = "macos")]
#[tokio::test]
async fn mdm_untrusted_approval_requirement_allows_startup() -> std::io::Result<()> {
use base64::Engine;
let codex_home = TempDir::new()?;
std::fs::write(
codex_home.path().join(CONFIG_TOML_FILE),
r#"approval_policy = "on-request"
"#,
)?;
let config = ConfigBuilder::default()
.codex_home(codex_home.path().to_path_buf())
.fallback_cwd(Some(codex_home.path().to_path_buf()))
.loader_overrides(LoaderOverrides {
managed_config_path: None,
managed_preferences_base64: Some(String::new()),
macos_managed_config_requirements_base64: Some(
base64::prelude::BASE64_STANDARD.encode(
br#"
allowed_approval_policies = ["untrusted"]
"#,
),
),
})
.build()
.await?;
assert_eq!(
config.permissions.approval_policy.value(),
AskForApproval::UnlessTrusted
);
Ok(())
}
#[cfg(target_os = "macos")]
#[tokio::test]
async fn mdm_untrusted_approval_requirement_allows_startup_with_cli_override()
-> std::io::Result<()> {
use base64::Engine;
let codex_home = TempDir::new()?;
let config = ConfigBuilder::default()
.codex_home(codex_home.path().to_path_buf())
.fallback_cwd(Some(codex_home.path().to_path_buf()))
.cli_overrides(vec![(
"approval_policy".to_string(),
TomlValue::String("on-request".to_string()),
)])
.loader_overrides(LoaderOverrides {
managed_config_path: None,
managed_preferences_base64: Some(String::new()),
macos_managed_config_requirements_base64: Some(
base64::prelude::BASE64_STANDARD.encode(
br#"
allowed_approval_policies = ["untrusted"]
"#,
),
),
})
.build()
.await?;
assert_eq!(
config.permissions.approval_policy.value(),
AskForApproval::UnlessTrusted
);
Ok(())
}
}
#[cfg(test)]