Commit 9855e893 authored by okhin's avatar okhin 🚴

Merge branch '49-ajouter-des-flags-sur-le-contenu' into 'rp2'

Resolve "Ajouter des flags sur le contenu"

See merge request !41
parents 3aed3da5 a725135e
Pipeline #2607 passed with stages
in 3 minutes and 3 seconds
......@@ -24,7 +24,8 @@ class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ('id', 'url', 'title', 'tags', 'extracts',
'status', 'score', 'priority')
'status', 'score', 'priority',
'archive', 'quote', 'speak')
def create(self, validated_data):
article = Article.add_new_url(**validated_data)
......
......@@ -25,7 +25,7 @@ class ArticleFactory(factory.django.DjangoModelFactory):
published_at = FuzzyDateTime(
datetime.datetime(2014, 1, 1, tzinfo=pytz.UTC))
status = FuzzyChoice(STATUS_CHOICES)
status = FuzzyChoice([s[0] for s in STATUS_CHOICES])
@factory.post_generation
def tags(self, create, extracted, **kwargs):
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2019-05-15 10:50
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('rp', '0021_auto_20190507_1438'),
]
operations = [
migrations.AddField(
model_name='article',
name='archive',
field=models.BooleanField(default=False, verbose_name='Article archived'),
),
migrations.AddField(
model_name='article',
name='quote',
field=models.BooleanField(default=False, verbose_name='Article directly quotes us'),
),
migrations.AddField(
model_name='article',
name='speak',
field=models.BooleanField(default=False, verbose_name='Article speaks of us'),
),
]
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.core import files
from django.contrib.auth.decorators import permission_required
from taggit.managers import TaggableManager
from newspaper import Article as ArticleParser, ArticleException
......@@ -91,12 +92,23 @@ class Article(models.Model):
#: priority: True if article have priority
priority = models.BooleanField(default=False)
#: Comma separated list of short tags to describe the article (eg: "Privacy", "Copyright").
#: List of tags used to add subject and topics to an article
tags = TaggableManager(blank=True)
#: Score of the article, modifiedby upvote and downvote methods
score = models.IntegerField(default=0)
#: If the publication is "archived" (not visible by default from the public
#: feeds), this flag is set to True
archive = models.BooleanField(_("Article archived"), default=False)
#: If the article is quoting something LQDN said or wrote
quote = models.BooleanField(_("Article directly quotes us"),
default=False)
#: If the article speaks about something LQDN did or wrote
speak = models.BooleanField(_("Article speaks of us"), default=False)
class Meta:
verbose_name = _("Article")
verbose_name_plural = _("Articles")
......@@ -115,8 +127,37 @@ class Article(models.Model):
""" Returns article title. """
return self.title
# Finite state logic
# Flags logic
def toggle_speak(self):
"""Toggle the speak flag"""
self.speak = not self.speak
self.save()
def toggle_archive(self):
"""Toggle the archive flag"""
self.archive = not self.archive
self.save()
def toggle_quote(self):
"""Toggle the quote flag"""
self.quote = not self.quote
self.save()
@transition(field=status, source=['DRAFT', 'NEW', 'PUBLISHED'],
target=RETURN_VALUE('DRAFT', 'NEW', 'PUBLISHED',),
permission="rp.can_edit")
def set_flags(self, archive=False, speak=False, quote=False):
"""
This method is used to set _all_ the flags in the state their given as
arguments of this method. The default is False which will unset all flags.
"""
self.archive = archive
self.speak = speak
self.quote = quote
self.save()
return self.status
# Finite state logic
@transition(field=status, source='DRAFT', target='PUBLISHED',
permission="rp.can_change_status")
def publish(self):
......
......@@ -11,6 +11,7 @@ from rp.views.articles import ArticleList
class TestArticle(TestCase):
def setUp(self):
self.article = ArticleFactory()
self.newarticle = ArticleFactory(status='NEW')
def test_init(self):
assert RpConfig.name == "rp"
......@@ -37,6 +38,53 @@ class TestArticle(TestCase):
assert article_again.status == 'NEW'
assert article_again.score == 2
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
class TestArticleViews(TestCase):
def setUp(self):
self.client = Client()
......@@ -68,14 +116,6 @@ class TestArticleViews(TestCase):
r = self.client.get('/rp/by-tag/zogzog')
assert len(r.context['object_list']) == 0
def test_filter_view(self):
new = [article for article in self.articles if article.status == 'NEW']
r = self.client.get('/rp/by-tag/new')
assert len(r.context['object_list']) == len(new)
r = self.client.get('/rp/by-tag/nosuchtag')
assert len(r.context['object_list']) == 0
def test_search_view(self):
article = ArticleFactory(title=u'Zog Zog chez les schtroumphs',
lang='FR')
......
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