More API testing.
authorRadek Czajka <rczajka@rczajka.pl>
Wed, 16 Jan 2019 23:42:29 +0000 (00:42 +0100)
committerRadek Czajka <rczajka@rczajka.pl>
Wed, 16 Jan 2019 23:42:29 +0000 (00:42 +0100)
25 files changed:
src/api/tests/res/responses/audiobooks.json [deleted file]
src/api/tests/res/responses/blog.json [deleted file]
src/api/tests/res/responses/books-child.json [new file with mode: 0644]
src/api/tests/res/responses/books-grandchild.json [new file with mode: 0644]
src/api/tests/res/responses/books-parent.json [new file with mode: 0644]
src/api/tests/res/responses/books.json [new file with mode: 0644]
src/api/tests/res/responses/collection.json [new file with mode: 0644]
src/api/tests/res/responses/collections.json
src/api/tests/res/responses/daisy.json [deleted file]
src/api/tests/res/responses/ebooks.json
src/api/tests/res/responses/filter-books.json
src/api/tests/res/responses/fragment.json [new file with mode: 0644]
src/api/tests/res/responses/fragments.json [new file with mode: 0644]
src/api/tests/res/responses/newest.json [deleted file]
src/api/tests/res/responses/preview.json [deleted file]
src/api/tests/res/responses/recommended.json [deleted file]
src/api/tests/res/responses/tags.json [new file with mode: 0644]
src/api/tests/tests.py
src/catalogue/__init__.py
src/catalogue/fixtures/test-books.yaml
src/catalogue/models/book.py
src/catalogue/models/collection.py
src/catalogue/test_utils.py
src/catalogue/utils.py
src/wolnelektury/settings/test.py

