use color_eyre::eyre::{self, WrapErr};
use helm_schema::AnalysisSession;
use helm_schema_cli::{GenerateOptions, ProviderOptions, SchemaProfile};
use indoc::indoc;
use vfs::VfsPath;
const CHART_YAML: &str = indoc! {"
apiVersion: v2
name: app
version: 0.1.0
"};
const VALUES_YAML: &str = indoc! {"
targetNamespaces: ~
backupStorageLocation: ~
"};
const NOTES: &str = indoc! {r#"
Thank you for installing {{ .Chart.Name }}.
Scanning namespaces: {{ tpl .Values.targetNamespaces . }}
{{- $breaking := "" }}
{{- if kindIs "map" .Values.backupStorageLocation }}
{{- $breaking = print $breaking "backupStorageLocation moved to the list form" }}
{{- end }}
{{- if $breaking }}
{{- fail $breaking }}
{{- end }}
"#};
const TEMPLATE: &str = indoc! {r#"
apiVersion: v1
kind: ConfigMap
metadata:
name: app
data:
placeholder: "static"
"#};
fn generated_schema() -> eyre::Result<serde_json::Value> {
let chart_dir = VfsPath::new(vfs::MemoryFS::new());
test_util::write(&chart_dir.join("Chart.yaml")?, CHART_YAML)?;
test_util::write(&chart_dir.join("values.yaml")?, VALUES_YAML)?;
test_util::write(&chart_dir.join("templates/NOTES.txt")?, NOTES)?;
test_util::write(&chart_dir.join("templates/cm.yaml")?, TEMPLATE)?;
let opts = GenerateOptions {
chart_dir,
include_tests: false,
include_subchart_values: true,
values_files: Vec::new(),
infer_required: false,
emission: SchemaProfile::default().into(),
provider: ProviderOptions {
k8s_versions: vec!["v1.35.0".to_string()],
k8s_schema_cache_dir: None,
allow_net: false,
crd_catalog_cache_dir: Some(test_util::cold_provider_cache_root("crd")),
disable_k8s_schemas: true,
crd_override_dir: None,
..Default::default()
},
};
AnalysisSession::new(opts)
.generated_schema()
.map(|generated| generated.schema)
.map_err(eyre::Report::from)
.wrap_err("generate schema")
}
#[test]
fn notes_template_consumers_and_validators_become_schema_evidence() -> eyre::Result<()> {
let _guard = test_util::builder().with_tracing(false).build()?;
let schema = generated_schema()?;
let validator = jsonschema::validator_for(&schema).expect("schema validator");
assert!(
validator.is_valid(&serde_json::json!({ "targetNamespaces": "ns-a,ns-b" })),
"strings feed the notes' tpl call",
);
assert!(
!validator.is_valid(&serde_json::json!({ "targetNamespaces": { "a": 1 } })),
"a truthy non-string reaches the notes' tpl call and aborts rendering",
);
assert!(
validator.is_valid(&serde_json::json!({
"targetNamespaces": "ns-a",
"backupStorageLocation": [{ "name": "x" }]
})),
"the supported list form renders",
);
assert!(
!validator.is_valid(&serde_json::json!({
"targetNamespaces": "ns-a",
"backupStorageLocation": { "name": "x" }
})),
"the notes validator terminates rendering for the legacy map form",
);
Ok(())
}