bookwyrm/bookwyrm/tests/views/test_search.py
2024-04-24 15:35:19 +02:00

184 lines
7 KiB
Python

""" test for app action functionality """
import json
from unittest.mock import patch
from django.contrib.auth.models import AnonymousUser
from django.http import JsonResponse
from django.template.response import TemplateResponse
from django.test import TestCase
from django.test.client import RequestFactory
from bookwyrm import models, views
from bookwyrm.book_search import SearchResult
from bookwyrm.settings import BASE_URL
from bookwyrm.tests.validate_html import validate_html
class Views(TestCase):
"""tag views"""
@classmethod
def setUpTestData(cls):
"""we need basic test data and mocks"""
with (
patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"),
patch("bookwyrm.activitystreams.populate_stream_task.delay"),
patch("bookwyrm.lists_stream.populate_lists_task.delay"),
):
cls.local_user = models.User.objects.create_user(
"mouse@local.com",
"mouse@mouse.com",
"mouseword",
local=True,
localname="mouse",
remote_id="https://example.com/users/mouse",
)
cls.work = models.Work.objects.create(title="Test Work")
cls.book = models.Edition.objects.create(
title="Test Book",
remote_id="https://example.com/book/1",
parent_work=cls.work,
)
models.SiteSettings.objects.create()
def setUp(self):
"""individual test setup"""
self.factory = RequestFactory()
def test_search_json_response(self):
"""searches local data only and returns book data in json format"""
view = views.Search.as_view()
request = self.factory.get("", {"q": "Test Book"})
with patch("bookwyrm.views.search.is_api_request") as is_api:
is_api.return_value = True
response = view(request)
self.assertIsInstance(response, JsonResponse)
data = json.loads(response.content)
self.assertEqual(len(data), 1)
self.assertEqual(data[0]["title"], "Test Book")
self.assertEqual(data[0]["key"], f"{BASE_URL}/book/{self.book.id}")
def test_search_no_query(self):
"""just the search page"""
view = views.Search.as_view()
# we need a connector for this, sorry
request = self.factory.get("")
with patch("bookwyrm.views.search.is_api_request") as is_api:
is_api.return_value = False
response = view(request)
self.assertIsInstance(response, TemplateResponse)
validate_html(response.render())
def test_search_books(self):
"""searches remote connectors"""
view = views.Search.as_view()
connector = models.Connector.objects.create(
identifier="example.com",
connector_file="openlibrary",
base_url="https://example.com",
books_url="https://example.com/books",
covers_url="https://example.com/covers",
search_url="https://example.com/search?q=",
)
mock_result = SearchResult(title="Mock Book", connector=connector, key="hello")
request = self.factory.get("", {"q": "Test Book", "remote": True})
request.user = self.local_user
with patch("bookwyrm.views.search.is_api_request") as is_api:
is_api.return_value = False
with patch("bookwyrm.connectors.connector_manager.search") as remote_search:
remote_search.return_value = [
{"results": [mock_result], "connector": connector}
]
response = view(request)
self.assertIsInstance(response, TemplateResponse)
validate_html(response.render())
local_results = response.context_data["results"]
self.assertEqual(local_results[0].title, "Test Book")
connector_results = response.context_data["remote_results"]
self.assertEqual(connector_results[0]["results"][0].title, "Mock Book")
def test_search_book_anonymous(self):
"""Don't search remote for logged out user"""
view = views.Search.as_view()
connector = models.Connector.objects.create(
identifier="example.com",
connector_file="openlibrary",
base_url="https://example.com",
books_url="https://example.com/books",
covers_url="https://example.com/covers",
search_url="https://example.com/search?q=",
)
mock_result = SearchResult(title="Mock Book", connector=connector, key="hello")
request = self.factory.get("", {"q": "Test Book", "remote": True})
anonymous_user = AnonymousUser
anonymous_user.is_authenticated = False
request.user = anonymous_user
with patch("bookwyrm.views.search.is_api_request") as is_api:
is_api.return_value = False
with patch("bookwyrm.connectors.connector_manager.search") as remote_search:
remote_search.return_value = [
{"results": [mock_result], "connector": connector}
]
response = view(request)
self.assertIsInstance(response, TemplateResponse)
validate_html(response.render())
local_results = response.context_data["results"]
self.assertEqual(local_results[0].title, "Test Book")
connector_results = response.context_data.get("remote_results")
self.assertIsNone(connector_results)
def test_search_users(self):
"""searches remote connectors"""
view = views.Search.as_view()
request = self.factory.get("", {"q": "mouse", "type": "user"})
request.user = self.local_user
response = view(request)
self.assertIsInstance(response, TemplateResponse)
validate_html(response.render())
self.assertEqual(response.context_data["results"][0], self.local_user)
def test_search_users_logged_out(self):
"""searches remote connectors"""
view = views.Search.as_view()
request = self.factory.get("", {"q": "mouse", "type": "user"})
anonymous_user = AnonymousUser
anonymous_user.is_authenticated = False
request.user = anonymous_user
response = view(request)
validate_html(response.render())
self.assertTrue("results" in response.context_data)
def test_search_lists(self):
"""searches remote connectors"""
with (
patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"),
patch("bookwyrm.lists_stream.remove_list_task.delay"),
):
booklist = models.List.objects.create(
user=self.local_user, name="test list"
)
view = views.Search.as_view()
request = self.factory.get("", {"q": "test", "type": "list"})
request.user = self.local_user
response = view(request)
self.assertIsInstance(response, TemplateResponse)
validate_html(response.render())
self.assertEqual(response.context_data["results"][0], booklist)