Add search
This commit is contained in:
parent
b5b240fb99
commit
942965d262
5 changed files with 90 additions and 3 deletions
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
15
templates/search.html
Normal 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 %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue