Some tests for various API endpoints.
authorRadek Czajka <rczajka@rczajka.pl>
Tue, 15 Jan 2019 23:34:07 +0000 (00:34 +0100)
committerRadek Czajka <rczajka@rczajka.pl>
Tue, 15 Jan 2019 23:39:10 +0000 (00:39 +0100)
17 files changed:
src/api/tests.py [deleted file]
src/api/tests/__init__.py [new file with mode: 0644]
src/api/tests/res/responses/audiobooks.json [new file with mode: 0644]
src/api/tests/res/responses/blog.json [new file with mode: 0644]
src/api/tests/res/responses/collections.json [new file with mode: 0644]
src/api/tests/res/responses/daisy.json [new file with mode: 0644]
src/api/tests/res/responses/ebooks.json [new file with mode: 0644]
src/api/tests/res/responses/filter-books.json [new file with mode: 0644]
src/api/tests/res/responses/newest.json [new file with mode: 0644]
src/api/tests/res/responses/preview.json [new file with mode: 0644]
src/api/tests/res/responses/recommended.json [new file with mode: 0644]
src/api/tests/tests.py [new file with mode: 0644]
src/catalogue/fixtures/collection-boy.json [deleted file]
src/catalogue/fixtures/test-books.yaml [new file with mode: 0644]
src/manage.py
src/wolnelektury/settings/test.py [new file with mode: 0644]
src/wolnelektury/test_utils.py [new file with mode: 0644]

