Files
rune/tests/test_auto_label_priority.py
Nick 3186566514 fix(gitea): reconcile priority labels by numeric Gitea ID (#2467)
Issue #2467 carried both P0 and P2 because name-based label DELETE returned 404 and the workflow silently ignored it. Use the numeric ID API, enforce exactly one priority, clear stale unprioritized flags, and execute the workflow JavaScript against a Gitea-compatible fake in regression tests.
2026-10-05 22:14:47 +01:00

42 lines
1.8 KiB
Python

"""Exercise the Gitea auto-label script, not just its YAML shape."""
import shutil
import subprocess
from pathlib import Path
import pytest
import yaml
def test_duplicate_priority_reconciled_by_numeric_id(tmp_path):
node = shutil.which("node")
if node is None:
pytest.skip("node not installed")
workflow = yaml.safe_load((Path(__file__).parents[1] / ".gitea/workflows/auto-label.yml").read_text())
script = workflow["jobs"]["auto-label"]["steps"][0]["with"]["script"]
fixture = """
const labels = [{name:'P0 — critical',id:23},{name:'P2 — medium',id:25}];
const context = {payload:{action:'labeled',issue:{state:'open',number:2467,
title:'Scaffolding completion',body:'kind: feature\\nspine protocol'}},
repo:{owner:'conductor',repo:'rune'}};
const github = {rest:{issues:{
listLabelsOnIssue: async () => ({data:labels.map(x => ({...x}))}),
addLabels: async ({labels:names}) => {
for (const name of names) labels.push({name,id:100+labels.length});
}
}},request: async (route,{id}) => {
if (!route.includes('/labels/{id}') || typeof id !== 'number')
throw new Error('Gitea requires numeric label ID');
const index=labels.findIndex(x => x.id === id);
if (index < 0) throw new Error('missing label ID '+id);
labels.splice(index,1);
}};
"""
js = (fixture + "\n(async () => {\n" + script + "\n})().then(() => {\n"
+ "const priorities=labels.filter(x => /^P[0-3] — /.test(x.name));\n"
+ "if (priorities.length !== 1 || priorities[0].id !== 23) process.exitCode=1;\n"
+ "}).catch(e => {console.error(e);process.exitCode=1;});\n")
path = tmp_path / "priority.js"
path.write_text(js)
run = subprocess.run([node, str(path)], capture_output=True, text=True, timeout=10)
assert run.returncode == 0, run.stdout + run.stderr