1 # -*- coding: utf-8 -*-
2 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
5 from django.core.files.base import ContentFile
6 from catalogue.test_utils import *
7 from catalogue import models
8 from librarian import WLURI
10 from os import path, makedirs
13 class BookImportLogicTests(WLTestCase):
16 WLTestCase.setUp(self)
17 self.book_info = BookInfoStub(
18 url=WLURI.from_slug(u"default-book"),
19 about=u"http://wolnelektury.pl/example/URI/default_book",
20 title=u"Default Book",
21 author=PersonStub(("Jim",), "Lazy"),
28 self.expected_tags = [
29 ('author', 'jim-lazy'),
34 self.expected_tags.sort()
36 def test_empty_book(self):
37 book_text = "<utwor />"
38 book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
40 self.assertEqual(book.title, "Default Book")
41 self.assertEqual(book.slug, "default-book")
42 self.assert_(book.parent is None)
43 self.assertFalse(book.has_html_file())
45 # no fragments generated
46 self.assertEqual(book.fragments.count(), 0)
48 # TODO: this should be filled out probably...
49 self.assertEqual(book.wiki_link, '')
50 self.assertEqual(book.gazeta_link, '')
51 self.assertEqual(book.description, '')
53 tags = [(tag.category, tag.slug) for tag in book.tags]
56 self.assertEqual(tags, self.expected_tags)
58 def test_not_quite_empty_book(self):
59 """ Not empty, but without any real text.
61 Should work like any other non-empty book.
64 book_text = """<utwor>
66 <nazwa_utworu>Nic</nazwa_utworu>
70 book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
71 self.assertTrue(book.has_html_file())
73 def test_book_with_fragment(self):
74 book_text = """<utwor>
76 <akap><begin id="m01" /><motyw id="m01">Love</motyw>Ala ma kota<end id="m01" /></akap>
77 </opowiadanie></utwor>
80 book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
81 self.assertTrue(book.has_html_file())
83 self.assertEqual(book.fragments.count(), 1)
84 self.assertEqual(book.fragments.all()[0].text, u'<p class="paragraph">Ala ma kota</p>\n')
86 self.assert_(('theme', 'love') in [(tag.category, tag.slug) for tag in book.fragments.all()[0].tags])
88 def test_book_with_empty_theme(self):
89 """ empty themes should be ignored """
91 book_text = """<utwor>
93 <akap><begin id="m01" /><motyw id="m01"> , Love , , </motyw>Ala ma kota<end id="m01" /></akap>
94 </opowiadanie></utwor>
97 book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
98 self.assert_([('theme', 'love')],
99 book.fragments.all()[0].tags.filter(category='theme').values_list('category', 'slug'))
101 def test_book_with_no_theme(self):
102 """ fragments with no themes shouldn't be created at all """
104 book_text = """<utwor>
106 <akap><begin id="m01" /><motyw id="m01"></motyw>Ala ma kota<end id="m01" /></akap>
107 </opowiadanie></utwor>
110 book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
111 self.assertEqual(book.fragments.count(), 0)
112 self.assertEqual(book.tags.filter(category='theme').count(), 0)
114 def test_book_with_invalid_slug(self):
115 """ Book with invalid characters in slug shouldn't be imported """
116 self.book_info.url = WLURI.from_slug(u"default_book")
117 book_text = "<utwor />"
118 with self.assertRaises(ValueError):
119 models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
121 def test_book_replace_title(self):
122 book_text = """<utwor />"""
123 models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
124 self.book_info.title = u"Extraordinary"
125 book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info, overwrite=True)
127 tags = [(tag.category, tag.slug) for tag in book.tags]
130 self.assertEqual(tags, self.expected_tags)
132 def test_book_replace_author(self):
133 book_text = """<utwor />"""
134 models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
135 self.book_info.author = PersonStub(("Hans", "Christian"), "Andersen")
136 book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info, overwrite=True)
138 tags = [(tag.category, tag.slug) for tag in book.tags]
141 self.expected_tags.remove(('author', 'jim-lazy'))
142 self.expected_tags.append(('author', 'hans-christian-andersen'))
143 self.expected_tags.sort()
145 self.assertEqual(tags, self.expected_tags)
147 # the old tag shouldn't disappear
148 models.Tag.objects.get(slug="jim-lazy", category="author")
150 def test_book_remove_fragment(self):
151 book_text = """<utwor>
154 <begin id="m01" /><motyw id="m01">Love</motyw>Ala ma kota<end id="m01" />
155 <begin id="m02" /><motyw id="m02">Hatred</motyw>To kot Ali<end id="m02" />
157 </opowiadanie></utwor>
159 book_text_after = """<utwor>
162 <begin id="m01" /><motyw id="m01">Love</motyw>Ala ma kota<end id="m01" />
165 </opowiadanie></utwor>
168 book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
169 self.assertEqual(book.fragments.count(), 2)
170 book = models.Book.from_text_and_meta(ContentFile(book_text_after), self.book_info, overwrite=True)
171 self.assertEqual(book.fragments.count(), 1)
173 def test_multiple_tags(self):
174 book_text = """<utwor />"""
175 self.book_info.authors = self.book_info.author, PersonStub(("Joe",), "Dilligent"),
176 self.book_info.kinds = self.book_info.kind, 'Y-Kind',
177 self.book_info.genres = self.book_info.genre, 'Y-Genre',
178 self.book_info.epochs = self.book_info.epoch, 'Y-Epoch',
180 self.expected_tags.extend([
181 ('author', 'joe-dilligent'),
182 ('genre', 'y-genre'),
183 ('epoch', 'y-epoch'),
186 self.expected_tags.sort()
188 book = models.Book.from_text_and_meta(ContentFile(book_text), self.book_info)
189 tags = [(tag.category, tag.slug) for tag in book.tags]
192 self.assertEqual(tags, self.expected_tags)
195 class ChildImportTests(WLTestCase):
198 WLTestCase.setUp(self)
199 self.child_info = BookInfoStub(
203 author=PersonStub(("Joe",), "Doe"),
207 self.parent_info = BookInfoStub(
211 author=PersonStub(("Jim",), "Lazy"),
212 parts=[self.child_info.url],
213 **info_args("Parent")
216 def test_child(self):
217 text = """<utwor />"""
218 child = models.Book.from_text_and_meta(ContentFile(text), self.child_info)
219 parent = models.Book.from_text_and_meta(ContentFile(text), self.parent_info)
220 author = parent.tags.get(category='author')
221 books = self.client.get(author.get_absolute_url()).context['object_list']
222 self.assertEqual(len(books), 1, "Only parent book should be visible on author's page")
224 def test_child_replace(self):
225 parent_text = """<utwor />"""
226 child_text = """<utwor>
228 <akap><begin id="m01" /><motyw id="m01">Pies</motyw>Ala ma kota<end id="m01" /></akap>
229 </opowiadanie></utwor>
231 child = models.Book.from_text_and_meta(ContentFile(child_text), self.child_info)
232 parent = models.Book.from_text_and_meta(ContentFile(parent_text), self.parent_info)
233 child_text = """<utwor>
235 <akap><begin id="m01" /><motyw id="m01">Kot</motyw>Ala ma kota<end id="m01" /></akap>
236 </opowiadanie></utwor>
238 child = models.Book.from_text_and_meta(ContentFile(child_text), self.child_info, overwrite=True)
239 themes = parent.related_themes()
240 self.assertEqual(['Kot'], [tag.name for tag in themes], 'wrong related theme list')
243 class TreeImportTest(WLTestCase):
245 WLTestCase.setUp(self)
246 self.child_info = BookInfoStub(
250 author=PersonStub(("Joe",), "Doe"),
253 self.CHILD_TEXT = """<utwor>
255 <akap><begin id="m01" /><motyw id="m01">Pies</motyw>
256 Ala ma kota<end id="m01" /></akap>
257 </opowiadanie></utwor>
259 self.child = models.Book.from_text_and_meta(
260 ContentFile(self.CHILD_TEXT), self.child_info)
262 self.book_info = BookInfoStub(
266 author=PersonStub(("Joe",), "Doe"),
267 parts=[self.child_info.url],
270 self.BOOK_TEXT = """<utwor />"""
271 self.book = models.Book.from_text_and_meta(
272 ContentFile(self.BOOK_TEXT), self.book_info)
274 self.parent_info = BookInfoStub(
278 author=PersonStub(("Jim",), "Lazy"),
279 parts=[self.book_info.url],
280 **info_args("Parent")
282 self.PARENT_TEXT = """<utwor />"""
283 self.parent = models.Book.from_text_and_meta(
284 ContentFile(self.PARENT_TEXT), self.parent_info)
288 list(self.client.get('/katalog/gatunek/x-genre/').context['object_list']),
290 u"There should be only parent on common tag page."
292 # pies = models.Tag.objects.get(slug='pies')
293 themes = self.parent.related_themes()
294 self.assertEqual(len(themes), 1, u"There should be child theme in parent theme counter.")
295 # TODO: book_count is deprecated, update here.
296 # epoch = models.Tag.objects.get(slug='x-epoch')
297 # self.assertEqual(epoch.book_count, 1, u"There should be only parent in common tag's counter.")
299 def test_child_republish(self):
300 child_text = """<utwor>
302 <akap><begin id="m01" /><motyw id="m01">Pies, Kot</motyw>
303 Ala ma kota<end id="m01" /></akap>
304 </opowiadanie></utwor>
306 models.Book.from_text_and_meta(
307 ContentFile(child_text), self.child_info, overwrite=True)
309 list(self.client.get('/katalog/gatunek/x-genre/').context['object_list']),
311 u"There should only be parent on common tag page."
313 # pies = models.Tag.objects.get(slug='pies')
314 # kot = models.Tag.objects.get(slug='kot')
315 self.assertEqual(len(self.parent.related_themes()), 2,
316 u"There should be child themes in parent theme counter.")
317 # TODO: book_count is deprecated, update here.
318 # epoch = models.Tag.objects.get(slug='x-epoch')
319 # self.assertEqual(epoch.book_count, 1, u"There should only be parent in common tag's counter.")
321 def test_book_change_child(self):
322 second_child_info = BookInfoStub(
326 author=PersonStub(("Joe",), "Doe"),
327 **info_args("Second Child")
329 second_child_text = """<utwor>
331 <akap><begin id="m01" /><motyw id="m01">Kot</motyw>
332 Ala ma kota<end id="m01" /></akap>
333 </opowiadanie></utwor>
335 # Import a second child.
336 second_child = models.Book.from_text_and_meta(
337 ContentFile(second_child_text), second_child_info)
338 # The book has only this new child now.
339 self.book_info.parts = [second_child_info.url]
340 self.book = models.Book.from_text_and_meta(
341 ContentFile(self.BOOK_TEXT), self.book_info, overwrite=True)
344 set(self.client.get('/katalog/gatunek/x-genre/').context['object_list']),
345 {self.parent, self.child},
346 u"There should be parent and old child on common tag page."
348 # kot = models.Tag.objects.get(slug='kot')
349 self.assertEqual(len(self.parent.related_themes()), 1,
350 u"There should only be new child themes in parent theme counter.")
351 # # book_count deprecated, update test.
352 # epoch = models.Tag.objects.get(slug='x-epoch')
353 # self.assertEqual(epoch.book_count, 2,
354 # u"There should be parent and old child in common tag's counter.")
356 list(self.client.get('/katalog/lektura/parent/motyw/kot/').context['fragments']),
357 [second_child.fragments.all()[0]],
358 u"There should be new child's fragments on parent's theme page."
361 list(self.client.get('/katalog/lektura/parent/motyw/pies/').context['fragments']),
363 u"There should be no old child's fragments on parent's theme page."
367 class MultilingualBookImportTest(WLTestCase):
369 WLTestCase.setUp(self)
370 common_uri = WLURI.from_slug('common-slug')
372 self.pol_info = BookInfoStub(
376 author=PersonStub(("Joe",), "Doe"),
377 variant_of=common_uri,
378 **info_args(u"Książka")
381 self.eng_info = BookInfoStub(
385 author=PersonStub(("Joe",), "Doe"),
386 variant_of=common_uri,
387 **info_args("A book", "eng")
390 def test_multilingual_import(self):
391 book_text = """<utwor><opowiadanie><akap>A</akap></opowiadanie></utwor>"""
393 models.Book.from_text_and_meta(ContentFile(book_text), self.pol_info)
394 models.Book.from_text_and_meta(ContentFile(book_text), self.eng_info)
397 set([b.language for b in models.Book.objects.all()]),
399 'Books imported in wrong languages.'
403 class BookImportGenerateTest(WLTestCase):
405 WLTestCase.setUp(self)
406 xml = path.join(path.dirname(__file__), 'files/fraszka-do-anusie.xml')
407 self.book = models.Book.from_xml_file(xml)
409 def test_gen_pdf(self):
410 self.book.pdf_file.build()
411 book = models.Book.objects.get(pk=self.book.pk)
412 self.assertTrue(path.exists(book.pdf_file.path))
414 def test_gen_pdf_parent(self):
415 """This book contains a child."""
416 xml = path.join(path.dirname(__file__), "files/fraszki.xml")
417 parent = models.Book.from_xml_file(xml)
418 parent.pdf_file.build()
419 parent = models.Book.objects.get(pk=parent.pk)
420 self.assertTrue(path.exists(parent.pdf_file.path))
422 def test_custom_pdf(self):
423 from catalogue.tasks import build_custom_pdf
424 out = 'test-custom.pdf'
425 absoulute_path = path.join(settings.MEDIA_ROOT, out)
427 if not path.exists(path.dirname(absoulute_path)):
428 makedirs(path.dirname(absoulute_path))
430 build_custom_pdf(self.book.id, customizations=['nofootnotes', '13pt', 'a4paper'], file_name=out)
431 self.assertTrue(path.exists(absoulute_path))