reimbursinator/back/backend/test_backend.py

343 lines
14 KiB
Python

from django.test import TestCase
from rest_framework.test import APIRequestFactory, force_authenticate
from backend.models import Report
from users.models import CustomUser
from unittest.mock import MagicMock, Mock, patch
from datetime import date
from backend.views import *
import json
class BackendTests(TestCase):
# Set up functions
##################
def create_test_user(self, email, first, last, password):
"""
Create a test user and return it.
"""
user = CustomUser.objects.create_user(username=email, email=email, first_name=first, last_name=last, password=password)
return user
def setUp(self):
"""
Create a couple test users and save them in the database.
"""
self.test_user_1 = self.create_test_user('one@one.com', 'One', 'Mr. One', '1password')
self.test_user_1.save()
self.test_user_2 = self.create_test_user('two@two.com', 'Two', 'Mr. Two', '1password')
self.test_user_2.save()
# Report-related Tests
######################
def mock_report():
"""
Generates a mock object with the attributes of a report.
"""
r = Mock()
r.report_pk = 1
r.title = 'Report Title'
r.date_created = '2019-03-01'
r.date_submitted = '2019-03-01'
r.submitted = False
r.reference_number = '12345'
return r
def test_create_report_logged_in(self):
"""
Test when an authenticated user tries to submit a report.
"""
factory = APIRequestFactory()
request = factory.post('/api/v1/report', {'title':'Test Report', 'reference':'12345'})
user = CustomUser.objects.get(email='one@one.com')
force_authenticate(request, user=user)
response = create_report(request)
self.assertEqual(response.status_code, 200)
report = Report.objects.get(user_id=user)
self.assertEqual(report.title, 'Test Report')
def test_create_report_logged_out(self):
"""
Test when an unauthenticated user tries to create a report.
"""
factory = APIRequestFactory()
request = factory.post('/api/v1/report', {'title':'Test Report', 'reference':'12345'})
response = create_report(request)
self.assertEqual(response.status_code, 401)
@patch('backend.models.Report.objects.filter', Mock(return_value=[mock_report()]))
@patch('backend.views.get_sections', Mock(return_value={}))
def test_get_report(self):
result = get_report(1)
self.assertEqual(
result,
{
'date_created':'2019-03-01',
'reference_number':'12345',
'report_pk':1,
'title':'Report Title',
'date_submitted':'2019-03-01',
'submitted':False
}
)
def test_report_submit_for_review_logged_out(self):
"""
Test for when an unauthenticated user tries to submit a report for review.
"""
factory = APIRequestFactory()
request = factory.put('/api/v1/report/1')
response = report_detail(request)
self.assertEqual(response.status_code, 401)
def test_report_submit_for_review_logged_in_not_finalized(self):
"""
Test for when an authenticated user tries to submit for review a report
that has not been finalized yet.
"""
factory = APIRequestFactory()
add_report_request = factory.post('/api/v1/report', {'title':'Test Report', 'reference':'12345'})
user = CustomUser.objects.get(email='one@one.com')
force_authenticate(add_report_request, user=user)
create_report(add_report_request)
review_request = factory.put('/api/v1/report/1')
force_authenticate(review_request, user=user)
response = report_detail(review_request, 1)
self.assertEqual(response.status_code, 200)
report = Report.objects.get(user_id=user)
self.assertFalse(report.submitted)
def test_report_submit_for_review_logged_in_already_finalized(self):
"""
Test for when an authenticated user tries to submit for review a report
that has already been finalized.
"""
factory = APIRequestFactory()
add_report_request = factory.post('/api/v1/report', {'title':'Test Report', 'reference':'12345'})
user = CustomUser.objects.get(email='one@one.com')
force_authenticate(add_report_request, user=user)
create_report(add_report_request)
report = Report.objects.get(user_id=user)
report.submitted = True
report.save()
review_request = factory.put('/api/v1/report/1')
force_authenticate(review_request, user=user)
response = report_detail(review_request, 1)
self.assertEqual(response.status_code, 409)
def test_report_finalize_logged_out(self):
"""
Test for when an unauthenticated user tries to finalize a report.
"""
factory = APIRequestFactory()
request = factory.put('/api/v1/report/1/final')
response = finalize_report(request, 1)
self.assertEqual(response.status_code, 401)
def test_report_finalize_wrong_owner(self):
"""
Test for when an authenticated user tries to finalize someone else's report.
"""
factory = APIRequestFactory()
# Create a report for user One
add_report_1_request = factory.post('/api/v1/report', {'title':'One\'s Report', 'reference':'12345'})
force_authenticate(add_report_1_request, user=self.test_user_1)
create_report(add_report_1_request)
# Create a report for user Two
add_report_2_request = factory.post('/api/v1/report', {'title':'Two\'s Report', 'reference':'12345'})
force_authenticate(add_report_2_request, user=self.test_user_2)
create_report(add_report_2_request)
# Try finalizing user Two's report with user One
request = factory.put('/api/v1/report/2/final')
force_authenticate(request, user=self.test_user_1)
response = finalize_report(request, 2)
self.assertEqual(response.status_code, 401)
def test_report_finalize_logged_in_not_finalized(self):
"""
Test for when an authenticated user tries to finalize a report
that has not been finalized yet.
"""
factory = APIRequestFactory()
add_report_request = factory.post('/api/v1/report', {'title':'Test Report', 'reference':'12345'})
user = CustomUser.objects.get(email='one@one.com')
force_authenticate(add_report_request, user=user)
create_report(add_report_request)
review_request = factory.put('/api/v1/report/1/final')
force_authenticate(review_request, user=user)
response = finalize_report(review_request, 1)
self.assertEqual(response.status_code, 200)
report = Report.objects.get(user_id=user)
self.assertTrue(report.submitted)
def test_report_finalize_logged_in_already_finalized(self):
"""
Test for when an authenticated user tries to finalize a report
that has already been finalized.
"""
factory = APIRequestFactory()
add_report_request = factory.post('/api/v1/report', {'title':'Test Report', 'reference':'12345'})
user = CustomUser.objects.get(email='one@one.com')
force_authenticate(add_report_request, user=user)
create_report(add_report_request)
report = Report.objects.get(user_id=user)
report.submitted = True
report.save()
review_request = factory.put('/api/v1/report/1/final')
force_authenticate(review_request, user=user)
response = finalize_report(review_request, 1)
self.assertEqual(response.status_code, 409)
def test_report_get_report_logged_in(self):
"""
Test for when an authenticated user tries to view a report.
"""
factory = APIRequestFactory()
add_report_request = factory.post('/api/v1/report', {'title':'Test Report', 'reference':'12345'})
user = CustomUser.objects.get(email='one@one.com')
force_authenticate(add_report_request, user=user)
create_report(add_report_request)
get_request = factory.get('/api/v1/report/1')
force_authenticate(get_request, user=user)
response = report_detail(get_request, 1)
self.assertEqual(response.status_code, 200)
report = Report.objects.get(user_id=user)
# Check that the json response contains the title of the report we want
j = json.loads(response.content.decode("utf-8", "strict"))
self.assertEqual(report.title, j['title'])
def test_report_delete_report_logged_in(self):
"""
Test for when an authenticated user tries to delete a report.
"""
factory = APIRequestFactory()
add_report_request = factory.post('/api/v1/report', {'title':'Test Report', 'reference':'12345'})
user = CustomUser.objects.get(email='one@one.com')
force_authenticate(add_report_request, user=user)
create_report(add_report_request)
delete_request = factory.delete('/api/v1/report/1')
force_authenticate(delete_request, user=user)
response = report_detail(delete_request, 1)
self.assertEqual(response.status_code, 200)
reports = Report.objects.filter(user_id=user)
self.assertEqual(len(reports), 0)
def test_user_owns_report_true(self):
"""
Test when a user owns a report
"""
factory = APIRequestFactory()
add_report_request = factory.post('/api/v1/report', {'title':'One\'s Report', 'reference':'12345'})
force_authenticate(add_report_request, user=self.test_user_1)
create_report(add_report_request)
self.assertTrue(user_owns_report(self.test_user_1, 1))
def test_user_owns_report_false(self):
"""
Test when a user doesn't own a report
"""
factory = APIRequestFactory()
add_report_request = factory.post('/api/v1/report', {'title':'One\'s Report', 'reference':'12345'})
force_authenticate(add_report_request, user=self.test_user_1)
create_report(add_report_request)
self.assertFalse(user_owns_report(self.test_user_2, 1))
# Section-related Tests
#######################
def test_user_owns_section_true(self):
"""
Test when a user owns a section
"""
factory = APIRequestFactory()
add_report_request = factory.post('/api/v1/report', {'title':'One\'s Report', 'reference':'12345'})
force_authenticate(add_report_request, user=self.test_user_1)
create_report(add_report_request)
report = Report.objects.get(id=1)
section = Section.objects.create(report_id=report, auto_submit=False, required=False, completed=False, title='Section Title', html_description='<p>Description.</p>', number=0)
section.save()
section_id = section.id
self.assertTrue(user_owns_section(self.test_user_1, section_id))
def test_user_owns_section_false(self):
"""
Test when a user doesn't own a section
"""
factory = APIRequestFactory()
add_report_request = factory.post('/api/v1/report', {'title':'One\'s Report', 'reference':'12345'})
force_authenticate(add_report_request, user=self.test_user_1)
create_report(add_report_request)
report = Report.objects.get(id=1)
section = Section.objects.create(report_id=report, auto_submit=False, required=False, completed=False, title='Section Title', html_description='<p>Description.</p>', number=0)
section.save()
section_id = section.id
self.assertFalse(user_owns_section(self.test_user_2, section_id))
@patch('backend.models.Field.objects.filter')
def test_section_complete_true(self, mocked):
"""
Test if a section has been completed.
"""
mocked.return_value = [
Mock(completed=True),
Mock(completed=False),
Mock(completed=False)
]
self.assertTrue(section_complete(1))
@patch('backend.models.Field.objects.filter')
def test_section_complete_false(self, mocked):
"""
Test if a section has been completed.
"""
mocked.return_value = [
Mock(completed=False),
Mock(completed=False),
Mock(completed=False)
]
self.assertFalse(section_complete(1))
# Field-related Tests
#####################
def generate_test_fields(self):
test_boolean = models.BooleanField(default=False)
test_boolean = True
test_decimal = models.DecimalField(max_digits=9, decimal_places=2, default=0)
test_decimal = 100.10
test_date = models.DateField(null=True, blank=True)
test_date = date(2019,3,1)
test_file = MagicMock()
test_file.__str__.return_value = '/path/to/the/file.jpg'
test_string = models.TextField(default='', blank=True)
test_string = 'Some String'
test_integer = models.IntegerField(default=0, blank=True)
test_integer = 100
fields = [
{'field_name':'boolean', 'value':test_boolean, 'field_type':'boolean'},
{'field_name':'decimal', 'value':test_decimal, 'field_type':'decimal'},
{'field_name':'date', 'value':'{}'.format(test_date), 'field_type':'date'},
{'field_name':'file', 'value':'{}'.format(test_file), 'field_type':'file'},
{'field_name':'string', 'value':'{}'.format(test_string), 'field_type':'string'},
{'field_name':'integer', 'value':test_integer, 'field_type':'integer'}
]
return fields
def test_generate_named_fields_for_section(self):
"""
Test the generation of key-value dictionary from fields.
"""
test_fields = self.generate_test_fields()
result = generate_named_fields_for_section(test_fields)
self.assertEqual(result, {
'boolean':True,
'decimal':100.10,
'date':'2019-03-01',
'file':'/path/to/the/file.jpg',
'string':'Some String',
'integer':100
})