Files
mono/shared/tests/test_url_utils.py
giles 00efbc2a35 Add unit test coverage for shared pure-logic modules (240 tests)
Track 1.1 of master plan: expand from sexp-only tests to cover
DTOs, HTTP signatures, HMAC auth, URL utilities, Jinja filters,
calendar helpers, config freeze, activity bus registry, parse
utilities, sexp helpers, error classes, and jinja bridge render API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:34:37 +00:00

109 lines
3.7 KiB
Python

"""Tests for URL join utilities."""
from __future__ import annotations
from shared.utils import _join_url_parts, join_url, normalize_text, soup_of
# ---------------------------------------------------------------------------
# _join_url_parts
# ---------------------------------------------------------------------------
class TestJoinUrlParts:
def test_empty_list(self):
assert _join_url_parts([]) == ""
def test_single_part(self):
assert _join_url_parts(["hello"]) == "hello"
def test_two_parts(self):
assert _join_url_parts(["https://example.com", "path"]) == "https://example.com/path"
def test_preserves_scheme(self):
assert _join_url_parts(["https://example.com/", "/api/", "v1"]) == "https://example.com/api/v1"
def test_trailing_slash_preserved(self):
result = _join_url_parts(["https://example.com", "path/"])
assert result.endswith("/")
def test_no_trailing_slash_when_last_has_none(self):
result = _join_url_parts(["https://example.com", "path"])
assert not result.endswith("/")
def test_strips_internal_slashes(self):
result = _join_url_parts(["https://example.com/", "/api/", "/v1"])
assert result == "https://example.com/api/v1"
def test_absolute_url_mid_list_replaces(self):
result = _join_url_parts(["https://old.com/foo", "https://new.com/bar"])
assert result == "https://new.com/bar"
def test_query_string_attached(self):
result = _join_url_parts(["https://example.com/path", "?key=val"])
assert result == "https://example.com/path?key=val"
def test_fragment_attached(self):
result = _join_url_parts(["https://example.com/path", "#section"])
assert result == "https://example.com/path#section"
def test_filters_none_and_empty(self):
result = _join_url_parts(["https://example.com", None, "", "path"])
assert result == "https://example.com/path"
def test_no_scheme(self):
result = _join_url_parts(["/foo", "bar", "baz/"])
assert result == "foo/bar/baz/"
def test_multiple_segments(self):
result = _join_url_parts(["https://example.com", "a", "b", "c/"])
assert result == "https://example.com/a/b/c/"
# ---------------------------------------------------------------------------
# join_url
# ---------------------------------------------------------------------------
class TestJoinUrl:
def test_string_input(self):
assert join_url("https://example.com") == "https://example.com"
def test_list_input(self):
assert join_url(["https://example.com", "path"]) == "https://example.com/path"
def test_tuple_input(self):
assert join_url(("https://example.com", "path/")) == "https://example.com/path/"
# ---------------------------------------------------------------------------
# normalize_text
# ---------------------------------------------------------------------------
class TestNormalizeText:
def test_collapses_whitespace(self):
assert normalize_text(" hello world ") == "hello world"
def test_tabs_and_newlines(self):
assert normalize_text("hello\t\nworld") == "hello world"
def test_empty_string(self):
assert normalize_text("") == ""
def test_none_input(self):
assert normalize_text(None) == ""
def test_single_word(self):
assert normalize_text(" word ") == "word"
# ---------------------------------------------------------------------------
# soup_of
# ---------------------------------------------------------------------------
class TestSoupOf:
def test_parses_html(self):
s = soup_of("<p>Hello <b>world</b></p>")
assert s.find("b").text == "world"
def test_empty_html(self):
s = soup_of("")
assert s.text == ""