91 lines
3.3 KiB
Rust
91 lines
3.3 KiB
Rust
use dever_runtime::{
|
|
adapter::{Document, Schema},
|
|
value::secret::Secret,
|
|
};
|
|
use serde::Deserialize;
|
|
|
|
const SCHEMAS: &[Schema] = &[Schema {
|
|
name: "demo.value",
|
|
implementations: &["local", "remote"],
|
|
}];
|
|
|
|
#[derive(Deserialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
struct Input {
|
|
offset: i64,
|
|
token: Secret,
|
|
}
|
|
|
|
#[test]
|
|
fn selection_is_explicit_and_only_the_selected_setting_is_decoded() {
|
|
let text = r#"{"adapter":{"demo.value":{"use":"remote","setting":{"offset":41,"token":"fixture-only-token"}}}}"#;
|
|
for _ in 0..100 {
|
|
let document = Document::parse(text.into()).unwrap();
|
|
let selections = document.select(SCHEMAS).unwrap();
|
|
assert_eq!(selections[0].index, 1);
|
|
let input: Input = selections[0].decode().unwrap();
|
|
assert_eq!(input.offset, 41);
|
|
assert_eq!(format!("{:?}", input.token), "Secret([REDACTED])");
|
|
drop(selections);
|
|
drop(document);
|
|
assert_eq!(format!("{:?}", input.token), "Secret([REDACTED])");
|
|
}
|
|
let document =
|
|
Document::parse(r#"{"adapter":{"demo.\u0076alue":{"use":"\u006cocal"}}}"#.into()).unwrap();
|
|
assert_eq!(document.select(SCHEMAS).unwrap()[0].index, 0);
|
|
let document = Document::parse("{}".into()).unwrap();
|
|
assert!(document.select(SCHEMAS).is_err());
|
|
let single = [Schema {
|
|
name: "demo.value",
|
|
implementations: &["default"],
|
|
}];
|
|
let selections = document.select(&single).unwrap();
|
|
assert_eq!(selections[0].index, 0);
|
|
assert!(selections[0].without_setting().is_ok());
|
|
assert!(selections[0].decode::<Input>().is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_configuration_is_bounded_strict_and_redacted() {
|
|
for text in [
|
|
"[]",
|
|
"[{}]",
|
|
"null",
|
|
"{} {}",
|
|
"{",
|
|
r#"{"adapter":null}"#,
|
|
r#"{"adapter":{},"adapter":{}}"#,
|
|
r#"{"adapter":{"demo.value":["local",{}]}}"#,
|
|
r#"{"adapter":{"demo.value":{"use":null}}}"#,
|
|
r#"{"adapter":{"demo.value":{"use":"fixture-only-token"}}}"#,
|
|
r#"{"adapter":{"fixture-only-token":{"use":"local"}}}"#,
|
|
r#"{"adapter":{"demo.value":{"use":"local","fixture-only-token":1}}}"#,
|
|
r#"{"adapter":{"demo.value":{"use":"local","use":"remote"}}}"#,
|
|
r#"{"adapter":{"demo.value":{"use":"local","setting":{"token":"a","token":"b"}}}}"#,
|
|
] {
|
|
let error = match Document::parse(text.into()) {
|
|
Err(error) => error,
|
|
Ok(document) => document.select(SCHEMAS).err().expect(text),
|
|
};
|
|
assert!(!error.contains("fixture-only-token"), "{error}");
|
|
}
|
|
let too_large = format!("{{\"text\":\"{}\"}}", "x".repeat(16 * 1024 * 1024));
|
|
assert!(Document::parse(too_large).is_err());
|
|
for setting in [
|
|
"null",
|
|
"{}",
|
|
r#"{"offset":"fixture-only-token","token":"x"}"#,
|
|
r#"{"offset":1,"token":5}"#,
|
|
r#"{"offset":1,"token":"x","extra":"fixture-only-token"}"#,
|
|
] {
|
|
let document = Document::parse(format!(
|
|
r#"{{"adapter":{{"demo.value":{{"use":"local","setting":{setting}}}}}}}"#
|
|
))
|
|
.unwrap();
|
|
let selections = document.select(SCHEMAS).unwrap();
|
|
let error = selections[0].decode::<Input>().err().expect(setting);
|
|
assert!(!error.contains("fixture-only-token"));
|
|
assert!(selections[0].without_setting().is_err());
|
|
}
|
|
}
|