diff --git a/crates/omnigraph-cli/tests/support/mod.rs b/crates/omnigraph-cli/tests/support/mod.rs index ab15d73..45694ea 100644 --- a/crates/omnigraph-cli/tests/support/mod.rs +++ b/crates/omnigraph-cli/tests/support/mod.rs @@ -129,7 +129,6 @@ defaults: query: roots: - . -policy: {{}} ", yaml_string(&graph.to_string_lossy()) ) @@ -151,7 +150,6 @@ defaults: query: roots: - . -policy: {{}} ", yaml_string(url) ) diff --git a/crates/omnigraph-config/src/lib.rs b/crates/omnigraph-config/src/lib.rs index e388d48..be42fe0 100644 --- a/crates/omnigraph-config/src/lib.rs +++ b/crates/omnigraph-config/src/lib.rs @@ -1017,6 +1017,8 @@ fn legacy_key_migration_hint(key: &str) -> Option<&'static str> { "project" => Some("remove it; it has no effect under `version: 1`"), "cli" => Some("rename to `defaults:`"), "server" => Some("rename to `serve:` (note `graph:` becomes the `graphs:` list)"), + "policy" => Some("move it onto the owning graph (`graphs..policy`)"), + "queries" => Some("move it onto the owning graph (`graphs..queries`)"), _ => None, } } @@ -1604,6 +1606,53 @@ cli: ); } + #[test] + fn version_one_rejects_top_level_policy() { + // Top-level `policy:`/`queries:` are removed under v1 — they belong on + // the owning graph entry. An empty `policy: {}` must error too (presence, + // not contents). + let err = load_yaml_err( + "version: 1\ngraphs:\n local:\n storage: ./demo.omni\npolicy:\n file: ./p.yaml\n", + ); + assert!( + err.contains("policy") && err.contains("graphs..policy"), + "v1 must reject top-level `policy:` and point at the per-graph block: {err}" + ); + } + + #[test] + fn version_one_rejects_top_level_queries() { + let err = load_yaml_err( + "version: 1\ngraphs:\n local:\n storage: ./demo.omni\n\ + queries:\n q:\n file: ./q.gq\n", + ); + assert!( + err.contains("queries") && err.contains("graphs..queries"), + "v1 must reject top-level `queries:` and point at the per-graph block: {err}" + ); + } + + #[test] + fn version_one_honors_per_graph_policy_and_queries() { + // The per-graph blocks (`graphs..policy` / `.queries`) are nested, + // not top-level, so the v1 key scan leaves them alone. + let config = load_yaml( + r#"version: 1 +graphs: + prod: + storage: s3://b/prod + policy: + file: ./prod.yaml + queries: + q: + file: ./q.gq +"#, + ); + assert!(config.resolve_target_policy_file("prod").is_some()); + assert_eq!(config.target_query_entries("prod").unwrap().len(), 1); + assert!(config.deprecation_warnings().is_empty()); + } + #[test] fn version_one_rejects_legacy_project_key() { // `version: 1` removes the `project:` block (no consumer). Writing it