Commit 02fe58d8 authored by Okhin's avatar Okhin

It should works now. Lots of change so no merge yet

parent 27de6840
Pipeline #2633 failed with stages
in 28 seconds
import json import six
from rest_framework import serializers from rest_framework import serializers
from taggit_serializer.serializers import (TagListSerializerField,
TaggitSerializer)
from taggit.models import Tag
from rp.models import Article from rp.models import Article
class TagListSerializer(serializers.ModelSerializer): class ArticleTagListSerializerField(TagListSerializerField):
name = serializers.CharField(max_length=200) # We need this to fix a serializer issue:
# https://stackoverflow.com/questions/52695298/using-django-taggit-and-django-taggit-serializer-with-issue
def to_internal_value(self, value):
if isinstance(value, six.string_types):
value = value.split(',')
class Meta: if not isinstance(value, list):
model = Tag self.fail('Not a list', input_type=(value).__name__)
fields = ('name', )
for s in value:
if not isinstance(s, six.string_types):
self.fail('Not a string')
self.child.run_validation(s)
return value
def to_representation(self, value): def to_representation(self, obj):
return json.dumps({'name': value.name}) if not isinstance(obj, list):
return [tag.name for tag in obj.all()]
return obj
class ArticleSerializer(serializers.ModelSerializer): class ArticleSerializer(TaggitSerializer, serializers.ModelSerializer):
#: List of short tags to describe the article (eg. "Privacy", "Copyright") #: List of short tags to describe the article (eg. "Privacy", "Copyright")
tags = TagListSerializer(help_text=""" tags = TagListSerializerField(help_text="""
List of short tags to describe the article (eg."Privacy", "Copyright"). List of short tags to describe the article (eg."Privacy", "Copyright").
It must be a valid JSON list of items with a field named name. It must be a valid JSON list of tags.
For instance [{"name": "Privacy"}, {"name": "Copyright"}] For instance ["Privacy", "Copyright"}]
""", many=True, required=False) """, required=False)
class Meta: class Meta:
model = Article model = Article
...@@ -39,7 +51,7 @@ class ArticleSerializer(serializers.ModelSerializer): ...@@ -39,7 +51,7 @@ class ArticleSerializer(serializers.ModelSerializer):
return article return article
def update(self, instance, validated_data): def update(self, instance, validated_data):
tags = validated_data.pop("tags") tags = validated_data.pop("tags", None)
# Let's update the classic fields of the # Let's update the classic fields of the
# instance first # instance first
...@@ -47,6 +59,7 @@ class ArticleSerializer(serializers.ModelSerializer): ...@@ -47,6 +59,7 @@ class ArticleSerializer(serializers.ModelSerializer):
setattr(instance, k, v) setattr(instance, k, v)
# Let's set the tags to what's provided # Let's set the tags to what's provided
instance.tags.set(*[t.name for t in tags]) if tags:
instance.tags.set(*tags)
instance.save() instance.save()
return instance return instance
...@@ -115,5 +115,5 @@ class ArticleTag(viewsets.ModelViewSet, mixins.ListModelMixin): ...@@ -115,5 +115,5 @@ class ArticleTag(viewsets.ModelViewSet, mixins.ListModelMixin):
serializer_class = ArticleSerializer serializer_class = ArticleSerializer
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(tags__name__in=[kwargs['filter_tag']]) self.queryset = self.queryset.filter(tags__name__in=[kwargs['filter_tag']]).distinct()
return super().list(request, args, kwargs) return super().list(request, args, kwargs)
...@@ -40,4 +40,11 @@ class ArticleFactory(factory.django.DjangoModelFactory): ...@@ -40,4 +40,11 @@ class ArticleFactory(factory.django.DjangoModelFactory):
quote = choice([True, False]) quote = choice([True, False])
speak = choice([True, False]) speak = choice([True, False])
tags = factory.RelatedFactoryList(TagFactory, size=lambda: randint(1, 10)) @factory.post_generation
def tags(self, create, extracted, **kwargs):
if not create:
return
if extracted:
for tag in extracted:
self.tags.add(tag)
from random import randint
import json import json
from django.test import TestCase, Client from django.test import TestCase, Client
from django.core import serializers
from django.contrib.auth.models import User, Permission from django.contrib.auth.models import User, Permission
from rest_framework.test import APIClient from rest_framework.test import APIClient
...@@ -100,7 +102,7 @@ class TestArticle(TestCase): ...@@ -100,7 +102,7 @@ class TestArticle(TestCase):
class TestArticleViews(TestCase): class TestArticleViews(TestCase):
def setUp(self): def setUp(self):
self.client = Client() self.client = Client()
self.articles = [ArticleFactory(tags=['Tag 1', 'Tag2']) self.articles = [ArticleFactory()
for i in range(0, 2 * ArticleList.paginate_by)] for i in range(0, 2 * ArticleList.paginate_by)]
self.user = User.objects.create(username="test", self.user = User.objects.create(username="test",
email="test@example.org", email="test@example.org",
...@@ -122,9 +124,9 @@ class TestArticleViews(TestCase): ...@@ -122,9 +124,9 @@ class TestArticleViews(TestCase):
assert len(r.context['object_list']) == 0 assert len(r.context['object_list']) == 0
def test_filter_tag(self): def test_filter_tag(self):
tag = self.articles[0].tags.all()[1] tag = 'Tag 1'
r = self.client.get('/rp/by-tag/{}'.format(tag.name)) r = self.client.get('/rp/by-tag/{}'.format(tag))
if r.context['is_paginated']: if r.context['is_paginated']:
assert len(r.context['object_list']) == ArticleList.paginate_by assert len(r.context['object_list']) == ArticleList.paginate_by
else: else:
...@@ -198,20 +200,19 @@ class TestArticleViews(TestCase): ...@@ -198,20 +200,19 @@ class TestArticleViews(TestCase):
self.user.user_permissions.add(Permission.objects.get( self.user.user_permissions.add(Permission.objects.get(
codename='can_edit')) codename='can_edit'))
self.client.force_login(user=self.user) self.client.force_login(user=self.user)
a = self.articles[0]
a.title = 'Zog Zog' a = json.loads(serializers.serialize('json', [self.articles[0]]))[0]
a.screenshot = '/tmp/{}.png'.format(a.pk) a['fields']['title'] = 'Zog Zog'
r = self.client.post('/rp/article/edit/{}'.format(a.pk), r = self.client.post('/rp/article/edit/{}/'.format(a['pk']), a['fields'])
a.__dict__) a = Article.objects.get(pk=a['pk'])
a.refresh_from_db() assert r.status_code == 302 # We're redirecting after edit
assert r.status_code == 302
assert a.title == 'Zog Zog' assert a.title == 'Zog Zog'
class TestArticleApi(TestCase): class TestArticleApi(TestCase):
def setUp(self): def setUp(self):
self.client = APIClient() self.client = APIClient()
self.articles = [ArticleFactory(tags=['Tag 1', 'Tag2']) self.articles = [ArticleFactory(tags=["Tag {}".format(n) for n in range(randint(1, 10))])
for i in range(0, 2 * ArticleList.paginate_by)] for i in range(0, 2 * ArticleList.paginate_by)]
self.user = User.objects.create(username="test", self.user = User.objects.create(username="test",
email="test@example.org", email="test@example.org",
...@@ -219,6 +220,7 @@ class TestArticleApi(TestCase): ...@@ -219,6 +220,7 @@ class TestArticleApi(TestCase):
self.jedi = User.objects.create(username="obiwan", self.jedi = User.objects.create(username="obiwan",
email="o.kennoby@example.org", email="o.kennoby@example.org",
password="Thisaintthedroidyourelookin") password="Thisaintthedroidyourelookin")
for a in self.articles: for a in self.articles:
a.save() a.save()
...@@ -240,21 +242,39 @@ class TestArticleApi(TestCase): ...@@ -240,21 +242,39 @@ class TestArticleApi(TestCase):
a = self.articles[0] a = self.articles[0]
a.title = 'Zog Zog' a.title = 'Zog Zog'
a.screenshot = "test.png" a.screenshot = "test.png"
r = self.client.put('/api/articles/{}/'.format(a.pk), a.__dict__) r = self.client.put('/api/articles/{}/'.format(a.pk),
a.__dict__)
assert r.status_code == 200 assert r.status_code == 200
a.refresh_from_db() a.refresh_from_db()
assert a.title == 'Zog Zog' assert a.title == 'Zog Zog'
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)
a = json.loads(serializers.serialize('json', [self.articles[0]]))[0]
a['fields']['tags'] = ['Tag 3']
a['fields']['screenshot'] = "test.png"
r = self.client.put('/api/articles/{}/'.format(a['pk']),
a['fields'],
format='json')
assert r.status_code == 200
a = Article.objects.get(pk=a['pk'])
assert list(a.tags.values('name',)) == [{'name': 'Tag 3'}]
def test_api_filter_tag(self): def test_api_filter_tag(self):
tag = self.articles[0].tags.all()[1] tag = 'Tag 1'
tagged = Article.objects.filter(tags__name__in=[tag]).count()
# All articles have Tag2 as a tag r = self.client.get('/api/articles-by-tag/{}/'.format(tag))
r = self.client.get('/api/articles-by-tag/{}/'.format(tag.name))
assert r.status_code == 200 assert r.status_code == 200
assert r.data['count'] == 2 * ArticleList.paginate_by assert r.data['count'] == tagged
# Case sensitivity checking - tags are sensitive to case # Case sensitivity checking - tags are sensitive to case
r = self.client.get('/api/articles-by-tag/{}/'.format(tag.name.lower())) r = self.client.get('/api/articles-by-tag/{}/'.format(tag.upper()))
assert r.status_code == 200 assert r.status_code == 200
assert r.data['count'] == 0 assert r.data['count'] == 0
...@@ -264,7 +284,6 @@ class TestArticleApi(TestCase): ...@@ -264,7 +284,6 @@ class TestArticleApi(TestCase):
assert r.data['count'] == 0 assert r.data['count'] == 0
def test_api_filter_search(self): def test_api_filter_search(self):
# text = ' '.join(self.articles[0].extracts.split(' ')[:10])
text = self.articles[0].title text = self.articles[0].title
r = self.client.get('/api/articles/', {'q': text}) r = self.client.get('/api/articles/', {'q': text})
assert r.status_code == 200 assert r.status_code == 200
...@@ -280,26 +299,25 @@ class TestArticleApi(TestCase): ...@@ -280,26 +299,25 @@ class TestArticleApi(TestCase):
a = ArticleFactory(tags=['ZogZog'],) a = ArticleFactory(tags=['ZogZog'],)
r = self.client.post('/api/articles/', r = self.client.post('/api/articles/',
{'url': a.url, 'title': a.title, {'url': a.url, 'title': a.title,
'tags': a.tags.all().values('name')}, 'tags': [t.name for t in a.tags.all()]},
format='json') format='json')
assert r.status_code == 401 assert r.status_code == 401
def test_api_tag_push_auth(self): def test_api_tag_push_auth(self):
self.client.force_login(user=self.user) self.client.force_login(user=self.user)
a = ArticleFactory(tags=['ZogZog', 'Blip Blop'], status='NEW') a = ArticleFactory(status='NEW')
r = self.client.post('/api/articles/', r = self.client.post('/api/articles/',
{'url': a.url, 'title': a.title, {'url': a.url, 'title': a.title,
'tags': a.tags.all().values('name')}, 'tags': a.tags.all()},
format='json') format='json')
assert r.status_code == 201 assert r.status_code == 201
assert list(a.tags.all().values('name')) == [json.loads(t) for t in r.data['tags']] assert list(a.tags.all()) == r.data['tags']
# Need to test if we keep the tags # Need to test if we keep the tags
r = self.client.post('/api/articles/', r = self.client.post('/api/articles/',
{'url': a.url, 'title': a.title, {'url': a.url, 'title': a.title},
},
format='json') format='json')
assert list(a.tags.all().values('name')) == [json.loads(t) for t in r.data['tags']] assert list(a.tags.all()) == r.data['tags']
def test_api_recover(self): def test_api_recover(self):
# Can we recover if we're no Jedis # Can we recover if we're no Jedis
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment