test_article.py 14.9 KB
Newer Older
1
from random import randint
2 3
import json

4
from django.test import TestCase, Client
5
from django.core import serializers
6
from django.contrib.auth.models import User, Permission
Okhin's avatar
Okhin committed
7
from rest_framework.test import APIClient
luxcem's avatar
luxcem committed
8

luxcem's avatar
luxcem committed
9 10 11
from rp.models import Article
from rp.factories import ArticleFactory
from rp.apps import RpConfig
12
from rp.views.articles import ArticleList
luxcem's avatar
luxcem committed
13 14


15
class TestArticle(TestCase):
luxcem's avatar
luxcem committed
16
    def setUp(self):
17
        self.article = ArticleFactory(archive=False, quote=False, speak=False)
18 19 20 21
        self.newarticle = ArticleFactory(status='NEW',
                                         archive=False,
                                         quote=False,
                                         speak=False)
luxcem's avatar
luxcem committed
22

luxcem's avatar
luxcem committed
23 24
    def test_init(self):
        assert RpConfig.name == "rp"
luxcem's avatar
luxcem committed
25

luxcem's avatar
luxcem committed
26 27
    def test_article(self):
        assert type(self.article) == Article
luxcem's avatar
luxcem committed
28
        assert str(self.article) == self.article.title
29

30 31 32 33 34 35 36 37 38
    def test_recover(self):
        article = ArticleFactory(status='NEW')
        article.recover()
        assert article.status == 'DRAFT'

        article = ArticleFactory(status='REJECTED')
        article.recover()
        assert article.status == 'DRAFT'

39 40 41 42 43
    def test_add_new_url(self):
        article = Article.add_new_url(url='https://www.example.org/article')
        assert article.status == 'NEW'
        assert article.score == 1

44 45
        article2 = Article.add_new_url(url='https://www.example.org/article',
                                       tags=["Tag 1", "Tag 2"])
46 47
        assert article2.status == 'NEW'
        assert article2.score == 2
48 49 50 51
        assert set(article2.tags.names()) == {"Tag 1", "Tag 2"}

        article3 = Article.add_new_url(url='https://www.example.org/article', 
                                       tags=["Merged Tag"])
52

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
    def test_flags(self):
        assert not self.article.archive
        assert not self.article.quote
        assert not self.article.speak

    def test_toggle_flags(self):
        self.newarticle.toggle_archive()
        assert self.newarticle.archive
        self.newarticle.toggle_archive()
        assert not self.newarticle.archive

        self.newarticle.toggle_quote()
        assert self.newarticle.quote
        self.newarticle.toggle_quote()
        assert not self.newarticle.quote

        self.newarticle.toggle_speak()
        assert self.newarticle.speak
        self.newarticle.toggle_speak()
        assert not self.newarticle.speak

    def test_set_flags(self):
        # Method signature is set_flags(boolean: archive = False,
        #                               boolean: speak = False,
        #                               boolean: quote = False)
        # All falsg set to their default values
        self.newarticle.set_flags()
        assert not self.newarticle.archive
        assert not self.newarticle.speak
        assert not self.newarticle.quote

        self.newarticle.set_flags(speak=True)
        assert not self.newarticle.archive
        assert self.newarticle.speak
        assert not self.newarticle.quote

        self.newarticle.set_flags(quote=True)
        assert not self.newarticle.archive
        assert not self.newarticle.speak
        assert self.newarticle.quote

        self.newarticle.set_flags(quote=True, speak=True)
        assert not self.newarticle.archive
        assert self.newarticle.speak
        assert self.newarticle.quote

Okhin's avatar
Okhin committed
99 100 101 102 103 104 105
    def test_update(self):
        old_title = self.article.title
        self.article.title = old_title[::-1]
        self.article.save()
        self.article.refresh_from_db()
        assert self.article.title != old_title

Okhin's avatar
Okhin committed
106 107 108 109 110
    def test_unpublish(self):
        a = ArticleFactory(status='PUBLISHED')
        a.unpublish()
        assert a.status == 'DRAFT'

111

112 113 114
class TestArticleViews(TestCase):
    def setUp(self):
        self.client = Client()
