def test_handle_status_mentions(self, _): """@mention a user in a post""" view = views.CreateStatus.as_view() with patch( "bookwyrm.preview_images.generate_user_preview_image_task.delay" ): user = models.User.objects.create_user( "rat@%s" % DOMAIN, "*****@*****.**", "password", local=True, localname="rat", ) form = forms.CommentForm({ "content": "hi @rat", "user": self.local_user.id, "book": self.book.id, "privacy": "public", }) request = self.factory.post("", form.data) request.user = self.local_user with patch("bookwyrm.activitystreams.ActivityStream.add_status" ) as redis_mock: view(request, "comment") self.assertTrue(redis_mock.called) status = models.Status.objects.get() self.assertEqual(list(status.mention_users.all()), [user]) self.assertEqual(models.Notification.objects.get().user, user) self.assertEqual(status.content, '<p>hi <a href="%s">@rat</a></p>' % user.remote_id)
def test_create_status_mentions(self, *_): """@mention a user in a post""" view = views.CreateStatus.as_view() user = models.User.objects.create_user( f"rat@{DOMAIN}", "*****@*****.**", "password", local=True, localname="rat", ) form = forms.CommentForm({ "content": "hi @rat", "user": self.local_user.id, "book": self.book.id, "privacy": "public", }) request = self.factory.post("", form.data) request.user = self.local_user view(request, "comment") status = models.Status.objects.get() self.assertEqual(list(status.mention_users.all()), [user]) self.assertEqual(models.Notification.objects.get().user, user) self.assertEqual(status.content, f'<p>hi <a href="{user.remote_id}">@rat</a></p>')
def test_edit_status_permission_denied(self, *_): """update an existing status""" status = models.Status.objects.create(content="status", user=self.local_user) view = views.CreateStatus.as_view() form = forms.CommentForm({ "content": "hi", "user": self.local_user.id, "book": self.book.id, "privacy": "public", }) request = self.factory.post("", form.data) request.user = self.remote_user with self.assertRaises(PermissionDenied): view(request, "comment", existing_status_id=status.id)
def test_handle_status_reply_with_mentions(self, _): """reply to a post with an @mention'ed user""" view = views.CreateStatus.as_view() with patch( "bookwyrm.preview_images.generate_user_preview_image_task.delay" ): user = models.User.objects.create_user("rat", "*****@*****.**", "password", local=True, localname="rat") form = forms.CommentForm({ "content": "hi @[email protected]", "user": self.local_user.id, "book": self.book.id, "privacy": "public", }) request = self.factory.post("", form.data) request.user = self.local_user with patch("bookwyrm.activitystreams.ActivityStream.add_status" ) as redis_mock: view(request, "comment") self.assertTrue(redis_mock.called) status = models.Status.objects.get() form = forms.ReplyForm({ "content": "right", "user": user.id, "privacy": "public", "reply_parent": status.id, }) request = self.factory.post("", form.data) request.user = user with patch("bookwyrm.activitystreams.ActivityStream.add_status" ) as redis_mock: view(request, "reply") self.assertTrue(redis_mock.called) reply = models.Status.replies(status).first() self.assertEqual(reply.content, "<p>right</p>") self.assertEqual(reply.user, user) # the mentioned user in the parent post is only included if @'ed self.assertFalse(self.remote_user in reply.mention_users.all()) self.assertTrue(self.local_user in reply.mention_users.all())
def test_handle_status(self): ''' create a status ''' view = views.CreateStatus.as_view() form = forms.CommentForm({ 'content': 'hi', 'user': self.local_user.id, 'book': self.book.id, 'privacy': 'public', }) request = self.factory.post('', form.data) request.user = self.local_user with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): view(request, 'comment') status = models.Comment.objects.get() self.assertEqual(status.content, '<p>hi</p>') self.assertEqual(status.user, self.local_user) self.assertEqual(status.book, self.book)
def test_handle_status(self): """ create a status """ view = views.CreateStatus.as_view() form = forms.CommentForm({ "content": "hi", "user": self.local_user.id, "book": self.book.id, "privacy": "public", }) request = self.factory.post("", form.data) request.user = self.local_user with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): view(request, "comment") status = models.Comment.objects.get() self.assertEqual(status.content, "<p>hi</p>") self.assertEqual(status.user, self.local_user) self.assertEqual(status.book, self.book)
def home_tab(request, tab): ''' user's homepage with activity feed ''' # TODO: why on earth would this be where the pagination is set page_size = 15 try: page = int(request.GET.get('page', 1)) except ValueError: page = 1 max_books = 5 book_count = 0 preset_shelves = ['reading', 'read', 'to-read'] suggested_books = [] for preset in preset_shelves: limit = max_books - book_count shelf = request.user.shelf_set.get(identifier=preset) shelf_books = shelf.shelfbook_set.order_by( '-updated_date').all()[:limit] shelf_preview = { 'name': shelf.name, 'books': [s.book for s in shelf_books] } suggested_books.append(shelf_preview) book_count += len(shelf_preview['books']) activities = get_activity_feed(request.user, tab) activity_count = activities.count() activities = activities[(page - 1) * page_size:page * page_size] next_page = '/?page=%d#feed' % (page + 1) prev_page = '/?page=%d#feed' % (page - 1) data = { 'title': 'Updates Feed', 'user': request.user, 'suggested_books': suggested_books, 'activities': activities, 'review_form': forms.ReviewForm(), 'quotation_form': forms.QuotationForm(), 'tab': tab, 'comment_form': forms.CommentForm(), 'next': next_page if activity_count > (page_size * page) else None, 'prev': prev_page if page > 1 else None, } return TemplateResponse(request, 'feed.html', data)
def test_create_status_comment(self, *_): """create a status""" view = views.CreateStatus.as_view() form = forms.CommentForm({ "content": "hi", "user": self.local_user.id, "book": self.book.id, "privacy": "public", }) request = self.factory.post("", form.data) request.user = self.local_user view(request, "comment") status = models.Comment.objects.get() self.assertEqual(status.raw_content, "hi") self.assertEqual(status.content, "<p>hi</p>") self.assertEqual(status.user, self.local_user) self.assertEqual(status.book, self.book) self.assertIsNone(status.edited_date)
def test_handle_status(self, _): """create a status""" view = views.CreateStatus.as_view() form = forms.CommentForm({ "content": "hi", "user": self.local_user.id, "book": self.book.id, "privacy": "public", }) request = self.factory.post("", form.data) request.user = self.local_user with patch("bookwyrm.activitystreams.ActivityStream.add_status" ) as redis_mock: view(request, "comment") self.assertTrue(redis_mock.called) status = models.Comment.objects.get() self.assertEqual(status.content, "<p>hi</p>") self.assertEqual(status.user, self.local_user) self.assertEqual(status.book, self.book)
def test_handle_status_reply_with_mentions(self): ''' reply to a post with an @mention'ed user ''' view = views.CreateStatus.as_view() user = models.User.objects.create_user('rat', '*****@*****.**', 'password', local=True, localname='rat') form = forms.CommentForm({ 'content': 'hi @[email protected]', 'user': self.local_user.id, 'book': self.book.id, 'privacy': 'public', }) request = self.factory.post('', form.data) request.user = self.local_user with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): view(request, 'comment') status = models.Status.objects.get() form = forms.ReplyForm({ 'content': 'right', 'user': user.id, 'privacy': 'public', 'reply_parent': status.id }) request = self.factory.post('', form.data) request.user = user with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): view(request, 'reply') reply = models.Status.replies(status).first() self.assertEqual(reply.content, '<p>right</p>') self.assertEqual(reply.user, user) # the mentioned user in the parent post is only included if @'ed self.assertFalse(self.remote_user in reply.mention_users.all()) self.assertTrue(self.local_user in reply.mention_users.all())
def test_edit_status_success(self, mock, *_): """update an existing status""" status = models.Status.objects.create(content="status", user=self.local_user) self.assertIsNone(status.edited_date) view = views.CreateStatus.as_view() form = forms.CommentForm({ "content": "hi", "user": self.local_user.id, "book": self.book.id, "privacy": "public", }) request = self.factory.post("", form.data) request.user = self.local_user view(request, "comment", existing_status_id=status.id) activity = json.loads(mock.call_args_list[1][1]["args"][1]) self.assertEqual(activity["type"], "Update") self.assertEqual(activity["object"]["id"], status.remote_id) status.refresh_from_db() self.assertEqual(status.content, "<p>hi</p>") self.assertIsNotNone(status.edited_date)
def test_create_status_reply_with_mentions(self, *_): """reply to a post with an @mention'ed user""" view = views.CreateStatus.as_view() user = models.User.objects.create_user("rat", "*****@*****.**", "password", local=True, localname="rat") form = forms.CommentForm({ "content": "hi @[email protected]", "user": self.local_user.id, "book": self.book.id, "privacy": "public", }) request = self.factory.post("", form.data) request.user = self.local_user view(request, "comment") status = models.Status.objects.get() form = forms.ReplyForm({ "content": "right", "user": user.id, "privacy": "public", "reply_parent": status.id, }) request = self.factory.post("", form.data) request.user = user view(request, "reply") reply = models.Status.replies(status).first() self.assertEqual(reply.content, "<p>right</p>") self.assertEqual(reply.user, user) # the mentioned user in the parent post is only included if @'ed self.assertFalse(self.remote_user in reply.mention_users.all()) self.assertTrue(self.local_user in reply.mention_users.all())
def test_handle_status_mentions(self): ''' @mention a user in a post ''' view = views.CreateStatus.as_view() user = models.User.objects.create_user('rat@%s' % DOMAIN, '*****@*****.**', 'password', local=True, localname='rat') form = forms.CommentForm({ 'content': 'hi @rat', 'user': self.local_user.id, 'book': self.book.id, 'privacy': 'public', }) request = self.factory.post('', form.data) request.user = self.local_user with patch('bookwyrm.models.activitypub_mixin.broadcast_task.delay'): view(request, 'comment') status = models.Status.objects.get() self.assertEqual(list(status.mention_users.all()), [user]) self.assertEqual(models.Notification.objects.get().user, user) self.assertEqual(status.content, '<p>hi <a href="%s">@rat</a></p>' % user.remote_id)
def comment(request): ''' create a book comment ''' form = forms.CommentForm(request.POST) return handle_status(request, form)
def book_page(request, book_id): ''' info about a book ''' book = models.Book.objects.select_subclasses().get(id=book_id) if is_api_request(request): return JsonResponse(book.to_activity(), encoder=ActivityEncoder) if isinstance(book, models.Work): book = book.default_edition if not book: return HttpResponseNotFound() work = book.parent_work if not work: return HttpResponseNotFound() reviews = models.Review.objects.filter(book__in=work.edition_set.all(), ) reviews = get_activity_feed(request.user, 'federated', model=reviews) user_tags = [] readthroughs = [] if request.user.is_authenticated: user_tags = models.Tag.objects.filter( book=book, user=request.user).values_list('identifier', flat=True) readthroughs = models.ReadThrough.objects.filter( user=request.user, book=book, ).order_by('start_date') rating = reviews.aggregate(Avg('rating')) tags = models.Tag.objects.filter(book=book).values( 'book', 'name', 'identifier').distinct().all() data = { 'title': book.title, 'book': book, 'reviews': reviews.filter(content__isnull=False), 'ratings': reviews.filter(content__isnull=True), 'rating': rating['rating__avg'], 'tags': tags, 'user_tags': user_tags, 'review_form': forms.ReviewForm(), 'quotation_form': forms.QuotationForm(), 'comment_form': forms.CommentForm(), 'readthroughs': readthroughs, 'tag_form': forms.TagForm(), 'path': '/book/%s' % book_id, 'cover_form': forms.CoverForm(instance=book), 'info_fields': [ { 'name': 'ISBN', 'value': book.isbn_13 }, { 'name': 'OCLC number', 'value': book.oclc_number }, { 'name': 'OpenLibrary ID', 'value': book.openlibrary_key }, { 'name': 'Goodreads ID', 'value': book.goodreads_key }, { 'name': 'Format', 'value': book.physical_format }, { 'name': 'Pages', 'value': book.pages }, ], } return TemplateResponse(request, 'book.html', data)