Compare commits

..

2 Commits

5 changed files with 137 additions and 12 deletions

View File

@ -636,5 +636,110 @@
} }
} }
] ]
},
{
"description": "STI Projections (Lacking Kind Discriminator Definitions)",
"database": {
"types": [
{
"name": "widget",
"variations": [
"widget"
],
"schemas": {
"widget": {
"type": "object",
"properties": {
"type": {
"type": "string"
}
}
},
"stock.widget": {
"type": "widget",
"properties": {
"kind": {
"type": "string"
},
"amount": {
"type": "integer"
}
}
},
"projected.widget": {
"type": "widget",
"properties": {
"alias": {
"type": "string"
}
}
}
}
}
],
"schemas": {
"stock_widget_validation": {
"type": "stock.widget"
},
"projected_widget_validation": {
"type": "projected.widget"
}
}
},
"tests": [
{
"description": "stock.widget securely expects kind when configured",
"schema_id": "stock_widget_validation",
"data": {
"type": "widget",
"amount": 5
},
"action": "validate",
"expect": {
"success": false,
"errors": [
{
"code": "MISSING_KIND",
"details": {
"path": ""
}
}
]
}
},
{
"description": "projected.widget seamlessly bypasses kind expectation when excluded from schema",
"schema_id": "projected_widget_validation",
"data": {
"type": "widget",
"alias": "Test Projection"
},
"action": "validate",
"expect": {
"success": true
}
},
{
"description": "projected.widget securely fails if user erroneously provides extra kind property",
"schema_id": "projected_widget_validation",
"data": {
"type": "widget",
"alias": "Test Projection",
"kind": "projected"
},
"action": "validate",
"expect": {
"success": false,
"errors": [
{
"code": "STRICT_PROPERTY_VIOLATION",
"details": {
"path": "kind"
}
}
]
}
}
]
} }
] ]

View File

@ -1559,6 +1559,24 @@ fn test_polymorphism_4_1() {
crate::tests::runner::run_test_case(&path, 4, 1).unwrap(); crate::tests::runner::run_test_case(&path, 4, 1).unwrap();
} }
#[test]
fn test_polymorphism_5_0() {
let path = format!("{}/fixtures/polymorphism.json", env!("CARGO_MANIFEST_DIR"));
crate::tests::runner::run_test_case(&path, 5, 0).unwrap();
}
#[test]
fn test_polymorphism_5_1() {
let path = format!("{}/fixtures/polymorphism.json", env!("CARGO_MANIFEST_DIR"));
crate::tests::runner::run_test_case(&path, 5, 1).unwrap();
}
#[test]
fn test_polymorphism_5_2() {
let path = format!("{}/fixtures/polymorphism.json", env!("CARGO_MANIFEST_DIR"));
crate::tests::runner::run_test_case(&path, 5, 2).unwrap();
}
#[test] #[test]
fn test_not_0_0() { fn test_not_0_0() {
let path = format!("{}/fixtures/not.json", env!("CARGO_MANIFEST_DIR")); let path = format!("{}/fixtures/not.json", env!("CARGO_MANIFEST_DIR"));

View File

@ -24,9 +24,6 @@ impl<'a> ValidationContext<'a> {
if let Some(obj) = self.instance.as_object() { if let Some(obj) = self.instance.as_object() {
for key in obj.keys() { for key in obj.keys() {
if key == "type" || key == "kind" {
continue; // Reserved keywords implicitly allowed
}
if !result.evaluated_keys.contains(key) && !self.overrides.contains(key) { if !result.evaluated_keys.contains(key) && !self.overrides.contains(key) {
result.errors.push(ValidationError { result.errors.push(ValidationError {
code: "STRICT_PROPERTY_VIOLATION".to_string(), code: "STRICT_PROPERTY_VIOLATION".to_string(),

View File

@ -54,6 +54,10 @@ impl<'a> ValidationContext<'a> {
// If the target mathematically declares a horizontal structural STI variation natively // If the target mathematically declares a horizontal structural STI variation natively
if schema_identifier_str.contains('.') { if schema_identifier_str.contains('.') {
let requires_kind = self.schema.compiled_properties.get()
.map_or(false, |p| p.contains_key("kind"));
if requires_kind {
if obj.get("kind").is_none() { if obj.get("kind").is_none() {
result.errors.push(ValidationError { result.errors.push(ValidationError {
code: "MISSING_KIND".to_string(), code: "MISSING_KIND".to_string(),
@ -64,6 +68,7 @@ impl<'a> ValidationContext<'a> {
result.evaluated_keys.insert("kind".to_string()); result.evaluated_keys.insert("kind".to_string());
} }
} }
}
} else { } else {
// If it isn't registered globally, it might be a nested Ad-Hoc candidate running via O(1) union routers. // If it isn't registered globally, it might be a nested Ad-Hoc candidate running via O(1) union routers.
// Because they lack manual type property descriptors, we natively shield "type" and "kind" keys from // Because they lack manual type property descriptors, we natively shield "type" and "kind" keys from

View File

@ -1 +1 @@
1.0.119 1.0.120