115
        self.articles = [ArticleFactory()
Okhin's avatar
Okhin committed
116 117 118 119
                         for i in range(0, 2 * ArticleList.paginate_by)]
        self.user = User.objects.create(username="test",
                                        email="test@example.org",
                                        password="test")
120 121 122 123 124 125 126 127 128 129 130
        for a in self.articles:
            a.save()

    def test_list_fr(self):
        # ArticleFactory use english by default, so we should have
        # no objects
        r = self.client.get('/rp/')
        assert len(r.context['object_list']) == 0

    def test_list_en(self):
        r = self.client.get('/rp/international')
131 132 133 134
        if r.context['is_paginated']:
            assert len(r.context['object_list']) == ArticleList.paginate_by
        else:
            assert len(r.context['object_list']) == 0
135 136

    def test_filter_tag(self):
137
        tag = 'Tag 1'
138

139
        r = self.client.get('/rp/by-tag/{}'.format(tag))
140 141 142 143
        if r.context['is_paginated']:
            assert len(r.context['object_list']) == ArticleList.paginate_by
        else:
            assert len(r.context['object_list']) == 0
144 145 146 147
        r = self.client.get('/rp/by-tag/zogzog')
        assert len(r.context['object_list']) == 0

    def test_search_view(self):
148
        article = ArticleFactory(title=u'Zog Zog chez les schtroumphs',
Okhin's avatar
Okhin committed
149 150 151
                                 lang='FR',
                                 archive=False,
                                 status='PUBLISHED')
152 153 154 155 156 157 158
        article.save()

        r = self.client.get('/rp/', {'q': 'Zog Zog'})
        assert len(r.context['article_list']) == 1
        r = self.client.get('/rp/', {'q': 'Gargamel was here'})
        assert len(r.context['article_list']) == 0

159
    def test_search_view_archived(self):
Okhin's avatar
Okhin committed
160 161 162
        archive = ArticleFactory(archive=True,
                                 lang='FR',
                                 status='PUBLISHED')
163 164 165 166 167 168 169 170

        r = self.client.get('/rp/', {'q': '', 'archive': 'true'})
        assert len(r.context['article_list']) == 1
        assert r.context['article_list'][0] == archive

        r = self.client.get('/rp/', {'archive': 'false'})
        assert len(r.context['article_list']) == 0

171
    def test_search_view_speaks(self):
Okhin's avatar
Okhin committed
172 173 174 175
        speak = ArticleFactory(speak=True,
                               archive=False,
                               lang='FR',
                               status='PUBLISHED')
176 177 178 179 180 181 182 183 184

        r = self.client.get('/rp/', {'q': '', 'speak': 'true'})
        assert len(r.context['article_list']) == 1
        assert r.context['article_list'][0] == speak

        r = self.client.get('/rp/', {'speak': 'false'})
        assert len(r.context['article_list']) == 0

    def test_search_view_quoted(self):
Okhin's avatar
Okhin committed
185 186 187 188
        quote = ArticleFactory(quote=True,
                               archive=False,
                               lang='FR',
                               status='PUBLISHED')
189 190 191 192 193 194 195 196

        r = self.client.get('/rp/', {'q': '', 'quote': 'true'})
        assert len(r.context['article_list']) == 1
        assert r.context['article_list'][0] == quote

        r = self.client.get('/rp/', {'quote': 'false'})
        assert len(r.context['article_list']) == 0

197 198 199 200 201 202
    def test_detail_view(self):
        # Let's find a published article
        self.client.force_login(user=self.user)
        a = self.articles[0]
        r = self.client.get('/rp/article/view/{}'.format(a.pk))
        assert r.context['object'] == a
Okhin's avatar
Okhin committed
203

Okhin's avatar
Okhin committed
204 205 206 207 208 209 210 211 212
    def test_article_edit_unauth(self):
        a = self.articles[0]
        r = self.client.post('/rp/article/edit/{}'.format(a.pk))
        assert r.status_code == 403

    def test_article_edit(self):
        self.user.user_permissions.add(Permission.objects.get(
            codename='can_edit'))
        self.client.force_login(user=self.user)
213

Okhin's avatar
Okhin committed
214
        pk = self.articles[0].pk
215 216 217
        a = {'title': 'Zog Zog',
             'status': 'NEW',
             'lang': 'FR',
218 219
             'url': 'https://www.example.org/',
             'tags': ["Merged Tag"]}
