From 6b622bac3ee1761cb3488aa163879181bbb757c3 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 27 Aug 2024 13:49:15 -0700 Subject: [PATCH] Adds more tests --- bookwyrm/tests/views/books/test_book.py | 42 +++++++++ bookwyrm/tests/views/test_suggestion_list.py | 95 +++++++++++++++++--- bookwyrm/views/books/books.py | 8 +- bookwyrm/views/suggestion_list.py | 4 +- 4 files changed, 132 insertions(+), 17 deletions(-) diff --git a/bookwyrm/tests/views/books/test_book.py b/bookwyrm/tests/views/books/test_book.py index afd0fa47e..49f2815dd 100644 --- a/bookwyrm/tests/views/books/test_book.py +++ b/bookwyrm/tests/views/books/test_book.py @@ -51,6 +51,11 @@ class BookViews(TestCase): remote_id="https://example.com/book/1", parent_work=cls.work, ) + cls.another_book = models.Edition.objects.create( + title="Another Example Edition", + remote_id="https://example.com/book/1", + parent_work=models.Work.objects.create(title="Another Work"), + ) models.SiteSettings.objects.create() @@ -134,6 +139,43 @@ class BookViews(TestCase): self.assertEqual(result.status_code, 200) self.assertEqual(result.context_data["statuses"].object_list[0], quote) + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") + def test_book_page_suggestions(self, *_): + """there are so many views, this just makes sure it LOADS""" + view = views.Book.as_view() + suggestion_list = models.SuggestionList.objects.create(suggests_for=self.work) + + request = self.factory.get("") + request.user = self.local_user + with patch("bookwyrm.views.books.books.is_api_request") as is_api: + is_api.return_value = False + result = view(request, self.book.id, user_statuses="review") + self.assertIsInstance(result, TemplateResponse) + validate_html(result.render()) + + self.assertEqual(result.status_code, 200) + self.assertEqual(result.context_data["suggestion_list"], suggestion_list) + + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") + def test_book_page_suggestions_with_items(self, *_): + """there are so many views, this just makes sure it LOADS""" + view = views.Book.as_view() + suggestion_list = models.SuggestionList.objects.create(suggests_for=self.work) + models.SuggestionListItem.objects.create( + book_list=suggestion_list, user=self.local_user, book=self.another_book + ) + + request = self.factory.get("") + request.user = self.local_user + with patch("bookwyrm.views.books.books.is_api_request") as is_api: + is_api.return_value = False + result = view(request, self.book.id, user_statuses="review") + self.assertIsInstance(result, TemplateResponse) + validate_html(result.render()) + + self.assertEqual(result.status_code, 200) + self.assertEqual(result.context_data["suggestion_list"], suggestion_list) + def test_book_page_invalid_id(self): """there are so many views, this just makes sure it LOADS""" view = views.Book.as_view() diff --git a/bookwyrm/tests/views/test_suggestion_list.py b/bookwyrm/tests/views/test_suggestion_list.py index 3eedfcc3a..5cdb9fad8 100644 --- a/bookwyrm/tests/views/test_suggestion_list.py +++ b/bookwyrm/tests/views/test_suggestion_list.py @@ -1,6 +1,7 @@ """ test for app action functionality """ from unittest.mock import patch +from django.core.exceptions import PermissionDenied from django.test import TestCase from django.test.client import RequestFactory @@ -28,6 +29,14 @@ class BookViews(TestCase): localname="mouse", remote_id="https://example.com/users/mouse", ) + cls.another_user = models.User.objects.create_user( + "rat@local.com", + "rat@rat.com", + "ratword", + local=True, + localname="rat", + remote_id="https://example.com/users/rat", + ) cls.work = models.Work.objects.create(title="Test Work") cls.book = models.Edition.objects.create( title="Example Edition", @@ -48,7 +57,7 @@ class BookViews(TestCase): def test_suggestion_list_get(self, *_): """start a suggestion list for a book""" - models.SuggestionList.objects.create(suggests_for=self.book) + models.SuggestionList.objects.create(suggests_for=self.work) view = views.SuggestionList.as_view() request = self.factory.get("") request.user = self.local_user @@ -58,7 +67,7 @@ class BookViews(TestCase): def test_suggestion_list_get_json(self, *_): """start a suggestion list for a book""" - models.SuggestionList.objects.create(suggests_for=self.book) + models.SuggestionList.objects.create(suggests_for=self.work) view = views.SuggestionList.as_view() request = self.factory.get("") request.user = self.local_user @@ -70,40 +79,106 @@ class BookViews(TestCase): def test_suggestion_create(self, *_): """start a suggestion list for a book""" - self.assertFalse(hasattr(self.book, "suggestion_list")) + self.assertFalse(hasattr(self.work, "suggestion_list")) view = views.SuggestionList.as_view() form = forms.SuggestionListForm() - form.data["suggests_for"] = self.book.id + form.data["suggests_for"] = self.work.id request = self.factory.post("", form.data) request.user = self.local_user view(request, self.book.id) - self.book.refresh_from_db() - self.assertTrue(hasattr(self.book, "suggestion_list")) + self.work.refresh_from_db() + self.assertTrue(hasattr(self.work, "suggestion_list")) - suggestion_list = self.book.suggestion_list - self.assertEqual(suggestion_list.suggests_for, self.book) + suggestion_list = self.work.suggestion_list + self.assertEqual(suggestion_list.suggests_for, self.work) self.assertEqual(suggestion_list.privacy, "public") self.assertEqual(suggestion_list.user, get_representative()) def test_book_add_suggestion(self, *_): """Add a book to the recommendation list""" - suggestion_list = models.SuggestionList.objects.create(suggests_for=self.book) + suggestion_list = models.SuggestionList.objects.create(suggests_for=self.work) view = views.book_add_suggestion + form = forms.SuggestionListItemForm() form.data["user"] = self.local_user.id form.data["book"] = self.another_book.id form.data["book_list"] = suggestion_list.id form.data["notes"] = "hello" + request = self.factory.post("", form.data) request.user = self.local_user - view(request, self.book.id) + view(request, self.work.id) self.assertEqual(suggestion_list.suggestionlistitem_set.count(), 1) item = suggestion_list.suggestionlistitem_set.first() self.assertEqual(item.book, self.another_book) self.assertEqual(item.user, self.local_user) self.assertEqual(item.notes, "hello") + + def test_book_remove_suggestion(self, *_): + """Remove a book from the recommendation list""" + suggestion_list = models.SuggestionList.objects.create(suggests_for=self.work) + item = models.SuggestionListItem.objects.create( + book_list=suggestion_list, user=self.local_user, book=self.another_book + ) + self.assertEqual(suggestion_list.suggestionlistitem_set.count(), 1) + + view = views.book_remove_suggestion + request = self.factory.post("", {"item": item.id}) + request.user = self.local_user + + view(request, self.work.id) + + self.assertEqual(suggestion_list.suggestionlistitem_set.count(), 0) + + def test_book_remove_suggestion_without_permission(self, *_): + """Remove a book from the recommendation list""" + suggestion_list = models.SuggestionList.objects.create(suggests_for=self.work) + item = models.SuggestionListItem.objects.create( + book_list=suggestion_list, user=self.local_user, book=self.another_book + ) + self.assertEqual(suggestion_list.suggestionlistitem_set.count(), 1) + + view = views.book_remove_suggestion + request = self.factory.post("", {"item": item.id}) + request.user = self.another_user + + with self.assertRaises(PermissionDenied): + view(request, self.work.id) + + self.assertEqual(suggestion_list.suggestionlistitem_set.count(), 1) + + def test_endorse_suggestion(self, *_): + """Endorse a suggestion""" + suggestion_list = models.SuggestionList.objects.create(suggests_for=self.work) + item = models.SuggestionListItem.objects.create( + book_list=suggestion_list, user=self.local_user, book=self.another_book + ) + self.assertEqual(item.endorsement.count(), 0) + view = views.endorse_suggestion + request = self.factory.post("") + request.user = self.another_user + + view(request, self.work.id, item.id) + + self.assertEqual(item.endorsement.count(), 1) + + def test_endorse_suggestion_by_self(self, *_): + """Endorse a suggestion error handling""" + suggestion_list = models.SuggestionList.objects.create(suggests_for=self.work) + item = models.SuggestionListItem.objects.create( + book_list=suggestion_list, user=self.local_user, book=self.another_book + ) + self.assertEqual(item.endorsement.count(), 0) + view = views.endorse_suggestion + request = self.factory.post("") + request.user = self.local_user + + view(request, self.work.id, item.id) + + # no impact + self.assertEqual(item.endorsement.count(), 0) diff --git a/bookwyrm/views/books/books.py b/bookwyrm/views/books/books.py index 2f4a59942..ad7f62e88 100644 --- a/bookwyrm/views/books/books.py +++ b/bookwyrm/views/books/books.py @@ -137,10 +137,10 @@ class Book(View): "quotation_count": book.quotation_set.filter(**filters).count(), } if hasattr(book.parent_work, "suggestion_list"): - suggestion_list = book.parent_work.suggestion_list - data["suggestion_list"] = suggestion_list + data["suggestion_list"] = book.parent_work.suggestion_list data["items"] = ( - suggestion_list.suggestionlistitem_set.prefetch_related( + data["suggestion_list"] + .suggestionlistitem_set.prefetch_related( "user", "book", "book__authors", "endorsement" ) .annotate(endorsement_count=Count("endorsement")) @@ -148,7 +148,7 @@ class Book(View): ) data["suggested_books"] = get_list_suggestions( - suggestion_list, + data["suggestion_list"], request.user, query=request.GET.get("suggestion_query", ""), ignore_book=book.parent_work, diff --git a/bookwyrm/views/suggestion_list.py b/bookwyrm/views/suggestion_list.py index e6187ac6f..a2cc9403e 100644 --- a/bookwyrm/views/suggestion_list.py +++ b/bookwyrm/views/suggestion_list.py @@ -95,7 +95,6 @@ class SuggestionList(View): @login_required @require_POST -@transaction.atomic def book_add_suggestion(request, book_id): """put a book on the suggestion list""" _ = get_object_or_404( @@ -106,8 +105,7 @@ def book_add_suggestion(request, book_id): if not form.is_valid(): return Book().get(request, book_id, add_failed=True) - item = form.save(request, commit=False) - item.save() + form.save(request) return redirect_to_referer(request)