mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-05-19 00:38:21 +00:00
257 lines
9.7 KiB
Python
257 lines
9.7 KiB
Python
"""test bookwyrm user export functions"""
|
|
import datetime
|
|
import json
|
|
import pathlib
|
|
|
|
from unittest.mock import patch
|
|
|
|
from django.utils import timezone
|
|
from django.test import TestCase
|
|
|
|
from bookwyrm import models
|
|
from bookwyrm.utils.tar import BookwyrmTarFile
|
|
|
|
|
|
class BookwyrmExportJob(TestCase):
|
|
"""testing user export functions"""
|
|
|
|
def setUp(self):
|
|
"""lots of stuff to set up for a user export"""
|
|
with (
|
|
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"),
|
|
patch("bookwyrm.lists_stream.remove_list_task.delay"),
|
|
patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"),
|
|
patch("bookwyrm.activitystreams.add_book_statuses_task"),
|
|
):
|
|
|
|
self.local_user = models.User.objects.create_user(
|
|
"mouse",
|
|
"mouse@mouse.mouse",
|
|
"password",
|
|
local=True,
|
|
localname="mouse",
|
|
name="Mouse",
|
|
summary="I'm a real bookmouse",
|
|
manually_approves_followers=False,
|
|
hide_follows=False,
|
|
show_goal=False,
|
|
show_suggested_users=False,
|
|
discoverable=True,
|
|
preferred_timezone="America/Los Angeles",
|
|
default_post_privacy="followers",
|
|
)
|
|
avatar_path = pathlib.Path(__file__).parent.joinpath(
|
|
"../../static/images/default_avi.jpg"
|
|
)
|
|
with open(avatar_path, "rb") as avatar_file:
|
|
self.local_user.avatar.save("mouse-avatar.jpg", avatar_file)
|
|
|
|
self.rat_user = models.User.objects.create_user(
|
|
"rat", "rat@rat.rat", "ratword", local=True, localname="rat"
|
|
)
|
|
|
|
self.badger_user = models.User.objects.create_user(
|
|
"badger",
|
|
"badger@badger.badger",
|
|
"badgerword",
|
|
local=True,
|
|
localname="badger",
|
|
)
|
|
|
|
models.AnnualGoal.objects.create(
|
|
user=self.local_user,
|
|
year=timezone.now().year,
|
|
goal=128937123,
|
|
privacy="followers",
|
|
)
|
|
|
|
self.list = models.List.objects.create(
|
|
name="My excellent list",
|
|
user=self.local_user,
|
|
remote_id="https://local.lists/1111",
|
|
)
|
|
|
|
self.saved_list = models.List.objects.create(
|
|
name="My cool list",
|
|
user=self.rat_user,
|
|
remote_id="https://local.lists/9999",
|
|
)
|
|
|
|
self.local_user.saved_lists.add(self.saved_list)
|
|
self.local_user.blocks.add(self.badger_user)
|
|
self.rat_user.followers.add(self.local_user)
|
|
|
|
# book, edition, author
|
|
self.author = models.Author.objects.create(name="Sam Zhu")
|
|
self.work = models.Work.objects.create(
|
|
title="Example Work", remote_id="https://example.com/book/1"
|
|
)
|
|
self.edition = models.Edition.objects.create(
|
|
title="Example Edition", parent_work=self.work
|
|
)
|
|
|
|
# edition cover
|
|
cover_path = pathlib.Path(__file__).parent.joinpath(
|
|
"../../static/images/default_avi.jpg"
|
|
)
|
|
with open(cover_path, "rb") as cover_file:
|
|
self.edition.cover.save("tèst.jpg", cover_file)
|
|
|
|
self.edition.authors.add(self.author)
|
|
|
|
# readthrough
|
|
self.readthrough_start = timezone.now()
|
|
finish = self.readthrough_start + datetime.timedelta(days=1)
|
|
models.ReadThrough.objects.create(
|
|
user=self.local_user,
|
|
book=self.edition,
|
|
start_date=self.readthrough_start,
|
|
finish_date=finish,
|
|
)
|
|
|
|
# shelve
|
|
read_shelf = models.Shelf.objects.get(
|
|
user=self.local_user, identifier="read"
|
|
)
|
|
models.ShelfBook.objects.create(
|
|
book=self.edition, shelf=read_shelf, user=self.local_user
|
|
)
|
|
|
|
# add to list
|
|
models.ListItem.objects.create(
|
|
book_list=self.list,
|
|
user=self.local_user,
|
|
book=self.edition,
|
|
approved=True,
|
|
order=1,
|
|
)
|
|
|
|
# review
|
|
models.Review.objects.create(
|
|
content="awesome",
|
|
name="my review",
|
|
rating=5,
|
|
user=self.local_user,
|
|
book=self.edition,
|
|
)
|
|
# comment
|
|
models.Comment.objects.create(
|
|
content="ok so far",
|
|
user=self.local_user,
|
|
book=self.edition,
|
|
progress=15,
|
|
)
|
|
# quote
|
|
models.Quotation.objects.create(
|
|
content="check this out",
|
|
quote="A rose by any other name",
|
|
user=self.local_user,
|
|
book=self.edition,
|
|
)
|
|
|
|
self.job = models.BookwyrmExportJob.objects.create(user=self.local_user)
|
|
|
|
# run the first stage of the export
|
|
with patch("bookwyrm.models.bookwyrm_export_job.create_archive_task.delay"):
|
|
models.bookwyrm_export_job.create_export_json_task(job_id=self.job.id)
|
|
self.job.refresh_from_db()
|
|
|
|
def test_add_book_to_user_export_job(self):
|
|
"""does AddBookToUserExportJob ...add the book to the export?"""
|
|
self.assertIsNotNone(self.job.export_json["books"])
|
|
self.assertEqual(len(self.job.export_json["books"]), 1)
|
|
book = self.job.export_json["books"][0]
|
|
|
|
self.assertEqual(book["work"]["id"], self.work.remote_id)
|
|
self.assertEqual(len(book["authors"]), 1)
|
|
self.assertEqual(len(book["shelves"]), 1)
|
|
self.assertEqual(len(book["lists"]), 1)
|
|
self.assertEqual(len(book["comments"]), 1)
|
|
self.assertEqual(len(book["reviews"]), 1)
|
|
self.assertEqual(len(book["quotations"]), 1)
|
|
self.assertEqual(len(book["readthroughs"]), 1)
|
|
|
|
self.assertEqual(book["edition"]["id"], self.edition.remote_id)
|
|
self.assertEqual(
|
|
book["edition"]["cover"]["url"], f"images/{self.edition.cover.name}"
|
|
)
|
|
|
|
def test_start_export_task(self):
|
|
"""test saved list task saves initial json and data"""
|
|
self.assertIsNotNone(self.job.export_data)
|
|
self.assertIsNotNone(self.job.export_json)
|
|
self.assertEqual(self.job.export_json["name"], self.local_user.name)
|
|
|
|
def test_export_saved_lists_task(self):
|
|
"""test export_saved_lists_task adds the saved lists"""
|
|
self.assertIsNotNone(self.job.export_json["saved_lists"])
|
|
self.assertEqual(
|
|
self.job.export_json["saved_lists"][0], self.saved_list.remote_id
|
|
)
|
|
|
|
def test_export_follows_task(self):
|
|
"""test export_follows_task adds the follows"""
|
|
self.assertIsNotNone(self.job.export_json["follows"])
|
|
self.assertEqual(self.job.export_json["follows"][0], self.rat_user.remote_id)
|
|
|
|
def test_export_blocks_task(self):
|
|
"""test export_blocks_task adds the blocks"""
|
|
self.assertIsNotNone(self.job.export_json["blocks"])
|
|
self.assertEqual(self.job.export_json["blocks"][0], self.badger_user.remote_id)
|
|
|
|
def test_export_reading_goals_task(self):
|
|
"""test export_reading_goals_task adds the goals"""
|
|
self.assertIsNotNone(self.job.export_json["goals"])
|
|
self.assertEqual(self.job.export_json["goals"][0]["goal"], 128937123)
|
|
|
|
def test_json_export(self):
|
|
"""test json_export job adds settings"""
|
|
self.assertIsNotNone(self.job.export_json["settings"])
|
|
self.assertFalse(self.job.export_json["settings"]["show_goal"])
|
|
self.assertEqual(
|
|
self.job.export_json["settings"]["preferred_timezone"],
|
|
"America/Los Angeles",
|
|
)
|
|
self.assertEqual(
|
|
self.job.export_json["settings"]["default_post_privacy"], "followers"
|
|
)
|
|
self.assertFalse(self.job.export_json["settings"]["show_suggested_users"])
|
|
|
|
def test_get_books_for_user(self):
|
|
"""does get_books_for_user get all the books"""
|
|
|
|
data = models.bookwyrm_export_job.get_books_for_user(self.local_user)
|
|
|
|
self.assertEqual(len(data), 1)
|
|
self.assertEqual(data[0].title, "Example Edition")
|
|
|
|
def test_archive(self):
|
|
"""actually create the TAR file"""
|
|
models.bookwyrm_export_job.create_archive_task(job_id=self.job.id)
|
|
self.job.refresh_from_db()
|
|
|
|
with (
|
|
self.job.export_data.open("rb") as tar_file,
|
|
BookwyrmTarFile.open(mode="r", fileobj=tar_file) as tar,
|
|
):
|
|
archive_json_file = tar.extractfile("archive.json")
|
|
data = json.load(archive_json_file)
|
|
|
|
# JSON from the archive should be what we want it to be
|
|
self.assertEqual(data, self.job.export_json)
|
|
|
|
# User avatar should be present in archive
|
|
with self.local_user.avatar.open() as expected_avatar:
|
|
archive_avatar = tar.extractfile(data["icon"]["url"])
|
|
self.assertEqual(expected_avatar.read(), archive_avatar.read())
|
|
|
|
# Edition cover should be present in archive
|
|
with self.edition.cover.open() as expected_cover:
|
|
archive_cover = tar.extractfile(
|
|
data["books"][0]["edition"]["cover"]["url"]
|
|
)
|
|
self.assertEqual(expected_cover.read(), archive_cover.read())
|