220
        r = self.client.post('/rp/article/edit/{}/'.format(pk), a)
Okhin's avatar
Okhin committed
221
        a = Article.objects.get(pk=pk)
222
        assert r.status_code == 302  # We're redirecting to the view or preview of the article
Okhin's avatar
Okhin committed
223
        assert a.title == 'Zog Zog'
224
        assert set(a.tags.names()) == set(self.articles[0].tags.names()) | {"merged tag"}
Okhin's avatar
Okhin committed
225

Okhin's avatar
Okhin committed
226 227 228 229

class TestArticleApi(TestCase):
    def setUp(self):
        self.client = APIClient()
230
        self.articles = [ArticleFactory(tags=["Tag {}".format(n) for n in range(randint(1, 10))])
Okhin's avatar
Okhin committed
231 232 233 234
                         for i in range(0, 2 * ArticleList.paginate_by)]
        self.user = User.objects.create(username="test",
                                        email="test@example.org",
                                        password="test")
235 236 237
        self.jedi = User.objects.create(username="obiwan",
                                        email="o.kennoby@example.org",
                                        password="Thisaintthedroidyourelookin")
238

Okhin's avatar
Okhin committed
239 240 241 242 243 244 245 246 247 248 249 250 251
        for a in self.articles:
            a.save()

    def test_api_get(self):
        r = self.client.get('/api/articles/1/', {})
        assert r.status_code == 200
        assert r.data['id'] == 1

    def test_api_list(self):
        r = self.client.get('/api/articles/', {})
        assert r.status_code == 200
        assert r.data['count'] == 2 * ArticleList.paginate_by

252 253 254 255 256
    def test_api_edit(self):
        self.user.user_permissions.add(Permission.objects.get(
            codename='can_edit'))
        self.client.force_login(user=self.user)

Okhin's avatar
Okhin committed
257 258 259 260
        pk = self.articles[0].pk
        article = {'title': 'Zog Zog',
                   'url': 'https://article.org/Zog+Zog'}
        r = self.client.put('/api/articles/{}/'.format(pk),
261 262
                            article,
                            format='json')
263

264
        assert r.status_code == 200
Okhin's avatar
Okhin committed
265
        assert Article.objects.get(pk=pk).title == 'Zog Zog'
266

267 268 269 270 271 272
    def test_api_edit_tags(self):
        # Checking that we indeed change the tags
        self.user.user_permissions.add(Permission.objects.get(
            codename='can_edit'))
        self.client.force_login(user=self.user)

Okhin's avatar
Okhin committed
273 274 275 276 277 278
        pk = self.articles[0].pk
        article = {'title': 'Zog Zog',
                   'url': 'https://article.org/Zog+Zog',
                   'tags': '["New Tag 1", "New Tag 2"]'}
        r = self.client.put('/api/articles/{}/'.format(pk),
                            article,
279 280
                            format='json')
        assert r.status_code == 200
Okhin's avatar
Okhin committed
281 282
        a = Article.objects.get(pk=pk)
        assert list(a.tags.values('name',).order_by('name')) == [{'name': 'New Tag 1'},
283
                                                                 {'name': 'New Tag 2'}]
284

Okhin's avatar
Okhin committed
285
    def test_api_filter_tag(self):
286 287
        tag = 'Tag 1'
        tagged = Article.objects.filter(tags__name__in=[tag]).count()
Okhin's avatar
Okhin committed
288

289
        r = self.client.get('/api/articles-by-tag/{}/'.format(tag))
Okhin's avatar
Okhin committed
290
        assert r.status_code == 200
291
        assert r.data['count'] == tagged
Okhin's avatar
Okhin committed
292 293

        # Case sensitivity checking - tags are sensitive to case
294
        r = self.client.get('/api/articles-by-tag/{}/'.format(tag.upper()))
Okhin's avatar
Okhin committed
295 296 297 298 299 300 301 302 303
        assert r.status_code == 200
        assert r.data['count'] == 0

        # No article should have the ZogZog tag
        r = self.client.get('/api/articles-by-tag/zogzog/')
        assert r.status_code == 200
        assert r.data['count'] == 0

    def test_api_filter_search(self):
304
        text = self.articles[0].title
305
        r = self.client.get('/api/articles/', {'q': text})
