Skip to content

Commit

Permalink
ft(user-read-stat):Get the articles read by user
Browse files Browse the repository at this point in the history
- user should be able to see the articles they have read
- write tests for the funcionality

[Delivers #162948931]
  • Loading branch information
Erastus Ruiru authored and Erastus Ruiru committed Feb 4, 2019
1 parent bf61254 commit 32a8a3a
Show file tree
Hide file tree
Showing 15 changed files with 401 additions and 10 deletions.
60 changes: 51 additions & 9 deletions authors/apps/articles/tests/test_articles.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from ..models import Article
from ...authentication.models import User
from authors.apps.authentication.messages import read_stats_message


class ArticleTestCase(APITestCase):
Expand All @@ -19,6 +20,7 @@ def setUp(self):
self.all_article_url = reverse("articles:articles")
self.login_url = reverse("auth:login")
self.register = reverse("auth:register")
self.read_stats = reverse("read:user_read_stats")
self.client = APIClient()
self.valid_article_data = {
"article": {
Expand Down Expand Up @@ -77,6 +79,13 @@ def get_slug_from_title(self, title):
)
return specific_article_url

def get_slug(self, title):
"""
Get slug
"""
slug = slugify(title)
return slug

def create_article(self, data):
"""
Create an article
Expand Down Expand Up @@ -117,22 +126,55 @@ def test_get_one_article(self):
)
self.assertEqual(response.status_code, 200)


def test_read_time(self):
def test_get_stat(self):
"""
Test GET /api/v1/article/<slug>/
"""
token = self.login(self.user_data)
self.create_article(self.valid_article_data['article'])
url = self.get_slug_from_title(
self.valid_article_data['article']['title'])
response = self.client.get(
url,
format="json",
HTTP_AUTHORIZATION="Bearer {}".format(token)
)
self.read_stats,
content_type='application/json',
HTTP_AUTHORIZATION="Bearer {}".format(token)
)
self.assertEqual(response.status_code, 200)
self.assertIn(response.data['read_time'],'0:01:00')

def test_read(self):
"""
Test reading an article that doesnot exist
"""
token = self.login(self.user_data)
self.create_article(self.valid_article_data['article'])
slug = "its-a-test-article"
response = self.client.get(
reverse("read:article_read", kwargs={
"slug":slug
}),
content_type='application/json',
HTTP_AUTHORIZATION="Bearer {}".format(token)
)
self.assertEqual(response.status_code, 404)
self.assertIn(response.data['message'],
read_stats_message['read_error'])

def test_read_new(self):
"""
"""
token = self.login(self.user_data)
self.create_article(self.valid_article_data['article'])
slug = self.get_slug(self.valid_article_data['article']['title'])
response = self.client.get(
reverse("read:article_read", kwargs={
"slug":slug
}),
content_type='application/json',
HTTP_AUTHORIZATION="Bearer {}".format(token)
)
self.assertEqual(response.status_code, 404)
self.assertIn(response.data['message'],
read_stats_message['read_error'])


def test_remove_one_article(self):
"""
Expand Down
13 changes: 13 additions & 0 deletions authors/apps/articles/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
from .serializers import ArticleSerializer, TagSerializers
from .messages import error_msgs, success_msg

from authors.apps.reading_stats.models import ReadStats


class ArticleAPIView(generics.ListCreateAPIView):
"""
Expand Down Expand Up @@ -92,6 +94,17 @@ def get(self, request, slug, *args, **kwargs):
raise exceptions.NotFound({
"message": error_msgs['not_found']
})
#this checks if an istance of read exists
#if it doesn't then it creates a new one
if request.user.id:
if not ReadStats.objects.filter(user=request.user, article=article).exists():
user_stat = ReadStats(
user = request.user,
article = article
)
user_stat.article_read = True
user_stat.save()

serializer = ArticleSerializer(
article,
context={
Expand Down
6 changes: 6 additions & 0 deletions authors/apps/authentication/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,9 @@
'Dislike': "Disliked",
'Null': "Null",
}

read_stats_message = {
"read_status":"Article has been read",
"read_update":"You have already read this article",
"read_error":"Article doesnot exist check details again"
}
Empty file.
3 changes: 3 additions & 0 deletions authors/apps/reading_stats/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
5 changes: 5 additions & 0 deletions authors/apps/reading_stats/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class ReadingStartsConfig(AppConfig):
name = 'reading_starts'
Empty file.
20 changes: 20 additions & 0 deletions authors/apps/reading_stats/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django.db import models

from authors.apps.authentication.models import User
from authors.apps.articles.models import Article


class ReadStats(models.Model):
"""
The model for user read starts
"""
user = models.ForeignKey(
User, on_delete=models.CASCADE, null=False, blank=False)
article = models.ForeignKey(
Article, on_delete=models.CASCADE, null=False, blank=False)
article_read = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

def __str__(self):
return self.article.title
22 changes: 22 additions & 0 deletions authors/apps/reading_stats/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from rest_framework import serializers

from .models import ReadStats


class ReadStatsSerializers(serializers.ModelSerializer):
""""
Serializer class for our ReadStats model
"""

article = serializers.SerializerMethodField()

class Meta:
model = ReadStats

fields = '__all__'

def get_article(self, stats):
return {
"article": stats.article.title,
"slug": stats.article.slug
}
Empty file.
Loading

0 comments on commit 32a8a3a

Please sign in to comment.