Test Gap Analysis
Test suite snapshot: 1,817 total tests β all pass β
Previous open issues still active: #376 (lean runtime, logging, MCP tools list), #647 (stage/job header repos branch, update_check parse_version).
This issue tracks three new gaps discovered in the 2026-05-20 cycle.
Priority Gaps
| Module |
Function/Path |
Why It Matters |
Suggested Test |
tools/azure_devops/extension.rs |
mcpg_servers() β invalid org name (contains dots, underscores, or spaces) |
The alphanumeric+hyphen org-name validation was explicitly tightened in #598 to prevent shell injection; the anyhow::bail! error path is never entered by any test |
Call mcpg_servers() with an org containing "my.org" or "my org" and assert is_err() with a message containing "invalid characters" |
tools/azure_devops/extension.rs |
mcpg_servers() β invalid toolset name (contains dots, underscores, spaces) |
Same pattern: toolset names are injected as npx ... -d <toolset> CLI args; the guard is only triggered by explicitly invalid input, and no test currently triggers it |
Call mcpg_servers() with toolsets: ["wit.invalid"] and assert is_err() |
safeoutputs/missing_data.rs |
execute_impl() β execution path never invoked |
missing_data has only 2 tests (test_result_has_correct_name, test_params_converts_to_result). Unlike report_incomplete.rs (which has a test_execute_impl_includes_context_when_present), missing_data's executor is never called in tests β the success message format and context-appending branch are both untested |
Add #[tokio::test] async fn test_execute_impl_produces_success_message() that constructs a result and calls execute_sanitized, asserting exec.success == true and exec.message.contains("API docs") |
Suggested Test Cases
1. mcpg_servers() β invalid org name rejects special characters
Add to the // ββ AzureDevOpsExtension βββββββββββββββββββββββββββββββββββββββ block in src/compile/extensions/tests.rs:
#[test]
fn test_ado_mcpg_servers_rejects_org_with_dot() {
let fm = minimal_front_matter();
let ctx = CompileContext::for_test_with_org(&fm, "my.corp");
let ext = AzureDevOpsExtension::new(AzureDevOpsToolConfig::Enabled(true));
let err = ext.mcpg_servers(&ctx).unwrap_err();
assert!(
err.to_string().contains("invalid characters"),
"Should reject org names with dots: {err}"
);
}
#[test]
fn test_ado_mcpg_servers_rejects_org_with_underscore() {
let fm = minimal_front_matter();
let ctx = CompileContext::for_test_with_org(&fm, "my_org");
let ext = AzureDevOpsExtension::new(AzureDevOpsToolConfig::Enabled(true));
let err = ext.mcpg_servers(&ctx).unwrap_err();
assert!(
err.to_string().contains("invalid characters"),
"Should reject org names with underscores: {err}"
);
}
2. mcpg_servers() β invalid toolset name rejects special characters
#[test]
fn test_ado_mcpg_servers_rejects_toolset_with_dot() {
let fm = minimal_front_matter();
let ctx = CompileContext::for_test_with_org(&fm, "myorg");
let config = AzureDevOpsToolConfig::Object(AzureDevOpsToolConfigObject {
enabled: true,
org: None,
toolsets: vec!["wit.invalid".to_string()],
allowed: vec![],
});
let ext = AzureDevOpsExtension::new(config);
let err = ext.mcpg_servers(&ctx).unwrap_err();
assert!(
err.to_string().contains("invalid characters") || err.to_string().contains("Invalid ADO toolset"),
"Should reject toolset names with dots: {err}"
);
}
3. missing_data.rs β execution path
Add to src/safeoutputs/missing_data.rs tests block:
#[tokio::test]
async fn test_execute_impl_success_without_context() {
let mut result: MissingDataResult = MissingDataParams {
data_type: "API docs".to_string(),
reason: "needed for integration".to_string(),
context: None,
}
.try_into()
.unwrap();
let exec = result
.execute_sanitized(&crate::safeoutputs::ExecutionContext::default())
.await
.unwrap();
assert!(exec.success, "missing-data should report success");
assert!(
exec.message.contains("API docs"),
"message should include data_type: {}",
exec.message
);
assert!(
exec.message.contains("needed for integration"),
"message should include reason: {}",
exec.message
);
}
#[tokio::test]
async fn test_execute_impl_success_with_context() {
let mut result: MissingDataResult = MissingDataParams {
data_type: "Database schema".to_string(),
reason: "required to generate migrations".to_string(),
context: Some("tried checking docs.example.com".to_string()),
}
.try_into()
.unwrap();
let exec = result
.execute_sanitized(&crate::safeoutputs::ExecutionContext::default())
.await
.unwrap();
assert!(exec.success);
assert!(
exec.message.contains("[tried checking docs.example.com]"),
"context should be appended in brackets: {}",
exec.message
);
}
Coverage Summary
| Module |
Public/Key Fns |
Tests |
Notes |
tools/azure_devops/extension.rs |
mcpg_servers |
valid org: 1, invalid org: 0 |
Error path added/tightened in #598 has no test; is_err() path for org+toolset never entered |
safeoutputs/missing_data.rs |
execute_impl / execute_sanitized |
0 |
report_incomplete.rs (same structure) has an executor test; missing_data does not |
This issue was created by the automated test gap finder. Previous runs: 2026-05-18 (issue #647), 2026-05-01 (issue #376). Open issues: #376, #647. Modules audited this cycle: tools/azure_devops/extension, safeoutputs/missing_data, ado/discovery, compile/extensions/tests. Total tests found: 1,817 (was 1,733 last cycle, +84).
Generated by Test Gap Finder Β· gh-aw-workflow-call-id: githubnext/ado-aw/test-gap-finder
Generated by Test Gap Finder Β· β 5.8M Β· β·
Test Gap Analysis
Test suite snapshot: 1,817 total tests β all pass β
Previous open issues still active: #376 (lean runtime, logging, MCP tools list), #647 (stage/job header repos branch, update_check parse_version).
This issue tracks three new gaps discovered in the 2026-05-20 cycle.
Priority Gaps
tools/azure_devops/extension.rsmcpg_servers()β invalid org name (contains dots, underscores, or spaces)anyhow::bail!error path is never entered by any testmcpg_servers()with an org containing"my.org"or"my org"and assertis_err()with a message containing"invalid characters"tools/azure_devops/extension.rsmcpg_servers()β invalid toolset name (contains dots, underscores, spaces)npx ... -d <toolset>CLI args; the guard is only triggered by explicitly invalid input, and no test currently triggers itmcpg_servers()withtoolsets: ["wit.invalid"]and assertis_err()safeoutputs/missing_data.rsexecute_impl()β execution path never invokedmissing_datahas only 2 tests (test_result_has_correct_name,test_params_converts_to_result). Unlikereport_incomplete.rs(which has atest_execute_impl_includes_context_when_present),missing_data's executor is never called in tests β the success message format and context-appending branch are both untested#[tokio::test] async fn test_execute_impl_produces_success_message()that constructs a result and callsexecute_sanitized, assertingexec.success == trueandexec.message.contains("API docs")Suggested Test Cases
1.
mcpg_servers()β invalid org name rejects special charactersAdd to the
// ββ AzureDevOpsExtension βββββββββββββββββββββββββββββββββββββββblock insrc/compile/extensions/tests.rs:2.
mcpg_servers()β invalid toolset name rejects special characters3.
missing_data.rsβ execution pathAdd to
src/safeoutputs/missing_data.rstests block:Coverage Summary
tools/azure_devops/extension.rsmcpg_serversis_err()path for org+toolset never enteredsafeoutputs/missing_data.rsexecute_impl/execute_sanitizedreport_incomplete.rs(same structure) has an executor test;missing_datadoes notThis issue was created by the automated test gap finder. Previous runs: 2026-05-18 (issue #647), 2026-05-01 (issue #376). Open issues: #376, #647. Modules audited this cycle:
tools/azure_devops/extension,safeoutputs/missing_data,ado/discovery,compile/extensions/tests. Total tests found: 1,817 (was 1,733 last cycle, +84).