slugify->slughifi, **kwargs in BookMedia.save
[wolnelektury.git] / apps / catalogue / tests / book_import.py
1 # -*- coding: utf-8 -*-
2 from django.core.files.base import ContentFile
3 from catalogue.test_utils import *
4 from catalogue import models
5
6 from nose.tools import raises
7
8
9 class BookImportLogicTests(WLTestCase):
10
11     def setUp(self):
12         WLTestCase.setUp(self)
13         self.book_info = BookInfoStub(
14             url=u"http://wolnelektury.pl/example/default-book",
15             about=u"http://wolnelektury.pl/example/URI/default_book",
16             title=u"Default Book",
17             author=PersonStub(("Jim",), "Lazy"),
18             kind="X-Kind",
19             genre="X-Genre",
20             epoch="X-Epoch",
21         )
22
23         self.expected_tags = [
24            ('author', 'jim-lazy'),
25            ('genre', 'x-genre'),
26            ('epoch', 'x-epoch'),
27            ('kind', 'x-kind'),
28         ]
29         self.expected_tags.sort()
30
31     def test_empty_book(self):
32         BOOK_TEXT = "<utwor />"
33         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
34
35         self.assertEqual(book.title, "Default Book")
36         self.assertEqual(book.slug, "default-book")
37         self.assert_(book.parent is None)
38         self.assertFalse(book.has_html_file())
39
40         # no fragments generated
41         self.assertEqual(book.fragments.count(), 0)
42
43         # TODO: this should be filled out probably...
44         self.assertEqual(book.wiki_link, '')
45         self.assertEqual(book.gazeta_link, '')
46         self.assertEqual(book._short_html, '')
47         self.assertEqual(book.description, '')
48
49         tags = [ (tag.category, tag.slug) for tag in book.tags ]
50         tags.sort()
51
52         self.assertEqual(tags, self.expected_tags)
53
54     def test_not_quite_empty_book(self):
55         """ Not empty, but without any real text.
56
57         Should work like any other non-empty book.
58         """
59
60         BOOK_TEXT = """<utwor>
61         <liryka_l>
62             <nazwa_utworu>Nic</nazwa_utworu>
63         </liryka_l></utwor>
64         """
65
66         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
67         self.assertTrue(book.has_html_file())
68
69     def test_book_with_fragment(self):
70         BOOK_TEXT = """<utwor>
71         <opowiadanie>
72             <akap><begin id="m01" /><motyw id="m01">Love</motyw>Ala ma kota<end id="m01" /></akap>
73         </opowiadanie></utwor>
74         """
75
76         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
77         self.assertTrue(book.has_html_file())
78
79         self.assertEqual(book.fragments.count(), 1)
80         self.assertEqual(book.fragments.all()[0].text, u'<p class="paragraph">Ala ma kota</p>\n')
81
82         self.assert_(('theme', 'love') in [ (tag.category, tag.slug) for tag in book.fragments.all()[0].tags ])
83
84     def test_book_with_empty_theme(self):
85         """ empty themes should be ignored """
86
87         BOOK_TEXT = """<utwor>
88         <opowiadanie>
89             <akap><begin id="m01" /><motyw id="m01"> , Love , , </motyw>Ala ma kota<end id="m01" /></akap>
90         </opowiadanie></utwor>
91         """
92
93         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
94         self.assert_([('theme', 'love')],
95                          [ (tag.category, tag.slug) for tag in book.fragments.all()[0].tags.filter(category='theme') ])
96
97     def test_book_with_no_theme(self):
98         """ fragments with no themes shouldn't be created at all """
99
100         BOOK_TEXT = """<utwor>
101         <opowiadanie>
102             <akap><begin id="m01" /><motyw id="m01"></motyw>Ala ma kota<end id="m01" /></akap>
103         </opowiadanie></utwor>
104         """
105
106         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
107         self.assertEqual(book.fragments.count(), 0)
108         self.assertEqual(book.tags.filter(category='theme').count(), 0)
109
110     @raises(ValueError)
111     def test_book_with_invalid_slug(self):
112         """ Book with invalid characters in slug shouldn't be imported """
113         self.book_info.url = "http://wolnelektury.pl/example/default_book"
114         BOOK_TEXT = "<utwor />"
115         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
116
117     def test_book_replace_title(self):
118         BOOK_TEXT = """<utwor />"""
119         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
120         self.book_info.title = u"Extraordinary"
121         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info, overwrite=True)
122
123         tags = [ (tag.category, tag.slug) for tag in book.tags ]
124         tags.sort()
125
126         self.assertEqual(tags, self.expected_tags)
127
128     def test_book_replace_author(self):
129         BOOK_TEXT = """<utwor />"""
130         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
131         self.book_info.author = PersonStub(("Hans", "Christian"), "Andersen")
132         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info, overwrite=True)
133
134         tags = [ (tag.category, tag.slug) for tag in book.tags ]
135         tags.sort()
136
137         self.expected_tags.remove(('author', 'jim-lazy'))
138         self.expected_tags.append(('author', 'hans-christian-andersen'))
139         self.expected_tags.sort()
140
141         self.assertEqual(tags, self.expected_tags)
142
143         # the old tag shouldn't disappear
144         models.Tag.objects.get(slug="jim-lazy", category="author")
145
146     def test_multiple_tags(self):
147         BOOK_TEXT = """<utwor />"""
148         self.book_info.authors = self.book_info.author, PersonStub(("Joe",), "Dilligent"),
149         self.book_info.kinds = self.book_info.kind, 'Y-Kind',
150         self.book_info.genres = self.book_info.genre, 'Y-Genre',
151         self.book_info.epochs = self.book_info.epoch, 'Y-Epoch',
152
153         self.expected_tags.extend([
154            ('author', 'joe-dilligent'),
155            ('genre', 'y-genre'),
156            ('epoch', 'y-epoch'),
157            ('kind', 'y-kind'),
158         ])
159         self.expected_tags.sort()
160
161         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
162         tags = [ (tag.category, tag.slug) for tag in book.tags ]
163         tags.sort()
164
165         self.assertEqual(tags, self.expected_tags)
166
167
168 class ChildImportTests(WLTestCase):
169
170     def setUp(self):
171         WLTestCase.setUp(self)
172         self.child_info = BookInfoStub(
173             genre='X-Genre',
174             epoch='X-Epoch',
175             kind='X-Kind',
176             author=PersonStub(("Joe",), "Doe"),
177             **info_args("Child")
178         )
179
180         self.parent_info = BookInfoStub(
181             genre='X-Genre',
182             epoch='X-Epoch',
183             kind='X-Kind',
184             author=PersonStub(("Jim",), "Lazy"),
185             parts=[self.child_info.url],
186             **info_args("Parent")
187         )
188
189     def test_child_replace(self):
190         PARENT_TEXT = """<utwor />"""
191         CHILD_TEXT = """<utwor>
192         <opowiadanie>
193             <akap><begin id="m01" /><motyw id="m01">Pies</motyw>Ala ma kota<end id="m01" /></akap>
194         </opowiadanie></utwor>
195         """
196         child = models.Book.from_text_and_meta(ContentFile(CHILD_TEXT), self.child_info)
197         parent = models.Book.from_text_and_meta(ContentFile(PARENT_TEXT), self.parent_info)
198         CHILD_TEXT = """<utwor>
199         <opowiadanie>
200             <akap><begin id="m01" /><motyw id="m01">Kot</motyw>Ala ma kota<end id="m01" /></akap>
201         </opowiadanie></utwor>
202         """
203         child = models.Book.from_text_and_meta(ContentFile(CHILD_TEXT), self.child_info, overwrite=True)
204
205         themes = self.client.get(parent.get_absolute_url()).context['book_themes']
206
207         self.assertEqual(['Kot'], [tag.name for tag in themes],
208                         'wrong related theme list')