Skip to content

Commit 471c40b

Browse files
test(validate): close ado_script/validate regression coverage gaps (#678)
* Initial plan * test: add coverage for ado_script path sync and validate branches Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/586b26a3-27f9-459a-882e-73f68b4b4f8e Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com>
1 parent 1379c79 commit 471c40b

2 files changed

Lines changed: 64 additions & 0 deletions

File tree

src/compile/extensions/ado_script.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,40 @@ mod tests {
427427
assert!(steps[2].contains("node '/tmp/ado-aw-scripts/ado-script/gate.js'"));
428428
}
429429

430+
#[test]
431+
fn gate_and_import_eval_paths_consistent_with_download_step() {
432+
let extract_dir = "/tmp/ado-aw-scripts/";
433+
assert!(
434+
GATE_EVAL_PATH.starts_with(extract_dir),
435+
"GATE_EVAL_PATH must be under the unzip -d destination"
436+
);
437+
assert!(
438+
IMPORT_EVAL_PATH.starts_with(extract_dir),
439+
"IMPORT_EVAL_PATH must be under the unzip -d destination"
440+
);
441+
let zip_prefix = "ado-script/";
442+
assert!(
443+
GATE_EVAL_PATH
444+
.strip_prefix(extract_dir)
445+
.expect("gate path should include extract dir")
446+
.starts_with(zip_prefix),
447+
"GATE_EVAL_PATH suffix must match zip internal path prefix used in release.yml"
448+
);
449+
assert!(
450+
IMPORT_EVAL_PATH
451+
.strip_prefix(extract_dir)
452+
.expect("import path should include extract dir")
453+
.starts_with(zip_prefix),
454+
"IMPORT_EVAL_PATH suffix must match zip internal path prefix used in release.yml"
455+
);
456+
let steps = install_and_download_steps();
457+
let download = &steps[1];
458+
assert!(
459+
download.contains("-d /tmp/ado-aw-scripts/"),
460+
"download step must unzip to /tmp/ado-aw-scripts/"
461+
);
462+
}
463+
430464
#[test]
431465
fn prepare_steps_empty_when_inlined_imports_true() {
432466
let ext = ext_with(None, None, true);

src/validate.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,17 @@ mod tests {
508508
assert!(!is_valid_version("1.0.0 -Source https://evil.com"));
509509
}
510510

511+
#[test]
512+
fn test_is_valid_artifact_name() {
513+
assert!(is_valid_artifact_name("my-artifact_v1.0"));
514+
assert!(is_valid_artifact_name("drop"));
515+
assert!(!is_valid_artifact_name(""));
516+
assert!(!is_valid_artifact_name("my artifact"));
517+
assert!(!is_valid_artifact_name("$(secretVar)"));
518+
assert!(!is_valid_artifact_name("../../etc/passwd"));
519+
assert!(!is_valid_artifact_name("{{inject}}"));
520+
}
521+
511522
#[test]
512523
fn test_is_valid_arg() {
513524
assert!(is_valid_arg("--verbose"));
@@ -601,6 +612,25 @@ mod tests {
601612
assert!(reject_ado_expressions("$[variables.x]", "param", "field").is_err());
602613
}
603614

615+
#[test]
616+
fn test_reject_ado_expressions_in_value_catches_injection_in_sequence() {
617+
let seq = serde_yaml::Value::Sequence(vec![
618+
serde_yaml::Value::String("safe".to_string()),
619+
serde_yaml::Value::String("$(secretVar)".to_string()),
620+
]);
621+
let result = reject_ado_expressions_in_value(&seq, "myParam", "default");
622+
assert!(result.is_err(), "Sequence with ADO expression must be rejected");
623+
}
624+
625+
#[test]
626+
fn test_reject_ado_expressions_in_value_allows_safe_sequence() {
627+
let seq = serde_yaml::Value::Sequence(vec![
628+
serde_yaml::Value::String("us-east".to_string()),
629+
serde_yaml::Value::String("eu-west".to_string()),
630+
]);
631+
assert!(reject_ado_expressions_in_value(&seq, "region", "default").is_ok());
632+
}
633+
604634
#[test]
605635
fn test_reject_pipeline_injection() {
606636
assert!(reject_pipeline_injection("normal value", "field").is_ok());

0 commit comments

Comments
 (0)