1 # -*- coding: utf-8 -*-
2 from __future__ import with_statement
4 from django.core.files.base import ContentFile, File
5 from catalogue.test_utils import *
6 from catalogue import models
7 from librarian import WLURI
9 from nose.tools import raises
10 from os import path, makedirs
12 class BookImportLogicTests(WLTestCase):
15 WLTestCase.setUp(self)
16 self.book_info = BookInfoStub(
17 url=WLURI.from_slug(u"default-book"),
18 about=u"http://wolnelektury.pl/example/URI/default_book",
19 title=u"Default Book",
20 author=PersonStub(("Jim",), "Lazy"),
27 self.expected_tags = [
28 ('author', 'jim-lazy'),
33 self.expected_tags.sort()
35 def test_empty_book(self):
36 BOOK_TEXT = "<utwor />"
37 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
39 self.assertEqual(book.title, "Default Book")
40 self.assertEqual(book.slug, "default-book")
41 self.assert_(book.parent is None)
42 self.assertFalse(book.has_html_file())
44 # no fragments generated
45 self.assertEqual(book.fragments.count(), 0)
47 # TODO: this should be filled out probably...
48 self.assertEqual(book.wiki_link, '')
49 self.assertEqual(book.gazeta_link, '')
50 self.assertEqual(book.description, '')
52 tags = [ (tag.category, tag.slug) for tag in book.tags ]
55 self.assertEqual(tags, self.expected_tags)
57 def test_not_quite_empty_book(self):
58 """ Not empty, but without any real text.
60 Should work like any other non-empty book.
63 BOOK_TEXT = """<utwor>
65 <nazwa_utworu>Nic</nazwa_utworu>
69 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
70 self.assertTrue(book.has_html_file())
72 def test_book_with_fragment(self):
73 BOOK_TEXT = """<utwor>
75 <akap><begin id="m01" /><motyw id="m01">Love</motyw>Ala ma kota<end id="m01" /></akap>
76 </opowiadanie></utwor>
79 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
80 self.assertTrue(book.has_html_file())
82 self.assertEqual(book.fragments.count(), 1)
83 self.assertEqual(book.fragments.all()[0].text, u'<p class="paragraph">Ala ma kota</p>\n')
85 self.assert_(('theme', 'love') in [ (tag.category, tag.slug) for tag in book.fragments.all()[0].tags ])
87 def test_book_with_empty_theme(self):
88 """ empty themes should be ignored """
90 BOOK_TEXT = """<utwor>
92 <akap><begin id="m01" /><motyw id="m01"> , Love , , </motyw>Ala ma kota<end id="m01" /></akap>
93 </opowiadanie></utwor>
96 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
97 self.assert_([('theme', 'love')],
98 [ (tag.category, tag.slug) for tag in book.fragments.all()[0].tags.filter(category='theme') ])
100 def test_book_with_no_theme(self):
101 """ fragments with no themes shouldn't be created at all """
103 BOOK_TEXT = """<utwor>
105 <akap><begin id="m01" /><motyw id="m01"></motyw>Ala ma kota<end id="m01" /></akap>
106 </opowiadanie></utwor>
109 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
110 self.assertEqual(book.fragments.count(), 0)
111 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 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
120 def test_book_replace_title(self):
121 BOOK_TEXT = """<utwor />"""
122 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
123 self.book_info.title = u"Extraordinary"
124 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info, overwrite=True)
126 tags = [ (tag.category, tag.slug) for tag in book.tags ]
129 self.assertEqual(tags, self.expected_tags)
131 def test_book_replace_author(self):
132 BOOK_TEXT = """<utwor />"""
133 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
134 self.book_info.author = PersonStub(("Hans", "Christian"), "Andersen")
135 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info, overwrite=True)
137 tags = [ (tag.category, tag.slug) for tag in book.tags ]
140 self.expected_tags.remove(('author', 'jim-lazy'))
141 self.expected_tags.append(('author', 'hans-christian-andersen'))
142 self.expected_tags.sort()
144 self.assertEqual(tags, self.expected_tags)
146 # the old tag shouldn't disappear
147 models.Tag.objects.get(slug="jim-lazy", category="author")
149 def test_book_remove_fragment(self):
150 BOOK_TEXT = """<utwor>
153 <begin id="m01" /><motyw id="m01">Love</motyw>Ala ma kota<end id="m01" />
154 <begin id="m02" /><motyw id="m02">Hatred</motyw>To kot Ali<end id="m02" />
156 </opowiadanie></utwor>
158 BOOK_TEXT_AFTER = """<utwor>
161 <begin id="m01" /><motyw id="m01">Love</motyw>Ala ma kota<end id="m01" />
164 </opowiadanie></utwor>
167 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
168 self.assertEqual(book.fragments.count(), 2)
169 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT_AFTER), self.book_info, overwrite=True)
170 self.assertEqual(book.fragments.count(), 1)
172 def test_multiple_tags(self):
173 BOOK_TEXT = """<utwor />"""
174 self.book_info.authors = self.book_info.author, PersonStub(("Joe",), "Dilligent"),
175 self.book_info.kinds = self.book_info.kind, 'Y-Kind',
176 self.book_info.genres = self.book_info.genre, 'Y-Genre',
177 self.book_info.epochs = self.book_info.epoch, 'Y-Epoch',
179 self.expected_tags.extend([
180 ('author', 'joe-dilligent'),
181 ('genre', 'y-genre'),
182 ('epoch', 'y-epoch'),
185 self.expected_tags.sort()
187 book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
188 tags = [ (tag.category, tag.slug) for tag in book.tags ]
191 self.assertEqual(tags, self.expected_tags)
194 class ChildImportTests(WLTestCase):
197 WLTestCase.setUp(self)
198 self.child_info = BookInfoStub(
202 author=PersonStub(("Joe",), "Doe"),
206 self.parent_info = BookInfoStub(
210 author=PersonStub(("Jim",), "Lazy"),
211 parts=[self.child_info.url],
212 **info_args("Parent")
215 def test_child(self):
216 TEXT = """<utwor />"""
217 child = models.Book.from_text_and_meta(ContentFile(TEXT), self.child_info)
218 parent = models.Book.from_text_and_meta(ContentFile(TEXT), self.parent_info)
219 author = parent.tags.get(category='author')
220 books = self.client.get(author.get_absolute_url()).context['object_list']
221 self.assertEqual(len(books), 1,
222 "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],
241 'wrong related theme list')
244 class TreeImportTest(WLTestCase):
246 WLTestCase.setUp(self)
247 self.child_info = BookInfoStub(
251 author=PersonStub(("Joe",), "Doe"),
254 self.CHILD_TEXT = """<utwor>
256 <akap><begin id="m01" /><motyw id="m01">Pies</motyw>
257 Ala ma kota<end id="m01" /></akap>
258 </opowiadanie></utwor>
260 self.child = models.Book.from_text_and_meta(
261 ContentFile(self.CHILD_TEXT), self.child_info)
263 self.book_info = BookInfoStub(
267 author=PersonStub(("Joe",), "Doe"),
268 parts=[self.child_info.url],
271 self.BOOK_TEXT = """<utwor />"""
272 self.book = models.Book.from_text_and_meta(
273 ContentFile(self.BOOK_TEXT), self.book_info)
275 self.parent_info = BookInfoStub(
279 author=PersonStub(("Jim",), "Lazy"),
280 parts=[self.book_info.url],
281 **info_args("Parent")
283 self.PARENT_TEXT = """<utwor />"""
284 self.parent = models.Book.from_text_and_meta(
285 ContentFile(self.PARENT_TEXT), self.parent_info)
289 list(self.client.get('/katalog/gatunek/x-genre/'
290 ).context['object_list']),
292 u"There should be only parent on common tag page."
294 pies = models.Tag.objects.get(slug='pies')
295 self.assertEqual(self.parent.theme_counter, {pies.pk: 1},
296 u"There should be child theme in parent theme counter."
298 epoch = models.Tag.objects.get(slug='x-epoch')
299 self.assertEqual(epoch.book_count, 1,
300 u"There should be only parent in common tag's counter."
303 def test_child_republish(self):
304 CHILD_TEXT = """<utwor>
306 <akap><begin id="m01" /><motyw id="m01">Pies, Kot</motyw>
307 Ala ma kota<end id="m01" /></akap>
308 </opowiadanie></utwor>
310 models.Book.from_text_and_meta(
311 ContentFile(CHILD_TEXT), self.child_info, overwrite=True)
313 list(self.client.get('/katalog/gatunek/x-genre/'
314 ).context['object_list']),
316 u"There should only be parent on common tag page."
318 pies = models.Tag.objects.get(slug='pies')
319 kot = models.Tag.objects.get(slug='kot')
320 self.assertEqual(self.parent.theme_counter, {pies.pk: 1, kot.pk: 1},
321 u"There should be child themes in parent theme counter."
323 epoch = models.Tag.objects.get(slug='x-epoch')
324 self.assertEqual(epoch.book_count, 1,
325 u"There should only be parent in common tag's counter."
328 def test_book_change_child(self):
329 second_child_info = BookInfoStub(
333 author=PersonStub(("Joe",), "Doe"),
334 **info_args("Second Child")
336 SECOND_CHILD_TEXT = """<utwor>
338 <akap><begin id="m01" /><motyw id="m01">Kot</motyw>
339 Ala ma kota<end id="m01" /></akap>
340 </opowiadanie></utwor>
342 # Import a second child.
343 second_child = models.Book.from_text_and_meta(
344 ContentFile(SECOND_CHILD_TEXT), second_child_info)
345 # The book has only this new child now.
346 self.book_info.parts = [second_child_info.url]
347 self.book = models.Book.from_text_and_meta(
348 ContentFile(self.BOOK_TEXT), self.book_info, overwrite=True)
351 set(self.client.get('/katalog/gatunek/x-genre/'
352 ).context['object_list']),
353 set([self.parent, self.child]),
354 u"There should be parent and old child on common tag page."
356 kot = models.Tag.objects.get(slug='kot')
357 self.assertEqual(self.parent.theme_counter, {kot.pk: 1},
358 u"There should only be new child themes in parent theme counter."
360 epoch = models.Tag.objects.get(slug='x-epoch')
361 self.assertEqual(epoch.book_count, 2,
362 u"There should be parent and old child in common tag's counter."
365 list(self.client.get('/katalog/lektura/parent/motyw/kot/'
366 ).context['fragments']),
367 [second_child.fragments.all()[0]],
368 u"There should be new child's fragments on parent's theme page."
371 list(self.client.get('/katalog/lektura/parent/motyw/pies/'
372 ).context['fragments']),
374 u"There should be no old child's fragments on parent's theme page."
378 class MultilingualBookImportTest(WLTestCase):
380 WLTestCase.setUp(self)
381 common_uri = WLURI.from_slug('common-slug')
383 self.pol_info = BookInfoStub(
387 author=PersonStub(("Joe",), "Doe"),
388 variant_of=common_uri,
389 **info_args(u"Książka")
392 self.eng_info = BookInfoStub(
396 author=PersonStub(("Joe",), "Doe"),
397 variant_of=common_uri,
398 **info_args("A book", "eng")
401 def test_multilingual_import(self):
402 BOOK_TEXT = """<utwor><opowiadanie><akap>A</akap></opowiadanie></utwor>"""
404 book1 = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.pol_info)
405 book2 = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.eng_info)
408 set([b.language for b in models.Book.objects.all()]),
410 'Books imported in wrong languages.'
414 class BookImportGenerateTest(WLTestCase):
416 WLTestCase.setUp(self)
417 xml = path.join(path.dirname(__file__), 'files/fraszka-do-anusie.xml')
418 self.book = models.Book.from_xml_file(xml)
420 def test_gen_pdf(self):
421 self.book.build_pdf()
422 book = models.Book.objects.get(pk=self.book.pk)
423 self.assertTrue(path.exists(book.pdf_file.path))
425 def test_gen_pdf_parent(self):
426 """This book contains a child."""
427 xml = path.join(path.dirname(__file__), "files/fraszki.xml")
428 parent = models.Book.from_xml_file(xml)
430 parent = models.Book.objects.get(pk=parent.pk)
431 self.assertTrue(path.exists(parent.pdf_file.path))
433 def test_custom_pdf(self):
434 from catalogue.tasks import build_custom_pdf
435 from catalogue.utils import get_dynamic_path
436 out = get_dynamic_path(None, 'test-custom', ext='pdf')
437 absoulute_path = path.join(settings.MEDIA_ROOT, out)
439 if not path.exists(path.dirname(absoulute_path)):
440 makedirs(path.dirname(absoulute_path))
442 build_custom_pdf(self.book.id,
443 customizations=['nofootnotes', '13pt', 'a4paper'], file_name=out)
444 self.assertTrue(path.exists(absoulute_path))