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