"""Unit tests for connectors/jira/validation.py — issue #83 defenses."""

import pytest

from connectors.jira.validation import is_valid_issue_key, safe_join_under


class TestIsValidIssueKey:
    @pytest.mark.parametrize("key", ["TEST-1", "PROJ-42", "ABC-123", "AB1-9", "A-1", "AB42-1234567"])
    def test_valid(self, key):
        assert is_valid_issue_key(key) is True

    @pytest.mark.parametrize(
        "key",
        [
            "",
            "test-1",          # lowercase
            "TEST",            # no dash
            "TEST-",           # no number
            "-1",              # no project
            "TEST-abc",        # non-numeric
            "../etc/passwd",
            "TEST/1",
            "TEST-1\x00",
            "TEST-1\r\n",
            "1-TEST",          # starts with digit
            "TEST-1.json",
            "ABC_DEF-1",       # underscore — Atlassian rejects, so do we
            "А-1",             # Cyrillic А (looks like Latin A)
            "TEST-٣",           # Arabic-Indic 3 — \\d would match, [0-9] doesn't
            "TEST-৩",           # Bengali 3
            "TEST-३",           # Devanagari 3
            "A" * 100 + "-1",  # absurd project length
            "A-" + "9" * 20,   # absurd issue number length
            None,
            123,
            ["TEST-1"],
        ],
    )
    def test_invalid(self, key):
        assert is_valid_issue_key(key) is False


class TestSafeJoinUnder:
    def test_normal_join(self, tmp_path):
        result = safe_join_under(tmp_path, "issues", "TEST-1.json")
        assert result == (tmp_path / "issues" / "TEST-1.json").resolve()

    def test_traversal_blocked(self, tmp_path):
        with pytest.raises(ValueError, match="Path traversal"):
            safe_join_under(tmp_path, "..", "evil")

    def test_nested_traversal_blocked(self, tmp_path):
        with pytest.raises(ValueError, match="Path traversal"):
            safe_join_under(tmp_path, "issues", "..", "..", "etc", "passwd")

    def test_absolute_path_blocked(self, tmp_path):
        with pytest.raises(ValueError, match="Path traversal"):
            safe_join_under(tmp_path, "/etc/passwd")

    def test_symlink_escape_blocked(self, tmp_path):
        # Create a symlink inside base that points outside.
        outside = tmp_path.parent / "outside_target"
        outside.mkdir(exist_ok=True)
        link = tmp_path / "escape"
        link.symlink_to(outside)
        with pytest.raises(ValueError, match="Path traversal"):
            safe_join_under(tmp_path, "escape", "x.json")
