forked from mirrors/bookwyrm
Merge branch 'main' into new-languages
This commit is contained in:
commit
ac1787ce6b
127 changed files with 1450 additions and 354 deletions
|
@ -1,85 +0,0 @@
|
|||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY="7(2w1sedok=aznpq)ta1mc4i%4h=xx@hxwx*o57ctsuml0x%fr"
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG=true
|
||||
USE_HTTPS=false
|
||||
|
||||
DOMAIN=your.domain.here
|
||||
#EMAIL=your@email.here
|
||||
|
||||
# Used for deciding which editions to prefer
|
||||
DEFAULT_LANGUAGE="English"
|
||||
|
||||
## Leave unset to allow all hosts
|
||||
# ALLOWED_HOSTS="localhost,127.0.0.1,[::1]"
|
||||
|
||||
MEDIA_ROOT=images/
|
||||
|
||||
# Database configuration
|
||||
PGPORT=5432
|
||||
POSTGRES_PASSWORD=securedbypassword123
|
||||
POSTGRES_USER=fedireads
|
||||
POSTGRES_DB=fedireads
|
||||
POSTGRES_HOST=db
|
||||
|
||||
# Redis activity stream manager
|
||||
MAX_STREAM_LENGTH=200
|
||||
REDIS_ACTIVITY_HOST=redis_activity
|
||||
REDIS_ACTIVITY_PORT=6379
|
||||
REDIS_ACTIVITY_PASSWORD=redispassword345
|
||||
|
||||
# Redis as celery broker
|
||||
REDIS_BROKER_PORT=6379
|
||||
REDIS_BROKER_PASSWORD=redispassword123
|
||||
|
||||
# Monitoring for celery
|
||||
FLOWER_PORT=8888
|
||||
FLOWER_USER=mouse
|
||||
FLOWER_PASSWORD=changeme
|
||||
|
||||
# Email config
|
||||
EMAIL_HOST=smtp.mailgun.org
|
||||
EMAIL_PORT=587
|
||||
EMAIL_HOST_USER=mail@your.domain.here
|
||||
EMAIL_HOST_PASSWORD=emailpassword123
|
||||
EMAIL_USE_TLS=true
|
||||
EMAIL_USE_SSL=false
|
||||
EMAIL_SENDER_NAME=admin
|
||||
# defaults to DOMAIN
|
||||
EMAIL_SENDER_DOMAIN=
|
||||
|
||||
# Query timeouts
|
||||
SEARCH_TIMEOUT=15
|
||||
QUERY_TIMEOUT=5
|
||||
|
||||
# Thumbnails Generation
|
||||
ENABLE_THUMBNAIL_GENERATION=false
|
||||
|
||||
# S3 configuration
|
||||
USE_S3=false
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
|
||||
# Commented are example values if you use a non-AWS, S3-compatible service
|
||||
# AWS S3 should work with only AWS_STORAGE_BUCKET_NAME and AWS_S3_REGION_NAME
|
||||
# non-AWS S3-compatible services will need AWS_STORAGE_BUCKET_NAME,
|
||||
# along with both AWS_S3_CUSTOM_DOMAIN and AWS_S3_ENDPOINT_URL
|
||||
|
||||
# AWS_STORAGE_BUCKET_NAME= # "example-bucket-name"
|
||||
# AWS_S3_CUSTOM_DOMAIN=None # "example-bucket-name.s3.fr-par.scw.cloud"
|
||||
# AWS_S3_REGION_NAME=None # "fr-par"
|
||||
# AWS_S3_ENDPOINT_URL=None # "https://s3.fr-par.scw.cloud"
|
||||
|
||||
|
||||
# Preview image generation can be computing and storage intensive
|
||||
# ENABLE_PREVIEW_IMAGES=True
|
||||
|
||||
# Specify RGB tuple or RGB hex strings,
|
||||
# or use_dominant_color_light / use_dominant_color_dark
|
||||
PREVIEW_BG_COLOR=use_dominant_color_light
|
||||
# Change to #FFF if you use use_dominant_color_dark
|
||||
PREVIEW_TEXT_COLOR=#363636
|
||||
PREVIEW_IMG_WIDTH=1200
|
||||
PREVIEW_IMG_HEIGHT=630
|
||||
PREVIEW_DEFAULT_COVER_COLOR=#002549
|
|
@ -397,9 +397,15 @@ def populate_streams_on_account_create(sender, instance, created, *args, **kwarg
|
|||
"""build a user's feeds when they join"""
|
||||
if not created or not instance.local:
|
||||
return
|
||||
transaction.on_commit(
|
||||
lambda: populate_streams_on_account_create_command(instance.id)
|
||||
)
|
||||
|
||||
|
||||
def populate_streams_on_account_create_command(instance_id):
|
||||
"""wait for the transaction to complete"""
|
||||
for stream in streams:
|
||||
populate_stream_task.delay(stream, instance.id)
|
||||
populate_stream_task.delay(stream, instance_id)
|
||||
|
||||
|
||||
@receiver(signals.pre_save, sender=models.ShelfBook)
|
||||
|
|
251
bookwyrm/lists_stream.py
Normal file
251
bookwyrm/lists_stream.py
Normal file
|
@ -0,0 +1,251 @@
|
|||
""" access the list streams stored in redis """
|
||||
from django.dispatch import receiver
|
||||
from django.db import transaction
|
||||
from django.db.models import signals, Count, Q
|
||||
|
||||
from bookwyrm import models
|
||||
from bookwyrm.redis_store import RedisStore
|
||||
from bookwyrm.tasks import app, MEDIUM, HIGH
|
||||
|
||||
|
||||
class ListsStream(RedisStore):
|
||||
"""all the lists you can see"""
|
||||
|
||||
def stream_id(self, user): # pylint: disable=no-self-use
|
||||
"""the redis key for this user's instance of this stream"""
|
||||
if isinstance(user, int):
|
||||
# allows the function to take an int or an obj
|
||||
return f"{user}-lists"
|
||||
return f"{user.id}-lists"
|
||||
|
||||
def get_rank(self, obj): # pylint: disable=no-self-use
|
||||
"""lists are sorted by updated date"""
|
||||
return obj.updated_date.timestamp()
|
||||
|
||||
def add_list(self, book_list):
|
||||
"""add a list to users' feeds"""
|
||||
# the pipeline contains all the add-to-stream activities
|
||||
self.add_object_to_related_stores(book_list)
|
||||
|
||||
def add_user_lists(self, viewer, user):
|
||||
"""add a user's lists to another user's feed"""
|
||||
# only add the lists that the viewer should be able to see
|
||||
lists = models.List.privacy_filter(viewer).filter(user=user)
|
||||
self.bulk_add_objects_to_store(lists, self.stream_id(viewer))
|
||||
|
||||
def remove_user_lists(self, viewer, user, exclude_privacy=None):
|
||||
"""remove a user's list from another user's feed"""
|
||||
# remove all so that followers only lists are removed
|
||||
lists = user.list_set
|
||||
if exclude_privacy:
|
||||
lists = lists.exclude(privacy=exclude_privacy)
|
||||
self.bulk_remove_objects_from_store(lists.all(), self.stream_id(viewer))
|
||||
|
||||
def get_list_stream(self, user):
|
||||
"""load the lists to be displayed"""
|
||||
lists = self.get_store(self.stream_id(user))
|
||||
return (
|
||||
models.List.objects.filter(id__in=lists)
|
||||
.annotate(item_count=Count("listitem", filter=Q(listitem__approved=True)))
|
||||
# hide lists with no approved books
|
||||
.filter(item_count__gt=0)
|
||||
.select_related("user")
|
||||
.prefetch_related("listitem_set")
|
||||
.order_by("-updated_date")
|
||||
.distinct()
|
||||
)
|
||||
|
||||
def populate_lists(self, user):
|
||||
"""go from zero to a timeline"""
|
||||
self.populate_store(self.stream_id(user))
|
||||
|
||||
def get_audience(self, book_list): # pylint: disable=no-self-use
|
||||
"""given a list, what users should see it"""
|
||||
# everybody who could plausibly see this list
|
||||
audience = models.User.objects.filter(
|
||||
is_active=True,
|
||||
local=True, # we only create feeds for users of this instance
|
||||
).exclude( # not blocked
|
||||
Q(id__in=book_list.user.blocks.all()) | Q(blocks=book_list.user)
|
||||
)
|
||||
|
||||
group = book_list.group
|
||||
# only visible to the poster and mentioned users
|
||||
if book_list.privacy == "direct":
|
||||
if group:
|
||||
audience = audience.filter(
|
||||
Q(id=book_list.user.id) # if the user is the post's author
|
||||
| ~Q(groups=group.memberships) # if the user is in the group
|
||||
)
|
||||
else:
|
||||
audience = audience.filter(
|
||||
Q(id=book_list.user.id) # if the user is the post's author
|
||||
)
|
||||
# only visible to the poster's followers and tagged users
|
||||
elif book_list.privacy == "followers":
|
||||
if group:
|
||||
audience = audience.filter(
|
||||
Q(id=book_list.user.id) # if the user is the list's owner
|
||||
| Q(following=book_list.user) # if the user is following the pwmer
|
||||
# if a user is in the group
|
||||
| Q(memberships__group__id=book_list.group.id)
|
||||
)
|
||||
else:
|
||||
audience = audience.filter(
|
||||
Q(id=book_list.user.id) # if the user is the list's owner
|
||||
| Q(following=book_list.user) # if the user is following the pwmer
|
||||
)
|
||||
return audience.distinct()
|
||||
|
||||
def get_stores_for_object(self, obj):
|
||||
return [self.stream_id(u) for u in self.get_audience(obj)]
|
||||
|
||||
def get_lists_for_user(self, user): # pylint: disable=no-self-use
|
||||
"""given a user, what lists should they see on this stream"""
|
||||
return models.List.privacy_filter(
|
||||
user,
|
||||
privacy_levels=["public", "followers"],
|
||||
)
|
||||
|
||||
def get_objects_for_store(self, store):
|
||||
user = models.User.objects.get(id=store.split("-")[0])
|
||||
return self.get_lists_for_user(user)
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=models.List)
|
||||
# pylint: disable=unused-argument
|
||||
def add_list_on_create(sender, instance, created, *args, **kwargs):
|
||||
"""add newly created lists streamsstreams"""
|
||||
if not created:
|
||||
return
|
||||
# when creating new things, gotta wait on the transaction
|
||||
transaction.on_commit(lambda: add_list_on_create_command(instance.id))
|
||||
|
||||
|
||||
@receiver(signals.post_delete, sender=models.List)
|
||||
# pylint: disable=unused-argument
|
||||
def remove_list_on_delete(sender, instance, *args, **kwargs):
|
||||
"""remove deleted lists to streams"""
|
||||
remove_list_task.delay(instance.id)
|
||||
|
||||
|
||||
def add_list_on_create_command(instance_id):
|
||||
"""runs this code only after the database commit completes"""
|
||||
add_list_task.delay(instance_id)
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=models.UserFollows)
|
||||
# pylint: disable=unused-argument
|
||||
def add_lists_on_follow(sender, instance, created, *args, **kwargs):
|
||||
"""add a newly followed user's lists to feeds"""
|
||||
if not created or not instance.user_subject.local:
|
||||
return
|
||||
add_user_lists_task.delay(instance.user_subject.id, instance.user_object.id)
|
||||
|
||||
|
||||
@receiver(signals.post_delete, sender=models.UserFollows)
|
||||
# pylint: disable=unused-argument
|
||||
def remove_lists_on_unfollow(sender, instance, *args, **kwargs):
|
||||
"""remove lists from a feed on unfollow"""
|
||||
if not instance.user_subject.local:
|
||||
return
|
||||
# remove all but public lists
|
||||
remove_user_lists_task.delay(
|
||||
instance.user_subject.id, instance.user_object.id, exclude_privacy="public"
|
||||
)
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=models.UserBlocks)
|
||||
# pylint: disable=unused-argument
|
||||
def remove_lists_on_block(sender, instance, *args, **kwargs):
|
||||
"""remove lists from all feeds on block"""
|
||||
# blocks apply ot all feeds
|
||||
if instance.user_subject.local:
|
||||
remove_user_lists_task.delay(instance.user_subject.id, instance.user_object.id)
|
||||
|
||||
# and in both directions
|
||||
if instance.user_object.local:
|
||||
remove_user_lists_task.delay(instance.user_object.id, instance.user_subject.id)
|
||||
|
||||
|
||||
@receiver(signals.post_delete, sender=models.UserBlocks)
|
||||
# pylint: disable=unused-argument
|
||||
def add_lists_on_unblock(sender, instance, *args, **kwargs):
|
||||
"""add lists back to all feeds on unblock"""
|
||||
# make sure there isn't a block in the other direction
|
||||
if models.UserBlocks.objects.filter(
|
||||
user_subject=instance.user_object,
|
||||
user_object=instance.user_subject,
|
||||
).exists():
|
||||
return
|
||||
|
||||
# add lists back to streams with lists from anyone
|
||||
if instance.user_subject.local:
|
||||
add_user_lists_task.delay(
|
||||
instance.user_subject.id,
|
||||
instance.user_object.id,
|
||||
)
|
||||
|
||||
# add lists back to streams with lists from anyone
|
||||
if instance.user_object.local:
|
||||
add_user_lists_task.delay(
|
||||
instance.user_object.id,
|
||||
instance.user_subject.id,
|
||||
)
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=models.User)
|
||||
# pylint: disable=unused-argument
|
||||
def populate_lists_on_account_create(sender, instance, created, *args, **kwargs):
|
||||
"""build a user's feeds when they join"""
|
||||
if not created or not instance.local:
|
||||
return
|
||||
transaction.on_commit(lambda: add_list_on_account_create_command(instance.id))
|
||||
|
||||
|
||||
def add_list_on_account_create_command(user_id):
|
||||
"""wait for the transaction to complete"""
|
||||
populate_lists_task.delay(user_id)
|
||||
|
||||
|
||||
# ---- TASKS
|
||||
@app.task(queue=MEDIUM)
|
||||
def populate_lists_task(user_id):
|
||||
"""background task for populating an empty list stream"""
|
||||
user = models.User.objects.get(id=user_id)
|
||||
ListsStream().populate_lists(user)
|
||||
|
||||
|
||||
@app.task(queue=MEDIUM)
|
||||
def remove_list_task(list_id):
|
||||
"""remove a list from any stream it might be in"""
|
||||
stores = models.User.objects.filter(local=True, is_active=True).values_list(
|
||||
"id", flat=True
|
||||
)
|
||||
|
||||
# delete for every store
|
||||
stores = [ListsStream().stream_id(idx) for idx in stores]
|
||||
ListsStream().remove_object_from_related_stores(list_id, stores=stores)
|
||||
|
||||
|
||||
@app.task(queue=HIGH)
|
||||
def add_list_task(list_id):
|
||||
"""add a list to any stream it should be in"""
|
||||
book_list = models.List.objects.get(id=list_id)
|
||||
ListsStream().add_list(book_list)
|
||||
|
||||
|
||||
@app.task(queue=MEDIUM)
|
||||
def remove_user_lists_task(viewer_id, user_id, exclude_privacy=None):
|
||||
"""remove all lists by a user from a viewer's stream"""
|
||||
viewer = models.User.objects.get(id=viewer_id)
|
||||
user = models.User.objects.get(id=user_id)
|
||||
ListsStream().remove_user_lists(viewer, user, exclude_privacy=exclude_privacy)
|
||||
|
||||
|
||||
@app.task(queue=MEDIUM)
|
||||
def add_user_lists_task(viewer_id, user_id):
|
||||
"""add all lists by a user to a viewer's stream"""
|
||||
viewer = models.User.objects.get(id=viewer_id)
|
||||
user = models.User.objects.get(id=user_id)
|
||||
ListsStream().add_user_lists(viewer, user)
|
34
bookwyrm/management/commands/populate_lists_streams.py
Normal file
34
bookwyrm/management/commands/populate_lists_streams.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
""" Re-create list streams """
|
||||
from django.core.management.base import BaseCommand
|
||||
from bookwyrm import lists_stream, models
|
||||
|
||||
|
||||
def populate_lists_streams():
|
||||
"""build all the lists streams for all the users"""
|
||||
print("Populating lists streams")
|
||||
users = models.User.objects.filter(
|
||||
local=True,
|
||||
is_active=True,
|
||||
).order_by("-last_active_date")
|
||||
print("This may take a long time! Please be patient.")
|
||||
for user in users:
|
||||
print(".", end="")
|
||||
lists_stream.populate_lists_task.delay(user.id)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""start all over with lists streams"""
|
||||
|
||||
help = "Populate list streams for all users"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"--stream",
|
||||
default=None,
|
||||
help="Specifies which time of stream to populate",
|
||||
)
|
||||
|
||||
# pylint: disable=no-self-use,unused-argument
|
||||
def handle(self, *args, **options):
|
||||
"""run feed builder"""
|
||||
populate_lists_streams()
|
|
@ -1,6 +1,6 @@
|
|||
""" Re-create user streams """
|
||||
from django.core.management.base import BaseCommand
|
||||
from bookwyrm import activitystreams, models
|
||||
from bookwyrm import activitystreams, lists_stream, models
|
||||
|
||||
|
||||
def populate_streams(stream=None):
|
||||
|
@ -13,6 +13,8 @@ def populate_streams(stream=None):
|
|||
).order_by("-last_active_date")
|
||||
print("This may take a long time! Please be patient.")
|
||||
for user in users:
|
||||
print(".", end="")
|
||||
lists_stream.populate_lists_task.delay(user.id)
|
||||
for stream_key in streams:
|
||||
print(".", end="")
|
||||
activitystreams.populate_stream_task.delay(stream_key, user.id)
|
||||
|
|
33
bookwyrm/migrations/0124_auto_20220106_1759.py
Normal file
33
bookwyrm/migrations/0124_auto_20220106_1759.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 3.2.10 on 2022-01-06 17:59
|
||||
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def get_admins(apps, schema_editor):
|
||||
"""add any superusers to the "admin" group"""
|
||||
|
||||
db_alias = schema_editor.connection.alias
|
||||
groups = apps.get_model("auth", "Group")
|
||||
try:
|
||||
group = groups.objects.using(db_alias).get(name="admin")
|
||||
except groups.DoesNotExist:
|
||||
# for tests
|
||||
return
|
||||
|
||||
users = apps.get_model("bookwyrm", "User")
|
||||
admins = users.objects.using(db_alias).filter(is_superuser=True)
|
||||
|
||||
for admin in admins:
|
||||
admin.groups.add(group)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("bookwyrm", "0123_alter_user_preferred_language"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(get_admins, reverse_code=migrations.RunPython.noop),
|
||||
]
|
|
@ -30,7 +30,8 @@ class RedisStore(ABC):
|
|||
# add the status to the feed
|
||||
pipeline.zadd(store, value)
|
||||
# trim the store
|
||||
pipeline.zremrangebyrank(store, 0, -1 * self.max_length)
|
||||
if self.max_length:
|
||||
pipeline.zremrangebyrank(store, 0, -1 * self.max_length)
|
||||
if not execute:
|
||||
return pipeline
|
||||
# and go!
|
||||
|
@ -38,10 +39,15 @@ class RedisStore(ABC):
|
|||
|
||||
def remove_object_from_related_stores(self, obj, stores=None):
|
||||
"""remove an object from all stores"""
|
||||
# if the stoers are provided, the object can just be an id
|
||||
if stores and isinstance(obj, int):
|
||||
obj_id = obj
|
||||
else:
|
||||
obj_id = obj.id
|
||||
stores = self.get_stores_for_object(obj) if stores is None else stores
|
||||
pipeline = r.pipeline()
|
||||
for store in stores:
|
||||
pipeline.zrem(store, -1, obj.id)
|
||||
pipeline.zrem(store, -1, obj_id)
|
||||
pipeline.execute()
|
||||
|
||||
def bulk_add_objects_to_store(self, objs, store):
|
||||
|
@ -49,7 +55,7 @@ class RedisStore(ABC):
|
|||
pipeline = r.pipeline()
|
||||
for obj in objs[: self.max_length]:
|
||||
pipeline.zadd(store, self.get_value(obj))
|
||||
if objs:
|
||||
if objs and self.max_length:
|
||||
pipeline.zremrangebyrank(store, 0, -1 * self.max_length)
|
||||
pipeline.execute()
|
||||
|
||||
|
@ -73,7 +79,7 @@ class RedisStore(ABC):
|
|||
pipeline.zadd(store, self.get_value(obj))
|
||||
|
||||
# only trim the store if objects were added
|
||||
if queryset.exists():
|
||||
if queryset.exists() and self.max_length:
|
||||
pipeline.zremrangebyrank(store, 0, -1 * self.max_length)
|
||||
pipeline.execute()
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
env = Env()
|
||||
env.read_env()
|
||||
DOMAIN = env("DOMAIN")
|
||||
VERSION = "0.1.0"
|
||||
VERSION = "0.1.1"
|
||||
|
||||
PAGE_LENGTH = env("PAGE_LENGTH", 15)
|
||||
DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English")
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import math
|
||||
import logging
|
||||
from django.dispatch import receiver
|
||||
from django.db import transaction
|
||||
from django.db.models import signals, Count, Q, Case, When, IntegerField
|
||||
|
||||
from bookwyrm import models
|
||||
|
@ -192,7 +193,7 @@ def update_user(sender, instance, created, update_fields=None, **kwargs):
|
|||
"""an updated user, neat"""
|
||||
# a new user is found, create suggestions for them
|
||||
if created and instance.local:
|
||||
rerank_suggestions_task.delay(instance.id)
|
||||
transaction.on_commit(lambda: update_new_user_command(instance.id))
|
||||
|
||||
# we know what fields were updated and discoverability didn't change
|
||||
if not instance.bookwyrm_user or (
|
||||
|
@ -212,6 +213,11 @@ def update_user(sender, instance, created, update_fields=None, **kwargs):
|
|||
remove_user_task.delay(instance.id)
|
||||
|
||||
|
||||
def update_new_user_command(instance_id):
|
||||
"""wait for transaction to complete"""
|
||||
rerank_suggestions_task.delay(instance_id)
|
||||
|
||||
|
||||
@receiver(signals.post_save, sender=models.FederatedServer)
|
||||
def domain_level_update(sender, instance, created, update_fields=None, **kwargs):
|
||||
"""remove users on a domain block"""
|
||||
|
|
141
bookwyrm/templates/about/about.html
Normal file
141
bookwyrm/templates/about/about.html
Normal file
|
@ -0,0 +1,141 @@
|
|||
{% extends 'about/layout.html' %}
|
||||
{% load humanize %}
|
||||
{% load i18n %}
|
||||
{% load utilities %}
|
||||
{% load bookwyrm_tags %}
|
||||
{% load cache %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "About" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block about_content %}
|
||||
{# seven day cache #}
|
||||
{% cache 604800 about_page %}
|
||||
{% get_book_superlatives as superlatives %}
|
||||
<section class="content pb-4">
|
||||
<h2>
|
||||
{% blocktrans with site_name=site.name %}Welcome to {{ site_name }}!{% endblocktrans %}
|
||||
</h2>
|
||||
|
||||
<p class="subtitle notification has-background-primary-light">
|
||||
{% blocktrans trimmed with site_name=site.name %}
|
||||
{{ site_name }} is part of <em>BookWyrm</em>, a network of independent, self-directed communities for readers.
|
||||
While you can interact seemlessly with users anywhere in the <a href="https://joinbookwyrm.com/instances/" target="_blank">BookWyrm network</a>, this community is unique.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
<div class="columns">
|
||||
{% if top_rated %}
|
||||
{% with book=superlatives.top_rated.default_edition rating=top_rated.rating %}
|
||||
<div class="column is-one-third is-flex">
|
||||
<div class="media notification">
|
||||
<div class="media-left">
|
||||
<a href="{{ book.local_path }}">
|
||||
{% include 'snippets/book_cover.html' with book=book cover_class='is-h-m' size='medium' aria='show' %}
|
||||
</a>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
{% blocktrans trimmed with title=book|book_title book_path=book.local_path site_name=site.name rating=rating|floatformat:1 %}
|
||||
<a href="{{ book_path }}"><em>{{ title }}</em></a> is {{ site_name }}'s most beloved book, with an average rating of {{ rating }} out of 5.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if wanted %}
|
||||
{% with book=superlatives.wanted.default_edition %}
|
||||
<div class="column is-one-third is-flex">
|
||||
<div class="media notification">
|
||||
<div class="media-left">
|
||||
<a href="{{ book.local_path }}">
|
||||
{% include 'snippets/book_cover.html' with book=book cover_class='is-h-m' size='medium' aria='show' %}
|
||||
</a>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
{% blocktrans trimmed with title=book|book_title book_path=book.local_path site_name=site.name %}
|
||||
More {{ site_name }} users want to read <a href="{{ book_path }}"><em>{{ title }}</em></a> than any other book.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if controversial %}
|
||||
{% with book=superlatives.controversial.default_edition %}
|
||||
<div class="column is-one-third is-flex">
|
||||
<div class="media notification">
|
||||
<div class="media-left">
|
||||
<a href="{{ book.local_path }}">
|
||||
{% include 'snippets/book_cover.html' with book=book cover_class='is-h-m' size='medium' aria='show' %}
|
||||
</a>
|
||||
</div>
|
||||
<div class="media-content">
|
||||
{% blocktrans trimmed with title=book|book_title book_path=book.local_path site_name=site.name %}
|
||||
<a href="{{ book_path }}"><em>{{ title }}</em></a> has the most divisive ratings of any book on {{ site_name }}.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<p>
|
||||
{% trans "Track your reading, talk about books, write reviews, and discover what to read next. Always ad-free, anti-corporate, and community-oriented, BookWyrm is human-scale software, designed to stay small and personal. If you have feature requests, bug reports, or grand dreams, <a href='https://joinbookwyrm.com/get-involved' target='_blank'>reach out</a> and make yourself heard." %}
|
||||
</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section class="block">
|
||||
<header class="content">
|
||||
<h2 class="title is-3">{% trans "Meet your admins" %}</h2>
|
||||
<p>
|
||||
{% url "conduct" as coc_path %}
|
||||
{% blocktrans with site_name=site.name %}
|
||||
{{ site_name }}'s moderators and administrators keep the site up and running, enforce the <a href="coc_path">code of conduct</a>, and respond when users report spam and bad behavior.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="columns is-multiline">
|
||||
{% for user in admins %}
|
||||
<div class="column">
|
||||
<div class="card is-stretchable">
|
||||
{% with role=user.groups.first.name %}
|
||||
<div class="card-header {% if role == "moderator" %}has-background-info-light{% else %}has-background-success-light{% endif %}">
|
||||
<span class="card-header-title is-size-7 pt-1 pb-1">
|
||||
{% if role == "moderator" %}
|
||||
{% trans "Moderator" %}
|
||||
{% else %}
|
||||
{% trans "Admin" %}
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% endwith %}
|
||||
|
||||
<div class="cord-content p-5">
|
||||
{% include 'user/user_preview.html' with user=user %}
|
||||
</div>
|
||||
|
||||
{% if request.user.is_authenticated and user.id != request.user.id %}
|
||||
<div class="has-background-white-bis card-footer">
|
||||
<div class="card-footer-item">
|
||||
{% include 'snippets/follow_button.html' with user=user minimal=True %}
|
||||
</div>
|
||||
<div class="card-footer-item">
|
||||
<a href="{% url 'direct-messages-user' user|username %}">{% trans "Send direct message" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% endcache %}
|
||||
{% endblock %}
|
15
bookwyrm/templates/about/conduct.html
Normal file
15
bookwyrm/templates/about/conduct.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
{% extends 'about/layout.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Code of Conduct" %}{% endblock %}
|
||||
|
||||
|
||||
{% block about_content %}
|
||||
<div class="block content">
|
||||
<h2>{% trans "Code of Conduct" %}</h2>
|
||||
<div class="content">
|
||||
{{ site.code_of_conduct | safe }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
57
bookwyrm/templates/about/layout.html
Normal file
57
bookwyrm/templates/about/layout.html
Normal file
|
@ -0,0 +1,57 @@
|
|||
{% extends 'landing/layout.html' %}
|
||||
{% load humanize %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block about_panel %}
|
||||
<div class="box">
|
||||
{% include "snippets/about.html" with size="m" %}
|
||||
{% if active_users %}
|
||||
<ul>
|
||||
<li class="tag is-size-6">
|
||||
<span class="mr-1">{% trans "Active users:" %}</span>
|
||||
<strong>{{ active_users|intcomma }}</strong>
|
||||
</li>
|
||||
<li class="tag is-size-6">
|
||||
<span class="mr-1">{% trans "Statuses posted:" %}</span>
|
||||
<strong>{{ status_count|intcomma }}</strong>
|
||||
</li>
|
||||
<li class="tag is-size-6">
|
||||
<span class="mr-1">{% trans "Software version:" %}</span>
|
||||
<strong>{{ version }}</strong>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
<div class="block columns pt-4">
|
||||
<nav class="menu column is-one-quarter">
|
||||
<h2 class="menu-label">{% blocktrans with site_name=site.name %}About {{ site_name }}{% endblocktrans %}</h2>
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
{% url 'about' as path %}
|
||||
<a href="{{ path }}" {% if request.path in path %}class="is-active"{% endif %}>
|
||||
{% trans "About" %}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
{% url 'conduct' as path %}
|
||||
<a href="{{ path }}" {% if request.path in path %}class="is-active"{% endif %}>
|
||||
{% trans "Code of Conduct" %}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
{% url 'privacy' as path %}
|
||||
<a href="{{ path }}" {% if request.path in path %}class="is-active"{% endif %}>
|
||||
{% trans "Privacy Policy" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="column">
|
||||
{% block about_content %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
15
bookwyrm/templates/about/privacy.html
Normal file
15
bookwyrm/templates/about/privacy.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
{% extends 'about/layout.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Privacy Policy" %}{% endblock %}
|
||||
|
||||
{% block about_content %}
|
||||
|
||||
<div class="block">
|
||||
<h2 class="title">{% trans "Privacy Policy" %}</h2>
|
||||
<div class="content">
|
||||
{{ site.privacy_policy | safe }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -1,37 +0,0 @@
|
|||
{% extends 'landing/layout.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block panel %}
|
||||
<div class="block columns mt-4">
|
||||
<nav class="menu column is-one-quarter">
|
||||
<h2 class="menu-label">{% blocktrans with site_name=site.name %}About {{ site_name }}{% endblocktrans %}</h2>
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
<a href="#coc">{% trans "Code of Conduct" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#privacy">{% trans "Privacy Policy" %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="column content">
|
||||
<div class="block" id="coc">
|
||||
<h2 class="title">{% trans "Code of Conduct" %}</h2>
|
||||
<div class="content">
|
||||
{{ site.code_of_conduct | safe }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr aria-hidden="true">
|
||||
|
||||
<div class="block" id="privacy">
|
||||
<h2 class="title">{% trans "Privacy Policy" %}</h2>
|
||||
<div class="content">
|
||||
{{ site.privacy_policy | safe }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -31,6 +31,7 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
{% block about_panel %}
|
||||
<section class="tile is-ancestor">
|
||||
<div class="tile is-7 is-parent">
|
||||
<div class="tile is-child box">
|
||||
|
@ -89,6 +90,7 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
{% block panel %}{% endblock %}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<div class="columns">
|
||||
<div class="column is-narrow is-hidden-mobile">
|
||||
<figure class="block is-w-xl">
|
||||
<figure class="block is-w-{% if size %}{{ size }}{% else %}xl{% endif %}">
|
||||
<img src="{% if site.logo %}{% get_media_prefix %}{{ site.logo }}{% else %}{% static "images/logo.png" %}{% endif %}" alt="BookWyrm logo">
|
||||
</figure>
|
||||
</div>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load humanize %}
|
||||
{% load cache %}
|
||||
|
||||
{% with status_type=status.status_type %}
|
||||
<div
|
||||
|
@ -15,6 +16,7 @@
|
|||
|
||||
<div class="columns is-gapless">
|
||||
{% if not hide_book %}
|
||||
{% cache 259200 content_status_book status.id %}
|
||||
{% with book=status.book|default:status.mention_books.first %}
|
||||
{% if book %}
|
||||
<div class="column is-cover">
|
||||
|
@ -34,6 +36,7 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endcache %}
|
||||
{% endif %}
|
||||
|
||||
<article class="column ml-3-tablet my-3-mobile">
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
{% load bookwyrm_tags %}
|
||||
{% load markdown %}
|
||||
{% load i18n %}
|
||||
{% load cache %}
|
||||
|
||||
{% if not hide_book %}
|
||||
{% cache 259200 generated_status_book status.id %}
|
||||
{% with book=status.book|default:status.mention_books.first %}
|
||||
<div class="columns is-mobile is-gapless">
|
||||
<a class="column is-cover is-narrow" href="{{ book.local_path }}">
|
||||
|
@ -24,6 +26,7 @@
|
|||
</div>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endcache %}
|
||||
{% endif %}
|
||||
|
||||
{% endspaceless %}
|
||||
|
|
|
@ -21,23 +21,23 @@
|
|||
<p><a href="{{ user.remote_id }}">{{ user.username }}</a></p>
|
||||
<p>{% blocktrans with date=user.created_date|naturaltime %}Joined {{ date }}{% endblocktrans %}</p>
|
||||
<p>
|
||||
{% if is_self %}
|
||||
{% if request.user.id == user.id %}
|
||||
|
||||
<a href="{% url 'user-followers' user|username %}">{% blocktrans count counter=user.followers.count %}{{ counter }} follower{% plural %}{{ counter }} followers{% endblocktrans %}</a>,
|
||||
<a href="{% url 'user-following' user|username %}">{% blocktrans with counter=user.following.count %}{{ counter }} following{% endblocktrans %}</a>
|
||||
<a href="{% url 'user-followers' user|username %}">{% blocktrans count counter=user.followers.count %}{{ counter }} follower{% plural %}{{ counter }} followers{% endblocktrans %}</a>,
|
||||
<a href="{% url 'user-following' user|username %}">{% blocktrans with counter=user.following.count %}{{ counter }} following{% endblocktrans %}</a>
|
||||
|
||||
{% elif request.user.is_authenticated %}
|
||||
|
||||
{% mutuals_count user as mutuals %}
|
||||
<a href="{% url 'user-followers' user|username %}">
|
||||
{% if mutuals %}
|
||||
{% blocktrans with mutuals_display=mutuals|intcomma count counter=mutuals %}{{ mutuals_display }} follower you follow{% plural %}{{ mutuals_display }} followers you follow{% endblocktrans %}
|
||||
{% elif request.user in user.following.all %}
|
||||
{% trans "Follows you" %}
|
||||
{% else %}
|
||||
{% trans "No followers you follow" %}
|
||||
{% endif %}
|
||||
</a>
|
||||
{% mutuals_count user as mutuals %}
|
||||
<a href="{% url 'user-followers' user|username %}">
|
||||
{% if mutuals %}
|
||||
{% blocktrans with mutuals_display=mutuals|intcomma count counter=mutuals %}{{ mutuals_display }} follower you follow{% plural %}{{ mutuals_display }} followers you follow{% endblocktrans %}
|
||||
{% elif request.user in user.following.all %}
|
||||
{% trans "Follows you" %}
|
||||
{% else %}
|
||||
{% trans "No followers you follow" %}
|
||||
{% endif %}
|
||||
</a>
|
||||
|
||||
{% endif %}
|
||||
</p>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
""" template filters """
|
||||
from django import template
|
||||
from django.db.models import Avg
|
||||
from django.db.models import Avg, StdDev, Count, F, Q
|
||||
|
||||
from bookwyrm import models
|
||||
from bookwyrm.views.feed import get_suggested_books
|
||||
|
@ -68,6 +68,57 @@ def load_subclass(status):
|
|||
return status
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=False)
|
||||
def get_book_superlatives():
|
||||
"""get book stats for the about page"""
|
||||
total_ratings = models.Review.objects.filter(local=True, deleted=False).count()
|
||||
data = {}
|
||||
data["top_rated"] = (
|
||||
models.Work.objects.annotate(
|
||||
rating=Avg(
|
||||
"editions__review__rating",
|
||||
filter=Q(editions__review__local=True, editions__review__deleted=False),
|
||||
),
|
||||
rating_count=Count(
|
||||
"editions__review",
|
||||
filter=Q(editions__review__local=True, editions__review__deleted=False),
|
||||
),
|
||||
)
|
||||
.annotate(weighted=F("rating") * F("rating_count") / total_ratings)
|
||||
.filter(rating__gt=4, weighted__gt=0)
|
||||
.order_by("-weighted")
|
||||
.first()
|
||||
)
|
||||
|
||||
data["controversial"] = (
|
||||
models.Work.objects.annotate(
|
||||
deviation=StdDev(
|
||||
"editions__review__rating",
|
||||
filter=Q(editions__review__local=True, editions__review__deleted=False),
|
||||
),
|
||||
rating_count=Count(
|
||||
"editions__review",
|
||||
filter=Q(editions__review__local=True, editions__review__deleted=False),
|
||||
),
|
||||
)
|
||||
.annotate(weighted=F("deviation") * F("rating_count") / total_ratings)
|
||||
.filter(weighted__gt=0)
|
||||
.order_by("-weighted")
|
||||
.first()
|
||||
)
|
||||
|
||||
data["wanted"] = (
|
||||
models.Work.objects.annotate(
|
||||
shelf_count=Count(
|
||||
"editions__shelves", filter=Q(editions__shelves__identifier="to-read")
|
||||
)
|
||||
)
|
||||
.order_by("-shelf_count")
|
||||
.first()
|
||||
)
|
||||
return data
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=False)
|
||||
def related_status(notification):
|
||||
"""for notifications"""
|
||||
|
|
|
@ -31,7 +31,7 @@ class BaseActivity(TestCase):
|
|||
"""we're probably going to re-use this so why copy/paste"""
|
||||
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.user = models.User.objects.create_user(
|
||||
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ class Activitystreams(TestCase):
|
|||
"""use a test csv"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ class Activitystreams(TestCase):
|
|||
"""use a test csv"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ class Activitystreams(TestCase):
|
|||
"""use a test csv"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ class Activitystreams(TestCase):
|
|||
"""use a test csv"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
|
|
|
@ -5,6 +5,8 @@ from bookwyrm import activitystreams, models
|
|||
|
||||
|
||||
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async")
|
||||
@patch("bookwyrm.lists_stream.add_user_lists_task.delay")
|
||||
@patch("bookwyrm.lists_stream.remove_user_lists_task.delay")
|
||||
class ActivitystreamsSignals(TestCase):
|
||||
"""using redis to build activity streams"""
|
||||
|
||||
|
@ -12,7 +14,7 @@ class ActivitystreamsSignals(TestCase):
|
|||
"""use a test csv"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
|
@ -32,11 +34,11 @@ class ActivitystreamsSignals(TestCase):
|
|||
work = models.Work.objects.create(title="test work")
|
||||
self.book = models.Edition.objects.create(title="test book", parent_work=work)
|
||||
|
||||
def test_add_status_on_create_ignore(self, _):
|
||||
def test_add_status_on_create_ignore(self, *_):
|
||||
"""a new statuses has entered"""
|
||||
activitystreams.add_status_on_create(models.User, self.local_user, False)
|
||||
|
||||
def test_add_status_on_create_deleted(self, _):
|
||||
def test_add_status_on_create_deleted(self, *_):
|
||||
"""a new statuses has entered"""
|
||||
with patch("bookwyrm.activitystreams.remove_status_task.delay"):
|
||||
status = models.Status.objects.create(
|
||||
|
@ -48,7 +50,7 @@ class ActivitystreamsSignals(TestCase):
|
|||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], status.id)
|
||||
|
||||
def test_add_status_on_create_created(self, _):
|
||||
def test_add_status_on_create_created(self, *_):
|
||||
"""a new statuses has entered"""
|
||||
status = models.Status.objects.create(
|
||||
user=self.remote_user, content="hi", privacy="public"
|
||||
|
@ -60,18 +62,18 @@ class ActivitystreamsSignals(TestCase):
|
|||
self.assertEqual(args["args"][0], status.id)
|
||||
self.assertEqual(args["queue"], "high_priority")
|
||||
|
||||
def test_populate_streams_on_account_create(self, _):
|
||||
def test_populate_streams_on_account_create_command(self, *_):
|
||||
"""create streams for a user"""
|
||||
with patch("bookwyrm.activitystreams.populate_stream_task.delay") as mock:
|
||||
activitystreams.populate_streams_on_account_create(
|
||||
models.User, self.local_user, True
|
||||
activitystreams.populate_streams_on_account_create_command(
|
||||
self.local_user.id
|
||||
)
|
||||
self.assertEqual(mock.call_count, 3)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], "books")
|
||||
self.assertEqual(args[1], self.local_user.id)
|
||||
|
||||
def test_remove_statuses_on_block(self, _):
|
||||
def test_remove_statuses_on_block(self, *_):
|
||||
"""don't show statuses from blocked users"""
|
||||
with patch("bookwyrm.activitystreams.remove_user_statuses_task.delay") as mock:
|
||||
models.UserBlocks.objects.create(
|
||||
|
@ -83,7 +85,7 @@ class ActivitystreamsSignals(TestCase):
|
|||
self.assertEqual(args[0], self.local_user.id)
|
||||
self.assertEqual(args[1], self.remote_user.id)
|
||||
|
||||
def test_add_statuses_on_unblock(self, _):
|
||||
def test_add_statuses_on_unblock(self, *_):
|
||||
"""re-add statuses on unblock"""
|
||||
with patch("bookwyrm.activitystreams.remove_user_statuses_task.delay"):
|
||||
block = models.UserBlocks.objects.create(
|
||||
|
@ -100,7 +102,7 @@ class ActivitystreamsSignals(TestCase):
|
|||
self.assertEqual(args[1], self.remote_user.id)
|
||||
self.assertEqual(kwargs["stream_list"], ["local", "books"])
|
||||
|
||||
def test_add_statuses_on_unblock_reciprocal_block(self, _):
|
||||
def test_add_statuses_on_unblock_reciprocal_block(self, *_):
|
||||
"""re-add statuses on unblock"""
|
||||
with patch("bookwyrm.activitystreams.remove_user_statuses_task.delay"):
|
||||
block = models.UserBlocks.objects.create(
|
||||
|
|
|
@ -11,7 +11,7 @@ class Activitystreams(TestCase):
|
|||
"""use a test csv"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
|
|
|
@ -30,7 +30,7 @@ class GoodreadsImport(TestCase):
|
|||
self.csv = open(datafile, "r", encoding=self.importer.encoding)
|
||||
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", "mouse@mouse.mouse", "password", local=True
|
||||
)
|
||||
|
|
|
@ -33,7 +33,7 @@ class GenericImporter(TestCase):
|
|||
self.csv = open(datafile, "r", encoding=self.importer.encoding)
|
||||
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", "mouse@mouse.mouse", "password", local=True
|
||||
)
|
||||
|
|
|
@ -32,7 +32,7 @@ class LibrarythingImport(TestCase):
|
|||
self.csv = open(datafile, "r", encoding=self.importer.encoding)
|
||||
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(
|
||||
"mmai", "mmai@mmai.mmai", "password", local=True
|
||||
)
|
||||
|
|
|
@ -30,7 +30,7 @@ class OpenLibraryImport(TestCase):
|
|||
self.csv = open(datafile, "r", encoding=self.importer.encoding)
|
||||
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", "mouse@mouse.mouse", "password", local=True
|
||||
)
|
||||
|
|
|
@ -30,7 +30,7 @@ class StorygraphImport(TestCase):
|
|||
self.csv = open(datafile, "r", encoding=self.importer.encoding)
|
||||
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", "mouse@mouse.mouse", "password", local=True
|
||||
)
|
||||
|
|
1
bookwyrm/tests/lists_stream/__init__.py
Normal file
1
bookwyrm/tests/lists_stream/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from . import *
|
109
bookwyrm/tests/lists_stream/test_signals.py
Normal file
109
bookwyrm/tests/lists_stream/test_signals.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
""" testing lists_stream """
|
||||
from unittest.mock import patch
|
||||
from django.test import TestCase
|
||||
from bookwyrm import lists_stream, models
|
||||
|
||||
|
||||
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async")
|
||||
class ListsStreamSignals(TestCase):
|
||||
"""using redis to build activity streams"""
|
||||
|
||||
def setUp(self):
|
||||
"""use a test csv"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
self.another_user = models.User.objects.create_user(
|
||||
"fish", "fish@fish.fish", "password", local=True, localname="fish"
|
||||
)
|
||||
with patch("bookwyrm.models.user.set_remote_server.delay"):
|
||||
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",
|
||||
)
|
||||
|
||||
def test_add_list_on_create_command(self, _):
|
||||
"""a new lists has entered"""
|
||||
book_list = models.List.objects.create(
|
||||
user=self.remote_user, name="hi", privacy="public"
|
||||
)
|
||||
with patch("bookwyrm.lists_stream.add_list_task.delay") as mock:
|
||||
lists_stream.add_list_on_create_command(book_list.id)
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], book_list.id)
|
||||
|
||||
def test_remove_list_on_delete(self, _):
|
||||
"""delete a list"""
|
||||
book_list = models.List.objects.create(
|
||||
user=self.remote_user, name="hi", privacy="public"
|
||||
)
|
||||
with patch("bookwyrm.lists_stream.remove_list_task.delay") as mock:
|
||||
lists_stream.remove_list_on_delete(models.List, book_list)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], book_list.id)
|
||||
|
||||
def test_populate_lists_on_account_create_command(self, _):
|
||||
"""create streams for a user"""
|
||||
with patch("bookwyrm.lists_stream.populate_lists_task.delay") as mock:
|
||||
lists_stream.add_list_on_account_create_command(self.local_user.id)
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], self.local_user.id)
|
||||
|
||||
@patch("bookwyrm.activitystreams.remove_user_statuses_task.delay")
|
||||
def test_remove_lists_on_block(self, *_):
|
||||
"""don't show lists from blocked users"""
|
||||
with patch("bookwyrm.lists_stream.remove_user_lists_task.delay") as mock:
|
||||
models.UserBlocks.objects.create(
|
||||
user_subject=self.local_user,
|
||||
user_object=self.remote_user,
|
||||
)
|
||||
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], self.local_user.id)
|
||||
self.assertEqual(args[1], self.remote_user.id)
|
||||
|
||||
@patch("bookwyrm.activitystreams.remove_user_statuses_task.delay")
|
||||
@patch("bookwyrm.activitystreams.add_user_statuses_task.delay")
|
||||
def test_add_lists_on_unblock(self, *_):
|
||||
"""re-add lists on unblock"""
|
||||
with patch("bookwyrm.lists_stream.remove_user_lists_task.delay"):
|
||||
block = models.UserBlocks.objects.create(
|
||||
user_subject=self.local_user,
|
||||
user_object=self.remote_user,
|
||||
)
|
||||
|
||||
with patch("bookwyrm.lists_stream.add_user_lists_task.delay") as mock:
|
||||
block.delete()
|
||||
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], self.local_user.id)
|
||||
self.assertEqual(args[1], self.remote_user.id)
|
||||
|
||||
@patch("bookwyrm.activitystreams.remove_user_statuses_task.delay")
|
||||
@patch("bookwyrm.activitystreams.add_user_statuses_task.delay")
|
||||
def test_add_lists_on_unblock_reciprocal_block(self, *_):
|
||||
"""dont' re-add lists on unblock if there's a block the other way"""
|
||||
with patch("bookwyrm.lists_stream.remove_user_lists_task.delay"):
|
||||
block = models.UserBlocks.objects.create(
|
||||
user_subject=self.local_user,
|
||||
user_object=self.remote_user,
|
||||
)
|
||||
block = models.UserBlocks.objects.create(
|
||||
user_subject=self.remote_user,
|
||||
user_object=self.local_user,
|
||||
)
|
||||
|
||||
with patch("bookwyrm.lists_stream.add_user_lists_task.delay") as mock:
|
||||
block.delete()
|
||||
|
||||
self.assertFalse(mock.called)
|
171
bookwyrm/tests/lists_stream/test_stream.py
Normal file
171
bookwyrm/tests/lists_stream/test_stream.py
Normal file
|
@ -0,0 +1,171 @@
|
|||
""" testing activitystreams """
|
||||
from datetime import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.test import TestCase
|
||||
from bookwyrm import lists_stream, models
|
||||
|
||||
|
||||
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async")
|
||||
@patch("bookwyrm.activitystreams.add_status_task.delay")
|
||||
@patch("bookwyrm.activitystreams.add_book_statuses_task.delay")
|
||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
|
||||
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
|
||||
class ListsStream(TestCase):
|
||||
"""using redis to build activity streams"""
|
||||
|
||||
def setUp(self):
|
||||
"""use a test csv"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
self.another_user = models.User.objects.create_user(
|
||||
"nutria",
|
||||
"nutria@nutria.nutria",
|
||||
"password",
|
||||
local=True,
|
||||
localname="nutria",
|
||||
)
|
||||
with patch("bookwyrm.models.user.set_remote_server.delay"):
|
||||
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.stream = lists_stream.ListsStream()
|
||||
|
||||
def test_lists_stream_ids(self, *_):
|
||||
"""the abstract base class for stream objects"""
|
||||
self.assertEqual(
|
||||
self.stream.stream_id(self.local_user),
|
||||
f"{self.local_user.id}-lists",
|
||||
)
|
||||
|
||||
def test_get_rank(self, *_):
|
||||
"""sort order for lists"""
|
||||
book_list = models.List.objects.create(
|
||||
user=self.remote_user, name="hi", privacy="public"
|
||||
)
|
||||
book_list.updated_date = datetime(2020, 1, 1, 0, 0, 0)
|
||||
self.assertEqual(self.stream.get_rank(book_list), 1577836800.0)
|
||||
|
||||
def test_add_user_lists(self, *_):
|
||||
"""add all of a user's lists"""
|
||||
book_list = models.List.objects.create(
|
||||
user=self.remote_user, name="hi", privacy="public"
|
||||
)
|
||||
with patch(
|
||||
"bookwyrm.lists_stream.ListsStream.bulk_add_objects_to_store"
|
||||
) as mock:
|
||||
self.stream.add_user_lists(self.local_user, self.remote_user)
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0][0], book_list)
|
||||
self.assertEqual(args[1], f"{self.local_user.id}-lists")
|
||||
|
||||
def test_remove_user_lists(self, *_):
|
||||
"""remove user's lists"""
|
||||
book_list = models.List.objects.create(
|
||||
user=self.remote_user, name="hi", privacy="public"
|
||||
)
|
||||
with patch(
|
||||
"bookwyrm.lists_stream.ListsStream.bulk_remove_objects_from_store"
|
||||
) as mock:
|
||||
self.stream.remove_user_lists(self.local_user, self.remote_user)
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0][0], book_list)
|
||||
self.assertEqual(args[1], f"{self.local_user.id}-lists")
|
||||
|
||||
def test_get_audience(self, *_):
|
||||
"""get a list of users that should see a list"""
|
||||
book_list = models.List.objects.create(
|
||||
user=self.remote_user, name="hi", privacy="public"
|
||||
)
|
||||
users = self.stream.get_audience(book_list)
|
||||
# remote users don't have feeds
|
||||
self.assertFalse(self.remote_user in users)
|
||||
self.assertTrue(self.local_user in users)
|
||||
self.assertTrue(self.another_user in users)
|
||||
|
||||
def test_get_audience_direct(self, *_):
|
||||
"""get a list of users that should see a list"""
|
||||
book_list = models.List.objects.create(
|
||||
user=self.remote_user,
|
||||
name="hi",
|
||||
privacy="direct",
|
||||
)
|
||||
users = self.stream.get_audience(book_list)
|
||||
self.assertFalse(users.exists())
|
||||
|
||||
book_list = models.List.objects.create(
|
||||
user=self.local_user,
|
||||
name="hi",
|
||||
privacy="direct",
|
||||
)
|
||||
users = self.stream.get_audience(book_list)
|
||||
self.assertTrue(self.local_user in users)
|
||||
self.assertFalse(self.another_user in users)
|
||||
self.assertFalse(self.remote_user in users)
|
||||
|
||||
def test_get_audience_followers_remote_user(self, *_):
|
||||
"""get a list of users that should see a list"""
|
||||
book_list = models.List.objects.create(
|
||||
user=self.remote_user,
|
||||
name="hi",
|
||||
privacy="followers",
|
||||
)
|
||||
users = self.stream.get_audience(book_list)
|
||||
self.assertFalse(users.exists())
|
||||
|
||||
def test_get_audience_followers_self(self, *_):
|
||||
"""get a list of users that should see a list"""
|
||||
book_list = models.List.objects.create(
|
||||
user=self.local_user,
|
||||
name="hi",
|
||||
privacy="followers",
|
||||
)
|
||||
users = self.stream.get_audience(book_list)
|
||||
self.assertTrue(self.local_user in users)
|
||||
self.assertFalse(self.another_user in users)
|
||||
self.assertFalse(self.remote_user in users)
|
||||
|
||||
def test_get_audience_followers_with_relationship(self, *_):
|
||||
"""get a list of users that should see a list"""
|
||||
self.remote_user.followers.add(self.local_user)
|
||||
book_list = models.List.objects.create(
|
||||
user=self.remote_user,
|
||||
name="hi",
|
||||
privacy="followers",
|
||||
)
|
||||
users = self.stream.get_audience(book_list)
|
||||
self.assertTrue(self.local_user in users)
|
||||
self.assertFalse(self.another_user in users)
|
||||
|
||||
def test_get_audience_followers_with_group(self, *_):
|
||||
"""get a list of users that should see a list"""
|
||||
group = models.Group.objects.create(name="test group", user=self.remote_user)
|
||||
models.GroupMember.objects.create(
|
||||
group=group,
|
||||
user=self.local_user,
|
||||
)
|
||||
|
||||
book_list = models.List.objects.create(
|
||||
user=self.remote_user, name="hi", privacy="followers", curation="group"
|
||||
)
|
||||
users = self.stream.get_audience(book_list)
|
||||
self.assertFalse(self.local_user in users)
|
||||
|
||||
book_list.group = group
|
||||
book_list.save(broadcast=False)
|
||||
|
||||
users = self.stream.get_audience(book_list)
|
||||
self.assertTrue(self.local_user in users)
|
||||
self.assertFalse(self.another_user in users)
|
109
bookwyrm/tests/lists_stream/test_tasks.py
Normal file
109
bookwyrm/tests/lists_stream/test_tasks.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
""" testing lists_stream """
|
||||
from unittest.mock import patch
|
||||
from django.test import TestCase
|
||||
from bookwyrm import lists_stream, models
|
||||
|
||||
|
||||
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
|
||||
@patch("bookwyrm.activitystreams.remove_user_statuses_task.delay")
|
||||
@patch("bookwyrm.activitystreams.add_user_statuses_task.delay")
|
||||
class Activitystreams(TestCase):
|
||||
"""using redis to build activity streams"""
|
||||
|
||||
def setUp(self):
|
||||
"""use a test csv"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
self.another_user = models.User.objects.create_user(
|
||||
"nutria",
|
||||
"nutria@nutria.nutria",
|
||||
"password",
|
||||
local=True,
|
||||
localname="nutria",
|
||||
)
|
||||
with patch("bookwyrm.models.user.set_remote_server.delay"):
|
||||
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",
|
||||
)
|
||||
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"):
|
||||
self.list = models.List.objects.create(
|
||||
user=self.local_user, name="hi", privacy="public"
|
||||
)
|
||||
|
||||
def test_populate_lists_task(self, *_):
|
||||
"""populate lists cache"""
|
||||
with patch("bookwyrm.lists_stream.ListsStream.populate_lists") as mock:
|
||||
lists_stream.populate_lists_task(self.local_user.id)
|
||||
self.assertTrue(mock.called)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], self.local_user)
|
||||
|
||||
with patch("bookwyrm.lists_stream.ListsStream.populate_lists") as mock:
|
||||
lists_stream.populate_lists_task(self.local_user.id)
|
||||
self.assertTrue(mock.called)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], self.local_user)
|
||||
|
||||
def test_remove_list_task(self, *_):
|
||||
"""remove a list from all streams"""
|
||||
with patch(
|
||||
"bookwyrm.lists_stream.ListsStream.remove_object_from_related_stores"
|
||||
) as mock:
|
||||
lists_stream.remove_list_task(self.list.id)
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], self.list.id)
|
||||
|
||||
def test_add_list_task(self, *_):
|
||||
"""add a list to all streams"""
|
||||
with patch("bookwyrm.lists_stream.ListsStream.add_list") as mock:
|
||||
lists_stream.add_list_task(self.list.id)
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], self.list)
|
||||
|
||||
def test_remove_user_lists_task(self, *_):
|
||||
"""remove all lists by a user from another users' feeds"""
|
||||
with patch("bookwyrm.lists_stream.ListsStream.remove_user_lists") as mock:
|
||||
lists_stream.remove_user_lists_task(
|
||||
self.local_user.id, self.another_user.id
|
||||
)
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], self.local_user)
|
||||
self.assertEqual(args[1], self.another_user)
|
||||
|
||||
with patch("bookwyrm.lists_stream.ListsStream.remove_user_lists") as mock:
|
||||
lists_stream.remove_user_lists_task(
|
||||
self.local_user.id, self.another_user.id
|
||||
)
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], self.local_user)
|
||||
self.assertEqual(args[1], self.another_user)
|
||||
|
||||
def test_add_user_lists_task(self, *_):
|
||||
"""add a user's lists to another users feeds"""
|
||||
with patch("bookwyrm.lists_stream.ListsStream.add_user_lists") as mock:
|
||||
lists_stream.add_user_lists_task(self.local_user.id, self.another_user.id)
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], self.local_user)
|
||||
self.assertEqual(args[1], self.another_user)
|
||||
|
||||
with patch("bookwyrm.lists_stream.ListsStream.add_user_lists") as mock:
|
||||
lists_stream.add_user_lists_task(self.local_user.id, self.another_user.id)
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
args = mock.call_args[0]
|
||||
self.assertEqual(args[0], self.local_user)
|
||||
self.assertEqual(args[1], self.another_user)
|
54
bookwyrm/tests/management/test_populate_lists_streams.py
Normal file
54
bookwyrm/tests/management/test_populate_lists_streams.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
""" test populating user streams """
|
||||
from unittest.mock import patch
|
||||
from django.test import TestCase
|
||||
|
||||
from bookwyrm import models
|
||||
from bookwyrm.management.commands.populate_lists_streams import populate_lists_streams
|
||||
|
||||
|
||||
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async")
|
||||
@patch("bookwyrm.activitystreams.add_status_task.delay")
|
||||
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
|
||||
class Activitystreams(TestCase):
|
||||
"""using redis to build activity streams"""
|
||||
|
||||
def setUp(self):
|
||||
"""we need some stuff"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
self.another_user = models.User.objects.create_user(
|
||||
"nutria",
|
||||
"nutria@nutria.nutria",
|
||||
"password",
|
||||
local=True,
|
||||
localname="nutria",
|
||||
)
|
||||
models.User.objects.create_user(
|
||||
"gerbil",
|
||||
"gerbil@nutria.nutria",
|
||||
"password",
|
||||
local=True,
|
||||
localname="gerbil",
|
||||
is_active=False,
|
||||
)
|
||||
with patch("bookwyrm.models.user.set_remote_server.delay"):
|
||||
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.book = models.Edition.objects.create(title="test book")
|
||||
|
||||
def test_populate_streams(self, *_):
|
||||
"""make sure the function on the redis manager gets called"""
|
||||
with patch("bookwyrm.lists_stream.populate_lists_task.delay") as list_mock:
|
||||
populate_lists_streams()
|
||||
self.assertEqual(list_mock.call_count, 2) # 2 users
|
|
@ -14,7 +14,7 @@ class Activitystreams(TestCase):
|
|||
"""we need some stuff"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
|
@ -25,6 +25,14 @@ class Activitystreams(TestCase):
|
|||
local=True,
|
||||
localname="nutria",
|
||||
)
|
||||
models.User.objects.create_user(
|
||||
"gerbil",
|
||||
"gerbil@gerbil.gerbil",
|
||||
"password",
|
||||
local=True,
|
||||
localname="gerbil",
|
||||
is_active=False,
|
||||
)
|
||||
with patch("bookwyrm.models.user.set_remote_server.delay"):
|
||||
self.remote_user = models.User.objects.create_user(
|
||||
"rat",
|
||||
|
@ -44,6 +52,11 @@ class Activitystreams(TestCase):
|
|||
user=self.local_user, content="hi", book=self.book
|
||||
)
|
||||
|
||||
with patch("bookwyrm.activitystreams.populate_stream_task.delay") as redis_mock:
|
||||
with patch(
|
||||
"bookwyrm.activitystreams.populate_stream_task.delay"
|
||||
) as redis_mock, patch(
|
||||
"bookwyrm.lists_stream.populate_lists_task.delay"
|
||||
) as list_mock:
|
||||
populate_streams()
|
||||
self.assertEqual(redis_mock.call_count, 6) # 2 users x 3 streams
|
||||
self.assertEqual(list_mock.call_count, 2) # 2 users
|
||||
|
|
|
@ -29,7 +29,7 @@ class ActivitypubMixins(TestCase):
|
|||
"""shared data"""
|
||||
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", "mouse@mouse.com", "mouseword", local=True, localname="mouse"
|
||||
)
|
||||
|
@ -332,7 +332,7 @@ class ActivitypubMixins(TestCase):
|
|||
self.assertEqual(activity["id"], "https://example.com/status/1/activity")
|
||||
self.assertEqual(activity["actor"], self.local_user.remote_id)
|
||||
self.assertEqual(activity["type"], "Delete")
|
||||
self.assertEqual(activity["to"], ["%s/followers" % self.local_user.remote_id])
|
||||
self.assertEqual(activity["to"], [f"{self.local_user.remote_id}/followers"])
|
||||
self.assertEqual(
|
||||
activity["cc"], ["https://www.w3.org/ns/activitystreams#Public"]
|
||||
)
|
||||
|
@ -374,7 +374,7 @@ class ActivitypubMixins(TestCase):
|
|||
for number in range(0, 2 * PAGE_LENGTH):
|
||||
models.Status.objects.create(
|
||||
user=self.local_user,
|
||||
content="test status {:d}".format(number),
|
||||
content=f"test status {number}",
|
||||
)
|
||||
page_1 = to_ordered_collection_page(
|
||||
models.Status.objects.all(), "http://fish.com/", page=1
|
||||
|
@ -400,7 +400,7 @@ class ActivitypubMixins(TestCase):
|
|||
for number in range(0, 2 * PAGE_LENGTH):
|
||||
models.Status.objects.create(
|
||||
user=self.local_user,
|
||||
content="test status {:d}".format(number),
|
||||
content=f"test status {number}",
|
||||
)
|
||||
|
||||
MockSelf = namedtuple("Self", ("remote_id"))
|
||||
|
|
|
@ -16,7 +16,7 @@ class BaseModel(TestCase):
|
|||
"""shared data"""
|
||||
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", "mouse@mouse.com", "mouseword", local=True, localname="mouse"
|
||||
)
|
||||
|
|
|
@ -27,6 +27,7 @@ from bookwyrm.settings import DOMAIN
|
|||
# pylint: disable=too-many-public-methods
|
||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
|
||||
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
|
||||
@patch("bookwyrm.lists_stream.populate_lists_task.delay")
|
||||
class ModelFields(TestCase):
|
||||
"""overwrites standard model feilds to work with activitypub"""
|
||||
|
||||
|
|
|
@ -14,21 +14,15 @@ class Group(TestCase):
|
|||
|
||||
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.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",
|
||||
|
@ -37,9 +31,6 @@ class Group(TestCase):
|
|||
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",
|
||||
|
|
|
@ -20,7 +20,7 @@ class ImportJob(TestCase):
|
|||
"""data is from a goodreads export of The Raven Tower"""
|
||||
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", "mouse@mouse.mouse", "password", local=True
|
||||
)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
""" testing models """
|
||||
from uuid import UUID
|
||||
from unittest.mock import patch
|
||||
from django.test import TestCase
|
||||
from uuid import UUID
|
||||
|
||||
from bookwyrm import models, settings
|
||||
|
||||
|
@ -14,7 +14,7 @@ class List(TestCase):
|
|||
"""look, a list"""
|
||||
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", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
|
||||
)
|
||||
|
@ -27,7 +27,7 @@ class List(TestCase):
|
|||
book_list = models.List.objects.create(
|
||||
name="Test List", user=self.local_user
|
||||
)
|
||||
expected_id = "https://%s/list/%d" % (settings.DOMAIN, book_list.id)
|
||||
expected_id = f"https://{settings.DOMAIN}/list/{book_list.id}"
|
||||
self.assertEqual(book_list.get_remote_id(), expected_id)
|
||||
|
||||
def test_to_activity(self, _):
|
||||
|
|
|
@ -15,7 +15,7 @@ class ReadThrough(TestCase):
|
|||
"""look, a shelf"""
|
||||
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.user = models.User.objects.create_user(
|
||||
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
|
||||
)
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
""" testing models """
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
from django.db import IntegrityError
|
||||
from django.test import TestCase
|
||||
|
||||
from bookwyrm import models
|
||||
|
||||
|
||||
@patch("bookwyrm.activitystreams.add_user_statuses_task.delay")
|
||||
@patch("bookwyrm.activitystreams.remove_user_statuses_task.delay")
|
||||
@patch("bookwyrm.lists_stream.add_user_lists_task.delay")
|
||||
@patch("bookwyrm.lists_stream.remove_user_lists_task.delay")
|
||||
class Relationship(TestCase):
|
||||
"""following, blocking, stuff like that"""
|
||||
|
||||
|
@ -24,14 +28,39 @@ class Relationship(TestCase):
|
|||
)
|
||||
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", "mouse@mouse.com", "mouseword", local=True, localname="mouse"
|
||||
)
|
||||
self.local_user.remote_id = "http://local.com/user/mouse"
|
||||
self.local_user.save(broadcast=False, update_fields=["remote_id"])
|
||||
|
||||
def test_user_follows_from_request(self, _):
|
||||
def test_user_follows(self, *_):
|
||||
"""basic functionality of user follows"""
|
||||
relationship = models.UserFollows.objects.create(
|
||||
user_subject=self.local_user, user_object=self.remote_user
|
||||
)
|
||||
self.assertEqual(relationship.status, "follows")
|
||||
activity = relationship.to_activity()
|
||||
self.assertEqual(activity.type, "Follow")
|
||||
self.assertEqual(
|
||||
relationship.remote_id,
|
||||
f"http://local.com/user/mouse#follows/{relationship.id}",
|
||||
)
|
||||
|
||||
def test_user_follows_blocks(self, *_):
|
||||
"""can't follow if you're blocked"""
|
||||
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"):
|
||||
models.UserBlocks.objects.create(
|
||||
user_subject=self.local_user, user_object=self.remote_user
|
||||
)
|
||||
|
||||
with self.assertRaises(IntegrityError):
|
||||
models.UserFollows.objects.create(
|
||||
user_subject=self.local_user, user_object=self.remote_user
|
||||
)
|
||||
|
||||
def test_user_follows_from_request(self, *_):
|
||||
"""convert a follow request into a follow"""
|
||||
with patch(
|
||||
"bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"
|
||||
|
@ -42,19 +71,19 @@ class Relationship(TestCase):
|
|||
activity = json.loads(mock.call_args[1]["args"][1])
|
||||
self.assertEqual(activity["type"], "Follow")
|
||||
self.assertEqual(
|
||||
request.remote_id, "http://local.com/user/mouse#follows/%d" % request.id
|
||||
request.remote_id, f"http://local.com/user/mouse#follows/{request.id}"
|
||||
)
|
||||
self.assertEqual(request.status, "follow_request")
|
||||
|
||||
rel = models.UserFollows.from_request(request)
|
||||
self.assertEqual(
|
||||
rel.remote_id, "http://local.com/user/mouse#follows/%d" % request.id
|
||||
rel.remote_id, f"http://local.com/user/mouse#follows/{request.id}"
|
||||
)
|
||||
self.assertEqual(rel.status, "follows")
|
||||
self.assertEqual(rel.user_subject, self.local_user)
|
||||
self.assertEqual(rel.user_object, self.remote_user)
|
||||
|
||||
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.apply_async"):
|
||||
request = models.UserFollowRequest.objects.create(
|
||||
|
@ -72,7 +101,7 @@ class Relationship(TestCase):
|
|||
self.assertEqual(rel.user_object, self.remote_user)
|
||||
|
||||
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async")
|
||||
def test_follow_request_activity(self, broadcast_mock, _):
|
||||
def test_follow_request_activity(self, broadcast_mock, *_):
|
||||
"""accept a request and make it a relationship"""
|
||||
models.UserFollowRequest.objects.create(
|
||||
user_subject=self.local_user,
|
||||
|
@ -84,7 +113,7 @@ class Relationship(TestCase):
|
|||
self.assertEqual(activity["type"], "Follow")
|
||||
|
||||
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async")
|
||||
def test_follow_request_accept(self, broadcast_mock, _):
|
||||
def test_follow_request_accept(self, broadcast_mock, *_):
|
||||
"""accept a request and make it a relationship"""
|
||||
self.local_user.manually_approves_followers = True
|
||||
self.local_user.save(
|
||||
|
@ -110,7 +139,7 @@ class Relationship(TestCase):
|
|||
self.assertEqual(rel.user_object, self.local_user)
|
||||
|
||||
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async")
|
||||
def test_follow_request_reject(self, broadcast_mock, _):
|
||||
def test_follow_request_reject(self, broadcast_mock, *_):
|
||||
"""accept a request and make it a relationship"""
|
||||
self.local_user.manually_approves_followers = True
|
||||
self.local_user.save(
|
||||
|
|
|
@ -9,6 +9,7 @@ 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.lists_stream.populate_lists_task.delay")
|
||||
@patch("bookwyrm.activitystreams.add_book_statuses_task.delay")
|
||||
@patch("bookwyrm.activitystreams.remove_book_statuses_task.delay")
|
||||
class Shelf(TestCase):
|
||||
|
@ -18,7 +19,7 @@ class Shelf(TestCase):
|
|||
"""look, a shelf"""
|
||||
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", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
|
||||
)
|
||||
|
@ -31,7 +32,7 @@ class Shelf(TestCase):
|
|||
shelf = models.Shelf.objects.create(
|
||||
name="Test Shelf", identifier="test-shelf", user=self.local_user
|
||||
)
|
||||
expected_id = "https://%s/user/mouse/books/test-shelf" % settings.DOMAIN
|
||||
expected_id = f"https://{settings.DOMAIN}/user/mouse/books/test-shelf"
|
||||
self.assertEqual(shelf.get_remote_id(), expected_id)
|
||||
|
||||
def test_to_activity(self, *_):
|
||||
|
|
|
@ -16,7 +16,7 @@ class SiteModels(TestCase):
|
|||
"""we need basic test data and mocks"""
|
||||
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.com",
|
||||
|
|
|
@ -28,7 +28,7 @@ class Status(TestCase):
|
|||
"""useful things for creating a status"""
|
||||
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", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
|
||||
)
|
||||
|
|
|
@ -15,7 +15,7 @@ class User(TestCase):
|
|||
def setUp(self):
|
||||
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.user = models.User.objects.create_user(
|
||||
"mouse@%s" % DOMAIN,
|
||||
"mouse@mouse.mouse",
|
||||
|
|
|
@ -16,7 +16,7 @@ class BookWyrmTags(TestCase):
|
|||
"""create some filler objects"""
|
||||
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.user = models.User.objects.create_user(
|
||||
"mouse@example.com",
|
||||
"mouse@mouse.mouse",
|
||||
|
|
|
@ -16,7 +16,7 @@ class InteractionTags(TestCase):
|
|||
"""create some filler objects"""
|
||||
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.user = models.User.objects.create_user(
|
||||
"mouse@example.com",
|
||||
"mouse@mouse.mouse",
|
||||
|
|
|
@ -17,7 +17,7 @@ class StatusDisplayTags(TestCase):
|
|||
"""create some filler objects"""
|
||||
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.user = models.User.objects.create_user(
|
||||
"mouse@example.com",
|
||||
"mouse@mouse.mouse",
|
||||
|
|
|
@ -17,7 +17,7 @@ class UtilitiesTags(TestCase):
|
|||
"""create some filler objects"""
|
||||
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.user = models.User.objects.create_user(
|
||||
"mouse@example.com",
|
||||
"mouse@mouse.mouse",
|
||||
|
@ -50,3 +50,10 @@ class UtilitiesTags(TestCase):
|
|||
"""uuid functionality"""
|
||||
uuid = utilities.get_uuid("hi")
|
||||
self.assertTrue(re.match(r"hi[A-Za-z0-9\-]", uuid))
|
||||
|
||||
def test_get_title(self, *_):
|
||||
"""the title of a book"""
|
||||
self.assertEqual(utilities.get_title(None), "")
|
||||
self.assertEqual(utilities.get_title(self.book), "Test Book")
|
||||
book = models.Edition.objects.create(title="Oh", subtitle="oh my")
|
||||
self.assertEqual(utilities.get_title(book), "Oh: oh my")
|
||||
|
|
|
@ -16,7 +16,7 @@ class Emailing(TestCase):
|
|||
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",
|
||||
|
|
|
@ -32,7 +32,7 @@ class PreviewImages(TestCase):
|
|||
)
|
||||
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(
|
||||
"possum@local.com",
|
||||
"possum@possum.possum",
|
||||
|
|
|
@ -39,19 +39,19 @@ class Signature(TestCase):
|
|||
"""create users and test data"""
|
||||
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.mouse = models.User.objects.create_user(
|
||||
"mouse@%s" % DOMAIN,
|
||||
f"mouse@{DOMAIN}",
|
||||
"mouse@example.com",
|
||||
"",
|
||||
local=True,
|
||||
localname="mouse",
|
||||
)
|
||||
self.rat = models.User.objects.create_user(
|
||||
"rat@%s" % DOMAIN, "rat@example.com", "", local=True, localname="rat"
|
||||
f"rat@{DOMAIN}", "rat@example.com", "", local=True, localname="rat"
|
||||
)
|
||||
self.cat = models.User.objects.create_user(
|
||||
"cat@%s" % DOMAIN, "cat@example.com", "", local=True, localname="cat"
|
||||
f"cat@{DOMAIN}", "cat@example.com", "", local=True, localname="cat"
|
||||
)
|
||||
|
||||
private_key, public_key = create_key_pair()
|
||||
|
@ -75,7 +75,7 @@ class Signature(TestCase):
|
|||
"HTTP_DIGEST": digest,
|
||||
"HTTP_CONTENT_TYPE": "application/activity+json; charset=utf-8",
|
||||
"HTTP_HOST": DOMAIN,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
def send_test_request( # pylint: disable=too-many-arguments
|
||||
|
|
|
@ -13,6 +13,7 @@ from bookwyrm.suggested_users import suggested_users, get_annotated_users
|
|||
@patch("bookwyrm.activitystreams.add_status_task.delay")
|
||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
|
||||
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
|
||||
@patch("bookwyrm.lists_stream.populate_lists_task.delay")
|
||||
@patch("bookwyrm.activitystreams.add_book_statuses_task.delay")
|
||||
@patch("bookwyrm.suggested_users.rerank_user_task.delay")
|
||||
@patch("bookwyrm.suggested_users.remove_user_task.delay")
|
||||
|
@ -23,7 +24,7 @@ class SuggestedUsers(TestCase):
|
|||
"""use a test csv"""
|
||||
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", "mouse@mouse.mouse", "password", local=True, localname="mouse"
|
||||
)
|
||||
|
@ -235,12 +236,3 @@ class SuggestedUsers(TestCase):
|
|||
)
|
||||
user_1_annotated = result.get(id=user_1.id)
|
||||
self.assertEqual(user_1_annotated.mutuals, 3)
|
||||
|
||||
def test_create_user_signal(self, *_):
|
||||
"""build suggestions for new users"""
|
||||
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") as mock:
|
||||
models.User.objects.create_user(
|
||||
"nutria", "nutria@nu.tria", "password", local=True, localname="nutria"
|
||||
)
|
||||
|
||||
self.assertEqual(mock.call_count, 1)
|
||||
|
|
|
@ -16,7 +16,7 @@ class AnnouncementViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -16,7 +16,7 @@ class DashboardViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -17,7 +17,7 @@ class EmailBlocklistViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -19,7 +19,7 @@ class FederationViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -16,7 +16,7 @@ class IPBlocklistViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -18,7 +18,7 @@ class ReportViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -18,7 +18,7 @@ class UserAdminViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -28,7 +28,7 @@ class BookViews(TestCase):
|
|||
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.com",
|
||||
|
|
|
@ -21,7 +21,7 @@ class EditBookViews(TestCase):
|
|||
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.com",
|
||||
|
|
|
@ -18,7 +18,7 @@ class BookViews(TestCase):
|
|||
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.com",
|
||||
|
|
|
@ -19,7 +19,7 @@ class ImportViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -16,7 +16,7 @@ class ImportManualReviewViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -16,7 +16,7 @@ class ImportTroubleshootViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -22,7 +22,7 @@ class Inbox(TestCase):
|
|||
|
||||
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
||||
"bookwyrm.activitystreams.populate_stream_task.delay"
|
||||
):
|
||||
), patch("bookwyrm.lists_stream.populate_lists_task.delay"):
|
||||
local_user = models.User.objects.create_user(
|
||||
"mouse@example.com",
|
||||
"mouse@mouse.com",
|
||||
|
|
|
@ -15,7 +15,7 @@ class InboxAdd(TestCase):
|
|||
"""basic user and book data"""
|
||||
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
||||
"bookwyrm.activitystreams.populate_stream_task.delay"
|
||||
):
|
||||
), patch("bookwyrm.lists_stream.populate_lists_task.delay"):
|
||||
local_user = models.User.objects.create_user(
|
||||
"mouse@example.com",
|
||||
"mouse@mouse.com",
|
||||
|
|
|
@ -15,7 +15,7 @@ class InboxActivities(TestCase):
|
|||
"""basic user and book data"""
|
||||
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@example.com",
|
||||
"mouse@mouse.com",
|
||||
|
|
|
@ -14,7 +14,7 @@ class InboxBlock(TestCase):
|
|||
"""basic user and book data"""
|
||||
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@example.com",
|
||||
"mouse@mouse.com",
|
||||
|
@ -57,7 +57,7 @@ class InboxBlock(TestCase):
|
|||
|
||||
with patch(
|
||||
"bookwyrm.activitystreams.remove_user_statuses_task.delay"
|
||||
) as redis_mock:
|
||||
) as redis_mock, patch("bookwyrm.lists_stream.remove_user_lists_task.delay"):
|
||||
views.inbox.activity_task(activity)
|
||||
self.assertTrue(redis_mock.called)
|
||||
views.inbox.activity_task(activity)
|
||||
|
@ -70,7 +70,9 @@ class InboxBlock(TestCase):
|
|||
self.assertFalse(models.UserFollowRequest.objects.exists())
|
||||
|
||||
@patch("bookwyrm.activitystreams.remove_user_statuses_task.delay")
|
||||
def test_handle_unblock(self, _):
|
||||
@patch("bookwyrm.lists_stream.add_user_lists_task.delay")
|
||||
@patch("bookwyrm.lists_stream.remove_user_lists_task.delay")
|
||||
def test_handle_unblock(self, *_):
|
||||
"""unblock a user"""
|
||||
self.remote_user.blocks.add(self.local_user)
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ class InboxCreate(TestCase):
|
|||
"""basic user and book data"""
|
||||
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@example.com",
|
||||
"mouse@mouse.com",
|
||||
|
|
|
@ -15,7 +15,7 @@ class InboxActivities(TestCase):
|
|||
"""basic user and book data"""
|
||||
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@example.com",
|
||||
"mouse@mouse.com",
|
||||
|
@ -51,7 +51,7 @@ class InboxActivities(TestCase):
|
|||
"type": "Delete",
|
||||
"to": ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
"cc": ["https://example.com/user/mouse/followers"],
|
||||
"id": "%s/activity" % self.status.remote_id,
|
||||
"id": f"{self.status.remote_id}/activity",
|
||||
"actor": self.remote_user.remote_id,
|
||||
"object": {"id": self.status.remote_id, "type": "Tombstone"},
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ class InboxActivities(TestCase):
|
|||
"type": "Delete",
|
||||
"to": ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
"cc": ["https://example.com/user/mouse/followers"],
|
||||
"id": "%s/activity" % self.status.remote_id,
|
||||
"id": f"{self.status.remote_id}/activity",
|
||||
"actor": self.remote_user.remote_id,
|
||||
"object": {"id": self.status.remote_id, "type": "Tombstone"},
|
||||
}
|
||||
|
@ -152,5 +152,7 @@ class InboxActivities(TestCase):
|
|||
"cc": [],
|
||||
},
|
||||
}
|
||||
views.inbox.activity_task(activity)
|
||||
with patch("bookwyrm.lists_stream.remove_list_task.delay") as mock:
|
||||
views.inbox.activity_task(activity)
|
||||
self.assertTrue(mock.called)
|
||||
self.assertFalse(models.List.objects.exists())
|
||||
|
|
|
@ -15,7 +15,7 @@ class InboxRelationships(TestCase):
|
|||
"""basic user and book data"""
|
||||
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@example.com",
|
||||
"mouse@mouse.com",
|
||||
|
@ -188,7 +188,8 @@ class InboxRelationships(TestCase):
|
|||
self.assertIsNone(self.local_user.followers.first())
|
||||
|
||||
@patch("bookwyrm.activitystreams.add_user_statuses_task.delay")
|
||||
def test_follow_accept(self, _):
|
||||
@patch("bookwyrm.lists_stream.add_user_lists_task.delay")
|
||||
def test_follow_accept(self, *_):
|
||||
"""a remote user approved a follow request from local"""
|
||||
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"):
|
||||
rel = models.UserFollowRequest.objects.create(
|
||||
|
|
|
@ -14,7 +14,7 @@ class InboxActivities(TestCase):
|
|||
"""basic user and book data"""
|
||||
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@example.com",
|
||||
"mouse@mouse.com",
|
||||
|
|
|
@ -14,7 +14,7 @@ class InboxRemove(TestCase):
|
|||
"""basic user and book data"""
|
||||
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@example.com",
|
||||
"mouse@mouse.com",
|
||||
|
|
|
@ -16,7 +16,7 @@ class InboxUpdate(TestCase):
|
|||
"""basic user and book data"""
|
||||
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@example.com",
|
||||
"mouse@mouse.com",
|
||||
|
@ -78,6 +78,7 @@ class InboxUpdate(TestCase):
|
|||
|
||||
@patch("bookwyrm.suggested_users.rerank_user_task.delay")
|
||||
@patch("bookwyrm.activitystreams.add_user_statuses_task.delay")
|
||||
@patch("bookwyrm.lists_stream.add_user_lists_task.delay")
|
||||
def test_update_user(self, *_):
|
||||
"""update an existing user"""
|
||||
models.UserFollows.objects.create(
|
||||
|
|
|
@ -19,7 +19,7 @@ class InviteViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -18,7 +18,7 @@ class LandingViews(TestCase):
|
|||
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",
|
||||
|
@ -49,7 +49,27 @@ class LandingViews(TestCase):
|
|||
|
||||
def test_about_page(self):
|
||||
"""there are so many views, this just makes sure it LOADS"""
|
||||
view = views.About.as_view()
|
||||
view = views.about
|
||||
request = self.factory.get("")
|
||||
request.user = self.local_user
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
validate_html(result.render())
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_conduct_page(self):
|
||||
"""there are so many views, this just makes sure it LOADS"""
|
||||
view = views.conduct
|
||||
request = self.factory.get("")
|
||||
request.user = self.local_user
|
||||
result = view(request)
|
||||
self.assertIsInstance(result, TemplateResponse)
|
||||
validate_html(result.render())
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_privacy_page(self):
|
||||
"""there are so many views, this just makes sure it LOADS"""
|
||||
view = views.privacy
|
||||
request = self.factory.get("")
|
||||
request.user = self.local_user
|
||||
result = view(request)
|
||||
|
|
|
@ -21,7 +21,7 @@ class LoginViews(TestCase):
|
|||
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@your.domain.here",
|
||||
"mouse@mouse.com",
|
||||
|
|
|
@ -21,7 +21,7 @@ class PasswordViews(TestCase):
|
|||
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.com",
|
||||
|
|
|
@ -16,6 +16,7 @@ from bookwyrm.tests.validate_html import validate_html
|
|||
# pylint: disable=too-many-public-methods
|
||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
|
||||
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
|
||||
@patch("bookwyrm.lists_stream.populate_lists_task.delay")
|
||||
class RegisterViews(TestCase):
|
||||
"""login and password management"""
|
||||
|
||||
|
@ -24,7 +25,7 @@ class RegisterViews(TestCase):
|
|||
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@your.domain.here",
|
||||
"mouse@mouse.com",
|
||||
|
|
|
@ -18,7 +18,7 @@ class BlockViews(TestCase):
|
|||
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",
|
||||
|
@ -61,7 +61,9 @@ class BlockViews(TestCase):
|
|||
|
||||
request = self.factory.post("")
|
||||
request.user = self.local_user
|
||||
with patch("bookwyrm.activitystreams.remove_user_statuses_task.delay"):
|
||||
with patch("bookwyrm.activitystreams.remove_user_statuses_task.delay"), patch(
|
||||
"bookwyrm.lists_stream.remove_user_lists_task.delay"
|
||||
):
|
||||
view(request, self.remote_user.id)
|
||||
block = models.UserBlocks.objects.get()
|
||||
self.assertEqual(block.user_subject, self.local_user)
|
||||
|
@ -76,7 +78,9 @@ class BlockViews(TestCase):
|
|||
request = self.factory.post("")
|
||||
request.user = self.local_user
|
||||
|
||||
with patch("bookwyrm.activitystreams.add_user_statuses_task.delay"):
|
||||
with patch("bookwyrm.activitystreams.add_user_statuses_task.delay"), patch(
|
||||
"bookwyrm.lists_stream.add_user_lists_task.delay"
|
||||
):
|
||||
views.unblock(request, self.remote_user.id)
|
||||
|
||||
self.assertFalse(models.UserBlocks.objects.exists())
|
||||
|
|
|
@ -17,7 +17,7 @@ class ChangePasswordViews(TestCase):
|
|||
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.com",
|
||||
|
|
|
@ -20,7 +20,7 @@ class DeleteUserViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -23,7 +23,7 @@ class EditUserViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -14,6 +14,7 @@ from bookwyrm.tests.validate_html import validate_html
|
|||
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async")
|
||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
|
||||
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
|
||||
@patch("bookwyrm.lists_stream.populate_lists_task.delay")
|
||||
@patch("bookwyrm.activitystreams.add_book_statuses_task.delay")
|
||||
@patch("bookwyrm.activitystreams.remove_book_statuses_task.delay")
|
||||
class ShelfViews(TestCase):
|
||||
|
@ -24,7 +25,7 @@ class ShelfViews(TestCase):
|
|||
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.com",
|
||||
|
|
|
@ -12,6 +12,7 @@ from bookwyrm import forms, models, views
|
|||
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async")
|
||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
|
||||
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
|
||||
@patch("bookwyrm.lists_stream.populate_lists_task.delay")
|
||||
@patch("bookwyrm.activitystreams.add_book_statuses_task.delay")
|
||||
@patch("bookwyrm.activitystreams.remove_book_statuses_task.delay")
|
||||
class ShelfActionViews(TestCase):
|
||||
|
@ -22,7 +23,7 @@ class ShelfActionViews(TestCase):
|
|||
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.com",
|
||||
|
@ -178,7 +179,7 @@ class ShelfActionViews(TestCase):
|
|||
"""delete a brand new custom shelf"""
|
||||
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
||||
"bookwyrm.activitystreams.populate_stream_task.delay"
|
||||
):
|
||||
), patch("bookwyrm.lists_stream.populate_lists_task.delay"):
|
||||
rat = models.User.objects.create_user(
|
||||
"rat@local.com",
|
||||
"rat@mouse.mouse",
|
||||
|
|
|
@ -26,7 +26,7 @@ class AnnualSummary(TestCase):
|
|||
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.com",
|
||||
|
|
|
@ -21,7 +21,7 @@ class AuthorViews(TestCase):
|
|||
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.com",
|
||||
|
|
|
@ -18,7 +18,7 @@ class DirectoryViews(TestCase):
|
|||
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.com",
|
||||
|
@ -34,6 +34,7 @@ class DirectoryViews(TestCase):
|
|||
|
||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
|
||||
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
|
||||
@patch("bookwyrm.lists_stream.populate_lists_task.delay")
|
||||
@patch("bookwyrm.suggested_users.rerank_user_task.delay")
|
||||
def test_directory_page(self, *_):
|
||||
"""there are so many views, this just makes sure it LOADS"""
|
||||
|
|
|
@ -16,7 +16,7 @@ class DiscoverViews(TestCase):
|
|||
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",
|
||||
|
|
|
@ -10,8 +10,7 @@ from django.template.response import TemplateResponse
|
|||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from bookwyrm import models
|
||||
from bookwyrm import views
|
||||
from bookwyrm import forms, models, views
|
||||
from bookwyrm.activitypub import ActivitypubResponse
|
||||
from bookwyrm.tests.validate_html import validate_html
|
||||
|
||||
|
@ -20,6 +19,7 @@ from bookwyrm.tests.validate_html import validate_html
|
|||
@patch("bookwyrm.activitystreams.add_status_task.delay")
|
||||
@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
|
||||
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
|
||||
@patch("bookwyrm.lists_stream.populate_lists_task.delay")
|
||||
@patch("bookwyrm.suggested_users.remove_user_task.delay")
|
||||
class FeedViews(TestCase):
|
||||
"""activity feed, statuses, dms"""
|
||||
|
@ -29,7 +29,7 @@ class FeedViews(TestCase):
|
|||
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",
|
||||
|
@ -62,6 +62,25 @@ class FeedViews(TestCase):
|
|||
validate_html(result.render())
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
@patch("bookwyrm.suggested_users.SuggestedUsers.get_suggestions")
|
||||
def test_save_feed_settings(self, *_):
|
||||
"""update display preferences"""
|
||||
self.assertEqual(
|
||||
self.local_user.feed_status_types,
|
||||
["review", "comment", "quotation", "everything"],
|
||||
)
|
||||
view = views.Feed.as_view()
|
||||
form = forms.FeedStatusTypesForm(instance=self.local_user)
|
||||
form.data["feed_status_types"] = "review"
|
||||
request = self.factory.post("", form.data)
|
||||
request.user = self.local_user
|
||||
|
||||
result = view(request, "home")
|
||||
|
||||
self.assertEqual(result.status_code, 200)
|
||||
self.local_user.refresh_from_db()
|
||||
self.assertEqual(self.local_user.feed_status_types, ["review"])
|
||||
|
||||
def test_status_page(self, *_):
|
||||
"""there are so many views, this just makes sure it LOADS"""
|
||||
view = views.Status.as_view()
|
||||
|
|
|
@ -13,6 +13,7 @@ from bookwyrm.tests.validate_html import validate_html
|
|||
|
||||
|
||||
@patch("bookwyrm.activitystreams.add_user_statuses_task.delay")
|
||||
@patch("bookwyrm.lists_stream.add_user_lists_task.delay")
|
||||
class FollowViews(TestCase):
|
||||
"""follows"""
|
||||
|
||||
|
@ -22,7 +23,7 @@ class FollowViews(TestCase):
|
|||
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.com",
|
||||
|
@ -56,7 +57,7 @@ class FollowViews(TestCase):
|
|||
parent_work=self.work,
|
||||
)
|
||||
|
||||
def test_handle_follow_remote(self, _):
|
||||
def test_handle_follow_remote(self, *_):
|
||||
"""send a follow request"""
|
||||
request = self.factory.post("", {"user": self.remote_user.username})
|
||||
request.user = self.local_user
|
||||
|
@ -71,11 +72,11 @@ class FollowViews(TestCase):
|
|||
self.assertEqual(rel.user_object, self.remote_user)
|
||||
self.assertEqual(rel.status, "follow_request")
|
||||
|
||||
def test_handle_follow_local_manually_approves(self, _):
|
||||
def test_handle_follow_local_manually_approves(self, *_):
|
||||
"""send a follow request"""
|
||||
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
||||
"bookwyrm.activitystreams.populate_stream_task.delay"
|
||||
):
|
||||
), patch("bookwyrm.lists_stream.populate_lists_task.delay"):
|
||||
rat = models.User.objects.create_user(
|
||||
"rat@local.com",
|
||||
"rat@rat.com",
|
||||
|
@ -97,11 +98,11 @@ class FollowViews(TestCase):
|
|||
self.assertEqual(rel.user_object, rat)
|
||||
self.assertEqual(rel.status, "follow_request")
|
||||
|
||||
def test_handle_follow_local(self, _):
|
||||
def test_handle_follow_local(self, *_):
|
||||
"""send a follow request"""
|
||||
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
||||
"bookwyrm.activitystreams.populate_stream_task.delay"
|
||||
):
|
||||
), patch("bookwyrm.lists_stream.populate_lists_task.delay"):
|
||||
rat = models.User.objects.create_user(
|
||||
"rat@local.com",
|
||||
"rat@rat.com",
|
||||
|
@ -124,6 +125,7 @@ class FollowViews(TestCase):
|
|||
self.assertEqual(rel.status, "follows")
|
||||
|
||||
@patch("bookwyrm.activitystreams.remove_user_statuses_task.delay")
|
||||
@patch("bookwyrm.lists_stream.remove_user_lists_task.delay")
|
||||
def test_handle_unfollow(self, *_):
|
||||
"""send an unfollow"""
|
||||
request = self.factory.post("", {"user": self.remote_user.username})
|
||||
|
@ -140,7 +142,7 @@ class FollowViews(TestCase):
|
|||
|
||||
self.assertEqual(self.remote_user.followers.count(), 0)
|
||||
|
||||
def test_handle_accept(self, _):
|
||||
def test_handle_accept(self, *_):
|
||||
"""accept a follow request"""
|
||||
self.local_user.manually_approves_followers = True
|
||||
self.local_user.save(
|
||||
|
@ -159,7 +161,7 @@ class FollowViews(TestCase):
|
|||
# follow relationship should exist
|
||||
self.assertEqual(self.local_user.followers.first(), self.remote_user)
|
||||
|
||||
def test_handle_reject(self, _):
|
||||
def test_handle_reject(self, *_):
|
||||
"""reject a follow request"""
|
||||
self.local_user.manually_approves_followers = True
|
||||
self.local_user.save(
|
||||
|
@ -178,7 +180,7 @@ class FollowViews(TestCase):
|
|||
# follow relationship should not exist
|
||||
self.assertEqual(models.UserFollows.objects.filter(id=rel.id).count(), 0)
|
||||
|
||||
def test_ostatus_follow_request(self, _):
|
||||
def test_ostatus_follow_request(self, *_):
|
||||
"""check ostatus subscribe template loads"""
|
||||
request = self.factory.get(
|
||||
"", {"acct": "https%3A%2F%2Fexample.com%2Fusers%2Frat"}
|
||||
|
@ -189,7 +191,7 @@ class FollowViews(TestCase):
|
|||
validate_html(result.render())
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_remote_follow_page(self, _):
|
||||
def test_remote_follow_page(self, *_):
|
||||
"""check remote follow page loads"""
|
||||
request = self.factory.get("", {"acct": "mouse@local.com"})
|
||||
request.user = self.remote_user
|
||||
|
@ -198,7 +200,7 @@ class FollowViews(TestCase):
|
|||
validate_html(result.render())
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_ostatus_follow_success(self, _):
|
||||
def test_ostatus_follow_success(self, *_):
|
||||
"""check remote follow success page loads"""
|
||||
request = self.factory.get("")
|
||||
request.user = self.remote_user
|
||||
|
@ -208,7 +210,7 @@ class FollowViews(TestCase):
|
|||
validate_html(result.render())
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
def test_remote_follow(self, _):
|
||||
def test_remote_follow(self, *_):
|
||||
"""check follow from remote page loads"""
|
||||
request = self.factory.post("", {"user": self.remote_user.id})
|
||||
request.user = self.remote_user
|
||||
|
|
|
@ -17,7 +17,7 @@ class GetStartedViews(TestCase):
|
|||
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",
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue