diff --git a/bookwyrm/models/bookwyrm_export_job.py b/bookwyrm/models/bookwyrm_export_job.py
index c262d9b5c..c3a0b652a 100644
--- a/bookwyrm/models/bookwyrm_export_job.py
+++ b/bookwyrm/models/bookwyrm_export_job.py
@@ -153,20 +153,12 @@ def json_export(user):
comments = models.Comment.objects.filter(user=user, book=book["id"]).distinct()
book["comments"] = list(comments.values())
- logger.error("FINAL COMMENTS")
- logger.error(book["comments"])
# quotes
quotes = models.Quotation.objects.filter(user=user, book=book["id"]).distinct()
- # quote_statuses = models.Status.objects.filter(
- # id__in=quotes, user=kwargs["user"]
- # ).distinct()
book["quotes"] = list(quotes.values())
- logger.error("FINAL QUOTES")
- logger.error(book["quotes"])
-
# append everything
final_books.append(book)
diff --git a/bookwyrm/templates/preferences/export-user.html b/bookwyrm/templates/preferences/export-user.html
index 81f13bc22..393d8990e 100644
--- a/bookwyrm/templates/preferences/export-user.html
+++ b/bookwyrm/templates/preferences/export-user.html
@@ -12,15 +12,13 @@
{% trans "Your exported archive file will include all user data for import into another Bookwyrm server" %}
-
-
-
+
{% trans "Recent Exports" %}
diff --git a/bookwyrm/tests/models/test_bookwyrm_export_job.py b/bookwyrm/tests/models/test_bookwyrm_export_job.py
new file mode 100644
index 000000000..bd314e60e
--- /dev/null
+++ b/bookwyrm/tests/models/test_bookwyrm_export_job.py
@@ -0,0 +1,233 @@
+import datetime
+import time
+import json
+from unittest.mock import patch
+
+from django.core.serializers.json import DjangoJSONEncoder
+from django.test import TestCase
+from django.utils import timezone
+
+from bookwyrm import models
+import bookwyrm.models.bookwyrm_export_job as export_job
+
+
+class BookwyrmExport(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",
+ )
+
+ 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
+ )
+
+ 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
+ item = 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,
+ )
+
+ def test_json_export_user_settings(self):
+ """Test the json export function for basic user info"""
+ data = export_job.json_export(self.local_user)
+ user_data = json.loads(data)["user"]
+ self.assertEqual(user_data["username"], "mouse")
+ self.assertEqual(user_data["name"], "Mouse")
+ self.assertEqual(user_data["summary"], "I'm a real bookmouse")
+ self.assertEqual(user_data["manually_approves_followers"], False)
+ self.assertEqual(user_data["hide_follows"], False)
+ self.assertEqual(user_data["show_goal"], False)
+ self.assertEqual(user_data["show_suggested_users"], False)
+ self.assertEqual(user_data["discoverable"], True)
+ self.assertEqual(user_data["preferred_timezone"], "America/Los Angeles")
+ self.assertEqual(user_data["default_post_privacy"], "followers")
+
+ def test_json_export_extended_user_data(self):
+ """Test the json export function for other non-book user info"""
+ data = export_job.json_export(self.local_user)
+ json_data = json.loads(data)
+
+ # goal
+ self.assertEqual(len(json_data["goals"]), 1)
+ self.assertEqual(json_data["goals"][0]["goal"], 128937123)
+ self.assertEqual(json_data["goals"][0]["year"], timezone.now().year)
+ self.assertEqual(json_data["goals"][0]["privacy"], "followers")
+
+ # saved lists
+ self.assertEqual(len(json_data["saved_lists"]), 1)
+ self.assertEqual(json_data["saved_lists"][0], "https://local.lists/9999")
+
+ # follows
+ self.assertEqual(len(json_data["follows"]), 1)
+ self.assertEqual(json_data["follows"][0], "https://your.domain.here/user/rat")
+ # blocked users
+ self.assertEqual(len(json_data["blocked_users"]), 1)
+ self.assertEqual(
+ json_data["blocked_users"][0], "https://your.domain.here/user/badger"
+ )
+
+ def test_json_export_books(self):
+ """Test the json export function for extended user info"""
+
+ data = export_job.json_export(self.local_user)
+ json_data = json.loads(data)
+ start_date = json_data["books"][0]["readthroughs"][0]["start_date"]
+
+ self.assertEqual(len(json_data["books"]), 1)
+ self.assertEqual(json_data["books"][0]["title"], "Example Edition")
+ self.assertEqual(len(json_data["books"][0]["authors"]), 1)
+ self.assertEqual(json_data["books"][0]["authors"][0]["name"], "Sam Zhu")
+ self.assertEqual(
+ f'"{start_date}"', DjangoJSONEncoder().encode(self.readthrough_start)
+ )
+ self.assertEqual(json_data["books"][0]["shelves"][0]["identifier"], "read")
+ self.assertEqual(
+ json_data["books"][0]["shelf_books"]["read"][0]["book_id"], self.edition.id
+ )
+
+ self.assertEqual(len(json_data["books"][0]["lists"]), 1)
+ self.assertEqual(json_data["books"][0]["lists"][0]["name"], "My excellent list")
+ self.assertEqual(len(json_data["books"][0]["list_items"]), 1)
+ self.assertEqual(
+ json_data["books"][0]["list_items"]["My excellent list"][0]["book_id"],
+ self.edition.id,
+ )
+
+ self.assertEqual(len(json_data["books"][0]["reviews"]), 1)
+ self.assertEqual(len(json_data["books"][0]["comments"]), 1)
+ self.assertEqual(len(json_data["books"][0]["quotes"]), 1)
+
+ self.assertEqual(json_data["books"][0]["reviews"][0]["name"], "my review")
+ self.assertEqual(json_data["books"][0]["reviews"][0]["content"], "awesome")
+ self.assertEqual(json_data["books"][0]["reviews"][0]["rating"], "5.00")
+
+ self.assertEqual(json_data["books"][0]["comments"][0]["content"], "ok so far")
+ self.assertEqual(json_data["books"][0]["comments"][0]["progress"], 15)
+ self.assertEqual(json_data["books"][0]["comments"][0]["progress_mode"], "PG")
+
+ self.assertEqual(
+ json_data["books"][0]["quotes"][0]["content"], "check this out"
+ )
+ self.assertEqual(
+ json_data["books"][0]["quotes"][0]["quote"], "A rose by any other name"
+ )
+
+ def test_tar_export(self):
+ """test the tar export function"""
+
+ # TODO
+ pass
diff --git a/bookwyrm/tests/models/test_bookwyrm_import_model.py b/bookwyrm/tests/models/test_bookwyrm_import_job.py
similarity index 96%
rename from bookwyrm/tests/models/test_bookwyrm_import_model.py
rename to bookwyrm/tests/models/test_bookwyrm_import_job.py
index 644cbd265..61713cd17 100644
--- a/bookwyrm/tests/models/test_bookwyrm_import_model.py
+++ b/bookwyrm/tests/models/test_bookwyrm_import_job.py
@@ -70,15 +70,28 @@ class BookwyrmImport(TestCase):
self.tarfile = BookwyrmTarFile.open(
mode="r:gz", fileobj=open(archive_file, "rb")
)
- self.import_data = json.loads(
- self.tarfile.read("archive.json").decode("utf-8")
- )
+ self.import_data = json.loads(self.tarfile.read("archive.json").decode("utf-8"))
def test_update_user_profile(self):
"""Test update the user's profile from import data"""
- # TODO once the tar is set up
- pass
+ with patch("bookwyrm.suggested_users.remove_user_task.delay"), patch(
+ "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"
+ ):
+
+ models.bookwyrm_import_job.update_user_profile(
+ self.local_user, self.tarfile, self.import_data.get("user")
+ )
+ self.local_user.refresh_from_db()
+
+ self.assertEqual(
+ self.local_user.username, "mouse"
+ ) # username should not change
+ self.assertEqual(self.local_user.name, "Rat")
+ self.assertEqual(
+ self.local_user.summary,
+ "I love to make soup in Paris and eat pizza in New York",
+ )
def test_update_user_settings(self):
"""Test updating the user's settings from import data"""
@@ -543,6 +556,8 @@ class BookwyrmImport(TestCase):
self.assertEqual(
models.ShelfBook.objects.filter(user=self.local_user.id).count(), 2
)
+
+ # check we didn't create an extra shelf
self.assertEqual(
- models.Shelf.objects.filter(user=self.local_user.id).count(), 2
+ models.Shelf.objects.filter(user=self.local_user.id).count(), 4
)
diff --git a/bookwyrm/tests/views/preferences/test_export_user.py b/bookwyrm/tests/views/preferences/test_export_user.py
index c7594749b..1483fc4ec 100644
--- a/bookwyrm/tests/views/preferences/test_export_user.py
+++ b/bookwyrm/tests/views/preferences/test_export_user.py
@@ -49,26 +49,3 @@ class ExportUserViews(TestCase):
jobs = models.bookwyrm_export_job.BookwyrmExportJob.objects.count()
self.assertEqual(jobs, 1)
-
- def test_download_export_user_file(self, *_):
- """simple user export"""
-
- # TODO: need some help with this one
- job = models.bookwyrm_export_job.BookwyrmExportJob.objects.create(
- user=self.local_user
- )
- MockTask = namedtuple("Task", ("id"))
- with patch(
- "bookwyrm.models.bookwyrm_export_job.start_export_task.delay"
- ) as mock:
- mock.return_value = MockTask(b'{"name": "mouse"}')
- job.start_job()
-
- request = self.factory.get("")
- request.user = self.local_user
- job.refresh_from_db()
- export = views.ExportArchive.as_view()(request, job.id)
- self.assertIsInstance(export, HttpResponse)
- self.assertEqual(export.status_code, 200)
- # pylint: disable=line-too-long
- self.assertEqual(export.content, b'{"name": "mouse"}')