From b4c60c059197acc08b6a179d795c5be173f8da46 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 21 Dec 2020 14:25:10 -0800 Subject: [PATCH 1/6] Catches exception thrown when boosting unknown statuses --- bookwyrm/activitypub/base_activity.py | 7 +++++-- bookwyrm/tests/test_incoming.py | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/bookwyrm/activitypub/base_activity.py b/bookwyrm/activitypub/base_activity.py index c344c120..b9facf2f 100644 --- a/bookwyrm/activitypub/base_activity.py +++ b/bookwyrm/activitypub/base_activity.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, fields, MISSING from json import JSONEncoder from django.apps import apps -from django.db import transaction +from django.db import IntegrityError, transaction from bookwyrm.connectors import ConnectorException, get_data from bookwyrm.tasks import app @@ -92,7 +92,10 @@ class ActivityObject: with transaction.atomic(): # we can't set many to many and reverse fields on an unsaved object - instance.save() + try: + instance.save() + except IntegrityError as e: + raise ActivitySerializerError(e) # add many to many fields, which have to be set post-save for field in instance.many_to_many_fields: diff --git a/bookwyrm/tests/test_incoming.py b/bookwyrm/tests/test_incoming.py index 7e58da86..0269c64c 100644 --- a/bookwyrm/tests/test_incoming.py +++ b/bookwyrm/tests/test_incoming.py @@ -8,6 +8,7 @@ from django.http import HttpResponseBadRequest, HttpResponseNotAllowed, \ HttpResponseNotFound from django.test import TestCase from django.test.client import RequestFactory +import responses from bookwyrm import models, incoming @@ -421,6 +422,25 @@ class Incoming(TestCase): self.assertEqual(notification.related_status, self.status) + @responses.activate + def test_handle_discarded_boost(self): + ''' test a boost of a mastodon status that will be discarded ''' + activity = { + 'type': 'Announce', + 'id': 'http://www.faraway.com/boost/12', + 'actor': self.remote_user.remote_id, + 'object': self.status.to_activity(), + } + responses.add( + responses.GET, + 'http://www.faraway.com/boost/12', + json={'id': 'http://www.faraway.com/boost/12'}, + status=200) + incoming.handle_boost(activity) + self.assertEqual(models.Boost.objects.count(), 0) + + + def test_handle_unboost(self): ''' undo a boost ''' activity = { From fa1ddf359a26df3cffc5b91d8f21d26abf77e449 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 15 Dec 2020 13:59:37 -0800 Subject: [PATCH 2/6] create single outgoing tests file --- .../tests/data/ap_generated_shelve_note.json | 52 +++++ bookwyrm/tests/outgoing/__init__.py | 1 - bookwyrm/tests/outgoing/test_follow.py | 80 -------- .../tests/outgoing/test_remote_webfinger.py | 61 ------ bookwyrm/tests/outgoing/test_shelving.py | 69 ------- bookwyrm/tests/test_outgoing.py | 194 ++++++++++++++++++ 6 files changed, 246 insertions(+), 211 deletions(-) create mode 100644 bookwyrm/tests/data/ap_generated_shelve_note.json delete mode 100644 bookwyrm/tests/outgoing/__init__.py delete mode 100644 bookwyrm/tests/outgoing/test_follow.py delete mode 100644 bookwyrm/tests/outgoing/test_remote_webfinger.py delete mode 100644 bookwyrm/tests/outgoing/test_shelving.py create mode 100644 bookwyrm/tests/test_outgoing.py diff --git a/bookwyrm/tests/data/ap_generated_shelve_note.json b/bookwyrm/tests/data/ap_generated_shelve_note.json new file mode 100644 index 00000000..cc2fc7b7 --- /dev/null +++ b/bookwyrm/tests/data/ap_generated_shelve_note.json @@ -0,0 +1,52 @@ +{ + "id": "https://example.com/users/rat/generatednote/2567/activity", + "type": "Create", + "actor": "https://example.com/users/rat", + "object": { + "id": "https://example.com/users/rat/generatednote/2567", + "type": "GeneratedNote", + "url": null, + "inReplyTo": null, + "published": "2020-12-16T01:45:19.662734+00:00", + "attributedTo": "https://example.com/users/rat", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "cc": [ + "https://example.com/users/rat/followers" + ], + "content": "wants to read", + "replies": { + "id": "https://example.com/users/rat/generatednote/2567/replies", + "type": "OrderedCollection", + "totalItems": 0, + "first": "https://example.com/users/rat/generatednote/2567/replies?page=true", + "last": "https://example.com/users/rat/generatednote/2567/replies?page=true", + "name": "", + "@context": "https://www.w3.org/ns/activitystreams" + }, + "tag": [ + { + "href": "https://bookwyrm.social/book/37292", + "name": "Female Husbands", + "type": "Book" + } + ], + "attachment": [], + "sensitive": false, + "@context": "https://www.w3.org/ns/activitystreams" + }, + "to": [ + "https://example.com/users/rat/followers" + ], + "cc": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "signature": { + "creator": "https://example.com/users/rat#main-key", + "created": "2020-12-16T01:45:19.662734+00:00", + "signatureValue": "R+W8nN1CQAlREjSUeaQwJXZrXTOOLvpHQi9n/3vd8QKq+l6HJEpu7eAht9fjpk8YOKEgV3OUQ7w3E42wM4t+sFiaPoQjY6Xy9IOvx/2LcOZjSOtTkiZ1XnnVb3DSbl8BOBH02+cPvoR6k4LIPHm2IHYZ1UL02WdDWaicHEwl7bw=", + "type": "RsaSignature2017" + }, + "@context": "https://www.w3.org/ns/activitystreams" +} diff --git a/bookwyrm/tests/outgoing/__init__.py b/bookwyrm/tests/outgoing/__init__.py deleted file mode 100644 index b6e690fd..00000000 --- a/bookwyrm/tests/outgoing/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import * diff --git a/bookwyrm/tests/outgoing/test_follow.py b/bookwyrm/tests/outgoing/test_follow.py deleted file mode 100644 index d27db876..00000000 --- a/bookwyrm/tests/outgoing/test_follow.py +++ /dev/null @@ -1,80 +0,0 @@ -from unittest.mock import patch -from django.test import TestCase - -from bookwyrm import models, outgoing -from bookwyrm.settings import DOMAIN - - -class Following(TestCase): - def setUp(self): - with patch('bookwyrm.models.user.set_remote_server'): - self.remote_user = models.User.objects.create_user( - 'rat', 'rat@rat.com', 'ratword', - local=False, - remote_id='https://example.com/users/rat', - inbox='https://example.com/users/rat/inbox', - outbox='https://example.com/users/rat/outbox', - ) - self.local_user = models.User.objects.create_user( - 'mouse', 'mouse@mouse.com', 'mouseword', - local=True, - remote_id='http://local.com/users/mouse', - ) - - - def test_handle_follow(self): - self.assertEqual(models.UserFollowRequest.objects.count(), 0) - - with patch('bookwyrm.broadcast.broadcast_task.delay'): - outgoing.handle_follow(self.local_user, self.remote_user) - - rel = models.UserFollowRequest.objects.get() - - self.assertEqual(rel.user_subject, self.local_user) - self.assertEqual(rel.user_object, self.remote_user) - self.assertEqual(rel.status, 'follow_request') - - - def test_handle_unfollow(self): - self.remote_user.followers.add(self.local_user) - self.assertEqual(self.remote_user.followers.count(), 1) - with patch('bookwyrm.broadcast.broadcast_task.delay'): - outgoing.handle_unfollow(self.local_user, self.remote_user) - - self.assertEqual(self.remote_user.followers.count(), 0) - - - def test_handle_accept(self): - rel = models.UserFollowRequest.objects.create( - user_subject=self.local_user, - user_object=self.remote_user - ) - rel_id = rel.id - - with patch('bookwyrm.broadcast.broadcast_task.delay'): - outgoing.handle_accept(rel) - # request should be deleted - self.assertEqual( - models.UserFollowRequest.objects.filter(id=rel_id).count(), 0 - ) - # follow relationship should exist - self.assertEqual(self.remote_user.followers.first(), self.local_user) - - - def test_handle_reject(self): - rel = models.UserFollowRequest.objects.create( - user_subject=self.local_user, - user_object=self.remote_user - ) - rel_id = rel.id - - with patch('bookwyrm.broadcast.broadcast_task.delay'): - outgoing.handle_reject(rel) - # request should be deleted - self.assertEqual( - models.UserFollowRequest.objects.filter(id=rel_id).count(), 0 - ) - # follow relationship should not exist - self.assertEqual( - models.UserFollows.objects.filter(id=rel_id).count(), 0 - ) diff --git a/bookwyrm/tests/outgoing/test_remote_webfinger.py b/bookwyrm/tests/outgoing/test_remote_webfinger.py deleted file mode 100644 index 1bf884a6..00000000 --- a/bookwyrm/tests/outgoing/test_remote_webfinger.py +++ /dev/null @@ -1,61 +0,0 @@ -''' testing user lookup ''' -import json -import pathlib -from unittest.mock import patch - -from django.test import TestCase -import responses - -from bookwyrm import models, outgoing -from bookwyrm.settings import DOMAIN - -class TestOutgoingRemoteWebfinger(TestCase): - ''' overwrites standard model feilds to work with activitypub ''' - def setUp(self): - ''' get user data ready ''' - datafile = pathlib.Path(__file__).parent.joinpath( - '../data/ap_user.json' - ) - self.userdata = json.loads(datafile.read_bytes()) - del self.userdata['icon'] - - def test_existing_user(self): - ''' simple database lookup by username ''' - user = models.User.objects.create_user( - 'mouse', 'mouse@mouse.mouse', 'mouseword', local=True) - - result = outgoing.handle_remote_webfinger('@mouse@%s' % DOMAIN) - self.assertEqual(result, user) - - result = outgoing.handle_remote_webfinger('mouse@%s' % DOMAIN) - self.assertEqual(result, user) - - - @responses.activate - def test_load_user(self): - username = 'mouse@example.com' - wellknown = { - "subject": "acct:mouse@example.com", - "links": [ - { - "rel": "self", - "type": "application/activity+json", - "href": "https://example.com/user/mouse" - } - ] - } - responses.add( - responses.GET, - 'https://example.com/.well-known/webfinger?resource=acct:%s' \ - % username, - json=wellknown, - status=200) - responses.add( - responses.GET, - 'https://example.com/user/mouse', - json=self.userdata, - status=200) - with patch('bookwyrm.models.user.set_remote_server.delay'): - result = outgoing.handle_remote_webfinger('@mouse@example.com') - self.assertIsInstance(result, models.User) - self.assertEqual(result.username, 'mouse@example.com') diff --git a/bookwyrm/tests/outgoing/test_shelving.py b/bookwyrm/tests/outgoing/test_shelving.py deleted file mode 100644 index 5567784e..00000000 --- a/bookwyrm/tests/outgoing/test_shelving.py +++ /dev/null @@ -1,69 +0,0 @@ -from unittest.mock import patch -from django.test import TestCase - -from bookwyrm import models, outgoing - - -class Shelving(TestCase): - def setUp(self): - self.user = models.User.objects.create_user( - 'mouse', 'mouse@mouse.com', 'mouseword', - local=True, - remote_id='http://local.com/users/mouse', - ) - work = models.Work.objects.create( - title='Example work', - ) - self.book = models.Edition.objects.create( - title='Example Edition', - remote_id='https://example.com/book/1', - parent_work=work, - ) - self.shelf = models.Shelf.objects.create( - name='Test Shelf', - identifier='test-shelf', - user=self.user - ) - - - def test_handle_shelve(self): - with patch('bookwyrm.broadcast.broadcast_task.delay') as _: - outgoing.handle_shelve(self.user, self.book, self.shelf) - # make sure the book is on the shelf - self.assertEqual(self.shelf.books.get(), self.book) - - - def test_handle_shelve_to_read(self): - shelf = models.Shelf.objects.get(identifier='to-read') - - with patch('bookwyrm.broadcast.broadcast_task.delay') as _: - outgoing.handle_shelve(self.user, self.book, shelf) - # make sure the book is on the shelf - self.assertEqual(shelf.books.get(), self.book) - - - def test_handle_shelve_reading(self): - shelf = models.Shelf.objects.get(identifier='reading') - - with patch('bookwyrm.broadcast.broadcast_task.delay') as _: - outgoing.handle_shelve(self.user, self.book, shelf) - # make sure the book is on the shelf - self.assertEqual(shelf.books.get(), self.book) - - - def test_handle_shelve_read(self): - shelf = models.Shelf.objects.get(identifier='read') - - with patch('bookwyrm.broadcast.broadcast_task.delay') as _: - outgoing.handle_shelve(self.user, self.book, shelf) - # make sure the book is on the shelf - self.assertEqual(shelf.books.get(), self.book) - - - def test_handle_unshelve(self): - self.shelf.books.add(self.book) - self.shelf.save() - self.assertEqual(self.shelf.books.count(), 1) - with patch('bookwyrm.broadcast.broadcast_task.delay') as _: - outgoing.handle_unshelve(self.user, self.book, self.shelf) - self.assertEqual(self.shelf.books.count(), 0) diff --git a/bookwyrm/tests/test_outgoing.py b/bookwyrm/tests/test_outgoing.py new file mode 100644 index 00000000..2bdcb225 --- /dev/null +++ b/bookwyrm/tests/test_outgoing.py @@ -0,0 +1,194 @@ +''' sending out activities ''' +import json +import pathlib +from unittest.mock import patch + +from django.test import TestCase +import responses + +from bookwyrm import models, outgoing +from bookwyrm.settings import DOMAIN + + +class Outgoing(TestCase): + ''' sends out activities ''' + def setUp(self): + ''' we'll need some data ''' + with patch('bookwyrm.models.user.set_remote_server'): + self.remote_user = models.User.objects.create_user( + 'rat', 'rat@rat.com', 'ratword', + local=False, + remote_id='https://example.com/users/rat', + inbox='https://example.com/users/rat/inbox', + outbox='https://example.com/users/rat/outbox', + ) + self.local_user = models.User.objects.create_user( + 'mouse', 'mouse@mouse.com', 'mouseword', local=True, + remote_id='https://example.com/users/mouse', + ) + + datafile = pathlib.Path(__file__).parent.joinpath( + 'data/ap_user.json' + ) + self.userdata = json.loads(datafile.read_bytes()) + del self.userdata['icon'] + + self.book = models.Edition.objects.create( + title='Example Edition', + remote_id='https://example.com/book/1', + ) + self.shelf = models.Shelf.objects.create( + name='Test Shelf', + identifier='test-shelf', + user=self.user + ) + + + def test_handle_follow(self): + ''' send a follow request ''' + self.assertEqual(models.UserFollowRequest.objects.count(), 0) + + with patch('bookwyrm.broadcast.broadcast_task.delay'): + outgoing.handle_follow(self.local_user, self.remote_user) + + rel = models.UserFollowRequest.objects.get() + + self.assertEqual(rel.user_subject, self.local_user) + self.assertEqual(rel.user_object, self.remote_user) + self.assertEqual(rel.status, 'follow_request') + + + def test_handle_unfollow(self): + ''' send an unfollow ''' + self.remote_user.followers.add(self.local_user) + self.assertEqual(self.remote_user.followers.count(), 1) + with patch('bookwyrm.broadcast.broadcast_task.delay'): + outgoing.handle_unfollow(self.local_user, self.remote_user) + + self.assertEqual(self.remote_user.followers.count(), 0) + + + def test_handle_accept(self): + ''' accept a follow request ''' + rel = models.UserFollowRequest.objects.create( + user_subject=self.local_user, + user_object=self.remote_user + ) + rel_id = rel.id + + with patch('bookwyrm.broadcast.broadcast_task.delay'): + outgoing.handle_accept(rel) + # request should be deleted + self.assertEqual( + models.UserFollowRequest.objects.filter(id=rel_id).count(), 0 + ) + # follow relationship should exist + self.assertEqual(self.remote_user.followers.first(), self.local_user) + + + def test_handle_reject(self): + ''' reject a follow request ''' + rel = models.UserFollowRequest.objects.create( + user_subject=self.local_user, + user_object=self.remote_user + ) + rel_id = rel.id + + with patch('bookwyrm.broadcast.broadcast_task.delay'): + outgoing.handle_reject(rel) + # request should be deleted + self.assertEqual( + models.UserFollowRequest.objects.filter(id=rel_id).count(), 0 + ) + # follow relationship should not exist + self.assertEqual( + models.UserFollows.objects.filter(id=rel_id).count(), 0 + ) + + def test_existing_user(self): + ''' simple database lookup by username ''' + user = models.User.objects.create_user( + 'mouse', 'mouse@mouse.mouse', 'mouseword', local=True) + + result = outgoing.handle_remote_webfinger('@mouse@%s' % DOMAIN) + self.assertEqual(result, user) + + result = outgoing.handle_remote_webfinger('mouse@%s' % DOMAIN) + self.assertEqual(result, user) + + + @responses.activate + def test_load_user(self): + ''' find a remote user using webfinger ''' + username = 'mouse@example.com' + wellknown = { + "subject": "acct:mouse@example.com", + "links": [{ + "rel": "self", + "type": "application/activity+json", + "href": "https://example.com/user/mouse" + }] + } + responses.add( + responses.GET, + 'https://example.com/.well-known/webfinger?resource=acct:%s' \ + % username, + json=wellknown, + status=200) + responses.add( + responses.GET, + 'https://example.com/user/mouse', + json=self.userdata, + status=200) + with patch('bookwyrm.models.user.set_remote_server.delay'): + result = outgoing.handle_remote_webfinger('@mouse@example.com') + self.assertIsInstance(result, models.User) + self.assertEqual(result.username, 'mouse@example.com') + + + def test_handle_shelve(self): + ''' shelve a book ''' + with patch('bookwyrm.broadcast.broadcast_task.delay'): + outgoing.handle_shelve(self.user, self.book, self.shelf) + # make sure the book is on the shelf + self.assertEqual(self.shelf.books.get(), self.book) + + + def test_handle_shelve_to_read(self): + ''' special behavior for the to-read shelf ''' + shelf = models.Shelf.objects.get(identifier='to-read') + + with patch('bookwyrm.broadcast.broadcast_task.delay'): + outgoing.handle_shelve(self.user, self.book, shelf) + # make sure the book is on the shelf + self.assertEqual(shelf.books.get(), self.book) + + + def test_handle_shelve_reading(self): + ''' special behavior for the reading shelf ''' + shelf = models.Shelf.objects.get(identifier='reading') + + with patch('bookwyrm.broadcast.broadcast_task.delay'): + outgoing.handle_shelve(self.user, self.book, shelf) + # make sure the book is on the shelf + self.assertEqual(shelf.books.get(), self.book) + + + def test_handle_shelve_read(self): + ''' special behavior for the read shelf ''' + shelf = models.Shelf.objects.get(identifier='read') + + with patch('bookwyrm.broadcast.broadcast_task.delay'): + outgoing.handle_shelve(self.user, self.book, shelf) + # make sure the book is on the shelf + self.assertEqual(shelf.books.get(), self.book) + + + def test_handle_unshelve(self): + ''' remove a book from a shelf ''' + self.shelf.books.add(self.book) + self.shelf.save() + self.assertEqual(self.shelf.books.count(), 1) + with patch('bookwyrm.broadcast.broadcast_task.delay'): + outgoing.handle_unshelve(self.user, self.book, self.shelf) + self.assertEqual(self.shelf.books.count(), 0) From 65e9afd2712737991fe9e55dd27d1b6fd23d68d4 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 21 Dec 2020 14:54:27 -0800 Subject: [PATCH 3/6] Fixes user in outgoing tests --- bookwyrm/tests/test_outgoing.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bookwyrm/tests/test_outgoing.py b/bookwyrm/tests/test_outgoing.py index 2bdcb225..2a83d484 100644 --- a/bookwyrm/tests/test_outgoing.py +++ b/bookwyrm/tests/test_outgoing.py @@ -40,7 +40,7 @@ class Outgoing(TestCase): self.shelf = models.Shelf.objects.create( name='Test Shelf', identifier='test-shelf', - user=self.user + user=self.local_user ) @@ -149,7 +149,7 @@ class Outgoing(TestCase): def test_handle_shelve(self): ''' shelve a book ''' with patch('bookwyrm.broadcast.broadcast_task.delay'): - outgoing.handle_shelve(self.user, self.book, self.shelf) + outgoing.handle_shelve(self.local_user, self.book, self.shelf) # make sure the book is on the shelf self.assertEqual(self.shelf.books.get(), self.book) @@ -159,7 +159,7 @@ class Outgoing(TestCase): shelf = models.Shelf.objects.get(identifier='to-read') with patch('bookwyrm.broadcast.broadcast_task.delay'): - outgoing.handle_shelve(self.user, self.book, shelf) + outgoing.handle_shelve(self.local_user, self.book, shelf) # make sure the book is on the shelf self.assertEqual(shelf.books.get(), self.book) @@ -169,7 +169,7 @@ class Outgoing(TestCase): shelf = models.Shelf.objects.get(identifier='reading') with patch('bookwyrm.broadcast.broadcast_task.delay'): - outgoing.handle_shelve(self.user, self.book, shelf) + outgoing.handle_shelve(self.local_user, self.book, shelf) # make sure the book is on the shelf self.assertEqual(shelf.books.get(), self.book) @@ -179,7 +179,7 @@ class Outgoing(TestCase): shelf = models.Shelf.objects.get(identifier='read') with patch('bookwyrm.broadcast.broadcast_task.delay'): - outgoing.handle_shelve(self.user, self.book, shelf) + outgoing.handle_shelve(self.local_user, self.book, shelf) # make sure the book is on the shelf self.assertEqual(shelf.books.get(), self.book) @@ -190,5 +190,5 @@ class Outgoing(TestCase): self.shelf.save() self.assertEqual(self.shelf.books.count(), 1) with patch('bookwyrm.broadcast.broadcast_task.delay'): - outgoing.handle_unshelve(self.user, self.book, self.shelf) + outgoing.handle_unshelve(self.local_user, self.book, self.shelf) self.assertEqual(self.shelf.books.count(), 0) From e6105c6cb0000a49c8aeb76411f57124a80947c1 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 21 Dec 2020 14:54:45 -0800 Subject: [PATCH 4/6] Simplify edit user function --- bookwyrm/tests/test_view_actions.py | 30 +++++++++++++++++++++++++++++ bookwyrm/view_actions.py | 22 ++++++--------------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/bookwyrm/tests/test_view_actions.py b/bookwyrm/tests/test_view_actions.py index 77584c90..a23b602c 100644 --- a/bookwyrm/tests/test_view_actions.py +++ b/bookwyrm/tests/test_view_actions.py @@ -238,6 +238,36 @@ class ViewActions(TestCase): self.assertEqual(resp.template_name, 'password_reset.html') self.assertTrue(models.PasswordReset.objects.exists()) + + def test_password_change(self): + ''' change password ''' + password_hash = self.local_user.password + request = self.factory.post('', { + 'password': 'hi', + 'confirm-password': 'hi' + }) + request.user = self.local_user + resp = actions.password_change(request) + self.assertEqual(resp.template_name, 'user.html') + self.assertNotEqual(self.user.password, password_hash) + + def test_password_change_mismatch(self): + ''' change password ''' + password_hash = self.local_user.password + request = self.factory.post('', { + 'password': 'hi', + 'confirm-password': 'hihi' + }) + request.user = self.local_user + resp = actions.password_change(request) + self.assertEqual(resp.template_name, 'edit_user.html') + self.assertEqual(self.user.password, password_hash) + + + def test_edit_user(self): + ''' use a form to update a user ''' + + def test_switch_edition(self): ''' updates user's relationships to a book ''' work = models.Work.objects.create(title='test work') diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py index c3e4d2be..dcbdede4 100644 --- a/bookwyrm/view_actions.py +++ b/bookwyrm/view_actions.py @@ -159,7 +159,7 @@ def password_change(request): request.user.set_password(new_password) request.user.save() login(request, request.user) - return redirect('/user-edit') + return redirect('/user/%s' % request.user.localname) @login_required @@ -168,14 +168,11 @@ def edit_profile(request): ''' les get fancy with images ''' form = forms.EditUserForm(request.POST, request.FILES) if not form.is_valid(): - data = { - 'form': form, - 'user': request.user, - } + data = {'form': form, 'user': request.user} return TemplateResponse(request, 'edit_user.html', data) - request.user.name = form.data['name'] - request.user.email = form.data['email'] + user = form.save(commit=False) + if 'avatar' in form.files: # crop and resize avatar upload image = Image.open(form.files['avatar']) @@ -201,15 +198,8 @@ def edit_profile(request): # set the name to a hash extension = form.files['avatar'].name.split('.')[-1] filename = '%s.%s' % (uuid4(), extension) - request.user.avatar.save( - filename, - ContentFile(output.getvalue()) - ) - - request.user.summary = form.data['summary'] - request.user.manually_approves_followers = \ - form.cleaned_data['manually_approves_followers'] - request.user.save() + user.avatar.save(filename, ContentFile(output.getvalue())) + user.save() outgoing.handle_update_user(request.user) return redirect('/user/%s' % request.user.localname) From fcce1a5a3604ed935d0f4b9b56efd4e96e535c0e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 21 Dec 2020 15:44:11 -0800 Subject: [PATCH 5/6] Fixes outgoing tests --- bookwyrm/tests/test_outgoing.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/bookwyrm/tests/test_outgoing.py b/bookwyrm/tests/test_outgoing.py index 2a83d484..2c1d119c 100644 --- a/bookwyrm/tests/test_outgoing.py +++ b/bookwyrm/tests/test_outgoing.py @@ -33,9 +33,11 @@ class Outgoing(TestCase): self.userdata = json.loads(datafile.read_bytes()) del self.userdata['icon'] + work = models.Work.objects.create(title='Test Work') self.book = models.Edition.objects.create( title='Example Edition', remote_id='https://example.com/book/1', + parent_work=work ) self.shelf = models.Shelf.objects.create( name='Test Shelf', @@ -107,14 +109,11 @@ class Outgoing(TestCase): def test_existing_user(self): ''' simple database lookup by username ''' - user = models.User.objects.create_user( - 'mouse', 'mouse@mouse.mouse', 'mouseword', local=True) - result = outgoing.handle_remote_webfinger('@mouse@%s' % DOMAIN) - self.assertEqual(result, user) + self.assertEqual(result, self.local_user) result = outgoing.handle_remote_webfinger('mouse@%s' % DOMAIN) - self.assertEqual(result, user) + self.assertEqual(result, self.local_user) @responses.activate From db281d5154c69dac19315228407e6dda0617742e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 21 Dec 2020 16:19:36 -0800 Subject: [PATCH 6/6] Simplifies update user view --- bookwyrm/tests/test_view_actions.py | 19 +++++++++++++------ bookwyrm/view_actions.py | 5 +++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/bookwyrm/tests/test_view_actions.py b/bookwyrm/tests/test_view_actions.py index a23b602c..c1e6f860 100644 --- a/bookwyrm/tests/test_view_actions.py +++ b/bookwyrm/tests/test_view_actions.py @@ -6,7 +6,7 @@ from django.http.response import Http404 from django.test import TestCase from django.test.client import RequestFactory -from bookwyrm import view_actions as actions, models +from bookwyrm import forms, models, view_actions as actions from bookwyrm.settings import DOMAIN @@ -247,9 +247,9 @@ class ViewActions(TestCase): 'confirm-password': 'hi' }) request.user = self.local_user - resp = actions.password_change(request) - self.assertEqual(resp.template_name, 'user.html') - self.assertNotEqual(self.user.password, password_hash) + with patch('bookwyrm.view_actions.login'): + resp = actions.password_change(request) + self.assertNotEqual(self.local_user.password, password_hash) def test_password_change_mismatch(self): ''' change password ''' @@ -260,12 +260,19 @@ class ViewActions(TestCase): }) request.user = self.local_user resp = actions.password_change(request) - self.assertEqual(resp.template_name, 'edit_user.html') - self.assertEqual(self.user.password, password_hash) + self.assertEqual(self.local_user.password, password_hash) def test_edit_user(self): ''' use a form to update a user ''' + form = forms.EditUserForm(instance=self.local_user) + form.data['name'] = 'New Name' + request = self.factory.post('', form.data) + request.user = self.local_user + + with patch('bookwyrm.broadcast.broadcast_task.delay'): + actions.edit_profile(request) + self.assertEqual(self.local_user.name, 'New Name') def test_switch_edition(self): diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py index dcbdede4..5a7a059d 100644 --- a/bookwyrm/view_actions.py +++ b/bookwyrm/view_actions.py @@ -166,7 +166,8 @@ def password_change(request): @require_POST def edit_profile(request): ''' les get fancy with images ''' - form = forms.EditUserForm(request.POST, request.FILES) + form = forms.EditUserForm( + request.POST, request.FILES, instance=request.user) if not form.is_valid(): data = {'form': form, 'user': request.user} return TemplateResponse(request, 'edit_user.html', data) @@ -201,7 +202,7 @@ def edit_profile(request): user.avatar.save(filename, ContentFile(output.getvalue())) user.save() - outgoing.handle_update_user(request.user) + outgoing.handle_update_user(user) return redirect('/user/%s' % request.user.localname)