Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #15856 -- Added Macedonian localflavor. Many thanks to vasiliyeah.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16385 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 050e11956f8bf6589e8c93c6ccdbe5fc03e7e410 1 parent 9f3d76a
Jannis Leidel authored
100  django/contrib/localflavor/mk/forms.py
... ...
@@ -0,0 +1,100 @@
  1
+import datetime
  2
+
  3
+from django.core.validators import EMPTY_VALUES
  4
+from django.forms import ValidationError
  5
+from django.forms.fields import RegexField, Select
  6
+from django.utils.translation import ugettext_lazy as _
  7
+
  8
+from mk_choices import MK_MUNICIPALITIES
  9
+
  10
+
  11
+class MKIdentityCardNumberField(RegexField):
  12
+    """
  13
+    A Macedonian ID card number. Accepts both old and new format.
  14
+    """
  15
+    default_error_messages = {
  16
+        'invalid': _(u'Identity card numbers must contain'
  17
+                     ' either 4 to 7 digits or an uppercase letter and 7 digits.'),
  18
+    }
  19
+
  20
+    def __init__(self, *args, **kwargs):
  21
+        kwargs['min_length'] = None
  22
+        kwargs['max_length'] = 8
  23
+        regex = ur'(^[A-Z]{1}\d{7}$)|(^\d{4,7}$)'
  24
+        super(MKIdentityCardNumberField, self).__init__(regex, *args, **kwargs)
  25
+
  26
+
  27
+class MKMunicipalitySelect(Select):
  28
+    """
  29
+    A form ``Select`` widget that uses a list of Macedonian municipalities as
  30
+    choices. The label is the name of the municipality and the value
  31
+    is a 2 character code for the municipality.
  32
+    """
  33
+
  34
+    def __init__(self, attrs=None):
  35
+        super(MKMunicipalitySelect, self).__init__(attrs, choices = MK_MUNICIPALITIES)
  36
+
  37
+
  38
+class UMCNField(RegexField):
  39
+    """
  40
+    A form field that validates input as a unique master citizen
  41
+    number.
  42
+
  43
+    The format of the unique master citizen number has been kept the same from
  44
+    Yugoslavia. It is still in use in other countries as well, it is not applicable
  45
+    solely in Macedonia. For more information see:
  46
+    https://secure.wikimedia.org/wikipedia/en/wiki/Unique_Master_Citizen_Number
  47
+
  48
+    A value will pass validation if it complies to the following rules:
  49
+
  50
+    * Consists of exactly 13 digits
  51
+    * The first 7 digits represent a valid past date in the format DDMMYYY
  52
+    * The last digit of the UMCN passes a checksum test
  53
+    """
  54
+    default_error_messages = {
  55
+        'invalid': _(u'This field should contain exactly 13 digits.'),
  56
+        'date': _(u'The first 7 digits of the UMCN must represent a valid past date.'),
  57
+        'checksum': _(u'The UMCN is not valid.'),
  58
+    }
  59
+
  60
+    def __init__(self, *args, **kwargs):
  61
+        kwargs['min_length'] = None
  62
+        kwargs['max_length'] = 13
  63
+        super(UMCNField, self).__init__(r'^\d{13}$', *args, **kwargs)
  64
+
  65
+    def clean(self, value):
  66
+        value = super(UMCNField, self).clean(value)
  67
+
  68
+        if value in EMPTY_VALUES:
  69
+            return u''
  70
+
  71
+        if not self._validate_date_part(value):
  72
+            raise ValidationError(self.error_messages['date'])
  73
+        if self._validate_checksum(value):
  74
+            return value
  75
+        else:
  76
+            raise ValidationError(self.error_messages['checksum'])
  77
+
  78
+    def _validate_checksum(self, value):
  79
+        a,b,c,d,e,f,g,h,i,j,k,l,K = [int(digit) for digit in  value]
  80
+        m = 11 - (( 7*(a+g) + 6*(b+h) + 5*(c+i) + 4*(d+j) + 3*(e+k) + 2*(f+l)) % 11)
  81
+        if (m >= 1 and m <= 9) and K == m:
  82
+            return True
  83
+        elif m == 11 and K == 0:
  84
+            return True
  85
+        else:
  86
+            return False
  87
