Add search

This commit is contained in:
Joakim Hellsén 2024-03-26 03:08:58 +01:00
commit 942965d262
No known key found for this signature in database
GPG key ID: D196AE66FEBE1DC9
5 changed files with 90 additions and 3 deletions

View file

@ -244,3 +244,50 @@ class TestStats(TestCase):
response: str = get_db_size()
assert isinstance(response, str), f"Expected a string, got {response}"
assert "kB" in response, f"Expected 'kB' in response, got {response}"
class TestSearch(TestCase):
def setUp(self) -> None:
"""Create a test feed."""
self.domain: Domain = Domain.objects.create(
name="feedvault",
url="feedvault.se",
)
self.user: User = User.objects.create_user(
username="testuser",
email="hello@feedvault.se",
password="testpassword", # noqa: S106
)
self.feed: Feed = Feed.objects.create(
user=self.user,
bozo=False,
feed_url="https://feedvault.se/feed.xml",
domain=self.domain,
)
def test_search_page(self) -> None:
"""Test if the search page is accessible."""
response: HttpResponse = self.client.get(reverse("search"))
assert response.status_code == 200, f"Expected 200, got {response.status_code}"
def test_search_page_search(self) -> None:
"""Search for a term that doesn't exist."""
response: HttpResponse = self.client.get(reverse("search"), {"q": "test"})
assert response.status_code == 200, f"Expected 200, got {response.status_code}"
assert (
"No results found" in response.content.decode()
), f"Expected 'No results found' in response, got {response.content}"
def test_search_page_search_found(self) -> None:
"""Search for a term that exists."""
response: HttpResponse = self.client.get(reverse("search"), {"q": "feedvault"})
assert response.status_code == 200, f"Expected 200, got {response.status_code}"
assert "feedvault" in response.content.decode(), f"Expected 'feedvault' in response, got {response.content}"
def test_search_page_search_empty(self) -> None:
"""Search for an empty term. This should redirect to the feeds page."""
response: HttpResponse = self.client.get(reverse("search"), {"q": ""})
assert response.status_code == 200, f"Expected 302, got {response.status_code}"
assert (
"Latest Feeds" in response.content.decode()
), f"Expected 'Latest Feeds' in response, got {response.content}"

View file

@ -36,6 +36,7 @@ urlpatterns: list = [
{"sitemaps": sitemaps},
name="django.contrib.sitemaps.views.sitemap",
),
path(route="search/", view=views.SearchView.as_view(), name="search"),
path(route="domains/", view=views.DomainsView.as_view(), name="domains"),
path(route="domain/<int:domain_id>/", view=views.DomainView.as_view(), name="domain"),
path("api/v1/", api_v1.urls), # type: ignore # noqa: PGH003

View file

@ -43,7 +43,7 @@ class IndexView(View):
def get(self, request: HttpRequest) -> HttpResponse:
"""Load the index page."""
template = loader.get_template(template_name="index.html")
context = {
context: dict[str, str] = {
"description": "FeedVault allows users to archive and search their favorite web feeds.",
"keywords": "feed, rss, atom, archive, rss list",
"author": "TheLovinator",
@ -95,7 +95,7 @@ class FeedsView(View):
context: dict[str, str | Page | int] = {
"feeds": pages,
"description": "An archive of all feeds",
"description": "An archive of web feeds",
"keywords": "feed, rss, atom, archive, rss list",
"author": "TheLovinator",
"canonical": "https://feedvault.se/feeds/",
@ -450,3 +450,27 @@ class DomainView(View):
}
return render(request, "domain.html", context)
class SearchView(View):
"""Search view."""
def get(self, request: HtmxHttpRequest) -> HttpResponse:
"""Load the search page."""
query: str | None = request.GET.get("q", None)
if not query:
return FeedsView().get(request)
feeds: BaseManager[Feed] = Feed.objects.filter(feed_url__icontains=query).order_by("-created_at")[:100]
context = {
"feeds": feeds,
"description": f"Search results for {query}",
"keywords": f"feed, rss, atom, archive, rss list, {query}",
"author": "TheLovinator",
"canonical": f"https://feedvault.se/search/?q={query}",
"title": f"Search results for {query}",
"query": query,
}
return render(request, "search.html", context)

View file

@ -96,7 +96,7 @@
</small>
</div>
<div class="right">
<form action="#" method="get">
<form action="{% url 'search' %}" method="get">
<input type="text" name="q" placeholder="Search" />
<button type="submit">Search</button>
</form>

15
templates/search.html Normal file
View file

@ -0,0 +1,15 @@
{% extends "base.html" %}
{% block content %}
<h2>
Searched for:
"{{ query|default:"Search" }}"
</h2>
{% if feeds %}
{% for feed in feeds %}
<a href="{% url 'feed' feed.id %}">{{ feed.feed_url|default:"Unknown Feed" }} →</a>
<br>
{% endfor %}
{% else %}
<p>No results found.</p>
{% endif %}
{% endblock %}