[books] Add goodreads exports
This commit is contained in:
0
tests/books_tests/__init__.py
Normal file
0
tests/books_tests/__init__.py
Normal file
133
tests/books_tests/test_goodreads_export.py
Normal file
133
tests/books_tests/test_goodreads_export.py
Normal file
@ -0,0 +1,133 @@
|
||||
import csv
|
||||
from datetime import datetime
|
||||
from io import StringIO
|
||||
|
||||
import pytest
|
||||
from books.models import Author, Book
|
||||
from books.utils import GOODREADS_HEADERS
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from scrobbles.models import Scrobble
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def user():
|
||||
return User.objects.create_user(
|
||||
username="reader", email="reader@example.com", password="testpass"
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def book(user):
|
||||
primary = Author.objects.create(name="Nicholas A. Basbanes")
|
||||
secondary = Author.objects.create(name="Jane Q. Doe")
|
||||
book = Book.objects.create(
|
||||
title="A Gentle Madness",
|
||||
isbn_13="9780805061765",
|
||||
isbn_10="0805061762",
|
||||
pages=500,
|
||||
publisher="Holt Paperbacks",
|
||||
first_publish_year=1999,
|
||||
)
|
||||
book.authors.add(primary, secondary)
|
||||
book.tags.add("history", "books")
|
||||
return book
|
||||
|
||||
|
||||
def test_goodreads_export_requires_login(client):
|
||||
url = reverse("books:goodreads_export")
|
||||
response = client.get(url)
|
||||
assert response.status_code == 302
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_goodreads_export_empty(client, user):
|
||||
client.force_login(user)
|
||||
url = reverse("books:goodreads_export")
|
||||
response = client.get(url)
|
||||
assert response.status_code == 200
|
||||
assert response["Content-Type"] == "text/csv"
|
||||
rows = list(csv.reader(StringIO(response.content.decode())))
|
||||
assert rows[0] == GOODREADS_HEADERS
|
||||
assert len(rows) == 1
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_goodreads_export_marks_in_progress(client, user, book):
|
||||
Scrobble.objects.create(
|
||||
book=book,
|
||||
media_type=Scrobble.MediaType.BOOK,
|
||||
user=user,
|
||||
timestamp=timezone.make_aware(datetime(2023, 3, 1)),
|
||||
long_play_complete=False,
|
||||
)
|
||||
|
||||
client.force_login(user)
|
||||
url = reverse("books:goodreads_export")
|
||||
response = client.get(url)
|
||||
rows = list(csv.DictReader(StringIO(response.content.decode())))
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["Title"] == "A Gentle Madness"
|
||||
assert rows[0]["Author"] == "Nicholas A. Basbanes"
|
||||
assert rows[0]["Author l-f"] == "Basbanes, Nicholas A."
|
||||
assert rows[0]["Additional Authors"] == "Jane Q. Doe"
|
||||
assert rows[0]["ISBN"] == "0805061762"
|
||||
assert rows[0]["ISBN13"] == "9780805061765"
|
||||
assert rows[0]["Number of Pages"] == "500"
|
||||
assert rows[0]["Year Published"] == "1999"
|
||||
assert rows[0]["Exclusive Shelf"] == "currently-reading"
|
||||
assert rows[0]["Date Read"] == ""
|
||||
assert rows[0]["Date Added"] == "2023/03/01"
|
||||
assert rows[0]["Bookshelves"] == "books, history"
|
||||
assert rows[0]["Read Count"] == "1"
|
||||
assert rows[0]["Owned Copies"] == "0"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_goodreads_export_marks_finished(client, user, book):
|
||||
Scrobble.objects.create(
|
||||
book=book,
|
||||
media_type=Scrobble.MediaType.BOOK,
|
||||
user=user,
|
||||
timestamp=timezone.make_aware(datetime(2023, 5, 5)),
|
||||
long_play_complete=True,
|
||||
)
|
||||
|
||||
client.force_login(user)
|
||||
url = reverse("books:goodreads_export")
|
||||
response = client.get(url)
|
||||
rows = list(csv.DictReader(StringIO(response.content.decode())))
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["Exclusive Shelf"] == "read"
|
||||
assert rows[0]["Date Read"] == "2023/05/05"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_goodreads_export_date_added_is_first_scrobble(client, user, book):
|
||||
Scrobble.objects.create(
|
||||
book=book,
|
||||
media_type=Scrobble.MediaType.BOOK,
|
||||
user=user,
|
||||
timestamp=timezone.make_aware(datetime(2023, 3, 1)),
|
||||
long_play_complete=False,
|
||||
)
|
||||
Scrobble.objects.create(
|
||||
book=book,
|
||||
media_type=Scrobble.MediaType.BOOK,
|
||||
user=user,
|
||||
timestamp=timezone.make_aware(datetime(2023, 5, 5)),
|
||||
long_play_complete=True,
|
||||
)
|
||||
|
||||
client.force_login(user)
|
||||
url = reverse("books:goodreads_export")
|
||||
response = client.get(url)
|
||||
rows = list(csv.DictReader(StringIO(response.content.decode())))
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["Exclusive Shelf"] == "read"
|
||||
assert rows[0]["Date Added"] == "2023/03/01"
|
||||
assert rows[0]["Date Read"] == "2023/05/05"
|
||||
assert rows[0]["Read Count"] == "2"
|
||||
135
tests/books_tests/test_librarything_export.py
Normal file
135
tests/books_tests/test_librarything_export.py
Normal file
@ -0,0 +1,135 @@
|
||||
import csv
|
||||
from datetime import datetime
|
||||
from io import StringIO
|
||||
|
||||
import pytest
|
||||
from books.models import Author, Book
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from scrobbles.models import Scrobble
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def user():
|
||||
return User.objects.create_user(
|
||||
username="reader", email="reader@example.com", password="testpass"
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def book(user):
|
||||
author = Author.objects.create(name="Nicholas A. Basbanes")
|
||||
book = Book.objects.create(
|
||||
title="A Gentle Madness",
|
||||
isbn_13="0805061762",
|
||||
pages=500,
|
||||
publisher="Holt Paperbacks",
|
||||
first_publish_year=1999,
|
||||
)
|
||||
book.authors.add(author)
|
||||
return book
|
||||
|
||||
|
||||
def test_librarything_export_requires_login(client):
|
||||
url = reverse("books:librarything_export")
|
||||
response = client.get(url)
|
||||
assert response.status_code == 302
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_librarything_export_empty(client, user):
|
||||
client.force_login(user)
|
||||
url = reverse("books:librarything_export")
|
||||
response = client.get(url)
|
||||
assert response.status_code == 200
|
||||
assert response["Content-Type"] == "text/csv"
|
||||
rows = list(csv.reader(StringIO(response.content.decode())))
|
||||
assert rows[0] == [
|
||||
"TITLE",
|
||||
"AUTHOR (last, first)",
|
||||
"DATE",
|
||||
"ISBN",
|
||||
"PUBLICATION INFO",
|
||||
"TAGS",
|
||||
"RATING",
|
||||
"REVIEW",
|
||||
"DATE READ",
|
||||
"ENTRY DATE",
|
||||
"PAGE COUNT",
|
||||
"CALL NUMBER",
|
||||
]
|
||||
assert len(rows) == 1
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_librarything_export_marks_in_progress(client, user, book):
|
||||
Scrobble.objects.create(
|
||||
book=book,
|
||||
media_type=Scrobble.MediaType.BOOK,
|
||||
user=user,
|
||||
timestamp=timezone.make_aware(datetime(2023, 3, 1)),
|
||||
long_play_complete=False,
|
||||
)
|
||||
|
||||
client.force_login(user)
|
||||
url = reverse("books:librarything_export")
|
||||
response = client.get(url)
|
||||
rows = list(csv.DictReader(StringIO(response.content.decode())))
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["TITLE"] == "A Gentle Madness"
|
||||
assert rows[0]["AUTHOR (last, first)"] == "Basbanes, Nicholas A."
|
||||
assert rows[0]["ISBN"] == "0805061762"
|
||||
assert rows[0]["PAGE COUNT"] == "500"
|
||||
assert rows[0]["TAGS"] == "in-progress"
|
||||
assert rows[0]["DATE READ"] == ""
|
||||
assert rows[0]["ENTRY DATE"] == "2023-03-01"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_librarything_export_marks_finished(client, user, book):
|
||||
Scrobble.objects.create(
|
||||
book=book,
|
||||
media_type=Scrobble.MediaType.BOOK,
|
||||
user=user,
|
||||
timestamp=timezone.make_aware(datetime(2023, 5, 5)),
|
||||
long_play_complete=True,
|
||||
)
|
||||
|
||||
client.force_login(user)
|
||||
url = reverse("books:librarything_export")
|
||||
response = client.get(url)
|
||||
rows = list(csv.DictReader(StringIO(response.content.decode())))
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["TAGS"] == "finished"
|
||||
assert rows[0]["DATE READ"] == "2023-05-05"
|
||||
assert rows[0]["ENTRY DATE"] == "2023-05-05"
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_librarything_export_entry_date_is_first_scrobble(client, user, book):
|
||||
Scrobble.objects.create(
|
||||
book=book,
|
||||
media_type=Scrobble.MediaType.BOOK,
|
||||
user=user,
|
||||
timestamp=timezone.make_aware(datetime(2023, 3, 1)),
|
||||
long_play_complete=False,
|
||||
)
|
||||
Scrobble.objects.create(
|
||||
book=book,
|
||||
media_type=Scrobble.MediaType.BOOK,
|
||||
user=user,
|
||||
timestamp=timezone.make_aware(datetime(2023, 5, 5)),
|
||||
long_play_complete=True,
|
||||
)
|
||||
|
||||
client.force_login(user)
|
||||
url = reverse("books:librarything_export")
|
||||
response = client.get(url)
|
||||
rows = list(csv.DictReader(StringIO(response.content.decode())))
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["TAGS"] == "finished"
|
||||
assert rows[0]["ENTRY DATE"] == "2023-03-01"
|
||||
assert rows[0]["DATE READ"] == "2023-05-05"
|
||||
Reference in New Issue
Block a user