Browse Source

Merge branch 'master' into DIV-1022

# Conflicts:
#	edivorce/apps/core/static/css/main.css
pull/172/head
ariannedee 5 years ago
parent
commit
7b27ad520a
10 changed files with 112 additions and 50 deletions
  1. +2
    -18
      edivorce/apps/core/serializer.py
  2. +1
    -1
      edivorce/apps/core/static/css/main.css
  3. +15
    -0
      edivorce/apps/core/static/css/main.scss
  4. +3
    -5
      edivorce/apps/core/templates/partials/alias_field.html
  5. +1
    -1
      edivorce/apps/core/templates/partials/filing_location.html
  6. +11
    -3
      edivorce/apps/core/tests/test_api.py
  7. +3
    -3
      edivorce/apps/core/tests/test_logic.py
  8. +21
    -16
      edivorce/apps/core/tests/test_upload.py
  9. +37
    -2
      edivorce/apps/core/utils/conditional_logic.py
  10. +18
    -1
      edivorce/apps/core/validators.py

+ 2
- 18
edivorce/apps/core/serializer.py View File

@ -3,6 +3,7 @@ from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from .models import Document, UserResponse
from .validators import file_scan_validation, valid_file_extension, valid_doc_type, valid_rotation
class UserResponseSerializer(serializers.ModelSerializer):
@ -23,22 +24,10 @@ class UserResponseSerializer(serializers.ModelSerializer):
instance.save()
def valid_file_extension(file):
extension = file.name.split('.')[-1]
if extension.lower() not in ['pdf', 'png', 'gif', 'jpg', 'jpe', 'jpeg']:
raise ValidationError(f'File type not supported: {extension}')
def valid_doc_type(value):
valid_codes = ['AAI', 'AFDO', 'AFTL', 'CSA', 'EFSS', 'MC', 'NCV', 'OFI', 'RDP']
if value.upper() not in valid_codes:
raise ValidationError(f'Doc type not supported: {value}. Valid codes: {", ".join(valid_codes)}')
class CreateDocumentSerializer(serializers.ModelSerializer):
doc_type = serializers.CharField(required=True, validators=[valid_doc_type])
party_code = serializers.IntegerField(min_value=0, max_value=2, required=True)
file = serializers.FileField(required=True, validators=[valid_file_extension])
file = serializers.FileField(required=True, validators=[valid_file_extension,file_scan_validation])
filename = serializers.CharField(read_only=True)
size = serializers.IntegerField(read_only=True)
rotation = serializers.IntegerField(read_only=True)
@ -62,11 +51,6 @@ class CreateDocumentSerializer(serializers.ModelSerializer):
return response
def valid_rotation(value):
if value % 90 != 0:
raise serializers.ValidationError('Rotation must be 0, 90, 180, or 270')
class DocumentMetadataSerializer(serializers.ModelSerializer):
doc_type = serializers.CharField(read_only=True)
party_code = serializers.IntegerField(read_only=True)


+ 1
- 1
edivorce/apps/core/static/css/main.css
File diff suppressed because it is too large
View File


+ 15
- 0
edivorce/apps/core/static/css/main.scss View File

