Ticket #16497: mx_localflavors-1.3.diff

File mx_localflavors-1.3.diff, 23.4 KB (added by Andrés Torres, 13 years ago)

Diff for Django 1.3 version

  • AUTHORS

    diff --git a/AUTHORS b/AUTHORS
    index a19e49b..6dfb6f2 100644
    a b answer newbie questions, and generally made Django that much better:  
    528528    Gasper Zejn <zejn@kiberpipa.org>
    529529    Jarek Zgoda <jarek.zgoda@gmail.com>
    530530    Cheng Zhang
     531    Gerardo Orozco <gerardo.orozco.mosqueda@gmail.com>
     532    Andrés Torres Marroquín <andres.torres.marroquin@gmail.com>
    531533
    532534A big THANK YOU goes to:
    533535
  • django/contrib/localflavor/mx/forms.py

    diff --git a/django/contrib/localflavor/mx/forms.py b/django/contrib/localflavor/mx/forms.py
    index 9581937..7a10f90 100644
    a b  
     1# -*- coding: utf-8 -*-
    12"""
    23Mexican-specific form helpers.
    34"""
    45
    5 from django.forms.fields import Select
     6from django.forms import ValidationError
     7from django.forms.fields import Select, RegexField, CharField
     8from django.utils.translation import ugettext_lazy as _
     9from django.core.validators import EMPTY_VALUES
     10from django.contrib.localflavor.mx.mx_states import STATE_CHOICES
     11import re
     12
     13DATE_RE = r'\d{2}((01|03|05|07|08|10|12)(0[1-9]|[12]\d|3[01])|02(0[1-9]|[12]\d)|(04|06|09|11)(0[1-9]|[12]\d|30))'
     14
     15"""
     16This is the list of inconvenient words according to the `Anexo IV` of the
     17document described in the next link:
     18    www.sisi.org.mx/jspsi/documentos/2005/seguimiento/06101/0610100162005_065.doc
     19"""
     20
     21RFC_INCONVENIENT_WORDS = [
     22    u'BUEI', u'BUEY', u'CACA', u'CACO', u'CAGA', u'CAGO', u'CAKA', u'CAKO',
     23    u'COGE', u'COJA', u'COJE', u'COJI', u'COJO', u'CULO', u'FETO', u'GUEY',
     24    u'JOTO', u'KACA', u'KACO', u'KAGA', u'KAGO', u'KOGE', u'KOJO', u'KAKA',
     25    u'KULO', u'MAME', u'MAMO', u'MEAR', u'MEAS', u'MEON', u'MION', u'MOCO',
     26    u'MULA', u'PEDA', u'PEDO', u'PENE', u'PUTA', u'PUTO', u'QULO', u'RATA',
     27    u'RUIN'
     28]
     29
     30"""
     31This is the list of inconvenient words according to the `Anexo 2` of the
     32document described in the next link:
     33    http://portal.veracruz.gob.mx/pls/portal/url/ITEM/444112558A57C6E0E040A8C02E00695C
     34"""
     35CURP_INCONVENIENT_WORDS = [
     36   u'BACA', u'BAKA', u'BUEI', u'BUEY', u'CACA', u'CACO', u'CAGA', u'CAGO',
     37   u'CAKA', u'CAKO', u'COGE', u'COGI', u'COJA', u'COJE', u'COJI', u'COJO',
     38   u'COLA', u'CULO', u'FALO', u'FETO', u'GETA', u'GUEI', u'GUEY', u'JETA',
     39   u'JOTO', u'KACA', u'KACO', u'KAGA', u'KAGO', u'KAKA', u'KAKO', u'KOGE',
     40   u'KOGI', u'KOJA', u'KOJE', u'KOJI', u'KOJO', u'KOLA', u'KULO', u'LILO',
     41   u'LOCA', u'LOCO', u'LOKA', u'LOKO', u'MAME', u'MAMO', u'MEAR', u'MEAS',
     42   u'MEON', u'MIAR', u'MION', u'MOCO', u'MOKO', u'MULA', u'MULO', u'NACA',
     43   u'NACO', u'PEDA', u'PEDO', u'PENE', u'PIPI', u'PITO', u'POPO', u'PUTA',
     44   u'PUTO', u'QULO', u'RATA', u'ROBA', u'ROBE', u'ROBO', u'RUIN', u'SENO',
     45   u'TETA', u'VACA', u'VAGA', u'VAGO', u'VAKA', u'VUEI', u'VUEY', u'WUEI',
     46   u'WUEY'
     47]
    648
    749class MXStateSelect(Select):
    850    """
    951    A Select widget that uses a list of Mexican states as its choices.
    1052    """
    1153    def __init__(self, attrs=None):
    12         from mx_states import STATE_CHOICES
    1354        super(MXStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
    1455
     56class MXZipCodeField(RegexField):
     57    """
     58    A field that accepts a Mexican Zip Code.
     59
     60    More info about this:
     61        http://en.wikipedia.org/wiki/List_of_postal_codes_in_Mexico
     62    """
     63    default_error_messages = {
     64        'invalid': _(u'Enter a valid zip code in the format XXXXX.'),
     65    }
     66
     67    def __init__(self, *args, **kwargs):
     68        zip_code_re = ur'^(0[1-9]|[1][0-6]|[2-9]\d)(\d{3})$'
     69        super(MXZipCodeField, self).__init__(zip_code_re, *args, **kwargs)
     70
     71class MXRFCField(RegexField):
     72    """
     73    A field that validates a Mexican `Registro Federal de Contribuyentes` for
     74    either `Persona física` or `Persona moral`.
     75
     76    The `Persona física` RFC string is integrated by a juxtaposition of characters
     77    following the next pattern:
     78        Index    Format     Accepted Characters
     79        1        X          Any letter
     80        2        X          Any vowel
     81        3-4      XX         Any letter
     82        5-10     YYMMDD     Any valid date
     83        11-12    XX         Any letter or number between 0 and 9
     84        13       X          Any digit between 0 and 9 or the letter `A`
     85
     86    The `Persona moral` RFC string is integrated by a juxtaposition of characters
     87    following the next pattern:
     88        Index    Format     Accepted Characters
     89        1-3      XXX        Any letter including `&` and `Ñ` chars
     90        4-9      YYMMDD     Any valid date
     91        10-11    XX         Any letter or number between 0 and 9
     92        12       X          Any number between 0 and 9 or the letter `A`
     93
     94    More info about this:
     95        http://es.wikipedia.org/wiki/Registro_Federal_de_Contribuyentes_(M%C3%A9xico)
     96    """
     97    default_error_messages = {
     98        'invalid': _(u'Enter a valid RFC.'),
     99        'invalid_checksum': _(u'Invalid checksum for RFC.'),
     100    }
     101
     102    def __init__(self, min_length=9, max_length=13, *args, **kwargs):
     103        rfc_re = re.compile(ur'^([A-Z&Ññ]{3}|[A-Z][AEIOU][A-Z]{2})%s([A-Z0-9]{2}[0-9A])?$' % DATE_RE,
     104                            re.IGNORECASE)
     105        super(MXRFCField, self).__init__(rfc_re, min_length=min_length,
     106                                         max_length=max_length, *args, **kwargs)
     107
     108    def clean(self, value):
     109        value = super(MXRFCField, self).clean(value)
     110        if value in EMPTY_VALUES:
     111            return u''
     112        value = value.upper()
     113        if self._has_homoclave(value):
     114            if not value[-1] == self._checksum(value[:-1]):
     115                raise ValidationError(self.default_error_messages['invalid_checksum'])
     116        if self._has_inconvenient_word(value):
     117            raise ValidationError(self.default_error_messages['invalid'])
     118        return value
     119
     120    def _has_homoclave(self, rfc):
     121        """
     122        This check is done due to the existance of RFCs without a `homoclave`
     123        since the current algorithm to calculate it had not been created for
     124        the first RFCs ever in Mexico.
     125        """
     126        rfc_without_homoclave_re = re.compile(ur'^[A-Z&Ññ]{3,4}%s$' % DATE_RE,
     127                                              re.IGNORECASE)
     128        return not rfc_without_homoclave_re.match(rfc)
     129
     130    def _checksum(self, rfc):
     131        """
     132        More info about this procedure:
     133            www.sisi.org.mx/jspsi/documentos/2005/seguimiento/06101/0610100162005_065.doc
     134        """
     135        chars = u'0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ-Ñ'
     136        if len(rfc) is 11:
     137            rfc = '-' + rfc
     138
     139        sum_ = sum(i * chars.index(c) for i, c in zip(reversed(xrange(14)), rfc))
     140        checksum = 11 - sum_ % 11
     141
     142        if checksum == 10:
     143            return u'A'
     144        elif checksum == 11:
     145            return u'0'
     146        else:
     147            return unicode(checksum)
     148
     149    def _has_inconvenient_word(self, rfc):
     150        first_four = rfc[:4]
     151        return first_four in RFC_INCONVENIENT_WORDS
     152
     153class MXCURPField(RegexField):
     154    """
     155    A field that validates a Mexican `Clave Única de Registro de Población`.
     156
     157    The CURP is integrated by a juxtaposition of characters following the next
     158    pattern:
     159
     160    Index    Format    Accepted Characters
     161    1        X         Any letter
     162    2        X         Any vowel
     163    3-4      XX        Any letter
     164    5-10     YYMMDD    Any valid date
     165    11       X         Either `H` or `M`, depending on the person's gender
     166    12-13    XX        Any valid acronym for a state in Mexico
     167    14-16    XXX       Any consonant
     168    17       X         Any number between 0 and 9 or any letter
     169    18       X         Any number between 0 and 9
     170
     171    More info about this:
     172        http://www.condusef.gob.mx/index.php/clave-unica-de-registro-de-poblacion-curp
     173    """
     174    default_error_messages = {
     175        'invalid': _('Enter a valid CURP.'),
     176        'invalid_checksum': _(u'Invalid checksum for CURP.'),
     177    }
     178
     179    def __init__(self, min_length=18, max_length=18, *args, **kwargs):
     180        states_re = r'(AS|BC|BS|CC|CL|CM|CS|CH|DF|DG|GT|GR|HG|JC|MC|MN|MS|NT|NL|OC|PL|QT|QR|SP|SL|SR|TC|TS|TL|VZ|YN|ZS|NE)'
     181        consonants_re = r'[B-DF-HJ-NP-TV-Z]'
     182        curp_re = ur'^[A-Z][AEIOU][A-Z]{2}%s[HM]%s%s{3}[0-9A-Z]\d$' % (DATE_RE, states_re,
     183                                                      consonants_re)
     184        curp_re = re.compile(curp_re, re.IGNORECASE)
     185        super(MXCURPField, self).__init__(curp_re, min_length=min_length,
     186                                          max_length=max_length, *args, **kwargs)
     187
     188    def clean(self, value):
     189        value = super(MXCURPField, self).clean(value)
     190        if value in EMPTY_VALUES:
     191            return u''
     192        value = value.upper()
     193        if value[-1] != self._checksum(value[:-1]):
     194            raise ValidationError(self.default_error_messages['invalid_checksum'])
     195        if self._has_inconvenient_word(value):
     196            raise ValidationError(self.default_error_messages['invalid'])
     197        return value
     198
     199    def _checksum(self, value):
     200        chars = u'0123456789ABCDEFGHIJKLMN&OPQRSTUVWXYZ'
     201
     202        s = sum(i * chars.index(c) for i, c in zip(reversed(xrange(19)), value))
     203        checksum = 10 - s % 10
     204
     205        if checksum == 10:
     206            return u'0'
     207        return unicode(checksum)
     208
     209    def _has_inconvenient_word(self, curp):
     210        first_four = curp[:4]
     211        return first_four in CURP_INCONVENIENT_WORDS
  • new file django/contrib/localflavor/mx/models.py

    diff --git a/django/contrib/localflavor/mx/models.py b/django/contrib/localflavor/mx/models.py
    new file mode 100644
    index 0000000..dbeaaa6
    - +  
     1from django.utils.translation import ugettext_lazy as _
     2from django.db.models.fields import CharField
     3from django.contrib.localflavor.mx.mx_states import STATE_CHOICES
     4
     5class MXStateField(CharField):
     6    """
     7    A model field that uses a list of Mexican states as its choices.
     8    """
     9
     10    description = _("Mexico state (three uppercase letters)")
     11
     12    def __init__(self, *args, **kwargs):
     13        kwargs['choices'] = STATE_CHOICES
     14        kwargs['max_length'] = 3
     15        super(MXStateField, self).__init__(*args, **kwargs)
     16
     17class MXZipCodeField(CharField):
     18    """
     19    A model field that forms represent as a forms.MXZipCodeField field and
     20    stores the five-digit Mexican zip code.
     21    """
     22
     23    description = _("Mexico zip code")
     24
     25    def __init__(self, *args, **kwargs):
     26        kwargs['max_length'] = 5
     27        super(MXZipCodeField, self).__init__(*args, **kwargs)
     28
     29    def formfield(self, **kwargs):
     30        from django.contrib.localflavor.mx.forms import MXZipCodeField as Field
     31        defaults = {'form_class': Field}
     32        defaults.update(kwargs)
     33        return super(MXZipCodeField, self).formfield(**defaults)
     34
     35class MXRFCField(CharField):
     36    """
     37    A model field that forms represent as a forms.MXRFCField field and
     38    stores the value of a valid Mexican RFC.
     39    """
     40
     41    description = _("Mexican RFC")
     42
     43    def __init__(self, *args, **kwargs):
     44        kwargs['max_length'] = 13
     45        super(MXRFCField, self).__init__(*args, **kwargs)
     46
     47    def formfield(self, **kwargs):
     48        from django.contrib.localflavor.mx.forms import MXRFCField as Field
     49        defaults = {'form_class': Field}
     50        defaults.update(kwargs)
     51        return super(MXRFCField, self).formfield(**defaults)
     52
     53class MXCURPField(CharField):
     54    """
     55    A model field that forms represent as a forms.MXCURPField field and
     56    stores the value of a valid Mexican CURP.
     57    """
     58
     59    description = _("Mexican CURP")
     60
     61    def __init__(self, *args, **kwargs):
     62        kwargs['max_length'] = 18
     63        super(MXCURPField, self).__init__(*args, **kwargs)
     64
     65    def formfield(self, **kwargs):
     66        from django.contrib.localflavor.mx.forms import MXCURPField as Field
     67        defaults = {'form_class': Field}
     68        defaults.update(kwargs)
     69        return super(MXCURPField, self).formfield(**defaults)
     70 No newline at end of file
  • new file tests/regressiontests/forms/localflavor/mx.py

    diff --git a/tests/regressiontests/forms/localflavor/mx.py b/tests/regressiontests/forms/localflavor/mx.py
    new file mode 100644
    index 0000000..1ffc11c
    - +  
     1# -*- coding: utf-8 -*-
     2from django.contrib.localflavor.mx.forms import (MXZipCodeField, MXRFCField,
     3    MXStateSelect, MXCURPField)
     4
     5from utils import LocalFlavorTestCase
     6
     7
     8class MXLocalFlavorTests(LocalFlavorTestCase):
     9    def test_MXStateSelect(self):
     10        f = MXStateSelect()
     11        out = u'''<select name="state">
     12<option value="AGU">Aguascalientes</option>
     13<option value="BCN">Baja California</option>
     14<option value="BCS">Baja California Sur</option>
     15<option value="CAM">Campeche</option>
     16<option value="CHH">Chihuahua</option>
     17<option value="CHP">Chiapas</option>
     18<option value="COA">Coahuila</option>
     19<option value="COL">Colima</option>
     20<option value="DIF">Distrito Federal</option>
     21<option value="DUR">Durango</option>
     22<option value="GRO">Guerrero</option>
     23<option value="GUA">Guanajuato</option>
     24<option value="HID">Hidalgo</option>
     25<option value="JAL">Jalisco</option>
     26<option value="MEX">Estado de México</option>
     27<option value="MIC" selected="selected">Michoacán</option>
     28<option value="MOR">Morelos</option>
     29<option value="NAY">Nayarit</option>
     30<option value="NLE">Nuevo León</option>
     31<option value="OAX">Oaxaca</option>
     32<option value="PUE">Puebla</option>
     33<option value="QUE">Querétaro</option>
     34<option value="ROO">Quintana Roo</option>
     35<option value="SIN">Sinaloa</option>
     36<option value="SLP">San Luis Potosí</option>
     37<option value="SON">Sonora</option>
     38<option value="TAB">Tabasco</option>
     39<option value="TAM">Tamaulipas</option>
     40<option value="TLA">Tlaxcala</option>
     41<option value="VER">Veracruz</option>
     42<option value="YUC">Yucatán</option>
     43<option value="ZAC">Zacatecas</option>
     44</select>'''
     45        self.assertEqual(f.render('state', 'MIC'), out)
     46
     47    def test_MXZipCodeField(self):
     48        error_format = [u'Enter a valid zip code in the format XXXXX.']
     49        valid = {
     50            '58120': u'58120',
     51            '58502': u'58502',
     52            '59310': u'59310',
     53            '99999': u'99999',
     54        }
     55        invalid = {
     56            '17000': error_format,
     57            '18000': error_format,
     58            '19000': error_format,
     59            '00000': error_format,
     60        }
     61        self.assertFieldOutput(MXZipCodeField, valid, invalid)
     62
     63    def test_MXRFCField(self):
     64        error_format = [u'Enter a valid RFC.']
     65        error_checksum = [u'Invalid checksum for RFC.']
     66        valid = {
     67            'MoFN641205eX5': u'MOFN641205EX5',
     68            'ICa060120873': u'ICA060120873',
     69            'eUcG751104rT0': u'EUCG751104RT0',
     70            'GME08100195A': u'GME08100195A',
     71            'AA&060524KX5': u'AA&060524KX5',
     72            'CAÑ0708045P7': u'CAÑ0708045P7',
     73            'aaa000101aa9': u'AAA000101AA9',
     74        }
     75        invalid = {
     76            'MED0000000XA': error_format,
     77            '0000000000XA': error_format,
     78            'AAA000000AA6': error_format,
     79            # Dates
     80            'XXX880002XXX': error_format,
     81            'XXX880200XXX': error_format,
     82            'XXX880132XXX': error_format,
     83            'XXX880230XXX': error_format,
     84            'XXX880431XXX': error_format,
     85            # Incorrect checksum
     86            'MOGR650524E73': error_checksum,
     87            'HVA7810058F1': error_checksum,
     88            'MoFN641205eX2': error_checksum,
     89            'ICa060120871': error_checksum,
     90            'eUcG751104rT7': error_checksum,
     91            'GME081001955': error_checksum,
     92            'AA&060524KX9': error_checksum,
     93            'CAÑ0708045P2': error_checksum,
     94        }
     95        self.assertFieldOutput(MXRFCField, valid, invalid)
     96
     97    def test_MXCURPField(self):
     98        error_format = [u'Enter a valid CURP.']
     99        error_checksum = [u'Invalid checksum for CURP.']
     100        valid = {
     101            'AaMG890608HDFLJL00': u'AAMG890608HDFLJL00',
     102            'BAAd890419HMNRRV07': u'BAAD890419HMNRRV07',
     103            'VIAA900930MMNClL08': u'VIAA900930MMNCLL08',
     104            'HEGR891009HMNRRD09': u'HEGR891009HMNRRD09',
     105            'MARR890512HMNRMN09': u'MARR890512HMNRMN09',
     106            'MESJ890928HMNZNS00': u'MESJ890928HMNZNS00',
     107            'BAAA890317HDFRLL03': u'BAAA890317HDFRLL03',
     108            'TOMA880125HMNRRNO2': u'TOMA880125HMNRRNO2',
     109            'OOMG890727HMNRSR06': u'OOMG890727HMNRSR06',
     110            'AAAA000101HDFCCC09': u'AAAA000101HDFCCC09',
     111        }
     112        invalid = {
     113            'AAAA000000HDFCCC09': error_format,
     114            'AAAA000000HDFAAA03': error_format,
     115            'AAAA000000HXXCCC08': error_format,
     116            'AAAA000000XMNCCC02': error_format,
     117            'HEGR891009HMNRRD0A': error_format,
     118            'MARR890512HMNRMN0A': error_format,
     119            'AaMG890608HDFLJL01': error_checksum,
     120            'BAAd890419HMNRRV08': error_checksum,
     121            'VIAA900930MMNClL09': error_checksum,
     122            'MESJ890928HMNZNS01': error_checksum,
     123            'BAAA890317HDFRLL04': error_checksum,
     124            'TOMA880125HMNRRNO3': error_checksum,
     125            'OOMG890727HMNRSR07': error_checksum,
     126        }
     127        self.assertFieldOutput(MXCURPField, valid, invalid)
  • tests/regressiontests/forms/localflavortests.py

    diff --git a/tests/regressiontests/forms/localflavortests.py b/tests/regressiontests/forms/localflavortests.py
    index 5ee1c32..d8a57bd 100644
    a b from localflavor.is_ import ISLocalFlavorTests  
    1919from localflavor.it import ITLocalFlavorTests
    2020from localflavor.jp import JPLocalFlavorTests
    2121from localflavor.kw import KWLocalFlavorTests
     22from localflavor.mx import MXLocalFlavorTests
    2223from localflavor.nl import NLLocalFlavorTests
    2324from localflavor.pl import PLLocalFlavorTests
    2425from localflavor.pt import PTLocalFlavorTests
  • tests/regressiontests/forms/tests/__init__.py

    diff --git a/tests/regressiontests/forms/tests/__init__.py b/tests/regressiontests/forms/tests/__init__.py
    index 2d96b2f..561e4c9 100644
    a b from regressiontests.forms.localflavortests import (  
    1919    FRLocalFlavorTests, GenericLocalFlavorTests, IDLocalFlavorTests,
    2020    IELocalFlavorTests, ILLocalFlavorTests, ISLocalFlavorTests,
    2121    ITLocalFlavorTests, JPLocalFlavorTests, KWLocalFlavorTests,
    22     NLLocalFlavorTests, PLLocalFlavorTests, PTLocalFlavorTests,
    23     ROLocalFlavorTests, SELocalFlavorTests, SKLocalFlavorTests,
    24     TRLocalFlavorTests, UKLocalFlavorTests, USLocalFlavorTests,
    25     UYLocalFlavorTests, ZALocalFlavorTests
     22    MXLocalFlavorTests, NLLocalFlavorTests, PLLocalFlavorTests,
     23    PTLocalFlavorTests, ROLocalFlavorTests, SELocalFlavorTests,
     24    SKLocalFlavorTests, TRLocalFlavorTests, UKLocalFlavorTests,
     25    USLocalFlavorTests, UYLocalFlavorTests, ZALocalFlavorTests
    2626)
  • new file tests/regressiontests/localflavor/mx/forms.py

    diff --git a/tests/regressiontests/localflavor/mx/__init__.py b/tests/regressiontests/localflavor/mx/__init__.py
    new file mode 100644
    index 0000000..e69de29
    diff --git a/tests/regressiontests/localflavor/mx/forms.py b/tests/regressiontests/localflavor/mx/forms.py
    new file mode 100644
    index 0000000..8a45781
    - +  
     1from django.forms import ModelForm
     2from models import MXPersonProfile
     3
     4class MXPersonProfileForm(ModelForm):
     5    """docstring for MXPersonProfileForm"""
     6    class Meta:
     7        model = MXPersonProfile
  • new file tests/regressiontests/localflavor/mx/models.py

    diff --git a/tests/regressiontests/localflavor/mx/models.py b/tests/regressiontests/localflavor/mx/models.py
    new file mode 100644
    index 0000000..81a5018
    - +  
     1from django.db import models
     2from django.contrib.localflavor.mx.models import (MXStateField,
     3                        MXRFCField, MXCURPField, MXZipCodeField)
     4
     5# When creating models you need to remember to add a app_label as
     6# 'localflavor', so your model can be found
     7
     8class MXPersonProfile(models.Model):
     9    state = MXStateField()
     10    rfc = MXRFCField()
     11    curp = MXCURPField()
     12    zip_code = MXZipCodeField()
     13    class Meta:
     14        app_label = 'localflavor'
  • new file tests/regressiontests/localflavor/mx/tests.py

    diff --git a/tests/regressiontests/localflavor/mx/tests.py b/tests/regressiontests/localflavor/mx/tests.py
    new file mode 100644
    index 0000000..40da38a
    - +  
     1# -*- coding: utf-8 -*-
     2from django.test import TestCase
     3from forms import MXPersonProfileForm
     4
     5class MXLocalFlavorTests(TestCase):
     6    def setUp(self):
     7        self.form = MXPersonProfileForm({
     8            'state': 'MIC',
     9            'rfc': 'toma880125kv3',
     10            'curp': 'toma880125hmnrrn02',
     11            'zip_code': '58120',
     12        })
     13
     14    def test_get_display_methods(self):
     15        """Test that the get_*_display() methods are added to the model instances."""
     16        place = self.form.save()
     17        self.assertEqual(place.get_state_display(), u'Michoacán')
     18
     19    def test_errors(self):
     20        """Test that required MXFields throw appropriate errors."""
     21        form = MXPersonProfileForm({
     22            'state': 'Invalid state',
     23            'rfc': 'invalid rfc',
     24            'curp': 'invalid curp',
     25            'zip_code': 'xxx',
     26        })
     27        self.assertFalse(form.is_valid())
     28        self.assertEqual(form.errors['state'], [u'Select a valid choice. Invalid state is not one of the available choices.'])
     29        self.assertEqual(form.errors['rfc'], [u'Enter a valid RFC.'])
     30        self.assertEqual(form.errors['curp'], [u'Ensure this value has at least 18 characters (it has 12).', u'Enter a valid CURP.'])
     31        self.assertEqual(form.errors['zip_code'], [u'Enter a valid zip code in the format XXXXX.'])
     32
     33    def test_field_blank_option(self):
     34        """Test that the empty option is there."""
     35        state_select_html = """\
     36<select name="state" id="id_state">
     37<option value="">---------</option>
     38<option value="AGU">Aguascalientes</option>
     39<option value="BCN">Baja California</option>
     40<option value="BCS">Baja California Sur</option>
     41<option value="CAM">Campeche</option>
     42<option value="CHH">Chihuahua</option>
     43<option value="CHP">Chiapas</option>
     44<option value="COA">Coahuila</option>
     45<option value="COL">Colima</option>
     46<option value="DIF">Distrito Federal</option>
     47<option value="DUR">Durango</option>
     48<option value="GRO">Guerrero</option>
     49<option value="GUA">Guanajuato</option>
     50<option value="HID">Hidalgo</option>
     51<option value="JAL">Jalisco</option>
     52<option value="MEX">Estado de México</option>
     53<option value="MIC" selected="selected">Michoacán</option>
     54<option value="MOR">Morelos</option>
     55<option value="NAY">Nayarit</option>
     56<option value="NLE">Nuevo León</option>
     57<option value="OAX">Oaxaca</option>
     58<option value="PUE">Puebla</option>
     59<option value="QUE">Querétaro</option>
     60<option value="ROO">Quintana Roo</option>
     61<option value="SIN">Sinaloa</option>
     62<option value="SLP">San Luis Potosí</option>
     63<option value="SON">Sonora</option>
     64<option value="TAB">Tabasco</option>
     65<option value="TAM">Tamaulipas</option>
     66<option value="TLA">Tlaxcala</option>
     67<option value="VER">Veracruz</option>
     68<option value="YUC">Yucatán</option>
     69<option value="ZAC">Zacatecas</option>
     70</select>"""
     71        self.assertEqual(str(self.form['state']), state_select_html)
  • tests/regressiontests/localflavor/tests.py

    diff --git a/tests/regressiontests/localflavor/tests.py b/tests/regressiontests/localflavor/tests.py
    index 85e91a0..25de89f 100644
    a b from django.utils import unittest  
    33
    44# just import your tests here
    55from us.tests import *
     6from mx.tests import *
Back to Top