update tests
[wolnelektury.git] / apps / catalogue / tests / tags.py
1 # -*- coding: utf-8 -*-
2 from django.core.files.base import ContentFile
3 from django.test import Client
4 from catalogue import models
5 from catalogue.test_utils import *
6
7
8 class BooksByTagTests(WLTestCase):
9     """ tests the /katalog/category/tag page for found books """
10
11     def setUp(self):
12         WLTestCase.setUp(self)
13         author = PersonStub(("Common",), "Man")
14
15         # grandchild
16         self.gchild_info = BookInfoStub(genre='Genre', epoch='Epoch', kind='Kind', author=author,
17                                         **info_args("GChild"))
18         # child
19         self.child_info = BookInfoStub(genre='Genre', epoch='Epoch', kind='Other Kind', author=author,
20                                        parts=[self.gchild_info.url],
21                                        **info_args("Child"))
22         # parent
23         self.parent_info = BookInfoStub(genre='Genre', epoch='Epoch', kind='Kind', author=author,
24                                         parts=[self.child_info.url],
25                                         **info_args("Parent"))
26
27         self.book_file = ContentFile('<utwor />')
28
29     def test_nonexistent_tag(self):
30         """ Looking for a non-existent tag should yield 404 """
31         # NOTE: this yields a false positive, 'cause of URL change
32         self.assertEqual(404, self.client.get('/katalog/autor/czeslaw_milosz/').status_code)
33
34     def test_book_tag(self):
35         """ Looking for a book tag isn't permitted """
36         models.Book.from_text_and_meta(self.book_file, self.gchild_info)
37         self.assertEqual(404, self.client.get('/katalog/gchild/').status_code)
38
39     def test_tag_empty(self):
40         """ Tag with no books should return no books """
41         models.Book.from_text_and_meta(self.book_file, self.gchild_info)
42         models.Tag.objects.create(name='Empty tag', slug='empty', category='author')
43
44         context = self.client.get('/katalog/autor/empty/').context
45         self.assertEqual(0, len(context['object_list']))
46
47     def test_tag_eliminate(self):
48         """ Filtering by tag should only yield top-level qualifying books. """
49         for info in self.gchild_info, self.child_info, self.parent_info:
50             models.Book.from_text_and_meta(self.book_file, info)
51
52         # all three qualify
53         context = self.client.get('/katalog/gatunek/genre/').context
54         self.assertEqual([book.title for book in context['object_list']],
55                          ['Parent'])
56
57         # parent and gchild qualify, child doesn't
58         context = self.client.get('/katalog/rodzaj/kind/').context
59         self.assertEqual([book.title for book in context['object_list']],
60                          ['Parent'])
61
62         # Filtering by child's tag should yield the child
63         context = self.client.get('/katalog/rodzaj/other-kind/').context
64         self.assertEqual([book.title for book in context['object_list']],
65                          ['Child'])
66
67
68 class TagRelatedTagsTests(WLTestCase):
69     """ tests the /katalog/category/tag/ page for related tags """
70
71     def setUp(self):
72         WLTestCase.setUp(self)
73         self.client = Client()
74         author = PersonStub(("Common",), "Man")
75
76         gchild_info = BookInfoStub(author=author, genre="GchildGenre", epoch='Epoch', kind="Kind",
77                                    **info_args(u"GChild"))
78         child1_info = BookInfoStub(author=author, genre="ChildGenre", epoch='Epoch', kind="ChildKind",
79                                    parts=[gchild_info.url],
80                                    **info_args(u"Child1"))
81         child2_info = BookInfoStub(author=author, genre="ChildGenre", epoch='Epoch', kind="ChildKind",
82                                    **info_args(u"Child2"))
83         parent_info = BookInfoStub(author=author, genre="Genre", epoch='Epoch', kind="Kind",
84                                    parts=[child1_info.url, child2_info.url],
85                                    **info_args(u"Parent"))
86
87         for info in gchild_info, child1_info, child2_info, parent_info:
88             book_text = """<utwor><opowiadanie><akap>
89                 <begin id="m01" />
90                     <motyw id="m01">Theme, %sTheme</motyw>
91                     Ala ma kota
92                 <end id="m01" />
93                 </akap></opowiadanie></utwor>
94                 """ % info.title.encode('utf-8')
95             book = models.Book.from_text_and_meta(ContentFile(book_text), info)
96             book.save()
97
98         tag_empty = models.Tag(name='Empty tag', slug='empty', category='author')
99         tag_empty.save()
100
101     def test_empty(self):
102         """ empty tag should have no related tags """
103
104         cats = self.client.get('/katalog/autor/empty/').context['categories']
105         self.assertEqual(cats, {}, 'tags related to empty tag')
106
107     def test_has_related(self):
108         """ related own and descendants' tags should be generated """
109
110         cats = self.client.get('/katalog/rodzaj/kind/').context['categories']
111         self.assertTrue('Common Man' in [tag.name for tag in cats['author']],
112                         'missing `author` related tag')
113         self.assertTrue('Epoch' in [tag.name for tag in cats['epoch']],
114                         'missing `epoch` related tag')
115         self.assertTrue("ChildKind" in [tag.name for tag in cats['kind']],
116                         "missing `kind` related tag")
117         self.assertTrue("Genre" in [tag.name for tag in cats['genre']],
118                         'missing `genre` related tag')
119         self.assertTrue("ChildGenre" in [tag.name for tag in cats['genre']],
120                         "missing child's related tag")
121         self.assertTrue("GchildGenre" in [tag.name for tag in cats['genre']],
122                         "missing grandchild's related tag")
123         self.assertTrue('Theme' in [tag.name for tag in cats['theme']],
124                         "missing related theme")
125         self.assertTrue('Child1Theme' in [tag.name for tag in cats['theme']],
126                         "missing child's related theme")
127         self.assertTrue('GChildTheme' in [tag.name for tag in cats['theme']],
128                         "missing grandchild's related theme")
129
130
131     def test_related_differ(self):
132         """ related tags shouldn't include filtering tags """
133
134         response = self.client.get('/katalog/rodzaj/kind/')
135         cats = response.context['categories']
136         self.assertFalse('Kind' in [tag.name for tag in cats['kind']],
137                          'filtering tag wrongly included in related')
138         cats = self.client.get('/katalog/motyw/theme/').context['categories']
139         self.assertFalse('Theme' in [tag.name for tag in cats['theme']],
140                          'filtering theme wrongly included in related')
141
142     def test_parent_tag_once(self):
143         """ if parent and descendants have a common tag, count it only once """
144
145         cats = self.client.get('/katalog/rodzaj/kind/').context['categories']
146         self.assertEqual([(tag.name, tag.count) for tag in cats['epoch']],
147                          [('Epoch', 1)],
148                          'wrong related tag epoch tag on tag page')
149
150
151     def test_siblings_tags_count(self):
152         """ if children have tags and parent hasn't, count the children """
153
154         cats = self.client.get('/katalog/epoka/epoch/').context['categories']
155         self.assertTrue(('ChildKind', 2) in [(tag.name, tag.count) for tag in cats['kind']],
156                     'wrong related kind tags on tag page')
157
158         # all occurencies of theme should be counted
159         self.assertTrue(('Theme', 4) in [(tag.name, tag.count) for tag in cats['theme']],
160                     'wrong related theme count')
161
162
163 class CleanTagRelationTests(WLTestCase):
164     """ tests for tag relations cleaning after deleting things """
165
166     def setUp(self):
167         WLTestCase.setUp(self)
168         author = PersonStub(("Common",), "Man")
169
170         book_info = BookInfoStub(author=author, genre="G", epoch='E', kind="K",
171                                    **info_args(u"Book"))
172         book_text = """<utwor><opowiadanie><akap>
173             <begin id="m01" /><motyw id="m01">Theme</motyw>Ala ma kota
174             <end id="m01" />
175             </akap></opowiadanie></utwor>
176             """
177         self.book = models.Book.from_text_and_meta(ContentFile(book_text), book_info)
178
179     def test_delete_objects(self):
180         """ there should be no related tags left after deleting some objects """
181
182         models.Book.objects.all().delete()
183         cats = self.client.get('/katalog/rodzaj/k/').context['categories']
184         self.assertEqual(cats, {})
185         self.assertEqual(models.Fragment.objects.all().count(), 0,
186                          "orphaned fragments left")
187         self.assertEqual(models.Tag.intermediary_table_model.objects.all().count(), 0,
188                          "orphaned TagRelation objects left")
189
190     def test_deleted_tag(self):
191         """ there should be no tag relations left after deleting tags """
192
193         models.Tag.objects.all().delete()
194         self.assertEqual(len(self.book.related_info()['tags']), 0)
195         self.assertEqual(len(self.book.related_themes()), 0)
196         self.assertEqual(models.Tag.intermediary_table_model.objects.all().count(), 0,
197                          "orphaned TagRelation objects left")
198
199
200 class TestIdenticalTag(WLTestCase):
201
202     def setUp(self):
203         WLTestCase.setUp(self)
204         author = PersonStub((), "Tag")
205
206         self.book_info = BookInfoStub(author=author,
207                                  genre="tag",
208                                  epoch='tag',
209                                  kind="tag",
210                                    **info_args(u"tag"))
211         self.book_text = """<utwor>
212             <opowiadanie>
213             <akap>
214                 <begin id="m01" /><motyw id="m01">tag</motyw>Ala ma kota<end id="m01" />
215             </akap>
216             </opowiadanie>
217             </utwor>
218         """
219
220
221     def test_book_tags(self):
222         """ there should be all related tags in relevant categories """
223         book = models.Book.from_text_and_meta(ContentFile(self.book_text), self.book_info)
224
225         related_info = book.related_info()
226         related_themes = book.related_themes()
227         for category in 'author', 'kind', 'genre', 'epoch':
228             self.assertTrue('tag' in [tag[1] for tag in related_info['tags'][category]],
229                             'missing related tag for %s' % category)
230         self.assertTrue('tag' in [tag.slug for tag in related_themes])
231
232     def test_qualified_url(self):
233         models.Book.from_text_and_meta(ContentFile(self.book_text), self.book_info)
234         categories = {'author': 'autor', 'theme': 'motyw', 'epoch': 'epoka', 'kind':'rodzaj', 'genre':'gatunek'}
235         for cat, localcat in categories.iteritems():
236             context = self.client.get('/katalog/%s/tag/' % localcat).context
237             self.assertEqual(1, len(context['object_list']))
238             self.assertNotEqual({}, context['categories'])
239             self.assertFalse(cat in context['categories'])
240
241
242 class BookTagsTests(WLTestCase):
243     """ tests the /katalog/lektura/book/ page for related tags """
244
245     def setUp(self):
246         WLTestCase.setUp(self)
247         author1 = PersonStub(("Common",), "Man")
248         author2 = PersonStub(("Jim",), "Lazy")
249
250         child_info = BookInfoStub(authors=(author1, author2), genre="ChildGenre", epoch='Epoch', kind="ChildKind",
251                                    **info_args(u"Child"))
252         parent_info = BookInfoStub(author=author1, genre="Genre", epoch='Epoch', kind="Kind",
253                                    parts=[child_info.url],
254                                    **info_args(u"Parent"))
255
256         for info in child_info, parent_info:
257             book_text = """<utwor><opowiadanie><akap>
258                 <begin id="m01" />
259                     <motyw id="m01">Theme, %sTheme</motyw>
260                     Ala ma kota
261                 <end id="m01" />
262                 </akap></opowiadanie></utwor>
263                 """ % info.title.encode('utf-8')
264             models.Book.from_text_and_meta(ContentFile(book_text), info)
265
266     def test_book_tags(self):
267         """ book should have own tags and whole tree's themes """
268
269         book = models.Book.objects.get(slug='parent')
270         related_info = book.related_info()
271         related_themes = book.related_themes()
272
273         self.assertEqual(related_info['tags']['author'],
274                          [('Common Man', 'common-man')])
275         self.assertEqual(related_info['tags']['kind'],
276                          [('Kind', 'kind')])
277         self.assertEqual([(tag.name, tag.count) for tag in related_themes],
278                          [('ChildTheme', 1), ('ParentTheme', 1), ('Theme', 2)])
279
280     def test_main_page_tags(self):
281         """ test main page tags and counts """
282         from catalogue.templatetags.catalogue_tags import catalogue_menu
283         menu = catalogue_menu()
284         self.assertEqual([(tag.name, tag.book_count) for tag in menu['author']],
285                          [('Jim Lazy', 1), ('Common Man', 1)])
286         self.assertEqual([(tag.name, tag.book_count) for tag in menu['theme']],
287                          [('ChildTheme', 1), ('ParentTheme', 1), ('Theme', 2)])
288