+
  88
+    def _validate_date_part(self, value):
  89
+        daypart, monthpart, yearpart = int(value[:2]), int(value[2:4]), int(value[4:7])
  90
+        if yearpart >= 800:
  91
+            yearpart += 1000
  92
+        else:
  93
+            yearpart += 2000
  94
+        try:
  95
+            date = datetime.datetime(year = yearpart, month = monthpart, day = daypart).date()
  96
+        except ValueError:
  97
+            return False
  98
+        if date >= datetime.datetime.now().date():
  99
+            return False
  100
+        return True
92  django/contrib/localflavor/mk/mk_choices.py
... ...
@@ -0,0 +1,92 @@
  1
+# -*- coding: utf-8 -*-
  2
+"""
  3
+Macedonian municipalities per the reorganization from 2004.
  4
+"""
  5
+from django.utils.translation import ugettext_lazy as _
  6
+
  7
+MK_MUNICIPALITIES = (
  8
+    ('AD', _(u'Aerodrom')),
  9
+    ('AR', _(u'Aračinovo')),
  10
+    ('BR', _(u'Berovo')),
  11
+    ('TL', _(u'Bitola')),
  12
+    ('BG', _(u'Bogdanci')),
  13
+    ('VJ', _(u'Bogovinje')),
  14
+    ('BS', _(u'Bosilovo')),
  15
+    ('BN', _(u'Brvenica')),
  16
+    ('BU', _(u'Butel')),
  17
+    ('VA', _(u'Valandovo')),
  18
+    ('VL', _(u'Vasilevo')),
  19
+    ('VV', _(u'Vevčani')),
  20
+    ('VE', _(u'Veles')),
  21
+    ('NI', _(u'Vinica')),
  22
+    ('VC', _(u'Vraneštica')),
  23
+    ('VH', _(u'Vrapčište')),
  24
+    ('GB', _(u'Gazi Baba')),
  25
+    ('GV', _(u'Gevgelija')),
  26
+    ('GT', _(u'Gostivar')),
  27
+    ('GR', _(u'Gradsko')),
  28
+    ('DB', _(u'Debar')),
  29
+    ('DA', _(u'Debarca')),
  30
+    ('DL', _(u'Delčevo')),
  31
+    ('DK', _(u'Demir Kapija')),
  32
+    ('DM', _(u'Demir Hisar')),
  33
+    ('DE', _(u'Dolneni')),
  34
+    ('DR', _(u'Drugovo')),
  35
+    ('GP', _(u'Gjorče Petrov')),
  36
+    ('ZE', _(u'Želino')),
  37
+    ('ZA', _(u'Zajas')),
  38
+    ('ZK', _(u'Zelenikovo')),
  39
+    ('ZR', _(u'Zrnovci')),
  40
+    ('IL', _(u'Ilinden')),
  41
+    ('JG', _(u'Jegunovce')),
  42
+    ('AV', _(u'Kavadarci')),
  43
+    ('KB', _(u'Karbinci')),
  44
+    ('KX', _(u'Karpoš')),
  45
+    ('VD', _(u'Kisela Voda')),
  46
+    ('KH', _(u'Kičevo')),
  47
+    ('KN', _(u'Konče')),
  48
+    ('OC', _(u'Koćani')),
  49
+    ('KY', _(u'Kratovo')),
  50
+    ('KZ', _(u'Kriva Palanka')),
  51
+    ('KG', _(u'Krivogaštani')),
  52
+    ('KS', _(u'Kruševo')),
  53
+    ('UM', _(u'Kumanovo')),
  54
+    ('LI', _(u'Lipkovo')),
  55
+    ('LO', _(u'Lozovo')),
  56
+    ('MR', _(u'Mavrovo i Rostuša')),
  57
+    ('MK', _(u'Makedonska Kamenica')),
  58
+    ('MD', _(u'Makedonski Brod')),
  59
+    ('MG', _(u'Mogila')),
  60
+    ('NG', _(u'Negotino')),
  61
+    ('NV', _(u'Novaci')),
  62
+    ('NS', _(u'Novo Selo')),
  63
+    ('OS', _(u'Oslomej')),
  64
+    ('OD', _(u'Ohrid')),
  65
+    ('PE', _(u'Petrovec')),
  66
+    ('PH', _(u'Pehčevo')),
  67
+    ('PN', _(u'Plasnica')),
  68
+    ('PP', _(u'Prilep')),
  69
+    ('PT', _(u'Probištip')),
  70
+    ('RV', _(u'Radoviš')),
  71
+    ('RN', _(u'Rankovce')),
  72
+    ('RE', _(u'Resen')),
  73
+    ('RO', _(u'Rosoman')),
  74
+    ('AJ', _(u'Saraj')),
  75
+    ('SL', _(u'Sveti Nikole')),
  76
+    ('SS', _(u'Sopište')),
  77
+    ('SD', _(u'Star Dojran')),
  78
+    ('NA', _(u'Staro Nagoričane')),
  79
+    ('UG', _(u'Struga')),
  80
+    ('RU', _(u'Strumica')),
  81
+    ('SU', _(u'Studeničani')),
  82
+    ('TR', _(u'Tearce')),
  83
+    ('ET', _(u'Tetovo')),
  84
+    ('CE', _(u'Centar')),
  85
+    ('CZ', _(u'Centar-Župa')),
  86
+    ('CI', _(u'Čair')),
  87
+    ('CA', _(u'Čaška')),
  88
+    ('CH', _(u'Češinovo-Obleševo')),
  89
+    ('CS', _(u'Čučer-Sandevo')),
  90
+    ('ST', _(u'Štip')),
  91
+    ('SO', _(u'Šuto Orizari')),
  92
+)
44  django/contrib/localflavor/mk/models.py
... ...
@@ -0,0 +1,44 @@
  1
