"""Matching a requested URL against already-open tabs.""" from __future__ import annotations import pytest from browser_cli.url_match import ( find_reusable_tab, needs_navigation, normalize_mode, url_key, urls_match, ) def test_canonical_key_ignores_cosmetic_differences(): assert url_key("https://Example.com:443/app/?b=2&a=1#top") == url_key("https://www.example.com/app?a=1&b=2") def test_canonical_key_keeps_meaningful_differences(): assert url_key("https://example.com/app") != url_key("http://example.com/app") assert url_key("https://example.com/app") != url_key("https://example.com:8080/app") assert url_key("https://example.com/a") != url_key("https://example.com/b") assert url_key("https://example.com/a?x=1") != url_key("https://example.com/a?x=2") def test_non_urls_have_no_key(): assert url_key(None) is None assert url_key("") is None assert url_key("not a url") is None @pytest.mark.parametrize("reuse,reuse_domain,expected", [ (False, False, "none"), (None, False, "none"), (True, False, "similar"), ("exact", False, "exact"), ("ORIGIN", False, "origin"), (False, True, "origin"), (True, True, "origin"), ]) def test_flags_fold_into_modes(reuse, reuse_domain, expected): assert normalize_mode(reuse, reuse_domain) == expected def test_unknown_mode_is_rejected(): with pytest.raises(ValueError, match="Unknown reuse mode"): normalize_mode("fuzzy") def test_exact_mode_only_matches_identical_strings(): assert urls_match("https://example.com/app", "https://example.com/app", "exact") assert not urls_match("https://example.com/app", "https://example.com/app/", "exact") def test_similar_mode_matches_the_same_page(): assert urls_match("https://example.com/app/", "https://example.com/app#section", "similar") assert not urls_match("https://example.com/app", "https://example.com/other", "similar") assert not urls_match("https://example.com/app", "https://other.example/app", "similar") def test_similar_mode_treats_a_site_root_request_as_the_site(): assert urls_match("https://example.com/", "https://example.com/web/streams", "similar") assert not urls_match("https://example.com/web", "https://example.com/web/streams", "similar") def test_origin_mode_matches_any_page_of_the_site(): assert urls_match("https://example.com/web", "https://example.com/other", "origin") assert not urls_match("https://example.com/web", "http://example.com/web", "origin") def test_none_mode_never_matches(): assert not urls_match("https://example.com", "https://example.com", "none") assert find_reusable_tab([{"id": 1, "url": "https://example.com"}], "https://example.com", "none") is None def test_closest_tab_wins(): tabs = [ {"id": 1, "url": "https://example.com/web/streams/detail"}, {"id": 2, "url": "https://example.com/web"}, {"id": 3, "url": "https://example.com/web/?tab=1#x"}, ] assert find_reusable_tab(tabs, "https://example.com/web", "similar")["id"] == 2 assert find_reusable_tab(tabs, "https://example.com/", "similar")["id"] == 2 def test_matching_works_on_sdk_tab_objects(): from browser_cli.models import Tab tabs = [Tab(id=4, window_id=1, active=False, url="https://example.com/app?a=1")] assert find_reusable_tab(tabs, "https://example.com/app/#top?", "none") is None assert find_reusable_tab(tabs, "https://example.com/app?a=1", "similar").id == 4 def test_navigation_is_skipped_only_for_the_same_page(): assert not needs_navigation("https://example.com/app/", "https://example.com/app#top") assert needs_navigation("https://example.com/app", "https://example.com/app/next") assert needs_navigation(None, "https://example.com/app")