""" test for app action functionality """ from unittest.mock import patch from django.contrib.auth.models import AnonymousUser from django.http import Http404 from django.template.response import TemplateResponse from django.test import TestCase from django.test.client import RequestFactory from bookwyrm import models, views from bookwyrm.tests.validate_html import validate_html @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") class GroupViews(TestCase): """view group and edit details""" def setUp(self): """we need basic test data and mocks""" self.factory = RequestFactory() with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( "bookwyrm.activitystreams.populate_stream_task.delay" ), patch("bookwyrm.lists_stream.populate_lists_task.delay"): self.local_user = models.User.objects.create_user( "mouse@local.com", "mouse@mouse.mouse", "password", local=True, localname="mouse", ) self.rat = models.User.objects.create_user( "rat@local.com", "rat@rat.rat", "password", local=True, localname="rat", ) self.testgroup = models.Group.objects.create( name="Test Group", description="Initial description", user=self.local_user, privacy="public", ) self.membership = models.GroupMember.objects.create( group=self.testgroup, user=self.local_user ) self.anonymous_user = AnonymousUser self.anonymous_user.is_authenticated = False models.SiteSettings.objects.create() def test_group_get(self, _): """there are so many views, this just makes sure it LOADS""" view = views.Group.as_view() request = self.factory.get("") request.user = self.local_user result = view(request, group_id=self.testgroup.id) self.assertIsInstance(result, TemplateResponse) validate_html(result.render()) self.assertEqual(result.status_code, 200) def test_group_get_anonymous(self, _): """there are so many views, this just makes sure it LOADS""" self.testgroup.privacy = "followers" self.testgroup.save() view = views.Group.as_view() request = self.factory.get("") request.user = self.anonymous_user with self.assertRaises(Http404): view(request, group_id=self.testgroup.id) def test_usergroups_get(self, _): """there are so many views, this just makes sure it LOADS""" view = views.UserGroups.as_view() request = self.factory.get("") request.user = self.local_user result = view(request, username="mouse@local.com") self.assertIsInstance(result, TemplateResponse) validate_html(result.render()) self.assertEqual(result.status_code, 200) @patch("bookwyrm.suggested_users.SuggestedUsers.get_suggestions") def test_findusers_get(self, *_): """there are so many views, this just makes sure it LOADS""" view = views.FindUsers.as_view() request = self.factory.get("") request.user = self.local_user result = view(request, group_id=self.testgroup.id) self.assertIsInstance(result, TemplateResponse) validate_html(result.render()) self.assertEqual(result.status_code, 200) def test_findusers_get_with_query(self, _): """there are so many views, this just makes sure it LOADS""" view = views.FindUsers.as_view() request = self.factory.get("", {"user_query": "rat"}) request.user = self.local_user with patch("bookwyrm.suggested_users.SuggestedUsers.get_suggestions") as mock: mock.return_value = models.User.objects.all() result = view(request, group_id=self.testgroup.id) self.assertIsInstance(result, TemplateResponse) validate_html(result.render()) self.assertEqual(result.status_code, 200) def test_group_create(self, _): """create group view""" view = views.UserGroups.as_view() request = self.factory.post( "", { "name": "A group", "description": "wowzers", "privacy": "unlisted", "user": self.local_user.id, }, ) request.user = self.local_user result = view(request, "username") self.assertEqual(result.status_code, 302) new_group = models.Group.objects.filter(name="A group").get() self.assertEqual(new_group.description, "wowzers") self.assertEqual(new_group.privacy, "unlisted") self.assertTrue( models.GroupMember.objects.filter( group=new_group, user=self.local_user ).exists() ) def test_group_edit(self, _): """test editing a "group" database entry""" view = views.Group.as_view() request = self.factory.post( "", { "name": "Updated Group name", "description": "wow", "privacy": "direct", "user": self.local_user.id, }, ) request.user = self.local_user result = view(request, group_id=self.testgroup.id) self.assertEqual(result.status_code, 302) self.testgroup.refresh_from_db() self.assertEqual(self.testgroup.name, "Updated Group name") self.assertEqual(self.testgroup.description, "wow") self.assertEqual(self.testgroup.privacy, "direct") def test_delete_group(self, _): """delete a group""" request = self.factory.post("") request.user = self.local_user views.delete_group(request, self.testgroup.id) self.assertFalse(models.Group.objects.exists()) def test_invite_member(self, _): """invite a member to a group""" request = self.factory.post( "", { "group": self.testgroup.id, "user": self.rat.localname, }, ) request.user = self.local_user result = views.invite_member(request) self.assertEqual(result.status_code, 302) invite = models.GroupMemberInvitation.objects.get() self.assertEqual(invite.user, self.rat) self.assertEqual(invite.group, self.testgroup) def test_invite_member_twice(self, _): """invite a member to a group again""" request = self.factory.post( "", { "group": self.testgroup.id, "user": self.rat.localname, }, ) request.user = self.local_user result = views.invite_member(request) self.assertEqual(result.status_code, 302) result = views.invite_member(request) self.assertEqual(result.status_code, 302) def test_remove_member_denied(self, _): """remove member""" request = self.factory.post( "", { "group": self.testgroup.id, "user": self.local_user.localname, }, ) request.user = self.local_user result = views.remove_member(request) self.assertEqual(result.status_code, 400) def test_remove_member_non_member(self, _): """remove member but wait, that's not a member""" request = self.factory.post( "", { "group": self.testgroup.id, "user": self.rat.localname, }, ) request.user = self.local_user result = views.remove_member(request) # nothing happens self.assertEqual(result.status_code, 302) def test_remove_member_invited(self, _): """remove an invited member""" models.GroupMemberInvitation.objects.create( user=self.rat, group=self.testgroup, ) request = self.factory.post( "", { "group": self.testgroup.id, "user": self.rat.localname, }, ) request.user = self.local_user result = views.remove_member(request) self.assertEqual(result.status_code, 302) self.assertFalse(models.GroupMemberInvitation.objects.exists()) def test_remove_member_existing_member(self, _): """remove an invited member""" models.GroupMember.objects.create( user=self.rat, group=self.testgroup, ) request = self.factory.post( "", { "group": self.testgroup.id, "user": self.rat.localname, }, ) request.user = self.local_user result = views.remove_member(request) self.assertEqual(result.status_code, 302) self.assertEqual(models.GroupMember.objects.count(), 1) self.assertEqual(models.GroupMember.objects.first().user, self.local_user) notification = models.Notification.objects.get() self.assertEqual(notification.user, self.rat) self.assertEqual(notification.related_group, self.testgroup) self.assertEqual(notification.notification_type, "REMOVE") def test_accept_membership(self, _): """accept an invite""" models.GroupMemberInvitation.objects.create( user=self.rat, group=self.testgroup, ) request = self.factory.post("", {"group": self.testgroup.id}) request.user = self.rat views.accept_membership(request) self.assertFalse(models.GroupMemberInvitation.objects.exists()) self.assertTrue(self.rat in [m.user for m in self.testgroup.memberships.all()]) def test_reject_membership(self, _): """reject an invite""" models.GroupMemberInvitation.objects.create( user=self.rat, group=self.testgroup, ) request = self.factory.post("", {"group": self.testgroup.id}) request.user = self.rat views.reject_membership(request) self.testgroup.refresh_from_db() self.assertFalse(models.GroupMemberInvitation.objects.exists()) self.assertFalse(self.rat in [m.user for m in self.testgroup.memberships.all()])