+from django.db.models.fields import CharField
  2
+from django.utils.translation import ugettext_lazy as _
  3
+
  4
+from django.contrib.localflavor.mk.mk_choices import MK_MUNICIPALITIES
  5
+from django.contrib.localflavor.mk.forms import (UMCNField as UMCNFormField,
  6
+    MKIdentityCardNumberField as MKIdentityCardNumberFormField)
  7
+
  8
+
  9
+class MKIdentityCardNumberField(CharField):
  10
+
  11
+    description = _("Macedonian identity card number")
  12
+
  13
+    def __init__(self, *args, **kwargs):
  14
+        kwargs['max_length'] = 8
  15
+        super(MKIdentityCardNumberField, self).__init__(*args, **kwargs)
  16
+
  17
+    def formfield(self, **kwargs):
  18
+        defaults = {'form_class' : MKIdentityCardNumberFormField}
  19
+        defaults.update(kwargs)
  20
+        return super(MKIdentityCardNumberField, self).formfield(**defaults)
  21
+
  22
+
  23
+class MKMunicipalityField(CharField):
  24
+
  25
+    description = _("A Macedonian municipality (2 character code)")
  26
+
  27
+    def __init__(self, *args, **kwargs):
  28
+        kwargs['choices'] = MK_MUNICIPALITIES
  29
+        kwargs['max_length'] = 2
  30
+        super(MKMunicipalityField, self).__init__(*args, **kwargs)
  31
+
  32
+
  33
+class UMCNField(CharField):
  34
+
  35
+    description = _("Unique master citizen number (13 digits)")
  36
+
  37
+    def __init__(self, *args, **kwargs):
  38
+        kwargs['max_length'] = 13
  39
+        super(UMCNField, self).__init__(*args, **kwargs)
  40
+
  41
+    def formfield(self, **kwargs):
  42
+        defaults = {'form_class' : UMCNFormField}
  43
+        defaults.update(kwargs)
  44
+        return super(UMCNField, self).formfield(**defaults)
55  docs/ref/contrib/localflavor.txt
@@ -57,6 +57,7 @@ Countries currently supported by :mod:`~django.contrib.localflavor` are:
57 57
     * Italy_
58 58
     * Japan_
59 59
     * Kuwait_
  60
+    * Macedonia_
60 61
     * Mexico_
61 62
     * `The Netherlands`_
62 63
     * Norway_
@@ -110,6 +111,7 @@ Here's an example of how to use them::
110 111
 .. _Italy: `Italy (it)`_
111 112
 .. _Japan: `Japan (jp)`_
112 113
 .. _Kuwait: `Kuwait (kw)`_
  114
