Fix for covers generation.
[redakcja.git] / src / cover / tests.py
1 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
3 #
4 import re
5 from django.core.files.uploadedfile import SimpleUploadedFile
6 from django.conf import settings
7 from django.contrib.auth.models import User
8 from django.test import TestCase, override_settings
9 from unittest import skipUnless
10 from unittest.mock import patch
11 from documents.models import Book
12 from cover.forms import ImportForm
13 from cover.models import Image
14
15
16 IMAGE_PATH = __file__.rsplit('/', 1)[0] + '/tests/angelus-novus.jpeg'
17
18 with open(__file__.rsplit('/', 1)[0] + '/tests/book.xml') as f:
19     SAMPLE_XML = f.read()
20
21
22 @skipUnless(settings.TEST_INTEGRATION, 'Skip integration tests')
23 class FlickrTests(TestCase):
24     def assertEqualWithRe(self, dict1, dict2):
25         self.assertEqual(len(dict1), len(dict2))
26         for k, v in dict2.items():
27             if isinstance(v, re.Pattern):
28                 self.assertRegex(dict1[k], v)
29             else:
30                 self.assertEqual(dict1[k], v)
31
32     def test_flickr(self):
33         form = ImportForm({
34             "source_url": "https://www.flickr.com/photos/rczajka/6941928577/in/photostream"
35         })
36         self.assertTrue(form.is_valid())
37         self.assertEqualWithRe(
38             form.cleaned_data,
39             {
40                 'source_url': "https://www.flickr.com/photos/rczajka/6941928577/",
41                 'author': "Radek Czajka@Flickr",
42                 'title': "Pirate Stańczyk",
43                 'license_name': "CC BY 2.0",
44                 'license_url': "https://creativecommons.org/licenses/by/2.0/",
45                 'download_url': re.compile(r'\.staticflickr\.com'),
46             }
47         )
48
49     def test_wikimedia_fal(self):
50         form = ImportForm({
51             "source_url": "https://commons.wikimedia.org/wiki/File:Valdai_IverskyMon_asv2018_img47.jpg"
52         })
53         self.assertTrue(form.is_valid())
54         self.assertEqual(
55             form.cleaned_data,
56             {
57                 'title': 'Valdai IverskyMon asv2018 img47',
58                 'author': 'A.Savin',
59                 'source_url': 'https://commons.wikimedia.org/wiki/File:Valdai_IverskyMon_asv2018_img47.jpg',
60                 'download_url': 'https://upload.wikimedia.org/wikipedia/commons/4/43/Valdai_IverskyMon_asv2018_img47.jpg',
61                 'license_url': 'http://artlibre.org/licence/lal/en',
62                 'license_name': 'FAL'
63             }
64         )
65
66     def test_wikimedia_public_domain(self):
67         form = ImportForm({
68             "source_url": 'https://commons.wikimedia.org/wiki/File:Pymonenko_A_boy_in_a_straw_hat.jpg'
69         })
70         self.assertTrue(form.is_valid())
71         self.assertEqual(
72             form.cleaned_data,
73             {
74                 'title': 'Chłopiec w słomkowym kapeluszu',
75                 'author': 'Mykola Pymonenko',
76                 'source_url': 'https://commons.wikimedia.org/wiki/File:Pymonenko_A_boy_in_a_straw_hat.jpg',
77                 'download_url': 'https://upload.wikimedia.org/wikipedia/commons/9/9b/Pymonenko_A_boy_in_a_straw_hat.jpg',
78                 'license_url': 'https://pl.wikipedia.org/wiki/Domena_publiczna',
79                 'license_name': 'domena publiczna'
80             }
81         )
82         
83     def test_mnw(self):
84         form = ImportForm({
85             "source_url": 'https://cyfrowe.mnw.art.pl/pl/katalog/511078'
86         })
87         self.assertTrue(form.is_valid())
88         self.assertEqualWithRe(
89             form.cleaned_data,
90             {
91                 'title': 'Chłopka (Baba ukraińska)',
92                 'author': 'Krzyżanowski, Konrad (1872-1922)',
93                 'source_url': 'https://cyfrowe.mnw.art.pl/pl/katalog/511078',
94                 'download_url': re.compile(r'https://cyfrowe-cdn\.mnw\.art\.pl/.*\.jpg'),
95                 'license_url': 'https://pl.wikipedia.org/wiki/Domena_publiczna',
96                 'license_name': 'domena publiczna'
97             }
98         )
99
100     def test_quick_import(self):
101         user = User.objects.create(username='test', is_superuser=True)
102         self.client.force_login(user)
103
104         book = Book.create(slug='test', text=SAMPLE_XML, creator=user)
105         
106         self.client.post(
107             '/cover/quick-import/1/',
108             {
109                 'url': 'https://cyfrowe.mnw.art.pl/pl/katalog/511078'
110             }
111         )
112
113         self.assertEqual(Image.objects.all().count(), 1)
114         self.assertEqual(book[0].history().count(), 2)
115         self.assertIn(
116             '<dc:relation.coverImage.attribution>Chłopka (Baba ukraińska), Krzyżanowski, Konrad (1872-1922), domena publiczna</dc:relation.coverImage.attribution>',
117             book.materialize()
118         )
119
120
121 class CoverPreviewTest(TestCase):
122     @classmethod
123     def setUpTestData(cls):
124         cls.book = Book.create(slug='test', text='<utwor/>', creator=None)
125
126     def test_preview_from_bad_xml(self):
127         response = self.client.post('/cover/preview/', data={"xml": ''})
128         self.assertEqual(response.status_code, 200)
129         self.assertEqual(response.content, b'/media/static/img/sample_cover.png')
130
131     @patch('cover.views.make_cover')
132     def test_preview_from_minimal_xml(self, make_cover):
133         response = self.client.post('/cover/preview/', data={"xml": SAMPLE_XML})
134         self.assertEqual(response.status_code, 200)
135         self.assertIn(b'/media/dynamic/cover/preview/', response.content)
136
137     def test_bad_book(self):
138         response = self.client.get('/cover/preview/test/')
139         self.assertEqual(response.status_code, 302)
140
141     @patch('cover.views.make_cover')
142     def test_good_book(self, make_cover):
143         self.book[0].commit(text=SAMPLE_XML)
144
145         response = self.client.get('/cover/preview/test/1/3/')
146         self.assertEqual(response.status_code, 404)
147
148         response = self.client.get('/cover/preview/test/1/')
149         self.assertEqual(response.status_code, 200)
150         self.assertNotIn('Content-Disposition', response)
151
152         response = self.client.get('/cover/preview/test/1/2/?download&width=100')
153         self.assertEqual(response.status_code, 200)
154         self.assertIn('attachment', response['Content-Disposition'])
155
156
157 class TestAddCover(TestCase):
158     @classmethod
159     def setUpTestData(cls):
160         cls.user = User.objects.create(username='test', is_superuser=True)
161
162     def test_add_image(self):
163         self.client.force_login(self.user)
164
165         response = self.client.get('/cover/add_image/')
166         self.assertEqual(response.status_code, 200)
167         
168         with open(IMAGE_PATH, 'rb') as image_file:
169             response = self.client.post(
170                 '/cover/add_image/',
171                 data={
172                     'title': 'Angelus Novus',
173                     'author': 'Paul Klee',
174                     'license_name': 'domena publiczna',
175                     'license_url': '',
176                     'file': image_file,
177                 }
178             )
179         self.assertEqual(Image.objects.all().count(), 1)
180
181 class TestCover(TestCase):
182     @classmethod
183     def setUpTestData(cls):
184         cls.user = User.objects.create(username='test', is_superuser=True)
185         with open(IMAGE_PATH, 'rb') as f:
186             cls.img = Image.objects.create(
187                 title='Angelus Novus',
188                 author='Paul Klee',
189                 license_name='domena publiczna',
190                 license_url='',
191                 file=SimpleUploadedFile(
192                     'angelus-novus.jpg',
193                     f.read(),
194                     content_type='image/jpeg'
195                 )
196             )
197
198     def test_image_list(self):
199         response = self.client.get('/cover/image/')
200         self.assertEqual(len(response.context['object_list']), 1)
201         
202     def test_image(self):
203         response = self.client.get('/cover/image/1/')
204         self.assertEqual(response.context['object'].title, 'Angelus Novus')
205
206     def test_edit_image(self):
207         self.client.force_login(self.user)
208         response = self.client.post('/cover/image/1/', {
209             'author': 'author',
210             'title': 'changed title',
211             'license_name': 'domena',
212             'cut_top': 1,
213             'cut_bottom': 1,
214             'cut_left': 1,
215             'cut_right': 1,
216         })
217
218         response = self.client.get('/cover/image/1/')
219         self.assertEqual(response.context['object'].title, 'changed title')
220         
221         
222     def test_image_file(self):
223         response = self.client.get('/cover/image/1/file/')
224         self.assertRegex(response['Location'], r'^/media/dynamic/cover/image/')