#[path = "query_support/fixtures.rs"]
mod fixtures;
use fixtures::{apply_shared_rule, init_repo, sdk, sdk_error};
use serde_json::json;
#[test]
fn get_returns_one_record_under_a_versioned_envelope() {
let directory = init_repo();
let repo = directory.path().to_str().unwrap();
let ids = apply_shared_rule(&directory);
let answer = sdk(
repo,
"get",
&json!({"node_type": "rule", "id": ids.rule.as_str()}),
);
assert_eq!(
answer["protocol_version"],
provenance_core::SDK_PROTOCOL_VERSION
);
assert_eq!(answer["operation"], "get");
assert_eq!(answer["found"], true);
assert_eq!(answer["node"]["node_type"], "rule");
assert_eq!(answer["node"]["id"], ids.rule);
assert_eq!(
answer["node"]["statement"],
"Share links expire within 30 days"
);
}
#[test]
fn get_carries_a_stamp_beside_the_answer() {
let directory = init_repo();
let repo = directory.path().to_str().unwrap();
let ids = apply_shared_rule(&directory);
let (ok, stdout, stderr) = fixtures::sdk_raw(
repo,
"get",
&json!({"node_type": "rule", "id": ids.rule.as_str()}),
);
assert!(ok, "{stderr}");
let answer: serde_json::Value = serde_json::from_str(&stdout).unwrap();
let stamp = &answer["stamp"];
assert!(stamp["serial"].as_i64().unwrap() >= 1);
assert!(stamp["digest"].as_str().unwrap().starts_with("sha256:"));
assert!(!stamp["instance_id"].as_str().unwrap().is_empty());
assert!(stamp["derivation"].is_u64());
assert_eq!(stamp["policy"], "catch_up");
assert_eq!(
stamp["attested"],
json!(["rules"]),
"get reads the rule from its table"
);
assert_eq!(stamp["live"], json!([]), "get reads nothing live");
assert!(answer.get("freshness_error").is_none());
assert_eq!(answer["found"], true);
}
#[test]
fn get_hides_a_retired_record_until_the_caller_asks_for_it() {
let directory = init_repo();
let repo = directory.path().to_str().unwrap();
let ids = apply_shared_rule(&directory);
let mut narrowed = fixtures::shared_rule_spec();
narrowed["requirements"] = json!([{
"key": "sharing",
"statement": "Shares are time bounded",
"sources": ["retention"]
}]);
narrowed["rules"][0]["requirements"] = json!(["sharing"]);
sdk(repo, "apply", &narrowed);
let active = sdk(
repo,
"get",
&json!({"node_type": "requirement", "id": ids.sessions.as_str()}),
);
assert_eq!(active["found"], false);
assert!(active.get("node").is_none());
let including = sdk(
repo,
"get",
&json!({
"node_type": "requirement",
"id": ids.sessions.as_str(),
"include_retired": true
}),
);
assert_eq!(including["found"], true);
assert_eq!(including["node"]["retired"], true);
assert_eq!(including["node"]["id"], ids.sessions);
}
#[test]
fn get_refuses_a_request_written_for_another_protocol_version() {
let directory = init_repo();
let repo = directory.path().to_str().unwrap();
let ids = apply_shared_rule(&directory);
let error = sdk_error(
repo,
"get",
&json!({"protocol_version": 2, "node_type": "rule", "id": ids.rule}),
);
let spoken = format!("speaks {}", provenance_core::SDK_PROTOCOL_VERSION);
assert!(
error.contains("protocol version 2") && error.contains(&spoken),
"error should name both versions: {error}"
);
}
#[test]
fn native_validation_errors_keep_the_original_single_error_line() {
let directory = init_repo();
let repo = directory.path().to_str().unwrap();
for (operation, request, expected) in [
(
"search",
json!({"text":"shared","limit":0}),
"Error: limit must be between 1 and 200\n".to_owned(),
),
(
"get",
json!({"node_type":"rule","id":"rule_missing","protocol_version":6}),
format!(
"Error: request names protocol version 6; this engine speaks {}\n",
provenance_core::SDK_PROTOCOL_VERSION
),
),
] {
let (ok, stdout, stderr) = fixtures::sdk_raw(repo, operation, &request);
assert!(!ok);
assert!(stdout.is_empty());
assert_eq!(stderr, expected);
}
}