Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IBAN updates #139

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions localflavor/generic/countries/iso_3166.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,5 @@
'ZA', # South Africa
'ZM', # Zambia
'ZW', # Zimbabwe
'XK' # Republic of Kosovo (user-assigned country code)
)
4 changes: 1 addition & 3 deletions localflavor/generic/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ def __init__(self, use_nordea_extensions=False, include_countries=None, *args, *

def to_python(self, value):
value = super(IBANFormField, self).to_python(value)
if value is not None:
return value.upper().replace(' ', '').replace('-', '')
return value
return value.upper().replace(' ', '').replace('-', '')

def prepare_value(self, value):
""" The display format for IBAN has a space every 4 characters. """
Expand Down
12 changes: 10 additions & 2 deletions localflavor/generic/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@

# Dictionary of ISO country code to IBAN length.
#
# References:
# The official IBAN Registry document is the best source for up-to-date information about IBAN formats and which
# countries are in IBAN.
#
# http://www.swift.com/dsp/resources/documents/IBAN_Registry.pdf
#
# Other Resources:
#
# https://en.wikipedia.org/wiki/International_Bank_Account_Number#IBAN_formats_by_country
# http://www.ecbs.org/iban/france-bank-account-number.html
# https://www.nordea.com/V%C3%A5ra+tj%C3%A4nster/Internationella+produkter+och+tj%C3%A4nster/Cash+Management/IBAN+countries/908472.html
Expand Down Expand Up @@ -79,9 +85,11 @@
'SI': 19, # Slovenia
'SK': 24, # Slovakia
'SM': 27, # San Marino
'TL': 23, # Timor-Leste
'TN': 24, # Tunisia
'TR': 26, # Turkey
'VG': 24} # British Virgin Islands
'VG': 24, # British Virgin Islands
'XK': 20} # Republic of Kosovo (user-assigned country code)


# Nordea has catalogued IBANs for some additional countries but they are not part of the office IBAN network yet.
Expand Down
41 changes: 37 additions & 4 deletions tests/test_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.test import SimpleTestCase, TestCase
from django.utils import formats

from localflavor.generic.countries.sepa import IBAN_SEPA_COUNTRIES
from localflavor.generic.models import BICField, IBANField
from localflavor.generic.validators import BICValidator, IBANValidator
from localflavor.generic.forms import DateField, DateTimeField, SplitDateTimeField, BICFormField, IBANFormField
Expand Down Expand Up @@ -111,6 +112,8 @@ def test_iban_validator(self):
'CH9300762011623852957',
'IL620108000000099999999',
'EE982200221111099080',

None,
]

invalid = {
Expand All @@ -121,8 +124,9 @@ def test_iban_validator(self):
'EE012200221111099080': 'Not a valid IBAN.',
}

iban_validator = IBANValidator()
for iban in valid:
IBANValidator(iban)
iban_validator(iban)

for iban in invalid:
self.assertRaisesMessage(ValidationError, invalid[iban], IBANValidator(), iban)
Expand Down Expand Up @@ -174,6 +178,8 @@ def test_iban_fields(self):
for input, output in valid.items():
self.assertEqual(iban_model_field.clean(input, None), output)

self.assertIsNone(iban_model_field.to_python(None))

# Invalid inputs for model field.
for input, errors in invalid.items():
with self.assertRaises(ValidationError) as context_manager:
Expand All @@ -193,6 +199,7 @@ def test_form_field_formatting(self):
self.assertEqual(iban_form_field.prepare_value('NL02ABNA0123456789'), 'NL02 ABNA 0123 4567 89')
self.assertEqual(iban_form_field.prepare_value('NL02 ABNA 0123 4567 89'), 'NL02 ABNA 0123 4567 89')
self.assertIsNone(iban_form_field.prepare_value(None))
self.assertEqual(iban_form_field.to_python(None), '')

def test_include_countries(self):
""" Test the IBAN model and form include_countries feature. """
Expand Down Expand Up @@ -226,15 +233,37 @@ def test_include_countries(self):
self.assertEqual(context_manager.exception.messages, errors)

def test_misconfigured_include_countries(self):
""" Test that an IBAN field or model raises an error when asked to validate a country not part of IBAN.
"""
# Test an unassigned ISO 3166-1 country code so that the tests will work even if a country joins IBAN.
""" Test that an IBAN field or model raises an error when asked to validate a country not part of IBAN. """
# Test an unassigned ISO 3166-1 country code.
self.assertRaises(ImproperlyConfigured, IBANValidator, include_countries=('JJ',))
self.assertRaises(ImproperlyConfigured, IBANValidator, use_nordea_extensions=True, include_countries=('JJ',))

# Test a Nordea IBAN when Nordea extensions are turned off.
self.assertRaises(ImproperlyConfigured, IBANValidator, include_countries=('AO',))

def test_sepa_countries(self):
""" Test include_countries using the SEPA counties. """
# A few SEPA valid IBANs.
valid = {
'GI75 NWBK 0000 0000 7099 453': 'GI75NWBK000000007099453',
'CH93 0076 2011 6238 5295 7': 'CH9300762011623852957',
'GB29 NWBK 6016 1331 9268 19': 'GB29NWBK60161331926819'
}

# A few non-SEPA valid IBANs.
invalid = {
'SA03 8000 0000 6080 1016 7519': ['SA IBANs are not allowed in this field.'],
'CR05 1520 2001 0262 8406 6': ['CR IBANs are not allowed in this field.'],
'XK05 1212 0123 4567 8906': ['XK IBANs are not allowed in this field.']
}

self.assertFieldOutput(IBANFormField, field_kwargs={'include_countries': IBAN_SEPA_COUNTRIES},
valid=valid, invalid=invalid)

def test_default_form(self):
iban_model_field = IBANField()
self.assertEqual(type(iban_model_field.formfield()), type(IBANFormField()))


class BICTests(TestCase):
def test_bic_validator(self):
Expand Down Expand Up @@ -304,3 +333,7 @@ def test_bic_model_field(self):
with self.assertRaises(ValidationError) as context_manager:
bic_model_field.clean(input, None)
self.assertEqual(errors, context_manager.exception.messages)

def test_default_form(self):
bic_model_field = BICField()
self.assertEqual(type(bic_model_field.formfield()), type(BICFormField()))