+.. _Macedonia: `Macedonia (mk)`_
113 115
 .. _Mexico: `Mexico (mx)`_
114 116
 .. _Norway: `Norway (no)`_
115 117
 .. _Peru: `Peru (pe)`_
@@ -652,8 +654,6 @@ Israel (``il``)
652 654
 .. _Israeli identification number: http://he.wikipedia.org/wiki/%D7%9E%D7%A1%D7%A4%D7%A8_%D7%96%D7%94%D7%95%D7%AA_(%D7%99%D7%A9%D7%A8%D7%90%D7%9C)
653 655
 .. _Luhn algorithm: http://en.wikipedia.org/wiki/Luhn_algorithm
654 656
 
655  
-
656  
-
657 657
 Italy (``it``)
658 658
 ==============
659 659
 
@@ -705,6 +705,57 @@ Kuwait (``kw``)
705 705
     * The birthdate of the person is a valid date.
706 706
     * The calculated checksum equals to the last digit of the Civil ID.
707 707
 
  708
+Macedonia (``mk``)
  709
+===================
  710
+
  711
+.. versionadded:: 1.4
  712
+
  713
+.. class:: mk.forms.MKIdentityCardNumberField
  714
+
  715
+    A form field that validates input as a Macedonian identity card number.
  716
+    Both old and new identity card numbers are supported.
  717
+
  718
+
  719
+.. class:: mk.forms.MKMunicipalitySelect
  720
+
  721
+    A form ``Select`` widget that uses a list of Macedonian municipalities as
  722
+    choices.
  723
+
  724
+
  725
+.. class:: mk.forms.UMCNField
  726
+
  727
+    A form field that validates input as a unique master citizen
  728
+    number.
  729
+
  730
+    The format of the unique master citizen number is not unique
  731
+    to Macedonia. For more information see:
  732
+    https://secure.wikimedia.org/wikipedia/en/wiki/Unique_Master_Citizen_Number
  733
+
  734
+    A value will pass validation if it complies to the following rules:
  735
+
  736
+    * Consists of exactly 13 digits
  737
+    * The first 7 digits represent a valid past date in the format DDMMYYY
  738
+    * The last digit of the UMCN passes a checksum test
  739
+
  740
+
  741
+.. class:: mk.models.MKIdentityCardNumberField
  742
+
  743
+   A model field that forms represent as a
  744
+   ``forms.MKIdentityCardNumberField`` field.
  745
+
  746
+
  747
+.. class:: mk.models.MKMunicipalityField
  748
+
  749
+   A model field that forms represent as a
  750
+   ``forms.MKMunicipalitySelect`` and stores the 2 character code of the
  751
+   municipality in the database.
  752
+
  753
+
  754
+.. class:: mk.models.UMCNField
  755
+
  756
+   A model field that forms represent as a ``forms.UMCNField`` field.
  757
+
  758
+
708 759
 Mexico (``mx``)
709 760
 ===============
710 761
 
0  localflavor/mk/__init__.py b/django/contrib/localflavor/mk/__init__.py
No changes.
131  tests/regressiontests/forms/localflavor/mk.py
... ...
@@ -0,0 +1,131 @@
  1
+from django.contrib.localflavor.mk.forms import (
  2
+    MKIdentityCardNumberField, MKMunicipalitySelect, UMCNField)
  3
+
  4
+from utils import LocalFlavorTestCase
  5
+
  6
+
  7
+class MKLocalFlavorTests(LocalFlavorTestCase):
  8
+
  9
+    def test_MKIdentityCardNumberField(self):
  10
+        error_invalid  = (u'Identity card numbers must contain'
  11
+            ' either 4 to 7 digits or an uppercase letter and 7 digits.')
  12
+        valid = {
  13
+            'L0018077':'L0018077',
  14
+            'A0078315' : 'A0078315',
  15
+        }
  16
+        invalid = {
  17
+            '123': error_invalid,
  18
+            'abcdf': error_invalid,
  19
+            '234390a': error_invalid,
  20
+        }
  21
+        self.assertFieldOutput(MKIdentityCardNumberField, valid, invalid)
  22
+
  23
+    def test_MKMunicipalitySelect(self):
  24
+        f = MKMunicipalitySelect()
  25
