Merge branch 'main' into image-absolute-url-getter

This commit is contained in:
Mouse Reeve
2021-10-20 15:12:06 -07:00
committed by GitHub
537 changed files with 34775 additions and 18490 deletions

View File

@ -20,18 +20,21 @@ from bookwyrm.settings import PAGE_LENGTH
# pylint: disable=invalid-name
@patch("bookwyrm.activitystreams.ActivityStream.add_status")
@patch("bookwyrm.activitystreams.add_status_task.delay")
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay")
class ActivitypubMixins(TestCase):
"""functionality shared across models"""
def setUp(self):
"""shared data"""
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.com", "mouseword", local=True, localname="mouse"
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.com", "mouseword", local=True, localname="mouse"
)
self.local_user.remote_id = "http://example.com/a/b"
self.local_user.save(broadcast=False)
self.local_user.save(broadcast=False, update_fields=["remote_id"])
with patch("bookwyrm.models.user.set_remote_server.delay"):
self.remote_user = models.User.objects.create_user(
"rat",
@ -189,7 +192,7 @@ class ActivitypubMixins(TestCase):
def test_get_recipients_combine_inboxes(self, *_):
"""should combine users with the same shared_inbox"""
self.remote_user.shared_inbox = "http://example.com/inbox"
self.remote_user.save(broadcast=False)
self.remote_user.save(broadcast=False, update_fields=["shared_inbox"])
with patch("bookwyrm.models.user.set_remote_server.delay"):
another_remote_user = models.User.objects.create_user(
"nutria",

View File

@ -1,5 +1,6 @@
""" testing models """
from unittest.mock import patch
from django.http import Http404
from django.test import TestCase
from bookwyrm import models
@ -13,9 +14,12 @@ class BaseModel(TestCase):
def setUp(self):
"""shared data"""
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.com", "mouseword", local=True, localname="mouse"
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.com", "mouseword", local=True, localname="mouse"
)
with patch("bookwyrm.models.user.set_remote_server.delay"):
self.remote_user = models.User.objects.create_user(
"rat",
@ -36,14 +40,14 @@ class BaseModel(TestCase):
"""these should be generated"""
self.test_model.id = 1
expected = self.test_model.get_remote_id()
self.assertEqual(expected, "https://%s/bookwyrmtestmodel/1" % DOMAIN)
self.assertEqual(expected, f"https://{DOMAIN}/bookwyrmtestmodel/1")
def test_remote_id_with_user(self):
"""format of remote id when there's a user object"""
self.test_model.user = self.local_user
self.test_model.id = 1
expected = self.test_model.get_remote_id()
self.assertEqual(expected, "https://%s/user/mouse/bookwyrmtestmodel/1" % DOMAIN)
self.assertEqual(expected, f"https://{DOMAIN}/user/mouse/bookwyrmtestmodel/1")
def test_set_remote_id(self):
"""this function sets remote ids after creation"""
@ -52,74 +56,77 @@ class BaseModel(TestCase):
instance = models.Work.objects.create(title="work title")
instance.remote_id = None
base_model.set_remote_id(None, instance, True)
self.assertEqual(
instance.remote_id, "https://%s/book/%d" % (DOMAIN, instance.id)
)
self.assertEqual(instance.remote_id, f"https://{DOMAIN}/book/{instance.id}")
# shouldn't set remote_id if it's not created
instance.remote_id = None
base_model.set_remote_id(None, instance, False)
self.assertIsNone(instance.remote_id)
@patch("bookwyrm.activitystreams.ActivityStream.add_status")
@patch("bookwyrm.activitystreams.add_status_task.delay")
def test_object_visible_to_user(self, _):
"""does a user have permission to view an object"""
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="public"
)
self.assertTrue(obj.visible_to_user(self.local_user))
self.assertIsNone(obj.raise_visible_to_user(self.local_user))
obj = models.Shelf.objects.create(
name="test", user=self.remote_user, privacy="unlisted"
)
self.assertTrue(obj.visible_to_user(self.local_user))
self.assertIsNone(obj.raise_visible_to_user(self.local_user))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="followers"
)
self.assertFalse(obj.visible_to_user(self.local_user))
with self.assertRaises(Http404):
obj.raise_visible_to_user(self.local_user)
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
self.assertFalse(obj.visible_to_user(self.local_user))
with self.assertRaises(Http404):
obj.raise_visible_to_user(self.local_user)
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
obj.mention_users.add(self.local_user)
self.assertTrue(obj.visible_to_user(self.local_user))
self.assertIsNone(obj.raise_visible_to_user(self.local_user))
@patch("bookwyrm.activitystreams.ActivityStream.add_status")
@patch("bookwyrm.activitystreams.add_status_task.delay")
def test_object_visible_to_user_follower(self, _):
"""what you can see if you follow a user"""
self.remote_user.followers.add(self.local_user)
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="followers"
)
self.assertTrue(obj.visible_to_user(self.local_user))
self.assertIsNone(obj.raise_visible_to_user(self.local_user))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
self.assertFalse(obj.visible_to_user(self.local_user))
with self.assertRaises(Http404):
obj.raise_visible_to_user(self.local_user)
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
obj.mention_users.add(self.local_user)
self.assertTrue(obj.visible_to_user(self.local_user))
self.assertIsNone(obj.raise_visible_to_user(self.local_user))
@patch("bookwyrm.activitystreams.ActivityStream.add_status")
@patch("bookwyrm.activitystreams.add_status_task.delay")
def test_object_visible_to_user_blocked(self, _):
"""you can't see it if they block you"""
self.remote_user.blocks.add(self.local_user)
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="public"
)
self.assertFalse(obj.visible_to_user(self.local_user))
with self.assertRaises(Http404):
obj.raise_visible_to_user(self.local_user)
obj = models.Shelf.objects.create(
name="test", user=self.remote_user, privacy="unlisted"
)
self.assertFalse(obj.visible_to_user(self.local_user))
with self.assertRaises(Http404):
obj.raise_visible_to_user(self.local_user)

