57dbf27a3073d528526a62c7bf7b7d7d004cf200
[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.description, '')
47
48         tags = [ (tag.category, tag.slug) for tag in book.tags ]
49         tags.sort()
50
51         self.assertEqual(tags, self.expected_tags)
52
53     def test_not_quite_empty_book(self):
54         """ Not empty, but without any real text.
55
56         Should work like any other non-empty book.
57         """
58
59         BOOK_TEXT = """<utwor>
60         <liryka_l>
61             <nazwa_utworu>Nic</nazwa_utworu>
62         </liryka_l></utwor>
63         """
64
65         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
66         self.assertTrue(book.has_html_file())
67
68     def test_book_with_fragment(self):
69         BOOK_TEXT = """<utwor>
70         <opowiadanie>
71             <akap><begin id="m01" /><motyw id="m01">Love</motyw>Ala ma kota<end id="m01" /></akap>
72         </opowiadanie></utwor>
73         """
74
75         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
76         self.assertTrue(book.has_html_file())
77
78         self.assertEqual(book.fragments.count(), 1)
79         self.assertEqual(book.fragments.all()[0].text, u'<p class="paragraph">Ala ma kota</p>\n')
80
81         self.assert_(('theme', 'love') in [ (tag.category, tag.slug) for tag in book.fragments.all()[0].tags ])
82
83     def test_book_with_empty_theme(self):
84         """ empty themes should be ignored """
85
86         BOOK_TEXT = """<utwor>
87         <opowiadanie>
88             <akap><begin id="m01" /><motyw id="m01"> , Love , , </motyw>Ala ma kota<end id="m01" /></akap>
89         </opowiadanie></utwor>
90         """
91
92         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
93         self.assert_([('theme', 'love')],
94                          [ (tag.category, tag.slug) for tag in book.fragments.all()[0].tags.filter(category='theme') ])
95
96     def test_book_with_no_theme(self):
97         """ fragments with no themes shouldn't be created at all """
98
99         BOOK_TEXT = """<utwor>
100         <opowiadanie>
101             <akap><begin id="m01" /><motyw id="m01"></motyw>Ala ma kota<end id="m01" /></akap>
102         </opowiadanie></utwor>
103         """
104
105         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
106         self.assertEqual(book.fragments.count(), 0)
107         self.assertEqual(book.tags.filter(category='theme').count(), 0)
108
109     @raises(ValueError)
110     def test_book_with_invalid_slug(self):
111         """ Book with invalid characters in slug shouldn't be imported """
112         self.book_info.url = "http://wolnelektury.pl/example/default_book"
113         BOOK_TEXT = "<utwor />"
114         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
115
116     def test_book_replace_title(self):
117         BOOK_TEXT = """<utwor />"""
118         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
119         self.book_info.title = u"Extraordinary"
120         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info, overwrite=True)
121
122         tags = [ (tag.category, tag.slug) for tag in book.tags ]
123         tags.sort()
124
125         self.assertEqual(tags, self.expected_tags)
126
127     def test_book_replace_author(self):
128         BOOK_TEXT = """<utwor />"""
129         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
130         self.book_info.author = PersonStub(("Hans", "Christian"), "Andersen")
131         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info, overwrite=True)
132
133         tags = [ (tag.category, tag.slug) for tag in book.tags ]
134         tags.sort()
135
136         self.expected_tags.remove(('author', 'jim-lazy'))
137         self.expected_tags.append(('author', 'hans-christian-andersen'))
138         self.expected_tags.sort()
139
140         self.assertEqual(tags, self.expected_tags)
141
142         # the old tag shouldn't disappear
143         models.Tag.objects.get(slug="jim-lazy", category="author")
144
145     def test_book_remove_fragment(self):
146         BOOK_TEXT = """<utwor>
147         <opowiadanie>
148             <akap>
149                 <begin id="m01" /><motyw id="m01">Love</motyw>Ala ma kota<end id="m01" />
150                 <begin id="m02" /><motyw id="m02">Hatred</motyw>To kot Ali<end id="m02" />
151             </akap>
152         </opowiadanie></utwor>
153         """
154         BOOK_TEXT_AFTER = """<utwor>
155         <opowiadanie>
156             <akap>
157                 <begin id="m01" /><motyw id="m01">Love</motyw>Ala ma kota<end id="m01" />
158                 To kot Ali
159             </akap>
160         </opowiadanie></utwor>
161         """
162
163         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
164         self.assertEqual(book.fragments.count(), 2)
165         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT_AFTER), self.book_info, overwrite=True)
166         self.assertEqual(book.fragments.count(), 1)
167
168     def test_multiple_tags(self):
169         BOOK_TEXT = """<utwor />"""
170         self.book_info.authors = self.book_info.author, PersonStub(("Joe",), "Dilligent"),
171         self.book_info.kinds = self.book_info.kind, 'Y-Kind',
172         self.book_info.genres = self.book_info.genre, 'Y-Genre',
173         self.book_info.epochs = self.book_info.epoch, 'Y-Epoch',
174
175         self.expected_tags.extend([
176            ('author', 'joe-dilligent'),
177            ('genre', 'y-genre'),
178            ('epoch', 'y-epoch'),
179            ('kind', 'y-kind'),
180         ])
181         self.expected_tags.sort()
182
183         book = models.Book.from_text_and_meta(ContentFile(BOOK_TEXT), self.book_info)
184         tags = [ (tag.category, tag.slug) for tag in book.tags ]
185         tags.sort()
186
187         self.assertEqual(tags, self.expected_tags)
188
189
190 class ChildImportTests(WLTestCase):
191
192     def setUp(self):
193         WLTestCase.setUp(self)
194         self.child_info = BookInfoStub(
195             genre='X-Genre',
196             epoch='X-Epoch',
197             kind='X-Kind',
198             author=PersonStub(("Joe",), "Doe"),
199             **info_args("Child")
200         )
201
202         self.parent_info = BookInfoStub(
203             genre='X-Genre',
204             epoch='X-Epoch',
205             kind='X-Kind',
206             author=PersonStub(("Jim",), "Lazy"),
207             parts=[self.child_info.url],
208             **info_args("Parent")
209         )
210
211     def test_child_replace(self):
212         PARENT_TEXT = """<utwor />"""
213         CHILD_TEXT = """<utwor>
214         <opowiadanie>
215             <akap><begin id="m01" /><motyw id="m01">Pies</motyw>Ala ma kota<end id="m01" /></akap>
216         </opowiadanie></utwor>
217         """
218         child = models.Book.from_text_and_meta(ContentFile(CHILD_TEXT), self.child_info)
219         parent = models.Book.from_text_and_meta(ContentFile(PARENT_TEXT), self.parent_info)
220         CHILD_TEXT = """<utwor>
221         <opowiadanie>
222             <akap><begin id="m01" /><motyw id="m01">Kot</motyw>Ala ma kota<end id="m01" /></akap>
223         </opowiadanie></utwor>
224         """
225         child = models.Book.from_text_and_meta(ContentFile(CHILD_TEXT), self.child_info, overwrite=True)
226
227         themes = self.client.get(parent.get_absolute_url()).context['book_themes']
228
229         self.assertEqual(['Kot'], [tag.name for tag in themes],
230                         'wrong related theme list')