@ -646,6 +646,21 @@ select.form-control {
}
}
div#other_names_fields {
.form-inline {
.form-group {
@media (min-width: 992px) {
flex: inherit;
}
}
label {
width: calc(100% - 90px);
text-align: left;
}
}
}
/* Buttons & Icons*/
.btn {
line-height: initial;


+ 3
- 5
edivorce/apps/core/templates/partials/alias_field.html View File

@ -1,5 +1,5 @@
{% load input_field %}
<div class="form-inline clearfix alias-field-group">
<div class="form-inline clearfix alias-field-group alias-header">
{% comment As per request, alias type will fixed to "also know as" %}
<select class="response-dropdown alias-type form-control" name={{name}}>
<option value="also known as" {% if alias_type == 'also known as' %} selected {% endif %}>Also known as</option>
@ -9,10 +9,8 @@
</select>
{% endcomment %}
<div class="alias-header">
<label>Also known as</label>
<input type="button" class="btn btn-danger btn-delete-name form-control pull-right" value="Delete" />
</div>
<label>Also known as</label>
<input type="button" class="btn btn-danger btn-delete-name form-control pull-right" value="Delete" />
<div class="form-group name-group alias-body">
<div>
<p>First Name</p>


+ 1
- 1
edivorce/apps/core/templates/partials/filing_location.html View File

@ -1,6 +1,6 @@
{% if court_registry_for_filing %}
<ul class="no-bullets" id="court-registry-location">
<li id="court-registry-city">{{ court_registry_for_filing }}</li>
<li id="court-registry-city"><b>{{ court_registry_for_filing }}</b></li>
<li id="court-registry-address"></li>
<li id="court-registry-postal-code"></li>
</ul>


+ 11
- 3
edivorce/apps/core/tests/test_api.py View File

@ -72,7 +72,10 @@ class APITest(APITestCase):
'party_code': 1
}
self.client.force_authenticate(self.user)
response = self.client.post(url, data)
with self.settings(CLAMAV_ENABLED=False):
response = self.client.post(url, data)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Document.objects.count(), 1)
@ -97,13 +100,18 @@ class APITest(APITestCase):
'party_code': 1
}
self.client.force_authenticate(self.user)
response = self.client.post(url, data)
with self.settings(CLAMAV_ENABLED=False):
response = self.client.post(url, data)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Document.objects.count(), 1)
file.seek(0) #
response = self.client.post(url, data)
with self.settings(CLAMAV_ENABLED=False):
response = self.client.post(url, data)
self.assertContains(response,
'This file appears to have already been uploaded for this document.',
status_code=status.HTTP_400_BAD_REQUEST)


+ 3
- 3
edivorce/apps/core/tests/test_logic.py View File

@ -32,13 +32,13 @@ class ConditionalLogicTestCase(TestCase):
self.assertIsNone(logic.get_cleaned_response_value(' '))
self.assertIsNone(logic.get_cleaned_response_value('[]'))
self.assertIsNone(logic.get_cleaned_response_value('[[""," "]]'))
self.assertIsNone(logic.get_cleaned_response_value('[["also known as",""]]'))
self.assertIsNone(logic.get_cleaned_response_value('[["also known as",""],["also known as",""]]'))
self.assertIsNone(logic.get_cleaned_response_value('[["also known as","","","",""]]'))
self.assertIsNone(logic.get_cleaned_response_value('[["also known as","","","",""],["also known as","","","",""]]'))
def test_get_cleaned_response_with_value(self):
self.assertIsNotNone(logic.get_cleaned_response_value('0'))
self.assertIsNotNone(logic.get_cleaned_response_value('["hi"]'))
self.assertIsNotNone(logic.get_cleaned_response_value('[["also known as","a"]]'))
self.assertIsNotNone(logic.get_cleaned_response_value('[["also known as","a","b","",""]]'))
def test_num_children(self):
# No children


+ 21
- 16
edivorce/apps/core/tests/test_upload.py View File

