1 # -*- coding: utf-8 -*-
 
   2 from django.conf import settings
 
   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.pdf_file.build()
 
 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)
 
 429         parent.pdf_file.build()
 
 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))