View File

@ -25,10 +25,12 @@ from bookwyrm.models.activitypub_mixin import ActivitypubMixin
from bookwyrm.settings import DOMAIN
# pylint: disable=too-many-public-methods
class ActivitypubFields(TestCase):
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
class ModelFields(TestCase):
"""overwrites standard model feilds to work with activitypub"""
def test_validate_remote_id(self):
def test_validate_remote_id(self, *_):
"""should look like a url"""
self.assertIsNone(fields.validate_remote_id("http://www.example.com"))
self.assertIsNone(fields.validate_remote_id("https://www.example.com"))
@ -45,7 +47,7 @@ class ActivitypubFields(TestCase):
"http://www.example.com/dlfjg 23/x",
)
def test_activitypub_field_mixin(self):
def test_activitypub_field_mixin(self, *_):
"""generic mixin with super basic to and from functionality"""
instance = fields.ActivitypubFieldMixin()
self.assertEqual(instance.field_to_activity("fish"), "fish")
@ -63,7 +65,7 @@ class ActivitypubFields(TestCase):
instance.name = "snake_case_name"
self.assertEqual(instance.get_activitypub_field(), "snakeCaseName")
def test_set_field_from_activity(self):
def test_set_field_from_activity(self, *_):
"""setter from entire json blob"""
@dataclass
@ -82,7 +84,7 @@ class ActivitypubFields(TestCase):
instance.set_field_from_activity(mock_model, data)
self.assertEqual(mock_model.field_name, "hi")
def test_set_activity_from_field(self):
def test_set_activity_from_field(self, *_):
"""set json field given entire model"""
@dataclass
@ -100,7 +102,7 @@ class ActivitypubFields(TestCase):
instance.set_activity_from_field(data, mock_model)
self.assertEqual(data["fieldName"], "bip")
def test_remote_id_field(self):
def test_remote_id_field(self, *_):
"""just sets some defaults on charfield"""
instance = fields.RemoteIdField()
self.assertEqual(instance.max_length, 255)
@ -109,7 +111,7 @@ class ActivitypubFields(TestCase):
with self.assertRaises(ValidationError):
instance.run_validators("http://www.example.com/dlfjg 23/x")
def test_username_field(self):
def test_username_field(self, *_):
"""again, just setting defaults on username field"""
instance = fields.UsernameField()
self.assertEqual(instance.activitypub_field, "preferredUsername")
@ -130,7 +132,7 @@ class ActivitypubFields(TestCase):
self.assertEqual(instance.field_to_activity("test@example.com"), "test")
def test_privacy_field_defaults(self):
def test_privacy_field_defaults(self, *_):
"""post privacy field's many default values"""
instance = fields.PrivacyField()
self.assertEqual(instance.max_length, 255)
@ -143,9 +145,18 @@ class ActivitypubFields(TestCase):
instance.public, "https://www.w3.org/ns/activitystreams#Public"
)
def test_privacy_field_set_field_from_activity(self):
def test_privacy_field_set_field_from_activity(self, *_):
"""translate between to/cc fields and privacy"""
with patch("bookwyrm.models.user.set_remote_server.delay"):
test_user = User.objects.create_user(
username="test_user@example.com",
local=False,
remote_id="https://example.com/test_user",
inbox="https://example.com/users/test_user/inbox",
followers_url="https://example.com/users/test_user/followers",
)
@dataclass(init=False)
class TestActivity(ActivityObject):
"""real simple mock"""
@ -154,6 +165,7 @@ class ActivitypubFields(TestCase):
cc: List[str]
id: str = "http://hi.com"
type: str = "Test"
attributedTo: str = test_user.remote_id
class TestPrivacyModel(ActivitypubMixin, BookWyrmModel):
"""real simple mock model because BookWyrmModel is abstract"""
@ -185,8 +197,18 @@ class ActivitypubFields(TestCase):
instance.set_field_from_activity(model_instance, data)
self.assertEqual(model_instance.privacy_field, "unlisted")
data.to = [test_user.followers_url]
data.cc = []
instance.set_field_from_activity(model_instance, data)
self.assertEqual(model_instance.privacy_field, "followers")
data.to = ["http://user_remote/followers"]
data.cc = ["http://mentioned_user/remote_id"]
instance.set_field_from_activity(model_instance, data)
self.assertEqual(model_instance.privacy_field, "followers")
@patch("bookwyrm.models.activitypub_mixin.ObjectMixin.broadcast")
@patch("bookwyrm.activitystreams.ActivityStream.add_status")
@patch("bookwyrm.activitystreams.add_status_task.delay")
def test_privacy_field_set_activity_from_field(self, *_):
"""translate between to/cc fields and privacy"""
user = User.objects.create_user(
@ -231,7 +253,7 @@ class ActivitypubFields(TestCase):
self.assertEqual(activity["to"], [user.remote_id])
self.assertEqual(activity["cc"], [])
def test_foreign_key(self):
def test_foreign_key(self, *_):
"""should be able to format a related model"""
instance = fields.ForeignKey("User", on_delete=models.CASCADE)
Serializable = namedtuple("Serializable", ("to_activity", "remote_id"))
@ -240,7 +262,7 @@ class ActivitypubFields(TestCase):
self.assertEqual(instance.field_to_activity(item), "https://e.b/c")
@responses.activate
def test_foreign_key_from_activity_str(self):
def test_foreign_key_from_activity_str(self, *_):
"""create a new object from a foreign key"""
instance = fields.ForeignKey(User, on_delete=models.CASCADE)
datafile = pathlib.Path(__file__).parent.joinpath("../data/ap_user.json")
@ -267,7 +289,7 @@ class ActivitypubFields(TestCase):
self.assertEqual(value.remote_id, "https://example.com/user/mouse")
self.assertEqual(value.name, "MOUSE?? MOUSE!!")
def test_foreign_key_from_activity_dict(self):
def test_foreign_key_from_activity_dict(self, *_):
"""test recieving activity json"""
instance = fields.ForeignKey(User, on_delete=models.CASCADE)
datafile = pathlib.Path(__file__).parent.joinpath("../data/ap_user.json")
@ -287,7 +309,7 @@ class ActivitypubFields(TestCase):
self.assertEqual(value.name, "MOUSE?? MOUSE!!")
# et cetera but we're not testing serializing user json
def test_foreign_key_from_activity_dict_existing(self):
def test_foreign_key_from_activity_dict_existing(self, *_):
"""test receiving a dict of an existing object in the db"""
instance = fields.ForeignKey(User, on_delete=models.CASCADE)
datafile = pathlib.Path(__file__).parent.joinpath("../data/ap_user.json")
@ -296,7 +318,7 @@ class ActivitypubFields(TestCase):
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
user.remote_id = "https://example.com/user/mouse"
user.save(broadcast=False)
user.save(broadcast=False, update_fields=["remote_id"])
User.objects.create_user(
"rat", "rat@rat.rat", "ratword", local=True, localname="rat"
@ -306,7 +328,7 @@ class ActivitypubFields(TestCase):
value = instance.field_from_activity(activitypub.Person(**userdata))
self.assertEqual(value, user)
def test_foreign_key_from_activity_str_existing(self):
def test_foreign_key_from_activity_str_existing(self, *_):
"""test receiving a remote id of an existing object in the db"""
instance = fields.ForeignKey(User, on_delete=models.CASCADE)
user = User.objects.create_user(
@ -319,14 +341,14 @@ class ActivitypubFields(TestCase):
value = instance.field_from_activity(user.remote_id)
self.assertEqual(value, user)
def test_one_to_one_field(self):
def test_one_to_one_field(self, *_):
"""a gussied up foreign key"""
instance = fields.OneToOneField("User", on_delete=models.CASCADE)
Serializable = namedtuple("Serializable", ("to_activity", "remote_id"))
item = Serializable(lambda: {"a": "b"}, "https://e.b/c")
self.assertEqual(instance.field_to_activity(item), {"a": "b"})
def test_many_to_many_field(self):
def test_many_to_many_field(self, *_):
"""lists!"""
instance = fields.ManyToManyField("User")
@ -344,7 +366,7 @@ class ActivitypubFields(TestCase):
self.assertEqual(instance.field_to_activity(items), "example.com/snake_case")
@responses.activate
def test_many_to_many_field_from_activity(self):
def test_many_to_many_field_from_activity(self, *_):
"""resolve related fields for a list, takes a list of remote ids"""
instance = fields.ManyToManyField(User)
datafile = pathlib.Path(__file__).parent.joinpath("../data/ap_user.json")
@ -364,7 +386,7 @@ class ActivitypubFields(TestCase):
self.assertEqual(len(value), 1)
self.assertIsInstance(value[0], User)
def test_tag_field(self):
def test_tag_field(self, *_):
"""a special type of many to many field"""
instance = fields.TagField("User")
@ -383,13 +405,14 @@ class ActivitypubFields(TestCase):
self.assertEqual(result[0].name, "Name")
self.assertEqual(result[0].type, "Serializable")
def test_tag_field_from_activity(self):
def test_tag_field_from_activity(self, *_):
"""loadin' a list of items from Links"""
# TODO
@responses.activate
@patch("bookwyrm.models.activitypub_mixin.ObjectMixin.broadcast")
def test_image_field(self, _):
@patch("bookwyrm.suggested_users.remove_user_task.delay")
def test_image_field(self, *_):
"""storing images"""
user = User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
@ -424,7 +447,7 @@ class ActivitypubFields(TestCase):
self.assertIsInstance(loaded_image, list)
self.assertIsInstance(loaded_image[1], ContentFile)
def test_image_serialize(self):
def test_image_serialize(self, *_):
"""make sure we're creating sensible image paths"""
ValueMock = namedtuple("ValueMock", ("url"))
value_mock = ValueMock("https://your.domain.here/images/fish.jpg")
@ -433,7 +456,7 @@ class ActivitypubFields(TestCase):
self.assertEqual(result.url, "https://your.domain.here/images/fish.jpg")
self.assertEqual(result.name, "hello")
def test_datetime_field(self):
def test_datetime_field(self, *_):
"""this one is pretty simple, it just has to use isoformat"""
instance = fields.DateTimeField()
now = timezone.now()
@ -441,12 +464,12 @@ class ActivitypubFields(TestCase):
self.assertEqual(instance.field_from_activity(now.isoformat()), now)
self.assertEqual(instance.field_from_activity("bip"), None)
def test_array_field(self):
def test_array_field(self, *_):
"""idk why it makes them strings but probably for a good reason"""
instance = fields.ArrayField(fields.IntegerField)
self.assertEqual(instance.field_to_activity([0, 1]), ["0", "1"])
def test_html_field(self):
def test_html_field(self, *_):
"""sanitizes html, the sanitizer has its own tests"""
instance = fields.HtmlField()
self.assertEqual(

View File

@ -0,0 +1,135 @@
""" testing models """
from unittest.mock import patch
from django.test import TestCase
from bookwyrm import models, settings
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay")
class Group(TestCase):
"""some activitypub oddness ahead"""
def setUp(self):
"""Set up for tests"""
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.owner_user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.rat = models.User.objects.create_user(
"rat", "rat@rat.rat", "ratword", local=True, localname="rat"
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.badger = models.User.objects.create_user(
"badger",
"badger@badger.badger",
"badgerword",
local=True,
localname="badger",
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.capybara = models.User.objects.create_user(
"capybara",
"capybara@capybara.capybara",
"capybaraword",
local=True,
localname="capybara",
)
self.public_group = models.Group.objects.create(
name="Public Group",
description="Initial description",
user=self.owner_user,
privacy="public",
)
self.private_group = models.Group.objects.create(
name="Private Group",
description="Top secret",
user=self.owner_user,
privacy="direct",
)
self.followers_only_group = models.Group.objects.create(
name="Followers Group",
description="No strangers",
user=self.owner_user,
privacy="followers",
)
models.GroupMember.objects.create(group=self.private_group, user=self.badger)
models.GroupMember.objects.create(
group=self.followers_only_group, user=self.badger
)
models.GroupMember.objects.create(group=self.public_group, user=self.capybara)
def test_group_members_can_see_followers_only_groups(self, _):
"""follower-only group should not be excluded from group listings for group members viewing"""
rat_groups = models.Group.privacy_filter(self.rat).all()
badger_groups = models.Group.privacy_filter(self.badger).all()
self.assertFalse(self.followers_only_group in rat_groups)
self.assertTrue(self.followers_only_group in badger_groups)
def test_group_members_can_see_private_groups(self, _):
"""direct privacy group should not be excluded from group listings for group members viewing"""
rat_groups = models.Group.privacy_filter(self.rat).all()
badger_groups = models.Group.privacy_filter(self.badger).all()
self.assertFalse(self.private_group in rat_groups)
self.assertTrue(self.private_group in badger_groups)
def test_group_members_can_see_followers_only_lists(self, _):
"""follower-only group booklists should not be excluded from group booklist listing for group members who do not follower list owner"""
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
followers_list = models.List.objects.create(
name="Followers List",
curation="group",
privacy="followers",
group=self.public_group,
user=self.owner_user,
)
rat_lists = models.List.privacy_filter(self.rat).all()
badger_lists = models.List.privacy_filter(self.badger).all()
capybara_lists = models.List.privacy_filter(self.capybara).all()
self.assertFalse(followers_list in rat_lists)
self.assertFalse(followers_list in badger_lists)
self.assertTrue(followers_list in capybara_lists)
def test_group_members_can_see_private_lists(self, _):
"""private group booklists should not be excluded from group booklist listing for group members"""
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
private_list = models.List.objects.create(
name="Private List",
privacy="direct",
curation="group",
group=self.public_group,
user=self.owner_user,
)
rat_lists = models.List.privacy_filter(self.rat).all()
badger_lists = models.List.privacy_filter(self.badger).all()
capybara_lists = models.List.privacy_filter(self.capybara).all()
self.assertFalse(private_list in rat_lists)
self.assertFalse(private_list in badger_lists)
self.assertTrue(private_list in capybara_lists)

View File

@ -9,8 +9,8 @@ from django.test import TestCase
import responses
from bookwyrm import models
from bookwyrm.book_search import SearchResult
from bookwyrm.connectors import connector_manager
from bookwyrm.connectors.abstract_connector import SearchResult
class ImportJob(TestCase):
@ -59,9 +59,12 @@ class ImportJob(TestCase):
unknown_read_data["Exclusive Shelf"] = "read"
unknown_read_data["Date Read"] = ""
user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
job = models.ImportJob.objects.create(user=user)
self.item_1 = models.ImportItem.objects.create(
job=job, index=1, data=currently_reading_data

View File

@ -11,9 +11,12 @@ class List(TestCase):
def setUp(self):
"""look, a list"""
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
work = models.Work.objects.create(title="hello")
self.book = models.Edition.objects.create(title="hi", parent_work=work)

View File

@ -1,6 +1,9 @@
""" testing models """
import datetime
from unittest.mock import patch
from django.test import TestCase
from django.core.exceptions import ValidationError
from django.utils import timezone
from bookwyrm import models
@ -10,36 +13,91 @@ class ReadThrough(TestCase):
def setUp(self):
"""look, a shelf"""
self.user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
self.work = models.Work.objects.create(title="Example Work")
self.edition = models.Edition.objects.create(
title="Example Edition", parent_work=self.work
)
self.readthrough = models.ReadThrough.objects.create(
user=self.user, book=self.edition
def test_valid_date(self):
"""can't finish a book before you start it"""
start = timezone.now()
finish = start + datetime.timedelta(days=1)
# just make sure there's no errors
models.ReadThrough.objects.create(
user=self.user,
book=self.edition,
start_date=start,
finish_date=finish,
)
def test_valid_date_null_start(self):
"""can't finish a book before you start it"""
start = timezone.now()
finish = start + datetime.timedelta(days=1)
# just make sure there's no errors
models.ReadThrough.objects.create(
user=self.user,
book=self.edition,
finish_date=finish,
)
def test_valid_date_null_finish(self):
"""can't finish a book before you start it"""
start = timezone.now()
# just make sure there's no errors
models.ReadThrough.objects.create(
user=self.user,
book=self.edition,
start_date=start,
)
def test_valid_date_null(self):
"""can't finish a book before you start it"""
# just make sure there's no errors
models.ReadThrough.objects.create(
user=self.user,
book=self.edition,
)
def test_valid_date_same(self):
"""can't finish a book before you start it"""
start = timezone.now()
# just make sure there's no errors
models.ReadThrough.objects.create(
user=self.user,
book=self.edition,
start_date=start,
finish_date=start,
)
def test_progress_update(self):
"""Test progress updates"""
self.readthrough.create_update() # No-op, no progress yet
self.readthrough.progress = 10
self.readthrough.create_update()
self.readthrough.progress = 20
self.readthrough.progress_mode = models.ProgressMode.PERCENT
self.readthrough.create_update()
readthrough = models.ReadThrough.objects.create(
user=self.user, book=self.edition
)
updates = self.readthrough.progressupdate_set.order_by("created_date").all()
readthrough.create_update() # No-op, no progress yet
readthrough.progress = 10
readthrough.create_update()
readthrough.progress = 20
readthrough.progress_mode = models.ProgressMode.PERCENT
readthrough.create_update()
updates = readthrough.progressupdate_set.order_by("created_date").all()
self.assertEqual(len(updates), 2)
self.assertEqual(updates[0].progress, 10)
self.assertEqual(updates[0].mode, models.ProgressMode.PAGE)
self.assertEqual(updates[1].progress, 20)
self.assertEqual(updates[1].mode, models.ProgressMode.PERCENT)
self.readthrough.progress = -10
self.assertRaises(ValidationError, self.readthrough.clean_fields)
update = self.readthrough.create_update()
readthrough.progress = -10
self.assertRaises(ValidationError, readthrough.clean_fields)
update = readthrough.create_update()
self.assertRaises(ValidationError, update.clean_fields)

View File

@ -1,10 +1,12 @@
""" testing models """
import json
from unittest.mock import patch
from django.test import TestCase
from bookwyrm import models
@patch("bookwyrm.activitystreams.add_user_statuses_task.delay")
class Relationship(TestCase):
"""following, blocking, stuff like that"""
@ -20,25 +22,23 @@ class Relationship(TestCase):
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, localname="mouse"
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.com", "mouseword", local=True, localname="mouse"
)
self.local_user.remote_id = "http://local.com/user/mouse"
self.local_user.save(broadcast=False)
self.local_user.save(broadcast=False, update_fields=["remote_id"])
def test_user_follows_from_request(self):
def test_user_follows_from_request(self, _):
"""convert a follow request into a follow"""
real_broadcast = models.UserFollowRequest.broadcast
def mock_broadcast(_, activity, user):
"""introspect what's being sent out"""
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Follow")
models.UserFollowRequest.broadcast = mock_broadcast
request = models.UserFollowRequest.objects.create(
user_subject=self.local_user, user_object=self.remote_user
)
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
request = models.UserFollowRequest.objects.create(
user_subject=self.local_user, user_object=self.remote_user
)
activity = json.loads(mock.call_args[0][1])
self.assertEqual(activity["type"], "Follow")
self.assertEqual(
request.remote_id, "http://local.com/user/mouse#follows/%d" % request.id
)
@ -51,9 +51,8 @@ class Relationship(TestCase):
self.assertEqual(rel.status, "follows")
self.assertEqual(rel.user_subject, self.local_user)
self.assertEqual(rel.user_object, self.remote_user)
models.UserFollowRequest.broadcast = real_broadcast
def test_user_follows_from_request_custom_remote_id(self):
def test_user_follows_from_request_custom_remote_id(self, _):
"""store a specific remote id for a relationship provided by remote"""
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
request = models.UserFollowRequest.objects.create(
@ -70,36 +69,26 @@ class Relationship(TestCase):
self.assertEqual(rel.user_subject, self.local_user)
self.assertEqual(rel.user_object, self.remote_user)
def test_follow_request_activity(self):
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay")
def test_follow_request_activity(self, broadcast_mock, _):
"""accept a request and make it a relationship"""
real_broadcast = models.UserFollowRequest.broadcast
def mock_broadcast(_, activity, user):
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"], self.remote_user.remote_id)
self.assertEqual(activity["type"], "Follow")
models.UserFollowRequest.broadcast = mock_broadcast
models.UserFollowRequest.objects.create(
user_subject=self.local_user,
user_object=self.remote_user,
)
models.UserFollowRequest.broadcast = real_broadcast
activity = json.loads(broadcast_mock.call_args[0][1])
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"], self.remote_user.remote_id)
self.assertEqual(activity["type"], "Follow")
def test_follow_request_accept(self):
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay")
def test_follow_request_accept(self, broadcast_mock, _):
"""accept a request and make it a relationship"""
real_broadcast = models.UserFollowRequest.broadcast
def mock_broadcast(_, activity, user):
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Accept")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["id"], "https://www.hi.com/")
self.local_user.manually_approves_followers = True
self.local_user.save(broadcast=False)
models.UserFollowRequest.broadcast = mock_broadcast
self.local_user.save(
broadcast=False, update_fields=["manually_approves_followers"]
)
request = models.UserFollowRequest.objects.create(
user_subject=self.remote_user,
user_object=self.local_user,
@ -107,32 +96,34 @@ class Relationship(TestCase):
)
request.accept()
activity = json.loads(broadcast_mock.call_args[0][1])
self.assertEqual(activity["type"], "Accept")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["id"], "https://www.hi.com/")
self.assertFalse(models.UserFollowRequest.objects.exists())
self.assertTrue(models.UserFollows.objects.exists())
rel = models.UserFollows.objects.get()
self.assertEqual(rel.user_subject, self.remote_user)
self.assertEqual(rel.user_object, self.local_user)
models.UserFollowRequest.broadcast = real_broadcast
def test_follow_request_reject(self):
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay")
def test_follow_request_reject(self, broadcast_mock, _):
"""accept a request and make it a relationship"""
real_broadcast = models.UserFollowRequest.broadcast
def mock_reject(_, activity, user):
self.assertEqual(user.remote_id, self.local_user.remote_id)
self.assertEqual(activity["type"], "Reject")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["id"], request.remote_id)
models.UserFollowRequest.broadcast = mock_reject
self.local_user.manually_approves_followers = True
self.local_user.save(broadcast=False)
self.local_user.save(
broadcast=False, update_fields=["manually_approves_followers"]
)
request = models.UserFollowRequest.objects.create(
user_subject=self.remote_user,
user_object=self.local_user,
)
request.reject()
activity = json.loads(broadcast_mock.call_args[0][1])
self.assertEqual(activity["type"], "Reject")
self.assertEqual(activity["actor"], self.local_user.remote_id)
self.assertEqual(activity["object"]["id"], request.remote_id)
self.assertFalse(models.UserFollowRequest.objects.exists())
self.assertFalse(models.UserFollows.objects.exists())
models.UserFollowRequest.broadcast = real_broadcast

View File

@ -7,18 +7,25 @@ from bookwyrm import models, settings
# pylint: disable=unused-argument
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
@patch("bookwyrm.activitystreams.add_book_statuses_task.delay")
@patch("bookwyrm.activitystreams.remove_book_statuses_task.delay")
class Shelf(TestCase):
"""some activitypub oddness ahead"""
def setUp(self):
"""look, a shelf"""
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
work = models.Work.objects.create(title="Test Work")
self.book = models.Edition.objects.create(title="test book", parent_work=work)
def test_remote_id(self):
def test_remote_id(self, *_):
"""shelves use custom remote ids"""
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
shelf = models.Shelf.objects.create(
@ -27,7 +34,7 @@ class Shelf(TestCase):
expected_id = "https://%s/user/mouse/books/test-shelf" % settings.DOMAIN
self.assertEqual(shelf.get_remote_id(), expected_id)
def test_to_activity(self):
def test_to_activity(self, *_):
"""jsonify it"""
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
shelf = models.Shelf.objects.create(
@ -41,7 +48,7 @@ class Shelf(TestCase):
self.assertEqual(activity_json["name"], "Test Shelf")
self.assertEqual(activity_json["owner"], self.local_user.remote_id)
def test_create_update_shelf(self):
def test_create_update_shelf(self, *_):
"""create and broadcast shelf creation"""
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock:
@ -62,7 +69,7 @@ class Shelf(TestCase):
self.assertEqual(activity["object"]["name"], "arthur russel")
self.assertEqual(shelf.name, "arthur russel")
def test_shelve(self):
def test_shelve(self, *_):
"""create and broadcast shelf creation"""
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"):
shelf = models.Shelf.objects.create(

View File

@ -0,0 +1,95 @@
""" testing models """
from datetime import timedelta
from unittest.mock import patch
from django.db import IntegrityError
from django.test import TestCase
from django.utils import timezone
from bookwyrm import models, settings
class SiteModels(TestCase):
"""tests for site models"""
def setUp(self):
"""we need basic test data and mocks"""
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.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",
)
def test_site_settings_absent(self):
"""create and load site settings"""
self.assertFalse(models.SiteSettings.objects.exists())
result = models.SiteSettings.get()
self.assertTrue(models.SiteSettings.objects.exists())
self.assertEqual(result.id, 1)
self.assertEqual(result.name, "BookWyrm")
def test_site_settings_present(self):
"""load site settings"""
models.SiteSettings.objects.create(id=1, name="Fish Town")
result = models.SiteSettings.get()
self.assertEqual(result.id, 1)
self.assertEqual(result.name, "Fish Town")
self.assertEqual(models.SiteSettings.objects.all().count(), 1)
def test_site_invite(self):
"""default invite"""
invite = models.SiteInvite.objects.create(
user=self.local_user,
)
self.assertTrue(invite.valid())
def test_site_invite_with_limit(self):
"""with use limit"""
# valid
invite = models.SiteInvite.objects.create(user=self.local_user, use_limit=1)
self.assertTrue(invite.valid())
# invalid
invite = models.SiteInvite.objects.create(user=self.local_user, use_limit=0)
self.assertFalse(invite.valid())
invite = models.SiteInvite.objects.create(
user=self.local_user, use_limit=1, times_used=1
)
self.assertFalse(invite.valid())
def test_site_invite_with_expiry(self):
"""with expiration date"""
date = timezone.now() + timedelta(days=1)
invite = models.SiteInvite.objects.create(user=self.local_user, expiry=date)
self.assertTrue(invite.valid())
date = timezone.now() - timedelta(days=1)
invite = models.SiteInvite.objects.create(user=self.local_user, expiry=date)
self.assertFalse(invite.valid())
def test_site_invite_link(self):
"""invite link generator"""
invite = models.SiteInvite.objects.create(user=self.local_user, code="hello")
self.assertEqual(invite.link, f"https://{settings.DOMAIN}/invite/hello")
def test_invite_request(self):
"""someone wants an invite"""
# normal and good
request = models.InviteRequest.objects.create(email="mouse.reeve@gmail.com")
self.assertIsNone(request.invite)
# already in use
with self.assertRaises(IntegrityError):
request = models.InviteRequest.objects.create(email="mouse@mouse.com")
def test_password_reset(self):
"""password reset token"""
token = models.PasswordReset.objects.create(user=self.local_user, code="hello")
self.assertTrue(token.valid())
self.assertEqual(token.link, f"https://{settings.DOMAIN}/password-reset/hello")

View File

@ -3,28 +3,34 @@ from unittest.mock import patch
from io import BytesIO
import pathlib
from PIL import Image
from django.http import Http404
from django.core.files.base import ContentFile
from django.db import IntegrityError
from django.contrib.auth.models import AnonymousUser
from django.test import TestCase
from django.utils import timezone
from PIL import Image
import responses
from bookwyrm import activitypub, models, settings
# pylint: disable=too-many-public-methods
# pylint: disable=line-too-long
@patch("bookwyrm.models.Status.broadcast")
@patch("bookwyrm.activitystreams.ActivityStream.add_status")
@patch("bookwyrm.activitystreams.ActivityStream.remove_object_from_related_stores")
@patch("bookwyrm.activitystreams.add_status_task.delay")
@patch("bookwyrm.activitystreams.remove_status_task.delay")
class Status(TestCase):
"""lotta types of statuses"""
def setUp(self):
"""useful things for creating a status"""
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
)
with patch("bookwyrm.models.user.set_remote_server.delay"):
self.remote_user = models.User.objects.create_user(
"rat",
@ -46,25 +52,32 @@ class Status(TestCase):
image.save(output, format=image.format)
self.book.cover.save("test.jpg", ContentFile(output.getvalue()))
self.anonymous_user = AnonymousUser
self.anonymous_user.is_authenticated = False
def test_status_generated_fields(self, *_):
"""setting remote id"""
status = models.Status.objects.create(content="bleh", user=self.local_user)
expected_id = "https://%s/user/mouse/status/%d" % (settings.DOMAIN, status.id)
expected_id = f"https://{settings.DOMAIN}/user/mouse/status/{status.id}"
self.assertEqual(status.remote_id, expected_id)
self.assertEqual(status.privacy, "public")
def test_replies(self, *_):
"""get a list of replies"""
parent = models.Status.objects.create(content="hi", user=self.local_user)
child = models.Status.objects.create(
parent = models.Status(content="hi", user=self.local_user)
parent.save(broadcast=False)
child = models.Status(
content="hello", reply_parent=parent, user=self.local_user
)
models.Review.objects.create(
child.save(broadcast=False)
sibling = models.Review(
content="hey", reply_parent=parent, user=self.local_user, book=self.book
)
models.Status.objects.create(
sibling.save(broadcast=False)
grandchild = models.Status(
content="hi hello", reply_parent=child, user=self.local_user
)
grandchild.save(broadcast=False)
replies = models.Status.replies(parent)
self.assertEqual(replies.count(), 2)
@ -72,6 +85,11 @@ class Status(TestCase):
# should select subclasses
self.assertIsInstance(replies.last(), models.Review)
self.assertEqual(parent.thread_id, parent.id)
self.assertEqual(child.thread_id, parent.id)
self.assertEqual(sibling.thread_id, parent.id)
self.assertEqual(grandchild.thread_id, parent.id)
def test_status_type(self, *_):
"""class name"""
self.assertEqual(models.Status().status_type, "Note")
@ -101,7 +119,7 @@ class Status(TestCase):
)
replies = parent.to_replies()
self.assertEqual(replies["id"], "%s/replies" % parent.remote_id)
self.assertEqual(replies["id"], f"{parent.remote_id}/replies")
self.assertEqual(replies["totalItems"], 2)
def test_status_to_activity(self, *_):
@ -117,15 +135,12 @@ class Status(TestCase):
def test_status_to_activity_tombstone(self, *_):
"""subclass of the base model version with a "pure" serializer"""
with patch(
"bookwyrm.activitystreams.ActivityStream.remove_object_from_related_stores"
):
status = models.Status.objects.create(
content="test content",
user=self.local_user,
deleted=True,
deleted_date=timezone.now(),
)
status = models.Status.objects.create(
content="test content",
user=self.local_user,
deleted=True,
deleted_date=timezone.now(),
)
activity = status.to_activity()
self.assertEqual(activity["id"], status.remote_id)
self.assertEqual(activity["type"], "Tombstone")
@ -168,7 +183,7 @@ class Status(TestCase):
self.assertEqual(activity["id"], status.remote_id)
self.assertEqual(
activity["content"],
'mouse test content <a href="%s">"Test Edition"</a>' % self.book.remote_id,
f'mouse test content <a href="{self.book.remote_id}">"Test Edition"</a>',
)
self.assertEqual(len(activity["tag"]), 2)
self.assertEqual(activity["type"], "Note")
@ -177,7 +192,7 @@ class Status(TestCase):
self.assertEqual(activity["attachment"][0].type, "Document")
self.assertEqual(
activity["attachment"][0].url,
"https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url),
f"https://{settings.MEDIA_FULL_URL}{self.book.cover.url}",
)
self.assertEqual(activity["attachment"][0].name, "Test Edition")
@ -202,13 +217,12 @@ class Status(TestCase):
self.assertEqual(activity["type"], "Note")
self.assertEqual(
activity["content"],
'test content<p>(comment on <a href="%s">"Test Edition"</a>)</p>'
% self.book.remote_id,
f'test content<p>(comment on <a href="{self.book.remote_id}">"Test Edition"</a>)</p>',
)
self.assertEqual(activity["attachment"][0].type, "Document")
self.assertEqual(
activity["attachment"][0].url,
"https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url),
f"https://{settings.MEDIA_FULL_URL}{self.book.cover.url}",
)
self.assertEqual(activity["attachment"][0].name, "Test Edition")
@ -240,13 +254,12 @@ class Status(TestCase):
self.assertEqual(activity["type"], "Note")
self.assertEqual(
activity["content"],
'a sickening sense <p>-- <a href="%s">"Test Edition"</a></p>'
"test content" % self.book.remote_id,
f'a sickening sense <p>-- <a href="{self.book.remote_id}">"Test Edition"</a></p>test content',
)
self.assertEqual(activity["attachment"][0].type, "Document")
self.assertEqual(
activity["attachment"][0].url,
"https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url),
"https://{settings.MEDIA_FULL_URL}{self.book.cover.url}",
)
self.assertEqual(activity["attachment"][0].name, "Test Edition")
@ -281,13 +294,13 @@ class Status(TestCase):
self.assertEqual(activity["type"], "Article")
self.assertEqual(
activity["name"],
'Review of "%s" (3 stars): Review\'s name' % self.book.title,
f'Review of "{self.book.title}" (3 stars): Review\'s name',
)
self.assertEqual(activity["content"], "test content")
self.assertEqual(activity["attachment"][0].type, "Document")
self.assertEqual(
activity["attachment"][0].url,
"https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url),
f"https://{settings.MEDIA_FULL_URL}{self.book.cover.url}",
)
self.assertEqual(activity["attachment"][0].name, "Test Edition")
@ -303,13 +316,13 @@ class Status(TestCase):
self.assertEqual(activity["id"], status.remote_id)
self.assertEqual(activity["type"], "Article")
self.assertEqual(
activity["name"], 'Review of "%s": Review name' % self.book.title
activity["name"], f'Review of "{self.book.title}": Review name'
)
self.assertEqual(activity["content"], "test content")
self.assertEqual(activity["attachment"][0].type, "Document")
self.assertEqual(
activity["attachment"][0].url,
"https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url),
f"https://{settings.MEDIA_FULL_URL}{self.book.cover.url}",
)
self.assertEqual(activity["attachment"][0].name, "Test Edition")
@ -325,13 +338,12 @@ class Status(TestCase):
self.assertEqual(activity["type"], "Note")
self.assertEqual(
activity["content"],
'Rated <em><a href="%s">%s</a></em>: 3 stars'
% (self.book.remote_id, self.book.title),
f'rated <em><a href="{self.book.remote_id}">{self.book.title}</a></em>: 3 stars',
)
self.assertEqual(activity["attachment"][0].type, "Document")
self.assertEqual(
activity["attachment"][0].url,
"https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url),
f"https://{settings.MEDIA_FULL_URL}{self.book.cover.url}",
)
self.assertEqual(activity["attachment"][0].name, "Test Edition")
@ -453,3 +465,60 @@ class Status(TestCase):
responses.add(responses.GET, "http://fish.com/nothing", status=404)
self.assertTrue(models.Status.ignore_activity(activity))
def test_raise_visible_to_user_public(self, *_):
"""privacy settings"""
status = models.Status.objects.create(
content="bleh", user=self.local_user, privacy="public"
)
self.assertIsNone(status.raise_visible_to_user(self.remote_user))
self.assertIsNone(status.raise_visible_to_user(self.local_user))
self.assertIsNone(status.raise_visible_to_user(self.anonymous_user))
def test_raise_visible_to_user_unlisted(self, *_):
"""privacy settings"""
status = models.Status.objects.create(
content="bleh", user=self.local_user, privacy="unlisted"
)
self.assertIsNone(status.raise_visible_to_user(self.remote_user))
self.assertIsNone(status.raise_visible_to_user(self.local_user))
self.assertIsNone(status.raise_visible_to_user(self.anonymous_user))
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
def test_raise_visible_to_user_followers(self, *_):
"""privacy settings"""
status = models.Status.objects.create(
content="bleh", user=self.local_user, privacy="followers"
)
status.raise_visible_to_user(self.local_user)
with self.assertRaises(Http404):
status.raise_visible_to_user(self.remote_user)
with self.assertRaises(Http404):
status.raise_visible_to_user(self.anonymous_user)
self.local_user.followers.add(self.remote_user)
self.assertIsNone(status.raise_visible_to_user(self.remote_user))
def test_raise_visible_to_user_followers_mentioned(self, *_):
"""privacy settings"""
status = models.Status.objects.create(
content="bleh", user=self.local_user, privacy="followers"
)
status.mention_users.set([self.remote_user])
self.assertIsNone(status.raise_visible_to_user(self.remote_user))
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
def test_raise_visible_to_user_direct(self, *_):
"""privacy settings"""
status = models.Status.objects.create(
content="bleh", user=self.local_user, privacy="direct"
)
status.raise_visible_to_user(self.local_user)
with self.assertRaises(Http404):
status.raise_visible_to_user(self.remote_user)
with self.assertRaises(Http404):
status.raise_visible_to_user(self.anonymous_user)
# mentioned user
status.mention_users.set([self.remote_user])
self.assertIsNone(status.raise_visible_to_user(self.remote_user))

View File

@ -5,31 +5,37 @@ from django.test import TestCase
import responses
from bookwyrm import models
from bookwyrm.settings import DOMAIN
from bookwyrm.settings import USE_HTTPS, DOMAIN
# pylint: disable=missing-class-docstring
# pylint: disable=missing-function-docstring
class User(TestCase):
protocol = "https://" if USE_HTTPS else "http://"
def setUp(self):
self.user = models.User.objects.create_user(
"mouse@%s" % DOMAIN,
"mouse@mouse.mouse",
"mouseword",
local=True,
localname="mouse",
name="hi",
bookwyrm_user=False,
)
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
"bookwyrm.activitystreams.populate_stream_task.delay"
):
self.user = models.User.objects.create_user(
"mouse@%s" % DOMAIN,
"mouse@mouse.mouse",
"mouseword",
local=True,
localname="mouse",
name="hi",
bookwyrm_user=False,
)
def test_computed_fields(self):
"""username instead of id here"""
expected_id = "https://%s/user/mouse" % DOMAIN
expected_id = f"{self.protocol}{DOMAIN}/user/mouse"
self.assertEqual(self.user.remote_id, expected_id)
self.assertEqual(self.user.username, "mouse@%s" % DOMAIN)
self.assertEqual(self.user.username, f"mouse@{DOMAIN}")
self.assertEqual(self.user.localname, "mouse")
self.assertEqual(self.user.shared_inbox, "https://%s/inbox" % DOMAIN)
self.assertEqual(self.user.inbox, "%s/inbox" % expected_id)
self.assertEqual(self.user.outbox, "%s/outbox" % expected_id)
self.assertEqual(self.user.shared_inbox, f"{self.protocol}{DOMAIN}/inbox")
self.assertEqual(self.user.inbox, f"{expected_id}/inbox")
self.assertEqual(self.user.outbox, f"{expected_id}/outbox")
self.assertEqual(self.user.followers_url, f"{expected_id}/followers")
self.assertIsNotNone(self.user.key_pair.private_key)
self.assertIsNotNone(self.user.key_pair.public_key)
@ -154,7 +160,8 @@ class User(TestCase):
self.assertIsNone(server.application_type)
self.assertIsNone(server.application_version)
def test_delete_user(self):
@patch("bookwyrm.suggested_users.remove_user_task.delay")
def test_delete_user(self, _):
"""deactivate a user"""
self.assertTrue(self.user.is_active)
with patch(