@ -2,15 +2,20 @@ import clamd
from clamd import BufferTooLongError
from unittest import mock
from django import forms
from django.test import TestCase
from django.core.files.uploadedfile import SimpleUploadedFile
from rest_framework import serializers
from ..validators import file_scan_validation
from ..models import Document
class TestUploadForm(forms.Form):
upload = forms.FileField(validators=[file_scan_validation])
class TestUploadSerializer(serializers.ModelSerializer):
upload = serializers.FileField(validators=[file_scan_validation])
class Meta:
model = Document
fields = ('upload', 'filename')
class UploadScanTests(TestCase):
@ -18,17 +23,17 @@ class UploadScanTests(TestCase):
def test_validation_disabled(self):
with self.settings(CLAMAV_ENABLED=False):
infected = SimpleUploadedFile('infected.txt', clamd.EICAR)
form = TestUploadForm(files={'upload': infected})
serializer = TestUploadSerializer(data={'upload': infected})
self.assertTrue(form.is_valid(), form.errors)
self.assertTrue(serializer.is_valid(), serializer.errors)
def test_validation_invalid_network_connection(self):
with self.settings(CLAMAV_TCP_PORT=9999):
infected = SimpleUploadedFile('infected.txt', clamd.EICAR)
form = TestUploadForm(files={'upload': infected})
serializer = TestUploadSerializer(data={'upload': infected})
self.assertFalse(form.is_valid())
self.assertEqual(form.errors['upload'][0], 'Unable to scan file.')
self.assertFalse(serializer.is_valid())
self.assertEqual(serializer.errors['upload'][0], 'Unable to scan file.')
@mock.patch('clamd.ClamdNetworkSocket.instream')
def test_validation_buffer_overflow(self, mock_clam):
@ -36,26 +41,26 @@ class UploadScanTests(TestCase):
# by default clamav has a 10mb limit for instream
clean = SimpleUploadedFile('clean.txt', b'clean file')
form = TestUploadForm(files={'upload': clean})
serializer = TestUploadSerializer(data={'upload': clean})
self.assertFalse(form.is_valid())
self.assertEqual(form.errors['upload'][0], 'Unable to scan file.')
self.assertFalse(serializer.is_valid())
self.assertEqual(serializer.errors['upload'][0], 'Unable to scan file.')
@mock.patch('clamd.ClamdNetworkSocket.instream')
def test_validation_virus_found(self, mock_clam):
mock_clam.return_value = {'stream': ('FOUND', 'Eicar-Test-Signature')}
infected = SimpleUploadedFile('infected.txt', clamd.EICAR)
form = TestUploadForm(files={'upload': infected})
serializer = TestUploadSerializer(data={'upload': infected})
self.assertFalse(form.is_valid())
self.assertEqual(form.errors['upload'][0], 'Infected file found.')
self.assertFalse(serializer.is_valid())
self.assertEqual(serializer.errors['upload'][0], 'Infected file found.')
@mock.patch('clamd.ClamdNetworkSocket.instream')
def test_validation_no_virus_found(self, mock_clam):
mock_clam.return_value = {'stream': ('OK', None)}
clean = SimpleUploadedFile('clean.txt', b'clean file')
form = TestUploadForm(files={'upload': clean})
serializer = TestUploadSerializer(data={'upload': clean})
self.assertTrue(form.is_valid())
self.assertTrue(serializer.is_valid())

+ 37
- 2
edivorce/apps/core/utils/conditional_logic.py View File

@ -194,7 +194,42 @@ def get_cleaned_response_value(response):
if response is None:
return None
response = response.strip()
search_text = response.replace('also known as', '')
if re.search(r'\w+', search_text):
if response.startswith('[["also known as","'):
return __get_cleaned_aka(response)
if re.search(r'\w+', response):
return response
return None
def __get_cleaned_aka(response):
"""Checks is other_name_you and other_name_spouse (a.k.a. fields) are valid, and
containt both a first name and a last name"""
try:
aka = json.loads(response)
except:
return None
if len(aka) == 0 or len(aka[0]) != 5:
return None
has_lastname1 = re.search(r'\w+', aka[0][1])
has_firstname1 = re.search(r'\w+', aka[0][2])
if has_lastname1 and has_firstname1:
if len(aka) == 1:
return response
has_lastname2 = re.search(r'\w+', aka[1][1])
has_firstname2 = re.search(r'\w+', aka[1][2])
# firstname and lastname can both be blank or both have values
# but you can't have a value for one and not the other.
if has_lastname2 and has_firstname2:
return response
if not has_lastname2 and not has_firstname2:
return response
return None

+ 18
- 1
edivorce/apps/core/validators.py View File

@ -2,7 +2,7 @@ import logging
import clamd
import sys
from django.core.exceptions import ValidationError
from rest_framework.exceptions import ValidationError
from django.conf import settings
logger = logging.getLogger(__name__)
@ -42,3 +42,20 @@ def file_scan_validation(file):
if result and result['stream'][0] == 'FOUND':
logger.warning('Virus found: {}'.format(file.name))
raise ValidationError('Infected file found.', code='infected')
def valid_file_extension(file):
extension = file.name.split('.')[-1]
if extension.lower() not in ['pdf', 'png', 'gif', 'jpg', 'jpe', 'jpeg']:
raise ValidationError(f'File type not supported: {extension}')
def valid_doc_type(value):
valid_codes = ['AAI', 'AFDO', 'AFTL', 'CSA', 'EFSS', 'MC', 'NCV', 'OFI', 'RDP']
if value.upper() not in valid_codes:
raise ValidationError(f'Doc type not supported: {value}. Valid codes: {", ".join(valid_codes)}')
def valid_rotation(value):
if value % 90 != 0:
raise ValidationError('Rotation must be 0, 90, 180, or 270')

Loading…
Cancel
Save