Files
links/tests/test_search_aliases.py
T
OpenClaw Sub-agent 595b99446b feat: ⌘K command palette + restore green nav (fixes mobile menu collapse)
- Command palette (Ctrl/Cmd+K or nav search icon): /search/palette/ groups
  links/pages/posts with jump/detail/edit actions, keyboard navigation
- Hero: stats inline under search pill, ⌘K chip on desktop, Random Images
  broken-image fallback to elegant SVG placeholder (layout untouched)
- Restore original green nav (bg-custom-blue). The frosted-glass nav from
  1.0.401 broke the mobile Menu dropdown: backdrop-filter creates a
  containing block, collapsing the fixed full-screen dropdown to 3px
- Palette tests: +5 cases (grouping, post match, management fields,
  empty query, no results)
2026-08-02 11:20:11 +10:00

161 lines
6.0 KiB
Python

"""Tests for the enhanced /search/aliases/ endpoint (search-driven library)."""
import pytest
from django.test import Client
from django.urls import reverse
from links.models import Link, Tag
@pytest.fixture
def db_links(db):
"""A small, deterministic link library for search tests."""
l1 = Link.objects.create(
alias="github", original_url="https://github.com", link_type="LINK", click_count=5,
description="Code hosting",
)
l2 = Link.objects.create(
alias="gitlab", original_url="https://gitlab.com", link_type="LINK", click_count=2,
description="Another code host",
)
l3 = Link.objects.create(
alias="docs", original_url="https://docs.example.com/{page,default=index}", link_type="LINK",
click_count=0, description="Template link",
)
l4 = Link.objects.create(
alias="notify", original_url="", link_type="ACTION",
action_config={"action_type": "discord_send"}, click_count=0,
)
tag = Tag.objects.create(name="dev")
l1.tags.add(tag)
return [l1, l2, l3, l4]
@pytest.mark.django_db
def test_search_aliases_matches_alias_and_returns_enriched_fields(client, db_links):
resp = client.get(reverse("search_aliases"), {"q": "git"})
assert resp.status_code == 200
data = resp.json()
aliases = {item["alias"] for item in data}
assert aliases == {"github", "gitlab"}
github = next(i for i in data if i["alias"] == "github")
# Enriched management fields are present and correct
assert github["id"] == db_links[0].id
assert github["link_type"] == "LINK"
assert github["detail_url"] == f"/link/{db_links[0].id}/"
assert github["edit_url"] == f"/link/{db_links[0].id}/edit/"
assert github["click_count"] == 5
assert github["description"] == "Code hosting"
assert github["original_url"] == "https://github.com"
# Backwards-compatible fields (hero autocomplete relies on these)
assert github["url"].endswith("/github/")
@pytest.mark.django_db
def test_search_aliases_matches_original_url(client, db_links):
resp = client.get(reverse("search_aliases"), {"q": "gitlab.com"})
assert resp.status_code == 200
assert [i["alias"] for i in resp.json()] == ["gitlab"]
@pytest.mark.django_db
def test_search_aliases_matches_description(client, db_links):
resp = client.get(reverse("search_aliases"), {"q": "template link"})
assert resp.status_code == 200
assert [i["alias"] for i in resp.json()] == ["docs"]
@pytest.mark.django_db
def test_search_aliases_matches_tag_name(client, db_links):
resp = client.get(reverse("search_aliases"), {"q": "dev"})
assert resp.status_code == 200
assert [i["alias"] for i in resp.json()] == ["github"]
@pytest.mark.django_db
def test_search_aliases_priority_exact_first(client, db_links):
resp = client.get(reverse("search_aliases"), {"q": "github"})
assert resp.status_code == 200
assert resp.json()[0]["alias"] == "github"
@pytest.mark.django_db
def test_search_aliases_empty_query_returns_recent(client, db_links):
# Touch l2 so it becomes the most recently updated (auto_now needs the
# field explicitly listed in update_fields to refresh).
db_links[1].click_count = 3
db_links[1].save(update_fields=["click_count", "updated_at"])
resp = client.get(reverse("search_aliases"))
assert resp.status_code == 200
data = resp.json()
assert len(data) >= 4
assert data[0]["alias"] == "gitlab" # most recently updated first
@pytest.mark.django_db
def test_search_aliases_action_type_surfaces(client, db_links):
resp = client.get(reverse("search_aliases"), {"q": "notify"})
assert resp.status_code == 200
item = resp.json()[0]
assert item["link_type"] == "ACTION"
assert item["detail_url"] == f"/link/{db_links[3].id}/"
@pytest.mark.django_db
def test_search_aliases_no_results(client, db_links):
resp = client.get(reverse("search_aliases"), {"q": "zzzznothing"})
assert resp.status_code == 200
assert resp.json() == []
# ---------------- /search/palette/ (⌘K command palette) ----------------
@pytest.mark.django_db
def test_palette_groups_links_pages_posts(client, db_links):
from links.models import Page, Post
Page.objects.create(url="https://github.com/about", title="About GitHub", summary="dev")
Post.objects.create(title="Weekly digest", summary="dev roundup", content="body")
resp = client.get(reverse("search_palette"), {"q": "github"})
assert resp.status_code == 200
data = resp.json()
# links group matches alias/url; pages group matches title/url
assert any(i["alias"] == "github" for i in data["links"])
assert any(i["title"] == "About GitHub" for i in data["pages"])
# posts group does not match "github"
assert data["posts"] == []
@pytest.mark.django_db
def test_palette_matches_posts(client, db_links):
from links.models import Post
Post.objects.create(title="Weekly digest", summary="dev roundup", content="body")
resp = client.get(reverse("search_palette"), {"q": "digest"})
data = resp.json()
assert any(i["title"] == "Weekly digest" for i in data["posts"])
assert data["posts"][0]["edit_url"].startswith("/ui/posts/")
@pytest.mark.django_db
def test_palette_link_entry_has_management_fields(client, db_links):
resp = client.get(reverse("search_palette"), {"q": "notify"})
data = resp.json()
item = next(i for i in data["links"] if i["alias"] == "notify")
assert item["link_type"] == "ACTION"
assert item["detail_url"] == f"/link/{db_links[3].id}/"
assert item["edit_url"] == f"/link/{db_links[3].id}/edit/"
@pytest.mark.django_db
def test_palette_empty_query_returns_recent_links(client, db_links):
resp = client.get(reverse("search_palette"))
data = resp.json()
assert len(data["links"]) >= 4
assert data["pages"] == []
assert data["posts"] == []
@pytest.mark.django_db
def test_palette_no_results(client, db_links):
resp = client.get(reverse("search_palette"), {"q": "zzzznothing"})
data = resp.json()
assert data == {"links": [], "pages": [], "posts": []}