+        out=u'''<select name="municipality">
  26
+<option value="AD">Aerodrom</option>
  27
+<option value="AR">Ara\u010dinovo</option>
  28
+<option value="BR">Berovo</option>
  29
+<option value="TL">Bitola</option>
  30
+<option value="BG">Bogdanci</option>
  31
+<option value="VJ">Bogovinje</option>
  32
+<option value="BS">Bosilovo</option>
  33
+<option value="BN">Brvenica</option>
  34
+<option value="BU">Butel</option>
  35
+<option value="VA">Valandovo</option>
  36
+<option value="VL">Vasilevo</option>
  37
+<option value="VV">Vev\u010dani</option>
  38
+<option value="VE">Veles</option>
  39
+<option value="NI">Vinica</option>
  40
+<option value="VC">Vrane\u0161tica</option>
  41
+<option value="VH">Vrap\u010di\u0161te</option>
  42
+<option value="GB">Gazi Baba</option>
  43
+<option value="GV">Gevgelija</option>
  44
+<option value="GT">Gostivar</option>
  45
+<option value="GR">Gradsko</option>
  46
+<option value="DB">Debar</option>
  47
+<option value="DA">Debarca</option>
  48
+<option value="DL" selected="selected">Del\u010devo</option>
  49
+<option value="DK">Demir Kapija</option>
  50
+<option value="DM">Demir Hisar</option>
  51
+<option value="DE">Dolneni</option>
  52
+<option value="DR">Drugovo</option>
  53
+<option value="GP">Gjor\u010de Petrov</option>
  54
+<option value="ZE">\u017delino</option>
  55
+<option value="ZA">Zajas</option>
  56
+<option value="ZK">Zelenikovo</option>
  57
+<option value="ZR">Zrnovci</option>
  58
+<option value="IL">Ilinden</option>
  59
+<option value="JG">Jegunovce</option>
  60
+<option value="AV">Kavadarci</option>
  61
+<option value="KB">Karbinci</option>
  62
+<option value="KX">Karpo\u0161</option>
  63
+<option value="VD">Kisela Voda</option>
  64
+<option value="KH">Ki\u010devo</option>
  65
+<option value="KN">Kon\u010de</option>
  66
+<option value="OC">Ko\u0107ani</option>
  67
+<option value="KY">Kratovo</option>
  68
+<option value="KZ">Kriva Palanka</option>
  69
+<option value="KG">Krivoga\u0161tani</option>
  70
+<option value="KS">Kru\u0161evo</option>
  71
+<option value="UM">Kumanovo</option>
  72
+<option value="LI">Lipkovo</option>
  73
+<option value="LO">Lozovo</option>
  74
+<option value="MR">Mavrovo i Rostu\u0161a</option>
  75
+<option value="MK">Makedonska Kamenica</option>
  76
+<option value="MD">Makedonski Brod</option>
  77
+<option value="MG">Mogila</option>
  78
+<option value="NG">Negotino</option>
  79
+<option value="NV">Novaci</option>
  80
+<option value="NS">Novo Selo</option>
  81
+<option value="OS">Oslomej</option>
  82
+<option value="OD">Ohrid</option>
  83
+<option value="PE">Petrovec</option>
  84
+<option value="PH">Peh\u010devo</option>
  85
+<option value="PN">Plasnica</option>
  86
+<option value="PP">Prilep</option>
  87
+<option value="PT">Probi\u0161tip</option>
  88
+<option value="RV">Radovi\u0161</option>
  89
+<option value="RN">Rankovce</option>
  90
+<option value="RE">Resen</option>
  91
+<option value="RO">Rosoman</option>
  92
+<option value="AJ">Saraj</option>
  93
+<option value="SL">Sveti Nikole</option>
  94
+<option value="SS">Sopi\u0161te</option>
  95
+<option value="SD">Star Dojran</option>
  96
+<option value="NA">Staro Nagori\u010dane</option>
  97
+<option value="UG">Struga</option>
  98
+<option value="RU">Strumica</option>
  99
+<option value="SU">Studeni\u010dani</option>
  100
+<option value="TR">Tearce</option>
  101
+<option value="ET">Tetovo</option>
  102
+<option value="CE">Centar</option>
  103
+<option value="CZ">Centar-\u017dupa</option>
  104
+<option value="CI">\u010cair</option>
  105
+<option value="CA">\u010ca\u0161ka</option>
  106
+<option value="CH">\u010ce\u0161inovo-Oble\u0161evo</option>
  107
+<option value="CS">\u010cu\u010der-Sandevo</option>
  108
+<option value="ST">\u0160tip</option>
  109
+<option value="SO">\u0160uto Orizari</option>
  110
+</select>'''
  111
