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"