Skip to content

Commit

Permalink
feat(comments): implement threaded comments
Browse files Browse the repository at this point in the history
users can comment articles and reply to comments
add tests for comment functionality

[Delivers #162163270]
  • Loading branch information
Kasulejoseph committed Dec 17, 2018
1 parent b62bcca commit ab1e2fe
Show file tree
Hide file tree
Showing 16 changed files with 503 additions and 67 deletions.
Binary file modified .DS_Store
Binary file not shown.
11 changes: 11 additions & 0 deletions authors/apps/articles/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
"""
Write customized exception classes here
"""
from rest_framework.exceptions import APIException

class PermisionDenied(APIException):
status_code = 403
default_detail = 'You dont have permission to perform this action'

class CommentDoesNotExist(APIException):
status_code = 404
default_detail = "Failed, comment or article doesnot exist"


16 changes: 15 additions & 1 deletion authors/apps/articles/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

# Generated by Django 2.1.3 on 2018-12-15 08:33

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
Expand Down Expand Up @@ -35,6 +36,19 @@ class Migration(migrations.Migration):
('description', models.CharField(db_index=True, max_length=255)),
],
),
migrations.CreateModel(
name='Comments',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('comment_body', models.TextField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now_add=True)),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='articles.Article')),
],
options={
'get_latest_by': ['created_at'],
},
),
migrations.CreateModel(
name='Tag',
fields=[
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Generated by Django 2.1.3 on 2018-12-13 10:57
# Generated by Django 2.1.3 on 2018-12-15 08:33

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion

Expand All @@ -9,11 +10,22 @@ class Migration(migrations.Migration):
initial = True

dependencies = [
('profiles', '0001_initial'),
('articles', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('profiles', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='comments',
name='author',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='comments',
name='parent',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='articles.Comments'),
),
migrations.AddField(
model_name='article',
name='author',
Expand Down
25 changes: 25 additions & 0 deletions authors/apps/articles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,29 @@ class Meta:
class Tag(models.Model):
tag = models.CharField(max_length=255)
slug = models.SlugField(db_index=True, unique=True)

class Comments(models.Model):
"""
This model implements adding comments to
the user article
"""
article = models.ForeignKey(Article, on_delete=models.CASCADE)
author = models.ForeignKey(User, on_delete=models.CASCADE)
comment_body = models.TextField(null=False, blank=False)
created_at = models.DateTimeField(auto_now_add=True)
parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE)
updated_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.comment_body

class Meta:
get_latest_by = ['created_at']

def children(self):
return Comments.objects.filter(parent=self)

@property
def is_parent(self):
return True

37 changes: 28 additions & 9 deletions authors/apps/articles/test/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class BaseTestArticles(APITestCase):

def setUp(self):
self.client = APIClient()
self.roni = self.save_user('roni', 'roni@a.com', 'P@ssword23lslsn')
self.sama = self.save_user('sama', 'samantha@a.com', 'P@ssword23lslsn')


self.data = {
"user": {
Expand Down Expand Up @@ -46,7 +49,11 @@ def setUp(self):
}
}
}

self.comment = {
"comment": {
"comment_body": "Hey, this is another comment for you "
}
}

self.updated_article = {

Expand Down Expand Up @@ -76,6 +83,19 @@ def setUp(self):
url = reverse('registration')
self.client.post(url, self.data, format='json')

def save_user(self, username, email, pwd):
validated_data = {'username': username,
'email': email, 'password': pwd}
return User.objects.create_user(**validated_data)


def get_samantha_token(self):
return self.sama.token()

def get_roni_token(self):
return self.roni.token()


def verify_account(self, token, uidb64):
request = APIRequestFactory().get(
reverse(
Expand All @@ -88,15 +108,14 @@ def verify_account(self, token, uidb64):
return response

def login_user(self):

request = APIRequestFactory().post(
reverse("registration")
)
user = User.objects.get()
token, uidb64 = RegistrationAPIView.generate_activation_link(
user, request, send=False)
self.verify_account(token, uidb64)
return User.objects.filter().first().token()

def create_article(self):
self.client.credentials(
HTTP_AUTHORIZATION='Bearer ' + self.login_user())
response = self.client.post(
'/api/users/login/', self.login_credentials, format='json')
jwt_token = response.data['token']
return jwt_token
'/api/articles/', data=self.article, format='json')
return response.data['slug']
Loading

0 comments on commit ab1e2fe

Please sign in to comment.