+        self.assertEqual(f.render('municipality', 'DL' ), out)
  112
+
  113
+    def test_UMCNField(self):
  114
+        error_invalid = [u'This field should contain exactly 13 digits.']
  115
+        error_checksum = [u'The UMCN is not valid.']
  116
+        error_date =  [u'The first 7 digits of the UMCN '
  117
+                        'must represent a valid past date.']
  118
+        valid = {
  119
+            '2402983450006': '2402983450006',
  120
+            '2803984430038': '2803984430038',
  121
+            '1909982045004': '1909982045004',
  122
+        }
  123
+        invalid = {
  124
+            '240298345': error_invalid,
  125
+            'abcdefghj': error_invalid,
  126
+            '2402082450006': error_date,
  127
+            '3002982450006': error_date,
  128
+            '2402983450007': error_checksum,
  129
+            '2402982450006': error_checksum,
  130
+        }
  131
+        self.assertFieldOutput(UMCNField, valid, invalid)
1  tests/regressiontests/forms/localflavortests.py
@@ -23,6 +23,7 @@
23 23
 from localflavor.it import ITLocalFlavorTests
24 24
 from localflavor.jp import JPLocalFlavorTests
25 25
 from localflavor.kw import KWLocalFlavorTests
  26
+from localflavor.mk import MKLocalFlavorTests
26 27
 from localflavor.nl import NLLocalFlavorTests
27 28
 from localflavor.pl import PLLocalFlavorTests
28 29
 from localflavor.pt import PTLocalFlavorTests
1  tests/regressiontests/forms/tests/__init__.py
@@ -36,6 +36,7 @@
36 36
     ITLocalFlavorTests,
37 37
     JPLocalFlavorTests,
38 38
     KWLocalFlavorTests,
  39
+    MKLocalFlavorTests,
39 40
     NLLocalFlavorTests,
40 41
     PLLocalFlavorTests,
41 42
     PTLocalFlavorTests,
0  tests/regressiontests/localflavor/mk/__init__.py
No changes.
7  tests/regressiontests/localflavor/mk/forms.py
... ...
@@ -0,0 +1,7 @@
  1
+from django.forms import ModelForm
  2
+from models import MKPerson
  3
+
  4
+class MKPersonForm(ModelForm):
  5
+
  6
+    class Meta:
  7
+        model = MKPerson
14  tests/regressiontests/localflavor/mk/models.py
... ...
@@ -0,0 +1,14 @@
  1
+from django.db import models
  2
+from django.contrib.localflavor.mk.models import (
  3
+    MKIdentityCardNumberField, MKMunicipalityField, UMCNField)
  4
+
  5
+class MKPerson(models.Model):
  6
+    first_name = models.CharField(max_length = 20)
  7
+    last_name = models.CharField(max_length = 20)
  8
+    umcn = UMCNField()
  9
+    id_number = MKIdentityCardNumberField()
  10
+    municipality  = MKMunicipalityField(blank = True)
  11
+    municipality_req = MKMunicipalityField(blank = False) 
  12
+
  13
+    class Meta:
  14
+        app_label = 'localflavor'
176  tests/regressiontests/localflavor/mk/tests.py
... ...
@@ -0,0 +1,176 @@
  1
+from django.test import TestCase
  2
+from forms import MKPersonForm
  3
+
  4
+class MKLocalflavorTests(TestCase):
  5
+    def setUp(self):
  6
+        self.form = MKPersonForm({
  7
+            'first_name':'Someone',
  8
+            'last_name':'Something',
  9
+            'umcn': '2402983450006',
  10
+            'municipality':'OD',
  11
+            'municipality_req':'VE',
  12
+            'id_number':'A1234567',
  13
+        })
  14
+
  15
+    def test_get_display_methods(self):
  16
