from pygitweb.actions import project_board_link
from pygitweb.templates_env import env, html_format, html_join, html_link, render_page, trusted_html


def test_table_escapes_plain_text() -> None:
	html = env.get_template("table.html").render(
		cols=["Name"],
		rows=[["<script>alert(1)</script>"]],
	)
	assert "<script>" not in html
	assert "&lt;script&gt;alert(1)&lt;/script&gt;" in html


def test_table_renders_link_without_double_escaping() -> None:
	cell = html_link("/p?a=commit&h=abc", "a<b", id="commit-link")
	html = env.get_template("table.html").render(cols=["Commit"], rows=[[cell]])
	assert 'href="/p?a=commit&amp;h=abc"' in html
	assert 'id="commit-link"' in html
	assert ">a&lt;b</a>" in html
	assert "&amp;amp;" not in html


def test_html_join_escapes_text_and_keeps_markup() -> None:
	joined = html_join([html_link("/a", "x"), " <", "a&b", ">"])
	assert str(joined) == '<a href="/a">x</a> &lt;a&amp;b&gt;'


def test_trusted_html_is_not_escaped_in_table() -> None:
	html = env.get_template("table.html").render(
		cols=["V"],
		rows=[[trusted_html("<em>ok</em>")]],
	)
	assert "<em>ok</em>" in html


def test_html_format_escapes_values() -> None:
	assert str(html_format("<pre>{}</pre>", "<hi>")) == "<pre>&lt;hi&gt;</pre>"


def test_render_page_uses_base_template_and_escapes_text() -> None:
	resp = render_page("message.html", title="Hello <x>", paragraphs=["Hi <there>"])
	text = resp.body.decode()
	assert text.startswith("<!DOCTYPE html>")
	assert "<title>Hello &lt;x&gt;</title>" in text
	assert "Hi &lt;there&gt;" in text
	assert text.count('<div class="page">') == 1
	assert "</body></html>" in text
	assert text.index('<div class="container-xl">') < text.index("Hi &lt;there&gt;")
	assert text.index("Hi &lt;there&gt;") < text.index("</body></html>")


def test_project_list_template_emits_links() -> None:
	resp = render_page(
		"project_list.html",
		title="Projects",
		notice=None,
		projects=[
			{
				"href": "/project/a<b",
				"path": "a<b",
				"descr": "d&d",
				"board_href": "/board/create?project=a%3Cb",
				"board_text": "create board",
				"board_style": None,
			}
		],
	)
	text = resp.body.decode()
	assert 'href="/project/a&lt;b"' in text
	assert ">a&lt;b</a>" in text
	assert "d&amp;d" in text
	assert ">create board</a>" in text
	assert 'href="/board/create?project=a%3Cb">create board</a>' in text


def test_project_board_link_points_at_existing_board(monkeypatch) -> None:
	monkeypatch.setattr(
		"pygitweb.actions.git_get_references",
		lambda _project, _prefix: [("Tasks", "refs/tags/boards/Tasks")],
	)
	assert str(project_board_link("demo")) == '<a href="/project/demo/board/">project board</a>'


def test_project_board_link_offers_create_when_missing(monkeypatch) -> None:
	monkeypatch.setattr("pygitweb.actions.git_get_references", lambda _project, _prefix: [])
	monkeypatch.setattr("pygitweb.actions.settings.AUTH", True)
	html = str(project_board_link("my proj"))
	assert 'href="/board/create?project=my%20proj"' in html
	assert 'style="color: #999; cursor: not-allowed;"' in html
	assert ">create board</a>" in html

	monkeypatch.setattr("pygitweb.actions.settings.AUTH", False)
	plain = str(project_board_link("my proj"))
	assert "style=" not in plain
	assert ">create board</a>" in plain