diff --git a/src/adapters/from_jsonschema.rs b/src/adapters/from_jsonschema.rs index 760e3a1..b95b747 100644 --- a/src/adapters/from_jsonschema.rs +++ b/src/adapters/from_jsonschema.rs @@ -170,9 +170,6 @@ fn spec_name_references_undeclared(spec: &OperationSpec, path_template: &str) -> .and_then(|p| p.as_object()) .map(|p| p.keys().cloned().collect::>()) .unwrap_or_default(); - if properties.is_empty() { - return false; - } let mut rest = path_template; while let Some(start) = rest.find('{') { let Some(end_rel) = rest[start..].find('}') else { @@ -722,4 +719,56 @@ mod tests { Err(e) => panic!("expected SchemaParse, got {e}"), } } + + #[test] + fn construction_rejects_placeholder_when_input_schema_has_no_properties() { + let spec = OperationSpec::new( + "svc/getWidget", + OperationType::Query, + Visibility::Internal, + serde_json::json!({"type":"object"}), + serde_json::json!({"type":"object"}), + vec![], + AccessControl::default(), + None, + ); + let result = FromJsonSchema::new( + spec, + test_config("svc", "https://api.example.com"), + "/widgets/{id}".to_string(), + "GET".to_string(), + test_http_client(), + ); + match result { + Err(AdapterError::SchemaParse { message }) => { + assert!(message.contains("placeholder"), "message was: {message}"); + assert!(message.contains("{id}"), "message was: {message}"); + } + Ok(_) => { + panic!("no-properties schema with a placeholder template must fail at construction") + } + Err(e) => panic!("expected SchemaParse, got {e}"), + } + + let spec = OperationSpec::new( + "svc/listWidgets", + OperationType::Query, + Visibility::Internal, + serde_json::json!({"type":"object"}), + serde_json::json!({"type":"object"}), + vec![], + AccessControl::default(), + None, + ); + let adapter = FromJsonSchema::new( + spec, + test_config("svc", "https://api.example.com"), + "/widgets".to_string(), + "GET".to_string(), + test_http_client(), + ) + .expect("placeholder-free template with a no-properties schema builds"); + let bundles = futures::executor::block_on(adapter.import()).unwrap(); + assert_eq!(bundles[0].spec.visibility, Visibility::Internal); + } }