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 taggit_serializer.serializers import (TagListSerializerField,
TaggitSerializer)
from taggit.models import Tag
from rp.models import Article
class TagListSerializer(serializers.ModelSerializer):
name = serializers.CharField(max_length=200)
class ArticleTagListSerializerField(TagListSerializerField):
# 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:
model = Tag
fields = ('name', )
if not isinstance(value, list):
self.fail('Not a list', input_type=(value).__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):
return json.dumps({'name': value.name})
def to_representation(self, obj):
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")
tags = TagListSerializer(help_text="""
tags = TagListSerializerField(help_text="""
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"}]
""", many=True, required=False)
For instance ["Privacy", "Copyright"}]
""", required=False)
class Meta:
model = Article
......@@ -39,7 +51,7 @@ class ArticleSerializer(serializers.ModelSerializer):
return article
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
# instance first
......@@ -47,6 +59,7 @@ class ArticleSerializer(serializers.ModelSerializer):
setattr(instance, k, v)
# 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()
return instance
......@@ -115,5 +115,5 @@ class ArticleTag(viewsets.ModelViewSet, mixins.ListModelMixin):
serializer_class = ArticleSerializer
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)
......@@ -40,4 +40,11 @@ class ArticleFactory(factory.django.DjangoModelFactory):
quote = 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
from django.test import TestCase, Client
from django.core import serializers
from django.contrib.auth.models import User, Permission
from rest_framework.test import APIClient
......@@ -100,7 +102,7 @@ class TestArticle(TestCase):
class TestArticleViews(TestCase):
def setUp(self):
self.client = Client()
self.articles = [ArticleFactory(tags=['Tag 1', 'Tag2'])
self.articles = [ArticleFactory()
for i in range(0, 2 * ArticleList.paginate_by)]
self.user = User.objects.create(username="test",
email="test@example.org",
......@@ -122,9 +124,9 @@ class TestArticleViews(TestCase):
assert len(r.context['object_list']) == 0
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']:
assert len(r.context['object_list']) == ArticleList.paginate_by
else:
......@@ -198,20 +200,19 @@ class TestArticleViews(TestCase):
self.user.user_permissions.add(Permission.objects.get(
codename='can_edit'))
self.client.force_login(user=self.user)
a = self.articles[0]
a.title = 'Zog Zog'
a.screenshot = '/tmp/{}.png'.format(a.pk)
r = self.client.post('/rp/article/edit/{}'.format(a.pk),
a.__dict__)
a.refresh_from_db()
assert r.status_code == 302
a = json.loads(serializers.serialize('json', [self.articles[0]]))[0]
a['fields']['title'] = 'Zog Zog'
r = self.client.post('/rp/article/edit/{}/'.format(a['pk']), a['fields'])
a = Article.objects.get(pk=a['pk'])
assert r.status_code == 302 # We're redirecting after edit
assert a.title == 'Zog Zog'
class TestArticleApi(TestCase):
def setUp(self):
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)]
self.user = User.objects.create(username="test",
email="test@example.org",
......@@ -219,6 +220,7 @@ class TestArticleApi(TestCase):
self.jedi = User.objects.create(username="obiwan",
email="o.kennoby@example.org",
password="Thisaintthedroidyourelookin")
for a in self.articles:
a.save()
......@@ -240,21 +242,39 @@ class TestArticleApi(TestCase):
a = self.articles[0]
a.title = 'Zog Zog'
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
a.refresh_from_db()
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):
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.name))
r = self.client.get('/api/articles-by-tag/{}/'.format(tag))
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
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.data['count'] == 0
......@@ -264,7 +284,6 @@ class TestArticleApi(TestCase):
assert r.data['count'] == 0
def test_api_filter_search(self):
# text = ' '.join(self.articles[0].extracts.split(' ')[:10])
text = self.articles[0].title
r = self.client.get('/api/articles/', {'q': text})
assert r.status_code == 200
......@@ -280,26 +299,25 @@ class TestArticleApi(TestCase):
a = ArticleFactory(tags=['ZogZog'],)
r = self.client.post('/api/articles/',
{'url': a.url, 'title': a.title,
'tags': a.tags.all().values('name')},
'tags': [t.name for t in a.tags.all()]},
format='json')
assert r.status_code == 401
def test_api_tag_push_auth(self):
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/',
{'url': a.url, 'title': a.title,
'tags': a.tags.all().values('name')},
'tags': a.tags.all()},
format='json')
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
r = self.client.post('/api/articles/',
{'url': a.url, 'title': a.title,
},
{'url': a.url, 'title': a.title},
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):
# 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