diff --git a/src/api/tests.py b/src/api/tests.py
deleted file mode 100644 (file)
index e02120d..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-# -*- coding: utf-8 -*-
-# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
-#
-from os import path
-
-from django.core.files.uploadedfile import SimpleUploadedFile
-from django.test import TestCase
-from django.test.utils import override_settings
-import json
-
-from catalogue.models import Book, Tag
-from picture.forms import PictureImportForm
-from picture.models import Picture
-import picture.tests
-
-
-@override_settings(
-    NO_SEARCH_INDEX=True,
-    CACHES={'default': {
-        'BACKEND': 'django.core.cache.backends.dummy.DummyCache'}},
-    SSIFY_CACHE_ALIASES=['default'],
-    SSIFY_RENDER=True,
-)
-class ApiTest(TestCase):
-    def load_json(self, url):
-        content = self.client.get(url).content
-        try:
-            data = json.loads(content)
-        except ValueError:
-            self.fail('No JSON could be decoded: %s' % content)
-        return data
-
-
-class BookTests(ApiTest):
-
-    def setUp(self):
-        self.tag = Tag.objects.create(category='author', slug='joe')
-        self.book = Book.objects.create(title='A Book', slug='a-book')
-        self.book_tagged = Book.objects.create(title='Tagged Book', slug='tagged-book')
-        self.book_tagged.tags = [self.tag]
-        self.book_tagged.save()
-
-    def test_book_list(self):
-        books = self.load_json('/api/books/')
-        self.assertEqual(len(books), 2,
-                         'Wrong book list.')
-
-    def test_tagged_books(self):
-        books = self.load_json('/api/authors/joe/books/')
-
-        self.assertEqual([b['title'] for b in books], [self.book_tagged.title],
-                         'Wrong tagged book list.')
-
-    def test_detail(self):
-        book = self.load_json('/api/books/a-book/')
-        self.assertEqual(book['title'], self.book.title,
-                         'Wrong book details.')
-
-
-class TagTests(ApiTest):
-
-    def setUp(self):
-        self.tag = Tag.objects.create(category='author', slug='joe', name='Joe')
-        self.book = Book.objects.create(title='A Book', slug='a-book')
-        self.book.tags = [self.tag]
-        self.book.save()
-
-    def test_tag_list(self):
-        tags = self.load_json('/api/authors/')
-        self.assertEqual(len(tags), 1,
-                         'Wrong tag list.')
-
-    def test_tag_detail(self):
-        tag = self.load_json('/api/authors/joe/')
-        self.assertEqual(tag['name'], self.tag.name,
-                         'Wrong tag details.')
-
-
-class PictureTests(ApiTest):
-    def test_publish(self):
-        slug = "kandinsky-composition-viii"
-        xml = SimpleUploadedFile(
-            'composition8.xml', open(path.join(picture.tests.__path__[0], "files", slug + ".xml")).read())
-        img = SimpleUploadedFile(
-            'kompozycja-8.png', open(path.join(picture.tests.__path__[0], "files", slug + ".png")).read())
-
-        import_form = PictureImportForm({}, {
-            'picture_xml_file': xml,
-            'picture_image_file': img
-            })
-
-        assert import_form.is_valid()
-        if import_form.is_valid():
-            import_form.save()
-
-        Picture.objects.get(slug=slug)
diff --git a/src/api/tests/__init__.py b/src/api/tests/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/api/tests/res/responses/audiobooks.json b/src/api/tests/res/responses/audiobooks.json
new file mode 100644 (file)
index 0000000..fe51488
--- /dev/null
@@ -0,0 +1 @@
+[]
diff --git a/src/api/tests/res/responses/blog.json b/src/api/tests/res/responses/blog.json
new file mode 100644 (file)
index 0000000..fe51488
--- /dev/null
@@ -0,0 +1 @@
+[]
diff --git a/src/api/tests/res/responses/collections.json b/src/api/tests/res/responses/collections.json
new file mode 100644 (file)
index 0000000..fe51488
--- /dev/null
@@ -0,0 +1 @@
+[]
diff --git a/src/api/tests/res/responses/daisy.json b/src/api/tests/res/responses/daisy.json
new file mode 100644 (file)
index 0000000..fe51488
--- /dev/null
@@ -0,0 +1 @@
+[]
diff --git a/src/api/tests/res/responses/ebooks.json b/src/api/tests/res/responses/ebooks.json
new file mode 100644 (file)
index 0000000..70084ef
--- /dev/null
@@ -0,0 +1,35 @@
+[
+    {
+        "fb2": "", 
+        "mobi": "", 
+        "author": "", 
+        "cover": "", 
+        "href": "https://example.com/api/books/child/", 
+        "pdf": "", 
+        "txt": "", 
+        "slug": "child", 
+        "epub": ""
+    }, 
+    {
+        "fb2": "https://example.com/media/fb2/grandchild.fb2", 
+        "mobi": "", 
+        "author": "", 
+        "cover": "", 
+        "href": "https://example.com/api/books/grandchild/", 
+        "pdf": "", 
+        "txt": "https://example.com/media/txt/grandchild.txt", 
+        "slug": "grandchild", 
+        "epub": ""
+    }, 
+    {
+        "fb2": "", 
+        "mobi": "https://example.com/media/mobi/parent.mobi", 
+        "author": "John Doe", 
+        "cover": "cover/parent.jpg", 
+        "href": "https://example.com/api/books/parent/", 
+        "pdf": "https://example.com/media/pdf/parent.pdf", 
+        "txt": "", 
+        "slug": "parent", 
+        "epub": "https://example.com/media/epub/parent.epub"
+    }
+]
diff --git a/src/api/tests/res/responses/filter-books.json b/src/api/tests/res/responses/filter-books.json
new file mode 100644 (file)
index 0000000..db41287
--- /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, 
+        "cover": "", 
+        "epoch": "", 
+        "href": "https://example.com/api/books/child/", 
+        "key": "book$child", 
+        "genre": "", 
+        "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, 
+        "cover": "", 
+        "epoch": "", 
+        "href": "https://example.com/api/books/grandchild/", 
+        "key": "book$grandchild", 
+        "genre": "", 
+        "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": false, 
+        "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", 
+        "slug": "parent", 
+        "cover_thumb": "https://example.com/media/cover/parent.jpg-139x193"
+    }
+]
diff --git a/src/api/tests/res/responses/newest.json b/src/api/tests/res/responses/newest.json
new file mode 100644 (file)
index 0000000..8abde74
--- /dev/null
@@ -0,0 +1,17 @@
+[
+    {
+        "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
new file mode 100644 (file)
index 0000000..fe51488
--- /dev/null
@@ -0,0 +1 @@
+[]
diff --git a/src/api/tests/res/responses/recommended.json b/src/api/tests/res/responses/recommended.json
new file mode 100644 (file)
index 0000000..fe51488
--- /dev/null
@@ -0,0 +1 @@
+[]
diff --git a/src/api/tests/tests.py b/src/api/tests/tests.py
new file mode 100644 (file)
index 0000000..32d394e
--- /dev/null
@@ -0,0 +1,119 @@
+# -*- coding: utf-8 -*-
+# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
+from os import path
+import json
+
+from django.core.files.uploadedfile import SimpleUploadedFile
+from django.test import TestCase
+from django.test.utils import override_settings
+
+from catalogue.models import Book, Tag
+from picture.forms import PictureImportForm
+from picture.models import Picture
+import picture.tests
+
+
+@override_settings(
+    NO_SEARCH_INDEX=True,
+    CACHES={'default': {
+        'BACKEND': 'django.core.cache.backends.dummy.DummyCache'}},
+)
+class ApiTest(TestCase):
+    def load_json(self, url):
+        content = self.client.get(url).content
+        try:
+            data = json.loads(content)
+        except ValueError:
+            self.fail('No JSON could be decoded: %s' % content)
+        return data
+
+    def assert_json_response(self, url, name):
+        data = self.load_json(url)
+        with open(path.join(path.dirname(__file__), 'res', 'responses', name)) as f:
+            good_data = json.load(f)
+        self.assertEqual(data, good_data, json.dumps(data, indent=4))
+
+
+class BookTests(ApiTest):
+
+    def setUp(self):
+        self.tag = Tag.objects.create(category='author', slug='joe')
+        self.book = Book.objects.create(title='A Book', slug='a-book')
+        self.book_tagged = Book.objects.create(title='Tagged Book', slug='tagged-book')
+        self.book_tagged.tags = [self.tag]
+        self.book_tagged.save()
+
+    def test_book_list(self):
+        books = self.load_json('/api/books/')
+        self.assertEqual(len(books), 2,
+                         'Wrong book list.')
+
+    def test_tagged_books(self):
+        books = self.load_json('/api/authors/joe/books/')
+
+        self.assertEqual([b['title'] for b in books], [self.book_tagged.title],
+                         'Wrong tagged book list.')
+
+    def test_detail(self):
+        book = self.load_json('/api/books/a-book/')
+        self.assertEqual(book['title'], self.book.title,
+                         'Wrong book details.')
+
+
+class TagTests(ApiTest):
+
+    def setUp(self):
+        self.tag = Tag.objects.create(category='author', slug='joe', name='Joe')
+        self.book = Book.objects.create(title='A Book', slug='a-book')
+        self.book.tags = [self.tag]
+        self.book.save()
+
+    def test_tag_list(self):
+        tags = self.load_json('/api/authors/')
+        self.assertEqual(len(tags), 1,
+                         'Wrong tag list.')
+
+    def test_tag_detail(self):
+        tag = self.load_json('/api/authors/joe/')
+        self.assertEqual(tag['name'], self.tag.name,
+                         'Wrong tag details.')
+
+
+class PictureTests(ApiTest):
+    def test_publish(self):
+        slug = "kandinsky-composition-viii"
+        xml = SimpleUploadedFile(
+            'composition8.xml', open(path.join(picture.tests.__path__[0], "files", slug + ".xml")).read())
+        img = SimpleUploadedFile(
+            'kompozycja-8.png', open(path.join(picture.tests.__path__[0], "files", slug + ".png")).read())
+
+        import_form = PictureImportForm({}, {
+            'picture_xml_file': xml,
+            'picture_image_file': img
+            })
+
+        assert import_form.is_valid()
+        if import_form.is_valid():
+            import_form.save()
+
+        Picture.objects.get(slug=slug)
+
+
+class URLTests(ApiTest):
+    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')
+        self.assert_json_response('/api/ebooks/', 'ebooks.json')
+        self.assert_json_response('/api/filter-books/', 'filter-books.json')
+        self.assert_json_response('/api/newest/', 'newest.json')
+
+        self.assert_json_response('/api/blog/', 'blog.json')
+        self.assert_json_response('/api/preview/', 'preview.json')
+        self.assert_json_response('/api/recommended/', 'recommended.json')
+
+        self.assert_json_response('/api/collections/', 'collections.json')
diff --git a/src/catalogue/fixtures/collection-boy.json b/src/catalogue/fixtures/collection-boy.json
deleted file mode 100644 (file)
index 1328b13..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-[
-    {
-        "pk": "promo",
-        "model": "chunks.chunk",
-        "fields": {
-            "content": "<div class=\"grid-line\" id=\"promo-box-header\"><h2 class=\"mono\">\r\n\r\n\r\nOh Boy!\r\n\r\n\r\n</h2></div><div id=\"promo-box-body\" class=\"accent4\"><p id=\"promo-box-title\" class=\"mono\"><span>\r\n\r\n\r\nBiblioteczka Boya\r\n\r\n\r\n</span></p><div id=\"promo-box-content\">\r\n\r\n\r\n<p>T\u0142umaczenia literatury francuskiej i nie tylko.</p>\r\n\r\n<p class=\"see-more\"><a href=\"/katalog/lektury/boy/\" >Biblioteczka Boya \u21d2</a></p>\r\n\r\n\r\n</div></div>",
-            "description": "boks promocyjny na g\u0142\u00f3wnej"
-        }
-    },
-    {
-        "pk": "boy",
-        "model": "catalogue.collection",
-        "fields": {
-            "book_slugs": "http://www.wolnelektury.pl/katalog/lektura/piesn-o-rolandzie/\nhttp://www.wolnelektury.pl/katalog/lektura/wielki-testament/\nhttp://www.wolnelektury.pl/katalog/lektura/skapiec/\nhttp://www.wolnelektury.pl/katalog/lektura/mieszczanin-szlachcicem/\nhttp://www.wolnelektury.pl/katalog/lektura/kandyd/\nhttp://www.wolnelektury.pl/katalog/lektura/rozprawa-o-metodzie/\nhttp://www.wolnelektury.pl/katalog/lektura/listy-perskie/\nhttp://www.wolnelektury.pl/katalog/lektura/spowiedz-dzieciecia-wieku/\nhttp://www.wolnelektury.pl/katalog/lektura/ubu-krol/\nhttp://www.wolnelektury.pl/katalog/lektura/legenda-o-tristanie-i-izoldzie/\nhttp://www.wolnelektury.pl/katalog/lektura/boy-swietoszek/\nhttp://www.wolnelektury.pl/katalog/lektura/mizantrop/\nhttp://www.wolnelektury.pl/katalog/lektura/kubus-fatalista-i-jego-pan/\nhttp://www.wolnelektury.pl/katalog/lektura/mysli/\nhttp://www.wolnelektury.pl/katalog/lektura/o-duchu-praw/\nhttp://www.wolnelektury.pl/katalog/lektura/proby/\nhttp://www.wolnelektury.pl/katalog/lektura/w-strone-swanna/\nhttp://www.wolnelektury.pl/katalog/lektura/gargantua-i-pantagruel/",
-            "description": "",
-            "title": "Biblioteczka Boya"
-        }
-    }
-]
\ No newline at end of file
diff --git a/src/catalogue/fixtures/test-books.yaml b/src/catalogue/fixtures/test-books.yaml
new file mode 100644 (file)
index 0000000..43ca447
--- /dev/null
@@ -0,0 +1,96 @@
+- model: catalogue.book
+  pk: 1
+  fields:
+    slug: parent
+    sort_key: parent
+    sort_key_author: john doe
+    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
+    created_at: "1970-01-03 0:0Z"
+    changed_at: "1970-01-03 0:0Z"
+    extra_info: "{\"epoch\": \"Barok\"}"
+- model: catalogue.book
+  pk: 2
+  fields:
+    slug: child
+    sort_key: child
+    parent: 1
+    created_at: "1970-01-02 0:0Z"
+    changed_at: "1970-01-02 0:0Z"
+- model: catalogue.book
+  pk: 3
+  fields:
+    slug: grandchild
+    sort_key: grandchild
+    parent: 2
+    txt_file: txt/grandchild.txt
+    html_file: html/grandchild.html
+    fb2_file: fb2/grandchild.fb2
+    created_at: "1970-01-01 0:0Z"
+    changed_at: "1970-01-01 0:0Z"
+
+- model: catalogue.tag
+  pk: 1
+  fields:
+    slug: john-doe
+    sort_key: john doe
+    category: author
+    name: John Doe
+    created_at: "1970-01-03 0:0Z"
+    changed_at: "1970-01-03 0:0Z"
+- model: catalogue.tag
+  pk: 2
+  fields:
+    slug: liryka
+    sort_key: liryka
+    category: kind
+    name: Liryka
+    created_at: "1970-01-03 0:0Z"
+    changed_at: "1970-01-03 0:0Z"
+- model: catalogue.tag
+  pk: 3
+  fields:
+    slug: barok
+    sort_key: barok
+    category: epoch
+    name: Barok
+    created_at: "1970-01-03 0:0Z"
+    changed_at: "1970-01-03 0:0Z"
+- model: catalogue.tag
+  pk: 4
+  fields:
+    slug: sonet
+    sort_key: sonet
+    category: genre
+    name: Sonet
+    created_at: "1970-01-03 0:0Z"
+    changed_at: "1970-01-03 0:0Z"
+
+- model: catalogue.tagrelation
+  pk: 1
+  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
+  pk: 3
+  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
+
index c1c055b..d69b6e5 100755 (executable)
@@ -8,7 +8,11 @@ sys.path = [
 ] + sys.path
 
 if __name__ == "__main__":
-    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wolnelektury.settings")
+    os.environ.setdefault(
+        "DJANGO_SETTINGS_MODULE",
+        "wolnelektury.settings.test"
+        if 'test' in sys.argv
+        else "wolnelektury.settings")
 
     from django.core.management import execute_from_command_line
 
diff --git a/src/wolnelektury/settings/test.py b/src/wolnelektury/settings/test.py
new file mode 100644 (file)
index 0000000..0de27c7
--- /dev/null
@@ -0,0 +1,3 @@
+from wolnelektury.settings import *
+
+THUMBNAIL_BACKEND = 'wolnelektury.test_utils.DummyThumbnailBackend'
diff --git a/src/wolnelektury/test_utils.py b/src/wolnelektury/test_utils.py
new file mode 100644 (file)
index 0000000..f22eb98
--- /dev/null
@@ -0,0 +1,7 @@
+class DummyThumbnailBackend:
+    class DummyThumbnail:
+        def __init__(self, url):
+            self.url = url
+
+    def get_thumbnail(self, file_, geometry_string, **options):
+        return self.DummyThumbnail(url='-'.join((file_.url, geometry_string)))