mirror of
https://github.com/openai/codex.git
synced 2026-10-31 19:28:49 +00:00
test: add approval requirements fallback regression coverage
This commit is contained in:
@@ -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#"
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)]
|
||||
|
||||
Reference in New Issue
Block a user