Okhin's avatar
Okhin committed
306 307 308
        assert r.status_code == 200
        assert r.data['count'] == 1
        assert r.data['results'][0]['id'] == self.articles[0].id
309

310 311 312 313 314
    def test_api_filter_flag_search(self):
        r = self.client.get('/api/articles/', {'quote': 'both'})
        assert r.status_code == 200
        assert r.data['count'] == len(self.articles)

315
    def test_api_tag_push_unauth(self):
Okhin's avatar
Okhin committed
316
        a = ArticleFactory()
317 318
        r = self.client.post('/api/articles/',
                             {'url': a.url, 'title': a.title,
Okhin's avatar
Okhin committed
319
                              'tags': '["Tag 1", "Tag 2"]'},
320
                             format='json')
321 322 323 324
        assert r.status_code == 401

    def test_api_tag_push_auth(self):
        self.client.force_login(user=self.user)
325
        a = ArticleFactory(status='NEW')
326 327
        r = self.client.post('/api/articles/',
                             {'url': a.url, 'title': a.title,
328
                              'tags': a.tags.all()},
329
                             format='json')
330
        assert r.status_code == 201
331
        assert list(a.tags.all()) == r.data['tags']
332 333 334

        # Need to test if we keep the tags
        r = self.client.post('/api/articles/',
335
                             {'url': a.url, 'title': a.title},
Okhin's avatar
Okhin committed
336
                             format='json')
337
        assert list(a.tags.all()) == r.data['tags']
338 339 340 341 342 343 344 345

    def test_api_recover(self):
        # Can we recover if we're no Jedis
        self.client.force_login(user=self.user)
        a = ArticleFactory(status='NEW')
        r = self.client.post('/api/articles/{}/recover/'.format(a.id))
        assert r.status_code == 403

Okhin's avatar
Okhin committed
346
        # Can we recover a NEW article and force it to DRAFT?
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
        self.user.user_permissions.add(Permission.objects.get(
            codename='can_change_status'))
        self.client.force_login(user=self.user)
        a = ArticleFactory(status='NEW')
        r = self.client.post('/api/articles/{}/recover/'.format(a.id))
        assert r.status_code == 200
        assert r.data['status'] == 'DRAFT'

        # Can we recovr a REJECTED article and force it to DRAFT?
        a = ArticleFactory(status='REJECTED')
        r = self.client.post('/api/articles/{}/recover/'.format(a.id))
        assert r.status_code == 200
        assert r.data['status'] == 'DRAFT'

        # We cannot recover a published article
        a = ArticleFactory(status='PUBLISHED')
        r = self.client.post('/api/articles/{}/recover/'.format(a.id))
364
        assert r.status_code == 400
365 366 367 368 369 370 371

    def test_api_set_priority(self):
        self.user.user_permissions.add(Permission.objects.get(
            codename='can_change_priority'))
        self.client.force_login(user=self.user)
        a = ArticleFactory(status='DRAFT')
        assert a.priority is False
372
        r = self.client.post('/api/articles/{}/set-priority/'.format(a.id))
373 374 375 376 377 378 379 380 381
        assert r.status_code == 200
        assert r.data['priority']

    def test_api_unset_priority(self):
        self.user.user_permissions.add(Permission.objects.get(
            codename='can_change_priority'))
        self.client.force_login(user=self.user)
        a = ArticleFactory(status='DRAFT', priority=True)
        assert a.priority
382
        r = self.client.post('/api/articles/{}/unset-priority/'.format(a.id))
383 384
        assert r.status_code == 200
        assert r.data['priority'] is False
Okhin's avatar
Okhin committed
385 386 387 388 389 390 391 392 393 394 395 396 397 398

    def test_api_unpublish_unauth(self):
        a = ArticleFactory(status='PUBLISHED')
        r = self.client.post('/api/articles/{}/unpublish/'.format(a.id))
        assert r.status_code == 401

    def test_api_unpublish(self):
        self.jedi.user_permissions.add(Permission.objects.get(
            codename='can_change_status'))
        self.client.force_login(self.jedi)
        a = ArticleFactory(status='PUBLISHED')
        r = self.client.post('/api/articles/{}/unpublish/'.format(a.id))
        assert r.status_code == 200
        assert r.data['status'] == 'DRAFT'