Skip to content

Commit

Permalink
Merge 2f727af into 7b19f21
Browse files Browse the repository at this point in the history
  • Loading branch information
Bakley committed May 16, 2019
2 parents 7b19f21 + 2f727af commit 1d1cd72
Show file tree
Hide file tree
Showing 16 changed files with 495 additions and 3 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,3 @@ db.sqlite3
# vscode
.vscode/
# migrations
migrations/
2 changes: 1 addition & 1 deletion authors/apps/appnotifications/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 2.2 on 2019-05-14 13:13
# Generated by Django 2.2 on 2019-05-16 13:46

from django.conf import settings
from django.db import migrations, models
Expand Down
2 changes: 1 addition & 1 deletion authors/apps/authentication/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 2.2 on 2019-05-13 15:50
# Generated by Django 2.2 on 2019-05-16 13:46

from django.db import migrations, models

Expand Down
Empty file.
7 changes: 7 additions & 0 deletions authors/apps/escalation/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from rest_framework.exceptions import APIException


class ArticleNotFound(APIException):
"""exception message"""
status_code = 404
default_detail = "Sorry we couldn't find that article."
32 changes: 32 additions & 0 deletions authors/apps/escalation/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Generated by Django 2.2 on 2019-05-16 13:03

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


class Migration(migrations.Migration):

initial = True

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

operations = [
migrations.CreateModel(
name='EscalationModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('timestamp', models.DateTimeField(auto_now_add=True)),
('reason', models.CharField(choices=[('Plagiarism', 'Reusing content without attribution (link and blockquotes)'), ('Rule Violation', 'Violates terms of agreement'), ('Spam', 'Creating multiple articles')], max_length=255)),
('description', models.CharField(max_length=128)),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='articles.Article')),
('reporter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'ordering': ['timestamp'],
},
),
]
Empty file.
42 changes: 42 additions & 0 deletions authors/apps/escalation/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from django.db import models
from django.contrib.auth import get_user_model

from authors.apps.articles.models import Article


User = get_user_model()


class EscalationModel(models.Model):
"""
Cases for escalation of an article
"""
EXCALATION_CHOICES = (
('Plagiarism',
'Reusing content without attribution (link and blockquotes)'),
('Rule Violation', 'Violates terms of agreement'),
('Spam', 'Creating multiple articles')

)

