Last active
November 6, 2016 20:50
-
-
Save levivm/624f9b3fe9598ae35caee229b17c02ea to your computer and use it in GitHub Desktop.
Test for review api endpoint using django.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# python imports | |
import json | |
from datetime import datetime | |
# third party imports | |
import mock | |
# django imports | |
from django.conf import settings | |
from django.contrib.auth.models import Permission | |
from django.utils.timezone import now, timedelta, utc | |
from guardian.shortcuts import assign_perm | |
from model_mommy import mommy | |
from rest_framework import status | |
from rest_framework.reverse import reverse | |
# project imports | |
from activities.factories import ActivityFactory, CalendarFactory | |
from activities.models import Activity, Calendar | |
from orders.factories import OrderFactory | |
from orders.models import Order | |
from reviews.models import Review | |
from utils.models import EmailTaskRecord | |
from utils.tests import BaseAPITestCase | |
class ReviewAPITest(BaseAPITestCase): | |
""" | |
Class to test the Review API functionality | |
""" | |
headers = {'content_type': 'application/json'} | |
def setUp(self): | |
# Calling the super (initialization) | |
super(ReviewAPITest, self).setUp() | |
# Objects needed | |
self.activity = ActivityFactory(organizer=self.organizer, published=True) | |
self.calendar = CalendarFactory(activity=self.activity, | |
initial_date=(now() - timedelta(days=2)).date() ) | |
self.order = OrderFactory(student=self.student, calendar=self.calendar, | |
status=Order.ORDER_APPROVED_STATUS) | |
self.post = {'rating': 4, 'comment': 'First comment!'} | |
self.read_review_post = {'rating': 4, 'comment': 'Im a read review!'} | |
self.unread_review_post = {'rating': 4, 'comment': 'Im an unread review!'} | |
self.put = {'rating': 2, 'reply': 'Thank you!'} | |
self.review = mommy.make(Review, author=self.student, activity=self.activity, **self.post) | |
self.read_review = mommy.make(Review, author=self.student, | |
activity=self.activity, read=True, **self.read_review_post) | |
self.unread_review = mommy.make(Review, author=self.student, | |
activity=self.activity, read=False, | |
**self.unread_review_post) | |
# URLs | |
self.list_by_organizer_url = reverse('reviews:list_by_organizer', | |
kwargs={'organizer_pk': self.organizer.id}) | |
self.list_by_student_url = reverse('reviews:list_by_student', | |
kwargs={'student_pk': self.student.id}) | |
self.create_url = reverse('reviews:create', kwargs={'activity_pk': self.activity.id}) | |
self.retrieve_update_delete_url = reverse('reviews:reply', kwargs={'pk': self.review.id}) | |
self.report_url = reverse('reviews:report', kwargs={'pk': self.review.id}) | |
self.read_url = reverse('reviews:read', kwargs={'pk': self.review.id}) | |
# Counters | |
self.review_count = Review.objects.count() | |
self.activity_reviews = self.activity.reviews.count() | |
# Set permissions | |
add_review = Permission.objects.get_by_natural_key('add_review', 'reviews', 'review') | |
add_review.user_set.add(self.student.user, self.another_student.user) | |
change_review = Permission.objects.get_by_natural_key('change_review', 'reviews', 'review') | |
change_review.user_set.add(self.organizer.user, self.another_organizer.user) | |
assign_perm('reviews.reply_review', user_or_group=self.organizer.user, obj=self.review) | |
assign_perm('reviews.report_review', user_or_group=self.organizer.user, obj=self.review) | |
assign_perm('reviews.read_review', user_or_group=self.organizer.user, obj=self.review) | |
def test_list_read_by_organizer(self): | |
""" | |
Test to list the read reviews by organizer | |
""" | |
data = { | |
'status':'read' | |
} | |
# Anonymous should return a list of reviews | |
response = self.client.get(self.list_by_organizer_url, data=data) | |
self.assertContains(response, self.read_review_post.get('comment')) | |
# Student should return a list of reviews | |
response = self.student_client.get(self.list_by_organizer_url, data=data) | |
self.assertContains(response, self.read_review_post.get('comment')) | |
# Organizer should return a list of reviews | |
response = self.organizer_client.get(self.list_by_organizer_url, data=data) | |
self.assertContains(response, self.read_review_post.get('comment')) | |
def test_list_unread_by_organizer(self): | |
""" | |
Test to list the unread reviews by organizer | |
""" | |
data = { | |
'status':'unread' | |
} | |
# Anonymous should return a list of reviews | |
response = self.client.get(self.list_by_organizer_url, data=data) | |
self.assertContains(response, self.unread_review_post.get('comment')) | |
# Student should return a list of reviews | |
response = self.student_client.get(self.list_by_organizer_url, data=data) | |
self.assertContains(response, self.unread_review_post.get('comment')) | |
# Organizer should return a list of reviews | |
response = self.organizer_client.get(self.list_by_organizer_url, data=data) | |
self.assertContains(response, self.unread_review_post.get('comment')) | |
def test_list_by_student(self): | |
""" | |
Test to list the reviews of a student | |
""" | |
# Anonymous should return unathorized | |
response = self.client.get(self.list_by_student_url) | |
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | |
# Organizer should not get the reviews | |
response = self.organizer_client.get(self.list_by_student_url) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
# Student who is not the owner should not get the reviews | |
response = self.another_student_client.get(self.list_by_student_url) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
# Student owner should get the reviews | |
response = self.student_client.get(self.list_by_student_url) | |
self.assertContains(response, self.post.get('comment')) | |
@mock.patch('utils.tasks.SendEmailTaskMixin.send_mail') | |
def test_create(self, send_mail): | |
""" | |
Test to create a review [POST] | |
""" | |
send_mail.return_value = [{ | |
'email': self.review.activity.organizer.user.email, | |
'status': 'sent', | |
'reject_reason': None, | |
}] | |
# Anonymous should return unauthorized | |
response = self.client.post(self.create_url, self.post) | |
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | |
self.assertEqual(Review.objects.count(), self.review_count) | |
# Organizer should return forbidden | |
response = self.organizer_client.post(self.create_url, self.post) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
self.assertEqual(Review.objects.count(), self.review_count) | |
# Student without order should not create a review | |
response = self.another_student_client.post(self.create_url, self.post) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
self.assertEqual(Review.objects.count(), self.review_count) | |
# Student should create a review | |
response = self.student_client.post(self.create_url, self.post) | |
review = Review.objects.get(id=response.data['id']) | |
self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data) | |
self.assertEqual(Review.objects.count(), self.review_count + 1) | |
self.assertEqual(self.activity.reviews.count(), self.activity_reviews + 1) | |
self.assertTrue(self.activity.organizer.user.has_perm(perm='reviews.reply_review', obj=review)) | |
self.assertTrue(self.activity.organizer.user.has_perm(perm='reviews.report_review', obj=review)) | |
self.assertTrue(EmailTaskRecord.objects.filter( | |
to=self.organizer.user.email, | |
status='sent').exists()) | |
def test_retrieve(self): | |
""" | |
Test to retrieve a review [GET] | |
""" | |
# Anonymous should return unauthorized | |
response = self.client.get(self.retrieve_update_delete_url) | |
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | |
# Organizer should not retrive a review | |
response = self.organizer_client.get(self.retrieve_update_delete_url) | |
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) | |
# Student should not retrive a review | |
response = self.student_client.get(self.retrieve_update_delete_url) | |
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) | |
@mock.patch('utils.tasks.SendEmailTaskMixin.send_mail') | |
def test_update(self, send_mail): | |
""" | |
Test to reply a review [PUT] | |
""" | |
send_mail.return_value = [{ | |
'email': self.review.author.user.email, | |
'status': 'sent', | |
'reject_reason': None, | |
}] | |
# Anonymous should return unauthorized | |
response = self.client.put(self.retrieve_update_delete_url, self.put) | |
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | |
# Student should not reply a review | |
response = self.student_client.put(self.retrieve_update_delete_url, self.put) | |
review = Review.objects.get(id=self.review.id) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
self.assertEqual(review.reply, '') | |
# Organizer should not reply a review if he is not the owner of the activity | |
response = self.another_organizer_client.put(self.retrieve_update_delete_url, self.put) | |
review = Review.objects.get(id=self.review.id) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
self.assertEqual(review.reply, '') | |
# Organizer should reply a review | |
replied_at = datetime(2015, 11, 8, 3, 30, tzinfo=utc) | |
with mock.patch('reviews.serializers.now') as mock_now: | |
mock_now.return_value = replied_at | |
response = self.organizer_client.put(self.retrieve_update_delete_url, self.put) | |
review = Review.objects.get(id=self.review.id) | |
self.assertEqual(response.status_code, status.HTTP_200_OK) | |
self.assertEqual(review.reply, 'Thank you!') | |
self.assertEqual(review.rating, 4) | |
self.assertEqual(review.replied_at, replied_at) | |
self.assertTrue(review.read) | |
self.assertTrue(EmailTaskRecord.objects.filter( | |
to=self.review.author.user.email, | |
status='sent').exists()) | |
def test_delete(self): | |
""" | |
Test to delete a review [DELETE] | |
""" | |
# Anoymous should return unauthorized | |
response = self.client.delete(self.retrieve_update_delete_url) | |
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | |
self.assertEqual(Review.objects.count(), self.review_count) | |
# Student should not delete a review | |
response = self.student_client.delete(self.retrieve_update_delete_url) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
self.assertEqual(Review.objects.count(), self.review_count) | |
# Organizer should not delete a review | |
response = self.organizer_client.delete(self.retrieve_update_delete_url) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
self.assertEqual(Review.objects.count(), self.review_count) | |
@mock.patch('reviews.tasks.SendReportReviewEmailTask.delay') | |
def test_report(self, delay): | |
""" | |
Test report a review [POST] | |
""" | |
# Anonymous should return unauthorized | |
response = self.client.post(self.report_url) | |
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | |
# Student should not report a review | |
response = self.student_client.post(self.report_url) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
# Organizer who is not the owner should not report a review | |
response = self.another_organizer_client.post(self.report_url) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
# Organizer owner should report a review | |
response = self.organizer_client.post(self.report_url) | |
review = Review.objects.get(id=self.review.id) | |
self.assertEqual(response.status_code, status.HTTP_200_OK) | |
self.assertTrue(review.reported) | |
self.assertTrue(review.read) | |
def test_mark_as_read(self): | |
""" | |
Test a review marked as read | |
""" | |
data = json.dumps({'read': True}) | |
# Anonymous should return unauthorized | |
response = self.client.put(self.read_url, data=data, **self.headers) | |
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | |
# Student should return forbidden | |
response = self.student_client.put(self.read_url, data=data, **self.headers) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
# Organizer should mark the review as read | |
response = self.organizer_client.put(self.read_url, data=data, **self.headers) | |
review = Review.objects.get(id=self.review.id) | |
self.assertEqual(response.status_code, status.HTTP_200_OK) | |
self.assertTrue(review.read) | |
# Organizer who is not the owner should not read a review | |
response = self.another_organizer_client.put(self.read_url, data=data, **self.headers) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
def test_mark_as_unread(self): | |
""" | |
Test a review marked as unread | |
""" | |
self.review.read = True | |
self.review.save() | |
data = json.dumps({'read': False}) | |
# Anonymous should return unauthorized | |
response = self.client.put(self.read_url, data=data, **self.headers) | |
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) | |
# Student should return forbidden | |
response = self.student_client.put(self.read_url, data=data, **self.headers) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) | |
# Organizer should mark the review as read | |
response = self.organizer_client.put(self.read_url, data=data, **self.headers) | |
review = Review.objects.get(id=self.review.id) | |
self.assertEqual(response.status_code, status.HTTP_200_OK) | |
self.assertFalse(review.read) | |
# Organizer who is not the owner should not read a review | |
response = self.another_organizer_client.put(self.read_url, data=data, **self.headers) | |
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment