Files
nisse/tests/test_resolve_settled.py
dongarandClaude Opus 5.5 33d030590d
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m58s
CI / e2e (pull_request) Successful in 7m41s
nisse-review marks a reply that settles its thread; the PR's author resolves it
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
2026-10-19 22:06:56 +00:00

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")