reporter = models.ForeignKey(User, on_delete=models.CASCADE)
article = models.ForeignKey(Article, on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
reason = models.CharField(max_length=255, choices=EXCALATION_CHOICES)
description = models.CharField(max_length=128)

class Meta:
ordering = ['timestamp', ]

def get_articles_details(self):
"""
Get all relevant articles details
"""
return {
"slug": self.article.slug,
"title": self.article.title,
"description": self.article.description,
"body": self.article.body,
"created_at": self.article.created_at,
"updated_at": self.article.updated_at
}
17 changes: 17 additions & 0 deletions authors/apps/escalation/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from .models import EscalationModel

from rest_framework import serializers


class EscalationSerializer(serializers.ModelSerializer):
"""
Escalation serializer
"""
# reporter = serializers.ReadOnlyField()
article = serializers.ReadOnlyField(source='get_articles_details')
reason = serializers.ChoiceField(
choices=['Plagiarism', 'Rule Violation', 'Spam'])

class Meta:
model = EscalationModel
fields = ('article', 'reason', 'description')
Empty file.
187 changes: 187 additions & 0 deletions authors/apps/escalation/tests/basetest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import json

from django.contrib.auth import get_user_model
from rest_framework.test import APITestCase, APIClient
from rest_framework.reverse import reverse
from rest_framework.authtoken.models import Token

from authors.apps.escalation.models import EscalationModel
from authors.apps.articles.models import Article
from django.conf import settings


User = get_user_model()


class BaseTest(APITestCase):
"""
Class to set up test case
"""

def setUp(self):
"""
Setting up the client
"""
self.client = APIClient()
self.login_url = reverse("authentication:login")
self.article_url = reverse("articles:article")

self.user1 = User.objects.create_user(
username="Pablo",
email="Escobar@pablo.com",
password="@Us3r.com"
)
self.user1.is_verified = True
self.user1.save()

self.user2 = User.objects.create_user(
username="Emirry",
email="ess@rry.com",
password="@Us3r.com"
)
self.user2.is_verified = True
self.user2.save()

self.user3 = User.objects.create_user(
username="Mercy",
email="mercy@hope.com",
password="@Us3r.com"
)
self.user3.is_verified = True
self.user3.is_staff = True
self.user3.save()

self.new_article = {
"title": "How to train your dragon",
"description": "Ever wonder how?",
"body": "You have to believe"
}

self.article = Article.objects.create(
title='this is mine',
description='I do not want it',
body='what is the purpose of body',
author=self.user2,
image='image/upload/v1557052449/tt30hqlfc3eaflfqtobo.jpg'
)
self.article.save()

def login(self, email, password):
"""
Method to login users
"""
return self.client.post(
self.login_url,
data=json.dumps({
"email": email,
"password": password
}), content_type="application/json")

def is_authenticated(self, email, password):
"""
Authenticate user
"""
login_details = self.login(email, password)
token = login_details.data['token']
return self.client.credentials(
HTTP_AUTHORIZATION='Bearer ' + token)

def create_article(self):
"""
Create a new article
"""
token = self.user2.token()
self.client.credentials(
HTTP_AUTHORIZATION='Bearer ' + token)
return self.client.post(self.article_url,
data=json.dumps(self.new_article),
content_type="application/json")

def escalate_an_article(self):
"""
Report an article that doesn't exist
"""
slug = "how-to-help"
url = reverse("escalation:escalate", args=[slug])
response = self.client.post(
url,
data=json.dumps({
"reason": "Rule Violation",
"description": "He broke some rules"
}),
content_type="application/json"
)
return response

def escalate_an_article_successfully(self):
"""
Report an article successfully
"""
slug = str(self.article.slug)
url = reverse("escalation:escalate", args=[slug])
response = self.client.post(
url,
data=json.dumps({
"reason": "Rule Violation",
"description": "He broke some rules"
}),
content_type="application/json"
)
return response

def escalate_an_article_twice(self):
"""
Try and report an article twice
"""
slug = str(self.article.slug)
url = reverse("escalation:escalate", args=[slug])
self.client.post(
url,
data=json.dumps({
"reason": "Rule Violation",
"description": "He broke some rules"
}),
content_type="application/json"
)
return self.client.post(
url,
data=json.dumps({
"reason": "Rule Violation",
"description": "He broke some rules"
}),
content_type="application/json"
)

def update_an_escalated_article(self):
"""
Update an eslation
"""
slug = str(self.article.slug)
url = reverse("escalation:escalate", args=[slug])
self.client.post(
url,
data=json.dumps({
"reason": "Rule Violation",
"description": "He broke some rules"
}),
content_type="application/json"
)
return self.client.post(
url,
data=json.dumps({
"reason": "Rule Violation",
"description": "He broke some rules, he posted someone else work and pasted as his"
}),
content_type="application/json"
)

def delete_article(self):
"""
Try and delete an article
"""
slug = str(self.article.slug)
url = reverse("escalation:escalate", args=[slug])
return self.client.delete(
url,
content_type="application/json"
)
90 changes: 90 additions & 0 deletions authors/apps/escalation/tests/test_escalation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import json

from rest_framework.views import status
from .basetest import BaseTest


class EscalationArticlesTest(BaseTest):
"""
Test cases for article escalation
"""
msg = "Sorry we couldn't find that article."
snitch = "You can't report your article."
user_delete = "Only Admins can delete a reported article"
report_twice = "You are not allowed to report twice"
admin_delete = "You successfully deleted the article"

def test_escalation_of_a_404_article(self):
"""
Test successful escalation of an article that doesn't exist
"""
token = self.user1.token()
self.client.credentials(
HTTP_AUTHORIZATION='Bearer ' + token)
resp = self.escalate_an_article()
self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND)
self.assertEqual(resp.data["detail"], self.msg)

def test_escalation_of_an_article(self):
"""
Test successful article escalation
"""
token = self.user1.token()
self.client.credentials(
HTTP_AUTHORIZATION='Bearer ' + token)
resp = self.escalate_an_article_successfully()
self.assertEqual(resp.status_code, status.HTTP_201_CREATED)

def test_update_escalation_of_an_article(self):
"""
Test successful updating an escalation
"""
token = self.user1.token()
self.client.credentials(
HTTP_AUTHORIZATION='Bearer ' + token)
resp = self.update_an_escalated_article()
self.assertEqual(resp.status_code, status.HTTP_201_CREATED)

def test_escalation_of_an_article_with_author(self):
"""
Test escalation with author
"""
token = self.user2.token()
self.client.credentials(
HTTP_AUTHORIZATION='Bearer ' + token)
resp = self.escalate_an_article_successfully()
self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)

def test_escalation_of_an_article_twice(self):
"""
Test unsuccessful article escalation twice
"""
token = self.user1.token()
self.client.credentials(
HTTP_AUTHORIZATION='Bearer ' + token)
resp = self.escalate_an_article_twice()
self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(resp.data["error"], self.report_twice)

def test_delete_of_an_escalated_article_with_user(self):
"""
Test unsuccessful article escalation deletion
"""
token = self.user1.token()
self.client.credentials(
HTTP_AUTHORIZATION='Bearer ' + token)
resp = self.delete_article()
self.assertEqual(resp.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(resp.data["error"], self.user_delete)

def test_delete_of_an_escalated_article_with_admin(self):
"""
Test unsuccessful article escalation deletion
"""
token = self.user3.token()
self.client.credentials(
HTTP_AUTHORIZATION='Bearer ' + token)
resp = self.delete_article()
self.assertEqual(resp.status_code, status.HTTP_200_OK)
self.assertEqual(resp.data["message"], self.admin_delete)

Loading

0 comments on commit 1d1cd72

Please sign in to comment.