+        """
  17
+        Test that the get_*_display() methods are added to the model instances.
  18
+        """
  19
+        person = self.form.save()
  20
+        self.assertEqual(person.get_municipality_display(), 'Ohrid')
  21
+        self.assertEqual(person.get_municipality_req_display(), 'Veles')
  22
+
  23
+    def test_municipality_required(self):
  24
+        """
  25
+        Test that required MKMunicipalityFields throw appropriate errors.
  26
+        """
  27
+
  28
+        form = MKPersonForm({
  29
+            'first_name':'Someone',
  30
+            'last_name':'Something',
  31
+            'umcn': '2402983450006',
  32
+            'municipality':'OD',
  33
+            'id_number':'A1234567',
  34
+        })
  35
+        self.assertFalse(form.is_valid())
  36
+        self.assertEqual(
  37
+            form.errors['municipality_req'], [u'This field is required.'])
  38
+
  39
+    def test_umcn_invalid(self):
  40
+        """
  41
+        Test that UMCNFields throw appropriate errors for invalid UMCNs.
  42
+        """
  43
+        form = MKPersonForm({
  44
+            'first_name':'Someone',
  45
+            'last_name':'Something',
  46
+            'umcn': '2402983450007',
  47
+            'municipality':'OD',
  48
+            'municipality_req':'VE',
  49
+            'id_number':'A1234567',
  50
+        })
  51
+        self.assertFalse(form.is_valid())
  52
+        self.assertEqual(form.errors['umcn'], [u'The UMCN is not valid.'])
  53
+
  54
+        form = MKPersonForm({
  55
+            'first_name':'Someone',
  56
+            'last_name':'Something',
  57
+            'umcn': '3002983450007',
  58
+            'municipality':'OD',
  59
+            'municipality_req':'VE',
  60
+            'id_number':'A1234567',
  61
+        })
  62
+        self.assertEqual(form.errors['umcn'],
  63
+                [u'The first 7 digits of the UMCN must represent a valid past date.'])
  64
+
  65
+    def test_idnumber_invalid(self):
  66
+        """
  67
+        Test that MKIdentityCardNumberFields throw
  68
+        appropriate errors for invalid values
  69
+        """
  70
+
  71
+        form = MKPersonForm({
  72
+            'first_name':'Someone',
  73
+            'last_name':'Something',
  74
+            'umcn': '2402983450007',
  75
+            'municipality':'OD',
  76
+            'municipality_req':'VE',
  77
+            'id_number':'A123456a',
  78
+        })
  79
+        self.assertFalse(form.is_valid())
  80
+        self.assertEqual(form.errors['id_number'],
  81
+            [u'Identity card numbers must contain either 4 to 7 '
  82
+              'digits or an uppercase letter and 7 digits.'])
  83
+
  84
+    def test_field_blank_option(self):
  85
+        """
  86
+        Test that the empty option is there.
  87
+        """
  88
