Merge pull request #129 from danieldupriest/more-tests
More tests, and simplified section update API endpoint
This commit is contained in:
commit
b4912a9edb
5 changed files with 138 additions and 14 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -2,6 +2,7 @@
|
||||||
# Edit at https://www.gitignore.io/?templates=linux,macos,python,django,windows,pycharm,intellij,visualstudio
|
# Edit at https://www.gitignore.io/?templates=linux,macos,python,django,windows,pycharm,intellij,visualstudio
|
||||||
|
|
||||||
### Django ###
|
### Django ###
|
||||||
|
*.env
|
||||||
*.log
|
*.log
|
||||||
*.pot
|
*.pot
|
||||||
*.pyc
|
*.pyc
|
||||||
|
@ -100,6 +101,7 @@ celerybeat-schedule
|
||||||
*.sage.py
|
*.sage.py
|
||||||
|
|
||||||
# Environments
|
# Environments
|
||||||
|
.env
|
||||||
.venv
|
.venv
|
||||||
env/
|
env/
|
||||||
venv/
|
venv/
|
||||||
|
|
|
@ -2,12 +2,15 @@ from django.test import TestCase
|
||||||
from rest_framework.test import APIRequestFactory, force_authenticate
|
from rest_framework.test import APIRequestFactory, force_authenticate
|
||||||
from backend.models import Report
|
from backend.models import Report
|
||||||
from users.models import CustomUser
|
from users.models import CustomUser
|
||||||
from unittest.mock import Mock, patch
|
from unittest.mock import MagicMock, Mock, patch
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from backend.views import *
|
from backend.views import *
|
||||||
import json
|
import json
|
||||||
|
|
||||||
class ReportTests(TestCase):
|
class BackendTests(TestCase):
|
||||||
|
|
||||||
|
# Set up functions
|
||||||
|
##################
|
||||||
|
|
||||||
def create_test_user(self, email, first, last, password):
|
def create_test_user(self, email, first, last, password):
|
||||||
"""
|
"""
|
||||||
|
@ -16,6 +19,18 @@ class ReportTests(TestCase):
|
||||||
user = CustomUser.objects.create_user(username=email, email=email, first_name=first, last_name=last, password=password)
|
user = CustomUser.objects.create_user(username=email, email=email, first_name=first, last_name=last, password=password)
|
||||||
return user
|
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():
|
def mock_report():
|
||||||
"""
|
"""
|
||||||
Generates a mock object with the attributes of a report.
|
Generates a mock object with the attributes of a report.
|
||||||
|
@ -29,15 +44,6 @@ class ReportTests(TestCase):
|
||||||
r.reference_number = '12345'
|
r.reference_number = '12345'
|
||||||
return r
|
return r
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
def test_create_report_logged_in(self):
|
def test_create_report_logged_in(self):
|
||||||
"""
|
"""
|
||||||
Test when an authenticated user tries to submit a report.
|
Test when an authenticated user tries to submit a report.
|
||||||
|
@ -219,3 +225,119 @@ class ReportTests(TestCase):
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
reports = Report.objects.filter(user_id=user)
|
reports = Report.objects.filter(user_id=user)
|
||||||
self.assertEqual(len(reports), 0)
|
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
|
||||||
|
})
|
|
@ -9,7 +9,7 @@ urlpatterns = [
|
||||||
path('reports', views.reports),
|
path('reports', views.reports),
|
||||||
path('report/<int:report_pk>', views.report_detail),
|
path('report/<int:report_pk>', views.report_detail),
|
||||||
path('report/<int:report_pk>/final', views.finalize_report),
|
path('report/<int:report_pk>/final', views.finalize_report),
|
||||||
path('report/<int:report_pk>/section/<int:section_pk>', views.section),
|
path('section/<int:section_pk>', views.section),
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns = format_suffix_patterns(urlpatterns)
|
urlpatterns = format_suffix_patterns(urlpatterns)
|
||||||
|
|
|
@ -270,7 +270,7 @@ def user_owns_section(user, section_id):
|
||||||
return report_to_check.user_id == user
|
return report_to_check.user_id == user
|
||||||
|
|
||||||
@api_view(['PUT'])
|
@api_view(['PUT'])
|
||||||
def section(request, report_pk, section_pk):
|
def section(request, section_pk):
|
||||||
"""
|
"""
|
||||||
Updates the specified section with new data.
|
Updates the specified section with new data.
|
||||||
|
|
||||||
|
|
|
@ -606,7 +606,7 @@ document.addEventListener("submit", function(event) {
|
||||||
let saveButton = event.target.lastElementChild;
|
let saveButton = event.target.lastElementChild;
|
||||||
animateButton(saveButton, " Saving...");
|
animateButton(saveButton, " Saving...");
|
||||||
const formData = new FormData(event.target);
|
const formData = new FormData(event.target);
|
||||||
const url = getEndpointDomain() + "api/v1/report/" + event.target.dataset.rid + "/section/" + event.target.dataset.sid;
|
const url = getEndpointDomain() + "api/v1/section/" + event.target.dataset.sid;
|
||||||
makeAjaxRequest("PUT", url, updateSection, saveButton, formData);
|
makeAjaxRequest("PUT", url, updateSection, saveButton, formData);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue