Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 36 additions & 23 deletions tests/unit/test_agent_completion_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2902,6 +2902,10 @@ def test_scheduled_scanner_detects_frozen_intent_changes(self):
labels: [{name: 'copilot-rabbit'}],
body: manifest + '\nFixes #870'
};
const prWithoutManifest = {
...base,
body: 'Fixes #870'
};
const rows = [
['valid', base, issue, true, []],
['draft', {...base, draft: true}, issue, true, ['draft_pr']],
Expand Down Expand Up @@ -2933,7 +2937,8 @@ def test_scheduled_scanner_detects_frozen_intent_changes(self):
run_id: 'run-1'
}) + ' -->\nFixes #870'
}, issue, true, ['agent_login_mismatch']],
['missing headings', base, {body: ''}, true, [
['missing headings use parsed manifest fallback', base, {body: ''}, true, []],
['missing headings without manifest fallback', prWithoutManifest, {body: ''}, true, [
'missing_agent_login',
'missing_agent_run_id'
]],
Expand Down Expand Up @@ -3024,20 +3029,21 @@ def test_scheduled_scanner_detects_frozen_intent_changes(self):
body: '## Agent login\nexample-agent[bot]\n' +
'## Agent run id\nrun-b'
};
const identityA = scheduledContractIdentity(870, issueA, true);
const identityB = scheduledContractIdentity(871, issueB, true);
const allNull = scheduledContractIdentity(0, null, true);
const noPrContext = null;
const identityA = scheduledContractIdentity(870, issueA, noPrContext, true);
const identityB = scheduledContractIdentity(871, issueB, noPrContext, true);
const allNull = scheduledContractIdentity(0, null, noPrContext, true);
const missingLogin = scheduledContractIdentity(870, {
body: '## Agent run id\nrun-a'
}, true);
}, noPrContext, true);
const missingRun = scheduledContractIdentity(870, {
body: '## Agent login\nexample-agent[bot]'
}, true);
}, noPrContext, true);
if (JSON.stringify(identityA) !== JSON.stringify({
issue_number: 870,
agent_login: 'example-agent[bot]',
run_id: 'run-a'
}) || scheduledContractIdentity(870, issueA, false) !== null) {
}) || scheduledContractIdentity(870, issueA, noPrContext, false) !== null) {
throw new Error('contract identity extraction failed');
}
const previous = {
Expand Down Expand Up @@ -3269,7 +3275,10 @@ def test_legacy_run_id_requires_an_unambiguous_delimiter(self):
workflow,
"function legacyRunId(",
)
self.assertEqual(len(functions), 1)
# legacyRunId is intentionally duplicated in the scheduled sweep script
# and the Collect repository evidence script because github-script steps
# execute in isolated runtimes and cannot share helper scope.
self.assertEqual(len(functions), 2)

assertions = r"""
const rows = [
Expand All @@ -3293,13 +3302,14 @@ def test_legacy_run_id_requires_an_unambiguous_delimiter(self):
}
}
"""
completed = subprocess.run(
["node", "-e", functions[0] + assertions],
check=False,
capture_output=True,
text=True,
)
self.assertEqual(completed.returncode, 0, completed.stderr)
for function in functions:
completed = subprocess.run(
["node", "-e", function + assertions],
check=False,
capture_output=True,
text=True,
)
self.assertEqual(completed.returncode, 0, completed.stderr)

def test_extract_run_id_duplicate_parser_matches_legacy(self):
workflow = self._workflow()
Expand Down Expand Up @@ -3356,7 +3366,9 @@ def test_pr_body_fallback_populates_identity_when_issue_fields_absent(self):
workflow,
"function legacyRunId(",
)
self.assertEqual(len(functions), 1)
# This enforces identical parsing behavior across the scheduled sweep
# and collector copies of legacyRunId.
self.assertEqual(len(functions), 2)

assertions = r"""
function section(body, headings) {
Expand Down Expand Up @@ -3426,13 +3438,14 @@ def test_pr_body_fallback_populates_identity_when_issue_fields_absent(self):
throw new Error('issue login should win over fallbacks: ' + fromIssue.login);
}
"""
completed = subprocess.run(
["node", "-e", functions[0] + assertions],
check=False,
capture_output=True,
text=True,
)
self.assertEqual(completed.returncode, 0, completed.stderr)
for function in functions:
completed = subprocess.run(
["node", "-e", function + assertions],
check=False,
capture_output=True,
text=True,
)
self.assertEqual(completed.returncode, 0, completed.stderr)

def test_mismatch_errors_require_manifest_match(self):
workflow = self._workflow()
Expand Down
Loading