The reviewer is read-only (R3), so Gitea refuses it resolving a thread. Now each reply says whether it settles its thread, and a settled reply carries <!-- nisse-review: settled -->. nisse-dev, as the author, resolves every comment on that thread's line when it watches the PR, and doesn't take the settled reply as a point to answer. scripts/resolve_settled.py does the same for PRs made by hand. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
74 lines
2.3 KiB
Python
74 lines
2.3 KiB
Python
"""scripts/resolve_settled.py: the threads nisse-review settled on a PR made
|
|
by hand get resolved, and nothing else does."""
|
|
|
|
import importlib.util
|
|
from pathlib import Path
|
|
from types import ModuleType
|
|
|
|
import httpx
|
|
import pytest
|
|
|
|
from nisse_core.gitea import SETTLED_MARKER, GiteaClient
|
|
|
|
SCRIPT = Path(__file__).parent.parent / "scripts" / "resolve_settled.py"
|
|
|
|
|
|
def script() -> ModuleType:
|
|
spec = importlib.util.spec_from_file_location("resolve_settled", SCRIPT)
|
|
assert spec and spec.loader
|
|
module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
def comment(n: int, line: int, body: str, resolver: str | None = None) -> dict:
|
|
return {
|
|
"id": n,
|
|
"body": body,
|
|
"path": "a.py",
|
|
"position": line,
|
|
"resolver": {"login": resolver} if resolver else None,
|
|
}
|
|
|
|
|
|
def fake_gitea(comments: list[dict], resolved: list[int]) -> GiteaClient:
|
|
def handler(request: httpx.Request) -> httpx.Response:
|
|
path = request.url.path
|
|
if path.endswith("/resolve"):
|
|
resolved.append(int(path.split("/")[-2]))
|
|
return httpx.Response(200)
|
|
if path.endswith("/reviews"):
|
|
return httpx.Response(200, json=[{"id": 1, "comments_count": 1}])
|
|
return httpx.Response(200, json=comments)
|
|
|
|
return GiteaClient("https://g.test", "tok", transport=httpx.MockTransport(handler))
|
|
|
|
|
|
def test_it_resolves_the_settled_threads_only(
|
|
capsys: pytest.CaptureFixture[str],
|
|
) -> None:
|
|
resolved: list[int] = []
|
|
gitea = fake_gitea(
|
|
[
|
|
comment(1, 3, "a point"),
|
|
comment(2, 3, "an answer"),
|
|
comment(3, 3, f"Conceded.\n\n{SETTLED_MARKER}"),
|
|
comment(4, 9, "still held"),
|
|
comment(5, 12, f"done\n{SETTLED_MARKER}", resolver="dongar"),
|
|
],
|
|
resolved,
|
|
)
|
|
assert script().main(["168"], gitea) == 0
|
|
assert resolved == [1, 2, 3]
|
|
assert "resolved 3 comment(s) on dev/nisse#168: 1, 2, 3" in capsys.readouterr().out
|
|
|
|
|
|
def test_it_reads_teas_default_login(tmp_path: Path) -> None:
|
|
config = tmp_path / "config.yml"
|
|
config.write_text(
|
|
"logins:\n"
|
|
" - {name: a, url: https://a.test, token: ta, default: false}\n"
|
|
" - {name: b, url: https://b.test, token: tb, default: true}\n"
|
|
)
|
|
assert script().tea_login(config) == ("https://b.test", "tb")
|