diff --git a/src/api/tests/res/responses/audiobooks.json b/src/api/tests/res/responses/audiobooks.json
deleted file mode 100644 (file)
index fe51488..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[]
diff --git a/src/api/tests/res/responses/blog.json b/src/api/tests/res/responses/blog.json
deleted file mode 100644 (file)
index fe51488..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[]
diff --git a/src/api/tests/res/responses/books-child.json b/src/api/tests/res/responses/books-child.json
new file mode 100644 (file)
index 0000000..4c5c134
--- /dev/null
@@ -0,0 +1,70 @@
+{
+    "epochs": [], 
+    "fragment_data": {
+        "html": "Fragment", 
+        "title": "Parent, Child"
+    }, 
+    "txt": "", 
+    "children": [
+        {
+            "kind": "", 
+            "full_sort_key": "$grandchild$3", 
+            "author": "", 
+            "url": "https://example.com/katalog/lektura/grandchild/", 
+            "cover_color": "#000000", 
+            "title": "Grandchild", 
+            "cover": "", 
+            "liked": null, 
+            "slug": "grandchild", 
+            "epoch": "", 
+            "href": "https://example.com/api/books/grandchild/", 
+            "genre": "Sonet", 
+            "simple_thumb": "", 
+            "has_audio": false, 
+            "cover_thumb": ""
+        }
+    ], 
+    "xml": "", 
+    "genres": [
+        {
+            "url": "https://example.com/katalog/gatunek/wiersz/", 
+            "href": "https://example.com/api/genres/wiersz/", 
+            "name": "Wiersz", 
+            "slug": "wiersz"
+        }
+    ], 
+    "title": "Child", 
+    "media": [], 
+    "html": "", 
+    "preview": false, 
+    "fb2": "", 
+    "kinds": [], 
+    "parent": {
+        "kind": "Liryka", 
+        "full_sort_key": "john doe$parent$1", 
+        "author": "John Doe", 
+        "url": "https://example.com/katalog/lektura/parent/", 
+        "cover_color": "#a6820a", 
+        "title": "Parent", 
+        "cover": "https://example.com/media/cover/parent.jpg", 
+        "liked": null, 
+        "slug": "parent", 
+        "epoch": "Barok", 
+        "href": "https://example.com/api/books/parent/", 
+        "genre": "Sonet", 
+        "simple_thumb": "https://example.com/media/cover_api_thumb/parent.jpg", 
+        "has_audio": true, 
+        "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193"
+    }, 
+    "cover_color": "#000000", 
+    "simple_cover": "", 
+    "authors": [], 
+    "audio_length": "", 
+    "epub": "", 
+    "cover_thumb": "", 
+    "mobi": "", 
+    "url": "https://example.com/katalog/lektura/child/", 
+    "cover": "", 
+    "pdf": "", 
+    "simple_thumb": ""
+}
diff --git a/src/api/tests/res/responses/books-grandchild.json b/src/api/tests/res/responses/books-grandchild.json
new file mode 100644 (file)
index 0000000..faf8c78
--- /dev/null
@@ -0,0 +1,52 @@
+{
+    "epochs": [], 
+    "fragment_data": {
+        "html": "Fragment", 
+        "title": "Parent, Child"
+    }, 
+    "txt": "https://example.com/media/txt/grandchild.txt", 
+    "children": [], 
+    "xml": "", 
+    "genres": [
+        {
+            "url": "https://example.com/katalog/gatunek/sonet/", 
+            "href": "https://example.com/api/genres/sonet/", 
+            "name": "Sonet", 
+            "slug": "sonet"
+        }
+    ], 
+    "title": "Grandchild", 
+    "media": [], 
+    "html": "https://example.com/media/html/grandchild.html", 
+    "preview": false, 
+    "fb2": "https://example.com/media/fb2/grandchild.fb2", 
+    "kinds": [], 
+    "parent": {
+        "kind": "", 
+        "full_sort_key": "$child$2", 
+        "author": "", 
+        "url": "https://example.com/katalog/lektura/child/", 
+        "cover_color": "#000000", 
+        "title": "Child", 
+        "cover": "", 
+        "liked": null, 
+        "slug": "child", 
+        "epoch": "", 
+        "href": "https://example.com/api/books/child/", 
+        "genre": "Wiersz", 
+        "simple_thumb": "", 
+        "has_audio": false, 
+        "cover_thumb": ""
+    }, 
+    "cover_color": "#000000", 
+    "simple_cover": "", 
+    "authors": [], 
+    "audio_length": "", 
+    "epub": "", 
+    "cover_thumb": "", 
+    "mobi": "", 
+    "url": "https://example.com/katalog/lektura/grandchild/", 
+    "cover": "", 
+    "pdf": "", 
+    "simple_thumb": ""
+}
diff --git a/src/api/tests/res/responses/books-parent.json b/src/api/tests/res/responses/books-parent.json
new file mode 100644 (file)
index 0000000..ade38cc
--- /dev/null
@@ -0,0 +1,87 @@
+{
+    "epochs": [
+        {
+            "url": "https://example.com/katalog/epoka/barok/", 
+            "href": "https://example.com/api/epochs/barok/", 
+            "name": "Barok", 
+            "slug": "barok"
+        }
+    ], 
+    "fragment_data": null, 
+    "txt": "", 
+    "children": [
+        {
+            "kind": "", 
+            "full_sort_key": "$child$2", 
+            "author": "", 
+            "url": "https://example.com/katalog/lektura/child/", 
+            "cover_color": "#000000", 
+            "title": "Child", 
+            "cover": "", 
+            "liked": null, 
+            "slug": "child", 
+            "epoch": "", 
+            "href": "https://example.com/api/books/child/", 
+            "genre": "Wiersz", 
+            "simple_thumb": "", 
+            "has_audio": false, 
+            "cover_thumb": ""
+        }
+    ], 
+    "xml": "https://example.com/media/xml/parent.xml", 
+    "genres": [
+        {
+            "url": "https://example.com/katalog/gatunek/sonet/", 
+            "href": "https://example.com/api/genres/sonet/", 
+            "name": "Sonet", 
+            "slug": "sonet"
+        }
+    ], 
+    "title": "Parent", 
+    "media": [
+        {
+            "url": "https://example.com/media/daisy/parent.daisy", 
+            "director": "", 
+            "type": "daisy", 
+            "name": "Parent DAISY", 
+            "artist": ""
+        }, 
+        {
+            "url": "https://example.com/media/mp3/parent.mp3", 
+            "director": "Director", 
+            "type": "mp3", 
+            "name": "Parent Audiobook", 
+            "artist": "Artist"
+        }
+    ], 
+    "html": "", 
+    "preview": false, 
+    "fb2": "", 
+    "kinds": [
+        {
+            "url": "https://example.com/katalog/rodzaj/liryka/", 
+            "href": "https://example.com/api/kinds/liryka/", 
+            "name": "Liryka", 
+            "slug": "liryka"
+        }
+    ], 
+    "parent": null, 
+    "cover_color": "#a6820a", 
+    "simple_cover": "https://example.com/media/simple_cover/parent.jpg", 
+    "authors": [
+        {
+            "url": "https://example.com/katalog/autor/john-doe/", 
+            "href": "https://example.com/api/authors/john-doe/", 
+            "name": "John Doe", 
+            "slug": "john-doe"
+        }
+    ], 
+    "audio_length": "1:00", 
+    "epub": "https://example.com/media/epub/parent.epub", 
+    "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193", 
+    "mobi": "https://example.com/media/mobi/parent.mobi", 
+    "url": "https://example.com/katalog/lektura/parent/", 
+    "cover": "https://example.com/media/cover/parent.jpg", 
+    "pdf": "https://example.com/media/pdf/parent.pdf", 
+    "simple_thumb": "https://example.com/media/cover_api_thumb/parent.jpg"
+}
diff --git a/src/api/tests/res/responses/books.json b/src/api/tests/res/responses/books.json
new file mode 100644 (file)
index 0000000..f83e74e
--- /dev/null
@@ -0,0 +1,50 @@
+[
+    {
+        "kind": "", 
+        "full_sort_key": "$child$2", 
+        "cover_color": "#000000", 
+        "author": "", 
+        "url": "https://example.com/katalog/lektura/child/", 
+        "has_audio": false, 
+        "title": "Child", 
+        "cover": "", 
+        "epoch": "", 
+        "href": "https://example.com/api/books/child/", 
+        "genre": "Wiersz", 
+        "simple_thumb": "", 
+        "slug": "child", 
+        "cover_thumb": ""
+    }, 
+    {
+        "kind": "", 
+        "full_sort_key": "$grandchild$3", 
+        "cover_color": "#000000", 
+        "author": "", 
+        "url": "https://example.com/katalog/lektura/grandchild/", 
+        "has_audio": false, 
+        "title": "Grandchild", 
+        "cover": "", 
+        "epoch": "", 
+        "href": "https://example.com/api/books/grandchild/", 
+        "genre": "Sonet", 
+        "simple_thumb": "", 
+        "slug": "grandchild", 
+        "cover_thumb": ""
+    }, 
+    {
+        "kind": "Liryka", 
+        "full_sort_key": "john doe$parent$1", 
+        "cover_color": "#a6820a", 
+        "author": "John Doe", 
+        "url": "https://example.com/katalog/lektura/parent/", 
+        "has_audio": true, 
+        "title": "Parent", 
+        "cover": "cover/parent.jpg", 
+        "epoch": "Barok", 
+        "href": "https://example.com/api/books/parent/", 
+        "genre": "Sonet", 
+        "simple_thumb": "https://example.com/media/cover_api_thumb/parent.jpg", 
+        "slug": "parent", 
+        "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193"
+    }
+]
diff --git a/src/api/tests/res/responses/collection.json b/src/api/tests/res/responses/collection.json
new file mode 100644 (file)
index 0000000..866abed
--- /dev/null
@@ -0,0 +1,24 @@
+{
+    "url": "https://example.com/katalog/lektury/a-collection/", 
+    "books": [
+        {
+            "kind": "Liryka", 
+            "full_sort_key": "john doe$parent$1", 
+            "author": "John Doe", 
+            "url": "https://example.com/katalog/lektura/parent/", 
+            "cover_color": "#a6820a", 
+            "title": "Parent", 
+            "cover": "https://example.com/media/cover/parent.jpg", 
+            "liked": null, 
+            "slug": "parent", 
+            "epoch": "Barok", 
+            "href": "https://example.com/api/books/parent/", 
+            "genre": "Sonet", 
+            "simple_thumb": "https://example.com/media/cover_api_thumb/parent.jpg", 
+            "has_audio": true, 
+            "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193"
+        }
+    ], 
+    "description": "Description", 
+    "title": "A Collection"
+}
index fe51488..a0852cd 100644 (file)
@@ -1 +1,7 @@
-[]
+[
+    {
+        "url": "https://example.com/katalog/lektury/a-collection/", 
+        "href": "https://example.com/dapi/collections/a-collection/", 
+        "title": "A Collection"
+    }
+]
diff --git a/src/api/tests/res/responses/daisy.json b/src/api/tests/res/responses/daisy.json
deleted file mode 100644 (file)
index fe51488..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[]
index 70084ef..171c153 100644 (file)
@@ -2,6 +2,7 @@
     {
         "fb2": "", 
         "mobi": "", 
     {
         "fb2": "", 
         "mobi": "", 
+        "title": "Child",
         "author": "", 
         "cover": "", 
         "href": "https://example.com/api/books/child/", 
         "author": "", 
         "cover": "", 
         "href": "https://example.com/api/books/child/", 
@@ -13,6 +14,7 @@
     {
         "fb2": "https://example.com/media/fb2/grandchild.fb2", 
         "mobi": "", 
     {
         "fb2": "https://example.com/media/fb2/grandchild.fb2", 
         "mobi": "", 
+        "title": "Grandchild",
         "author": "", 
         "cover": "", 
         "href": "https://example.com/api/books/grandchild/", 
         "author": "", 
         "cover": "", 
         "href": "https://example.com/api/books/grandchild/", 
@@ -24,6 +26,7 @@
     {
         "fb2": "", 
         "mobi": "https://example.com/media/mobi/parent.mobi", 
     {
         "fb2": "", 
         "mobi": "https://example.com/media/mobi/parent.mobi", 
+        "title": "Parent",
         "author": "John Doe", 
         "cover": "cover/parent.jpg", 
         "href": "https://example.com/api/books/parent/", 
         "author": "John Doe", 
         "cover": "cover/parent.jpg", 
         "href": "https://example.com/api/books/parent/", 
index db41287..b56ffb1 100644 (file)
@@ -6,11 +6,12 @@
         "author": "", 
         "url": "https://example.com/katalog/lektura/child/", 
         "has_audio": false, 
         "author": "", 
         "url": "https://example.com/katalog/lektura/child/", 
         "has_audio": false, 
+        "title": "Child", 
         "cover": "", 
         "epoch": "", 
         "href": "https://example.com/api/books/child/", 
         "key": "book$child", 
         "cover": "", 
         "epoch": "", 
         "href": "https://example.com/api/books/child/", 
         "key": "book$child", 
-        "genre": "", 
+        "genre": "Wiersz", 
         "simple_thumb": "", 
         "slug": "child", 
         "cover_thumb": ""
         "simple_thumb": "", 
         "slug": "child", 
         "cover_thumb": ""
         "author": "", 
         "url": "https://example.com/katalog/lektura/grandchild/", 
         "has_audio": false, 
         "author": "", 
         "url": "https://example.com/katalog/lektura/grandchild/", 
         "has_audio": false, 
+        "title": "Grandchild", 
         "cover": "", 
         "epoch": "", 
         "href": "https://example.com/api/books/grandchild/", 
         "key": "book$grandchild", 
         "cover": "", 
         "epoch": "", 
         "href": "https://example.com/api/books/grandchild/", 
         "key": "book$grandchild", 
-        "genre": "", 
+        "genre": "Sonet", 
         "simple_thumb": "", 
         "slug": "grandchild", 
         "cover_thumb": ""
         "simple_thumb": "", 
         "slug": "grandchild", 
         "cover_thumb": ""
         "cover_color": "#a6820a", 
         "author": "John Doe", 
         "url": "https://example.com/katalog/lektura/parent/", 
         "cover_color": "#a6820a", 
         "author": "John Doe", 
         "url": "https://example.com/katalog/lektura/parent/", 
-        "has_audio": false, 
+        "has_audio": true, 
+        "title": "Parent", 
         "cover": "cover/parent.jpg", 
         "epoch": "Barok", 
         "href": "https://example.com/api/books/parent/", 
         "key": "book$parent", 
         "genre": "Sonet", 
         "cover": "cover/parent.jpg", 
         "epoch": "Barok", 
         "href": "https://example.com/api/books/parent/", 
         "key": "book$parent", 
         "genre": "Sonet", 
-        "simple_thumb": "https://example.com/media/cover/parent_cover_api_thumb.jpg", 
+        "simple_thumb": "https://example.com/media/cover_api_thumb/parent.jpg", 
         "slug": "parent", 
         "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193"
     }
         "slug": "parent", 
         "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193"
     }
diff --git a/src/api/tests/res/responses/fragment.json b/src/api/tests/res/responses/fragment.json
new file mode 100644 (file)
index 0000000..40db3f4
--- /dev/null
@@ -0,0 +1,30 @@
+{
+    "url": "https://example.com/katalog/lektura/child.html#man-anchor", 
+    "text": "A fragment", 
+    "book": {
+        "kind": "", 
+        "full_sort_key": "$child$2", 
+        "author": "", 
+        "url": "https://example.com/katalog/lektura/child/", 
+        "cover_color": "#000000", 
+        "title": "Child", 
+        "cover": "", 
+        "liked": null, 
+        "slug": "child", 
+        "epoch": "", 
+        "href": "https://example.com/api/books/child/", 
+        "genre": "Wiersz", 
+        "simple_thumb": "", 
+        "has_audio": false, 
+        "cover_thumb": ""
+    }, 
+    "anchor": "an-anchor", 
+    "themes": [
+        {
+            "url": "https://example.com/katalog/motyw/koniec/", 
+            "href": "https://example.com/api/themes/koniec/", 
+            "name": "Koniec", 
+            "slug": "koniec"
+        }
+    ]
+}
diff --git a/src/api/tests/res/responses/fragments.json b/src/api/tests/res/responses/fragments.json
new file mode 100644 (file)
index 0000000..1733ba1
--- /dev/null
@@ -0,0 +1,24 @@
+[
+    {
+        "url": "https://example.com/katalog/lektura/child.html#man-anchor", 
+        "book": {
+            "kind": "", 
+            "full_sort_key": "$child$2", 
+            "author": "", 
+            "url": "https://example.com/katalog/lektura/child/", 
+            "cover_color": "#000000", 
+            "title": "Child", 
+            "cover": "", 
+            "liked": null, 
+            "slug": "child", 
+            "epoch": "", 
+            "href": "https://example.com/api/books/child/", 
+            "genre": "Wiersz", 
+            "simple_thumb": "", 
+            "has_audio": false, 
+            "cover_thumb": ""
+        }, 
+        "anchor": "an-anchor", 
+        "href": "https://example.com/api/books/child/fragments/an-anchor/"
+    }
+]
diff --git a/src/api/tests/res/responses/newest.json b/src/api/tests/res/responses/newest.json
deleted file mode 100644 (file)
index 8abde74..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-[
-    {
-        "kind": "Liryka", 
-        "full_sort_key": "john doe$parent$1", 
-        "cover_color": "#a6820a", 
-        "author": "John Doe", 
-        "url": "https://example.com/katalog/lektura/parent/", 
-        "has_audio": false, 
-        "cover": "cover/parent.jpg", 
-        "epoch": "Barok", 
-        "href": "https://example.com/api/books/parent/", 
-        "genre": "Sonet", 
-        "simple_thumb": "https://example.com/media/cover/parent_cover_api_thumb.jpg", 
-        "slug": "parent", 
-        "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193"
-    }
-]
diff --git a/src/api/tests/res/responses/preview.json b/src/api/tests/res/responses/preview.json
deleted file mode 100644 (file)
index fe51488..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[]
diff --git a/src/api/tests/res/responses/recommended.json b/src/api/tests/res/responses/recommended.json
deleted file mode 100644 (file)
index fe51488..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[]
diff --git a/src/api/tests/res/responses/tags.json b/src/api/tests/res/responses/tags.json
new file mode 100644 (file)
index 0000000..4729beb
--- /dev/null
@@ -0,0 +1,14 @@
+[
+    {
+        "url": "https://example.com/katalog/gatunek/sonet/", 
+        "href": "https://example.com/api/genres/sonet/", 
+        "name": "Sonet", 
+        "slug": "sonet"
+    }, 
+    {
+        "url": "https://example.com/katalog/gatunek/wiersz/", 
+        "href": "https://example.com/api/genres/wiersz/", 
+        "name": "Wiersz", 
+        "slug": "wiersz"
+    }
+]
index 32d394e..5486b5f 100644 (file)
@@ -35,6 +35,10 @@ class ApiTest(TestCase):
             good_data = json.load(f)
         self.assertEqual(data, good_data, json.dumps(data, indent=4))
 
             good_data = json.load(f)
         self.assertEqual(data, good_data, json.dumps(data, indent=4))
 
+    def assert_slugs(self, url, slugs):
+        have_slugs = [x['slug'] for x in self.load_json(url)]
+        self.assertEqual(have_slugs, slugs, have_slugs)
+
 
 class BookTests(ApiTest):
 
 
 class BookTests(ApiTest):
 
@@ -101,19 +105,87 @@ class PictureTests(ApiTest):
         Picture.objects.get(slug=slug)
 
 
         Picture.objects.get(slug=slug)
 
 
-class URLTests(ApiTest):
+class BooksTests(ApiTest):
     fixtures = ['test-books.yaml']
 
     fixtures = ['test-books.yaml']
 
-    def test_get(self):
-        # book lists
-        self.assert_json_response('/api/audiobooks/', 'audiobooks.json')
-        self.assert_json_response('/api/daisy/', 'daisy.json')
+    def test_books(self):
+       self.assert_json_response('/api/books/', 'books.json')
+       self.assert_json_response('/api/books/?new_api=true', 'books.json')
+
+        self.assert_slugs('/api/audiobooks/', ['parent'])
+        self.assert_slugs('/api/daisy/', ['parent'])
+        self.assert_slugs('/api/newest/', ['parent'])
+        self.assert_slugs('/api/parent_books/', ['parent'])
+        self.assert_slugs('/api/recommended/', ['parent'])
+
+        # Book paging.
+        self.assert_slugs('/api/books/after/grandchild/count/1/', ['parent'])
+        self.assert_slugs('/api/books/?new_api=true&after=$grandchild$3&count=1', ['parent'])
+
+        # By tag.
+       self.assert_slugs('/api/authors/john-doe/books/', ['parent'])
+       self.assert_slugs('/api/genres/sonet/books/?authors=john-doe', ['parent'])
+        # It is probably a mistake that this doesn't filter:
+       self.assert_slugs('/api/books/?authors=john-doe', ['child', 'grandchild', 'parent'])
+
+       # Parent books by tag.
+        # Notice this contains a grandchild, if a child doesn't have the tag.
+        # This probably isn't really intended behavior and should be redefined.
+       self.assert_slugs('/api/genres/sonet/parent_books/', ['grandchild', 'parent'])
+
+    def test_ebooks(self):
         self.assert_json_response('/api/ebooks/', 'ebooks.json')
         self.assert_json_response('/api/ebooks/', 'ebooks.json')
+
+    def test_filter_books(self):
         self.assert_json_response('/api/filter-books/', 'filter-books.json')
         self.assert_json_response('/api/filter-books/', 'filter-books.json')
-        self.assert_json_response('/api/newest/', 'newest.json')
+        self.assert_slugs(
+            '/api/filter-books/?lektura=false&preview=false',
+            ['child', 'grandchild', 'parent'])
+        self.assert_slugs(
+            '/api/filter-books/?lektura=true',
+            [])
 
 
-        self.assert_json_response('/api/blog/', 'blog.json')
-        self.assert_json_response('/api/preview/', 'preview.json')
-        self.assert_json_response('/api/recommended/', 'recommended.json')
+        Book.objects.filter(slug='child').update(preview=True)
+        self.assert_slugs('/api/filter-books/?preview=true', ['child'])
+        self.assert_slugs('/api/filter-books/?preview=false', ['grandchild', 'parent'])
+
+        self.assert_slugs('/api/filter-books/?audiobook=true', ['parent'])
+        self.assert_slugs('/api/filter-books/?audiobook=false', ['child', 'grandchild'])
 
 
+        self.assert_slugs('/api/filter-books/?genres=wiersz', ['child'])
+
+        self.assert_slugs('/api/filter-books/?search=parent', ['parent'])
+
+    def test_collections(self):
         self.assert_json_response('/api/collections/', 'collections.json')
         self.assert_json_response('/api/collections/', 'collections.json')
+        self.assert_json_response('/api/collections/a-collection/', 'collection.json')
+
+    def test_book(self):
+       self.assert_json_response('/api/books/parent/', 'books-parent.json')
+       self.assert_json_response('/api/books/child/', 'books-child.json')
+       self.assert_json_response('/api/books/grandchild/', 'books-grandchild.json')
+
+    def test_tags(self):
+       # List of tags by category.
+       self.assert_json_response('/api/genres/', 'tags.json')
+
+    def test_fragments(self):
+        # This is not supported, though it probably should be.
+       #self.assert_json_response('/api/books/child/fragments/', 'fragments.json')
+
+       self.assert_json_response('/api/genres/wiersz/fragments/', 'fragments.json')
+       self.assert_json_response('/api/genres/wiersz/fragments/', 'fragments.json')
+
+        self.assert_json_response('/api/books/child/fragments/an-anchor/', 'fragment.json')
+
+
+class BlogTests(ApiTest):
+    def test_get(self):
+        self.assertEqual(self.load_json('/api/blog/'), [])
+
+
+class PreviewTests(ApiTest):
+    def unauth(self):
+        self.assert_json_response('/api/preview/', 'preview.json')
+
+
index 16c1326..612517b 100644 (file)
@@ -4,6 +4,7 @@
 #
 import logging
 from django.conf import settings as settings
 #
 import logging
 from django.conf import settings as settings
+from django.utils.module_loading import import_string
 from catalogue.utils import AppSettings
 
 
 from catalogue.utils import AppSettings
 
 
@@ -25,6 +26,7 @@ class Settings(AppSettings):
     REDAKCJA_URL = "http://redakcja.wolnelektury.pl"
     GOOD_LICENSES = {r'CC BY \d\.\d', r'CC BY-SA \d\.\d'}
     RELATED_RANDOM_PICTURE_CHANCE = .5
     REDAKCJA_URL = "http://redakcja.wolnelektury.pl"
     GOOD_LICENSES = {r'CC BY \d\.\d', r'CC BY-SA \d\.\d'}
     RELATED_RANDOM_PICTURE_CHANCE = .5
+    GET_MP3_LENGTH = 'catalogue.utils.get_mp3_length'
 
     def _more_DONT_BUILD(self, value):
         for format_ in ['cover', 'pdf', 'epub', 'mobi', 'fb2', 'txt']:
 
     def _more_DONT_BUILD(self, value):
         for format_ in ['cover', 'pdf', 'epub', 'mobi', 'fb2', 'txt']:
@@ -45,5 +47,8 @@ class Settings(AppSettings):
                 value[format_] = getattr(settings, attname)
         return value
 
                 value[format_] = getattr(settings, attname)
         return value
 
+    def _more_GET_MP3_LENGTH(self, value):
+        return import_string(value)
+
 
 app_settings = Settings('CATALOGUE')
 
 app_settings = Settings('CATALOGUE')
index 43ca447..ad76368 100644 (file)
@@ -2,20 +2,25 @@
   pk: 1
   fields:
     slug: parent
   pk: 1
   fields:
     slug: parent
+    title: Parent
     sort_key: parent
     sort_key_author: john doe
     sort_key: parent
     sort_key_author: john doe
+    xml_file: xml/parent.xml
     epub_file: epub/parent.epub
     mobi_file: mobi/parent.mobi
     pdf_file: pdf/parent.pdf
     cover: cover/parent.jpg
     epub_file: epub/parent.epub
     mobi_file: mobi/parent.mobi
     pdf_file: pdf/parent.pdf
     cover: cover/parent.jpg
-    cover_api_thumb: cover/parent_cover_api_thumb.jpg
+    cover_api_thumb: cover_api_thumb/parent.jpg
+    simple_cover: simple_cover/parent.jpg
+    recommended: true
     created_at: "1970-01-03 0:0Z"
     changed_at: "1970-01-03 0:0Z"
     created_at: "1970-01-03 0:0Z"
     changed_at: "1970-01-03 0:0Z"
-    extra_info: "{\"epoch\": \"Barok\"}"
+    extra_info: '{"epoch": "Barok"}'
 - model: catalogue.book
   pk: 2
   fields:
     slug: child
 - model: catalogue.book
   pk: 2
   fields:
     slug: child
+    title: Child
     sort_key: child
     parent: 1
     created_at: "1970-01-02 0:0Z"
     sort_key: child
     parent: 1
     created_at: "1970-01-02 0:0Z"
@@ -24,6 +29,7 @@
   pk: 3
   fields:
     slug: grandchild
   pk: 3
   fields:
     slug: grandchild
+    title: Grandchild
     sort_key: grandchild
     parent: 2
     txt_file: txt/grandchild.txt
     sort_key: grandchild
     parent: 2
     txt_file: txt/grandchild.txt
     name: Sonet
     created_at: "1970-01-03 0:0Z"
     changed_at: "1970-01-03 0:0Z"
     name: Sonet
     created_at: "1970-01-03 0:0Z"
     changed_at: "1970-01-03 0:0Z"
+- model: catalogue.tag
+  pk: 5
+  fields:
+    slug: wiersz
+    sort_key: wiersz
+    category: genre
+    name: Wiersz
+    created_at: "1970-01-03 0:0Z"
+    changed_at: "1970-01-03 0:0Z"
+
 
 - model: catalogue.tagrelation
 
 - model: catalogue.tagrelation
-  pk: 1
   fields:
     tag: 1
     content_type: ['catalogue', 'book']
     object_id: 1
 - model: catalogue.tagrelation
   fields:
     tag: 1
     content_type: ['catalogue', 'book']
     object_id: 1
 - model: catalogue.tagrelation
-  pk: 2
   fields:
     tag: 2
     content_type: ['catalogue', 'book']
     object_id: 1
 - model: catalogue.tagrelation
   fields:
     tag: 2
     content_type: ['catalogue', 'book']
     object_id: 1
 - model: catalogue.tagrelation
-  pk: 3
   fields:
     tag: 3
     content_type: ['catalogue', 'book']
     object_id: 1
 - model: catalogue.tagrelation
   fields:
     tag: 3
     content_type: ['catalogue', 'book']
     object_id: 1
 - model: catalogue.tagrelation
-  pk: 4
   fields:
     tag: 4
     content_type: ['catalogue', 'book']
     object_id: 1
   fields:
     tag: 4
     content_type: ['catalogue', 'book']
     object_id: 1
+- model: catalogue.tagrelation
+  fields:
+    tag: 4
+    content_type: ['catalogue', 'book']
+    object_id: 3
+- model: catalogue.tagrelation
+  fields:
+    tag: 5
+    content_type: ['catalogue', 'book']
+    object_id: 2
+
+- model: catalogue.bookmedia
+  fields:
+    book: 1
+    type: mp3
+    name: Parent Audiobook
+    file: mp3/parent.mp3
+    uploaded_at: "1970-01-03 0:0Z"
+    extra_info: {"director_name": "Director", "artist_name": "Artist"}
+- model: catalogue.bookmedia
+  fields:
+    book: 1
+    type: daisy
+    name: Parent DAISY
+    file: daisy/parent.daisy
+    uploaded_at: "1970-01-03 0:0Z"
+
+- model: catalogue.fragment
+  id: 1
+  fields:
+    short_text: "Fragment"
+    text: "A fragment"
+    anchor: "an-anchor"
+    book: 2
+- model: catalogue.tagrelation
+  fields:
+    tag: 5
+    content_type: ['catalogue', 'fragment']
+    object_id: 1
+- model: catalogue.tag
+  pk: 101
+  fields:
+    slug: koniec
+    sort_key: koniec
+    category: theme
+    name: Koniec
+    created_at: "1970-01-03 0:0Z"
+    changed_at: "1970-01-03 0:0Z"
+- model: catalogue.tagrelation
+  fields:
+    tag: 101
+    content_type: ['catalogue', 'fragment']
+    object_id: 1
+
+- model: catalogue.collection
+  fields:
+    title: A Collection
+    slug: a-collection
+    description: Description
+    book_slugs: parent
 
 
index 8c53d9c..6e6c50f 100644 (file)
@@ -229,11 +229,9 @@ class Book(models.Model):
             return '%d:%02d:%02d' % (hours, minutes, seconds)
 
     def get_audio_length(self):
             return '%d:%02d:%02d' % (hours, minutes, seconds)
 
     def get_audio_length(self):
-        from mutagen.mp3 import MP3
         total = 0
         for media in self.get_mp3() or ():
         total = 0
         for media in self.get_mp3() or ():
-            audio = MP3(media.file.path)
-            total += audio.info.length
+            total += app_settings.GET_MP3_LENGTH(media.file.path)
         return int(total)
 
     def has_media(self, type_):
         return int(total)
 
     def has_media(self, type_):
index 15a4e2a..e952043 100644 (file)
@@ -14,10 +14,7 @@ class Collection(models.Model):
     title = models.CharField(_('title'), max_length=120, db_index=True)
     slug = models.SlugField(_('slug'), max_length=120, primary_key=True)
     description = models.TextField(_('description'), null=True, blank=True)
     title = models.CharField(_('title'), max_length=120, db_index=True)
     slug = models.SlugField(_('slug'), max_length=120, primary_key=True)
     description = models.TextField(_('description'), null=True, blank=True)
-
-    models.SlugField(_('slug'), max_length=120, unique=True, db_index=True)
     book_slugs = models.TextField(_('book slugs'))
     book_slugs = models.TextField(_('book slugs'))
-
     kind = models.CharField(_('kind'), max_length=10, blank=False, default='book', db_index=True,
                             choices=(('book', _('book')), ('picture', _('picture'))))
 
     kind = models.CharField(_('kind'), max_length=10, blank=False, default='book', db_index=True,
                             choices=(('book', _('book')), ('picture', _('picture'))))
 
index 18c5674..8c76b89 100644 (file)
@@ -91,3 +91,7 @@ def get_fixture(path, app=None):
         mod_path = extract_stack(limit=2)[0][0]
         f_path = join(dirname(abspath(mod_path)), 'files', path)
     return f_path
         mod_path = extract_stack(limit=2)[0][0]
         f_path = join(dirname(abspath(mod_path)), 'files', path)
     return f_path
+
+
+def get_mp3_length(path):
+    return 60
index 1c18841..380ec8e 100644 (file)
@@ -355,3 +355,7 @@ def gallery_path(slug):
 def gallery_url(slug):
     return '%s%s%s/' % (settings.MEDIA_URL, settings.IMAGE_DIR, slug)
 
 def gallery_url(slug):
     return '%s%s%s/' % (settings.MEDIA_URL, settings.IMAGE_DIR, slug)
 
+
+def get_mp3_length(path):
+    from mutagen.mp3 import MP3
+    return int(MP3(path).info.length)
index 0de27c7..0ad0e69 100644 (file)
@@ -1,3 +1,4 @@
 from wolnelektury.settings import *
 
 THUMBNAIL_BACKEND = 'wolnelektury.test_utils.DummyThumbnailBackend'
 from wolnelektury.settings import *
 
 THUMBNAIL_BACKEND = 'wolnelektury.test_utils.DummyThumbnailBackend'
+CATALOGUE_GET_MP3_LENGTH = 'catalogue.test_utils.get_mp3_length'