developer(ET): auto-commit from developer run_id=363
This commit is contained in:
101
tests/test_plane_issue_link.py
Normal file
101
tests/test_plane_issue_link.py
Normal file
@@ -0,0 +1,101 @@
|
||||
"""ORCH-067 — Group D: the shared plane_issue_link helper (AC-12).
|
||||
|
||||
``plane_issue_link(work_item_id, plane_issue_id=None, project_id=None, repo=None)``
|
||||
is the single source of the clickable issue number for cards AND alerts. It
|
||||
returns ``<a href=...>ORCH-NNN</a>`` when a usable Plane browser URL can be built,
|
||||
and ``html.escape(work_item_id)`` otherwise. It must NEVER raise — including on
|
||||
None arguments and a loopback base. No DB and no network are touched by this unit
|
||||
(project_id is passed explicitly here), so these are pure settings-driven cases.
|
||||
|
||||
Test id TC-12 from 04-test-plan.yaml.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
os.environ.setdefault("ORCH_PLANE_API_TOKEN", "test-token")
|
||||
os.environ.setdefault("ORCH_GITEA_TOKEN", "test-token")
|
||||
|
||||
import pytest # noqa: E402
|
||||
|
||||
from src import notifications as N # noqa: E402
|
||||
|
||||
|
||||
def _set(monkeypatch, **kw):
|
||||
s = N._get_settings()
|
||||
for k, v in kw.items():
|
||||
monkeypatch.setattr(s, k, v, raising=False)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# TC-12 / AC-12 — full data -> HTML link wrapping the number
|
||||
# --------------------------------------------------------------------------- #
|
||||
def test_tc12_full_data_returns_anchor(monkeypatch):
|
||||
_set(monkeypatch, plane_web_url="https://plane.example.org",
|
||||
plane_workspace_slug="acme")
|
||||
out = N.plane_issue_link("ORCH-067", plane_issue_id="iss-1",
|
||||
project_id="proj-9")
|
||||
expected = "https://plane.example.org/acme/projects/proj-9/issues/iss-1/"
|
||||
assert out == f'<a href="{expected}">ORCH-067</a>'
|
||||
|
||||
|
||||
def test_tc12_web_url_fallbacks_to_api_url(monkeypatch):
|
||||
# plane_web_url empty -> non-loopback plane_api_url is used as the base.
|
||||
_set(monkeypatch, plane_web_url="",
|
||||
plane_api_url="https://plane-fallback.example.org",
|
||||
plane_workspace_slug="acme")
|
||||
out = N.plane_issue_link("ORCH-067", plane_issue_id="iss-1",
|
||||
project_id="proj-9")
|
||||
assert 'href="https://plane-fallback.example.org/acme/' in out
|
||||
assert ">ORCH-067</a>" in out
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# TC-12 / AC-12 — insufficient data -> escaped number, NEVER an anchor
|
||||
# --------------------------------------------------------------------------- #
|
||||
@pytest.mark.parametrize("settings_kw,call_kw,reason", [
|
||||
({"plane_web_url": "", "plane_api_url": ""},
|
||||
{"plane_issue_id": "iss-1", "project_id": "proj-9"}, "no web base"),
|
||||
({"plane_web_url": "http://localhost:8091", "plane_api_url": ""},
|
||||
{"plane_issue_id": "iss-1", "project_id": "proj-9"}, "loopback base"),
|
||||
({"plane_web_url": "https://plane.example.org", "plane_workspace_slug": ""},
|
||||
{"plane_issue_id": "iss-1", "project_id": "proj-9"}, "no workspace"),
|
||||
({"plane_web_url": "https://plane.example.org", "plane_workspace_slug": "acme"},
|
||||
{"plane_issue_id": None, "project_id": "proj-9"}, "no issue id"),
|
||||
({"plane_web_url": "https://plane.example.org", "plane_workspace_slug": "acme"},
|
||||
{"plane_issue_id": "iss-1", "project_id": ""}, "no project id"),
|
||||
])
|
||||
def test_tc12_insufficient_data_returns_plain_number(monkeypatch, settings_kw,
|
||||
call_kw, reason):
|
||||
_set(monkeypatch, plane_web_url="https://plane.example.org",
|
||||
plane_api_url="http://localhost:8091", plane_workspace_slug="acme")
|
||||
_set(monkeypatch, **settings_kw)
|
||||
out = N.plane_issue_link("ORCH-067", repo=None, **call_kw)
|
||||
assert out == "ORCH-067", reason
|
||||
assert "<a href=" not in out
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# TC-12 / AC-12 — html-escaping + never raises on hostile / None input
|
||||
# --------------------------------------------------------------------------- #
|
||||
def test_tc12_escapes_work_item_id_in_link(monkeypatch):
|
||||
_set(monkeypatch, plane_web_url="https://plane.example.org",
|
||||
plane_workspace_slug="acme")
|
||||
out = N.plane_issue_link("ORCH&<67>", plane_issue_id="iss-1",
|
||||
project_id="proj-9")
|
||||
assert ">ORCH&<67></a>" in out # label escaped inside the anchor
|
||||
assert "<a href=" in out
|
||||
|
||||
|
||||
def test_tc12_escapes_work_item_id_unlinked(monkeypatch):
|
||||
_set(monkeypatch, plane_web_url="", plane_api_url="")
|
||||
out = N.plane_issue_link("ORCH&<67>", plane_issue_id="iss-1",
|
||||
project_id="proj-9")
|
||||
assert out == "ORCH&<67>" # escaped, no anchor
|
||||
|
||||
|
||||
def test_tc12_none_args_never_raise(monkeypatch):
|
||||
# All-None must not raise and must yield a (possibly empty) string.
|
||||
out = N.plane_issue_link(None)
|
||||
assert isinstance(out, str)
|
||||
# None work_item_id -> empty label, no anchor.
|
||||
assert "<a href=" not in out
|
||||
Reference in New Issue
Block a user