+        municipality_select_html = """\
  89
+<select name="municipality" id="id_municipality">
  90
+<option value="">---------</option>
  91
+<option value="AD">Aerodrom</option>
  92
+<option value="AR">Ara\xc4\x8dinovo</option>
  93
+<option value="BR">Berovo</option>
  94
+<option value="TL">Bitola</option>
  95
+<option value="BG">Bogdanci</option>
  96
+<option value="VJ">Bogovinje</option>
  97
+<option value="BS">Bosilovo</option>
  98
+<option value="BN">Brvenica</option>
  99
+<option value="BU">Butel</option>
  100
+<option value="VA">Valandovo</option>
  101
+<option value="VL">Vasilevo</option>
  102
+<option value="VV">Vev\xc4\x8dani</option>
  103
+<option value="VE">Veles</option>
  104
+<option value="NI">Vinica</option>
  105
+<option value="VC">Vrane\xc5\xa1tica</option>
  106
+<option value="VH">Vrap\xc4\x8di\xc5\xa1te</option>
  107
+<option value="GB">Gazi Baba</option>
  108
+<option value="GV">Gevgelija</option>
  109
+<option value="GT">Gostivar</option>
  110
+<option value="GR">Gradsko</option>
  111
+<option value="DB">Debar</option>
  112
+<option value="DA">Debarca</option>
  113
+<option value="DL">Del\xc4\x8devo</option>
  114
+<option value="DK">Demir Kapija</option>
  115
+<option value="DM">Demir Hisar</option>
  116
+<option value="DE">Dolneni</option>
  117
+<option value="DR">Drugovo</option>
  118
+<option value="GP">Gjor\xc4\x8de Petrov</option>
  119
+<option value="ZE">\xc5\xbdelino</option>
  120
+<option value="ZA">Zajas</option>
  121
+<option value="ZK">Zelenikovo</option>
  122
+<option value="ZR">Zrnovci</option>
  123
+<option value="IL">Ilinden</option>
  124
+<option value="JG">Jegunovce</option>
  125
+<option value="AV">Kavadarci</option>
  126
+<option value="KB">Karbinci</option>
  127
+<option value="KX">Karpo\xc5\xa1</option>
  128
+<option value="VD">Kisela Voda</option>
  129
+<option value="KH">Ki\xc4\x8devo</option>
  130
+<option value="KN">Kon\xc4\x8de</option>
  131
+<option value="OC">Ko\xc4\x87ani</option>
  132
+<option value="KY">Kratovo</option>
  133
+<option value="KZ">Kriva Palanka</option>
  134
+<option value="KG">Krivoga\xc5\xa1tani</option>
  135
+<option value="KS">Kru\xc5\xa1evo</option>
  136
+<option value="UM">Kumanovo</option>
  137
+<option value="LI">Lipkovo</option>
  138
+<option value="LO">Lozovo</option>
  139
+<option value="MR">Mavrovo i Rostu\xc5\xa1a</option>
  140
+<option value="MK">Makedonska Kamenica</option>
  141
+<option value="MD">Makedonski Brod</option>
  142
+<option value="MG">Mogila</option>
  143
+<option value="NG">Negotino</option>
  144
+<option value="NV">Novaci</option>
  145
+<option value="NS">Novo Selo</option>
  146
+<option value="OS">Oslomej</option>
  147
+<option value="OD" selected="selected">Ohrid</option>
  148
+<option value="PE">Petrovec</option>
  149
+<option value="PH">Peh\xc4\x8devo</option>
  150
+<option value="PN">Plasnica</option>
  151
+<option value="PP">Prilep</option>
  152
+<option value="PT">Probi\xc5\xa1tip</option>
  153
+<option value="RV">Radovi\xc5\xa1</option>
  154
+<option value="RN">Rankovce</option>
  155
+<option value="RE">Resen</option>
  156
+<option value="RO">Rosoman</option>
  157
+<option value="AJ">Saraj</option>
  158
+<option value="SL">Sveti Nikole</option>
  159
+<option value="SS">Sopi\xc5\xa1te</option>
  160
+<option value="SD">Star Dojran</option>
  161
+<option value="NA">Staro Nagori\xc4\x8dane</option>
  162
+<option value="UG">Struga</option>
  163
+<option value="RU">Strumica</option>
  164
+<option value="SU">Studeni\xc4\x8dani</option>
  165
+<option value="TR">Tearce</option>
  166
+<option value="ET">Tetovo</option>
  167
+<option value="CE">Centar</option>
  168
+<option value="CZ">Centar-\xc5\xbdupa</option>
  169
+<option value="CI">\xc4\x8cair</option>
  170
+<option value="CA">\xc4\x8ca\xc5\xa1ka</option>
  171
+<option value="CH">\xc4\x8ce\xc5\xa1inovo-Oble\xc5\xa1evo</option>
  172
+<option value="CS">\xc4\x8cu\xc4\x8der-Sandevo</option>
  173
+<option value="ST">\xc5\xa0tip</option>
  174
+<option value="SO">\xc5\xa0uto Orizari</option>
  175
+</select>"""
  176
+        self.assertEqual(str(self.form['municipality']), municipality_select_html)
4  tests/regressiontests/localflavor/tests.py
@@ -2,5 +2,7 @@
2 2
 from django.utils import unittest
3 3
 
4 4
 # just import your tests here
5  
-from us.tests import *
6 5
 from au.tests import *
  6
+from mk.tests import *
  7
+from us.tests import *
  8
+

0 notes on commit 050e119

Please sign in to comment.
Something went wrong with that request. Please try again.