================================
 Contraints when importing data
================================

Imported data must match the same constraints as data entered using the forms.

Set up
======

Create an addressbook and a browser to test the import:

>>> from icemac.addressbook.testing import create_addressbook
>>> from z3c.etestbrowser.wsgi import ExtendedTestBrowser as Browser
>>> ab = create_addressbook()

>>> browser = Browser()
>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
>>> browser.open('http://localhost/++skin++AddressBook/ab')
>>> browser.getLink('Master data').click()
>>> browser.getLink('Import data').click()

Ensuring constraints
====================

There are a number of constraints the imported data must fulfill
otherwise error messages are displayed. We test most constraints here
together:

  - last name of the person must not be empty

  - birth date column must be empty or contain a valid date

  - e-mail address must be valid

  - www address must be a URI

  - country must be either the ISO country code or the country name

  - data line must contain enough fields

Not each field must be selected on mapping fields. (Field `asdf` is
used as an example here.).

Whitespaces at beginning and end are striped. When a notes field
contains more then 20 characters it get nicely truncated. (See line
with `last_name` ``nice`` for both cases.)

Let's construct an import file which containts errors for this constraints:

>>> from StringIO import StringIO
>>> file_data = StringIO()
>>> file_data.write(
...     'last_name,birth_date,e_mail_addr,www,asdf,countries,pnotes\n'
...     ',1999-09-09,,,asdf,,\n'  # missing last name
...     '"wrong date",1981,,,,,,\n'
...     '"wrong e-mail",,i@me@de,,,,\n'
...     '"wrong home page address",,i@me.de,asdf,,,\n'
...     '"wrong country",,,,,D,\n'
...     '"country ISO code",,,,,AT,\n'
...     '"not enough fields",,\n'
...     '" nice "," 2006-06-06", r6@ab.info,'
...       '" http://www.r6.sf.net",," Switzerland ",'
...       '"  my r e a l l y   long, but also really nice  notes    "\n')

>>> file_data.seek(0)

The upload and import works as usual:

>>> from icemac.addressbook.testing import get_messages
>>> browser.getLink('file').click()
>>> browser.getControl('file').add_file(file_data, 'text/plain', 'errors.csv')
>>> browser.getControl('Add').click()
>>> get_messages(browser)
['"errors.csv" added.']
>>> browser.getLink('Import', index=0).click()
>>> browser.url
'http://localhost/++skin++AddressBook/ab/++attribute++importer/File/@@import'

The user chooses the reader as usual and maps the fields:

>>> browser.getControl('Next').click()
>>> print browser.url
http://localhost/++skin++AddressBook/ab/++attribute++importer/File/import/map
>>> browser.getControl('last name').displayValue = [
...     'last_name (wrong date, wrong e-mail)']
>>> browser.getControl('birth date').displayValue = [
...     'birth_date (1999-09-09, 1981)']
>>> browser.getControl('notes', index=0).displayValue = ['pnotes']
>>> browser.getControl('e-mail address').displayValue = [
...     'e_mail_addr (i@me@de)']
>>> browser.getControl('country').displayValue = ['countries']
>>> browser.getControl('URL').displayValue = ['www']
>>> browser.getControl('Next').click()

The review step shows the error messages:

>>> print browser.url
http://localhost/.../ab/++attribute++importer/File/import/review
>>> print browser.contents
<!DOCTYPE ...
    <table>
  <thead>
    <tr>
      <th><i> person</i><br />first name</th>
      <th><br />last name</th>
      <th><br />birth date</th>
      <th><br />keywords</th>
      <th><br />notes</th>
      <th><i>main postal address</i><br />address prefix</th>
      <th><br />street</th>
      <th><br />city</th>
      <th><br />zip</th>
      <th><br />country</th>
      <th><i>main phone number</i><br />number</th>
      <th><i>main e-mail address</i><br />e-mail address</th>
      <th><i>main home page address</i><br />URL</th>
    </tr>
  </thead>
  <tbody>
    <tr class="table-even-row">
      <td></td>
      <td></td>
      <td>1999-09-09</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
<tr class="table-even-row">
<td colspan="13">
Errors:
<ul class="errors">
<li>person -- last name: Required input is missing.</li>
</ul>
</td>
</tr>
    <tr class="table-odd-row">
      <td></td>
      <td>wrong date</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
<tr class="table-odd-row">
<td colspan="13">
Errors:
<ul class="errors">
<li>person -- birth date: 1981 is no valid date.</li>
</ul>
</td>
</tr>
    <tr class="table-even-row">
      <td></td>
      <td>wrong e-mail</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
<tr class="table-even-row">
<td colspan="13">
Errors:
<ul class="errors">
<li>e-mail address -- e-mail address: i@me@de is not a valid e-mail address.</li>
</ul>
</td>
</tr>
    <tr class="table-odd-row">
      <td></td>
      <td>wrong home page address</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td>i@me.de</td>
      <td></td>
    </tr>
<tr class="table-odd-row">
<td colspan="13">
Errors:
<ul class="errors">
<li>home page address -- URL: The specified URI is not valid.</li>
</ul>
</td>
</tr>
    <tr class="table-even-row">
      <td></td>
      <td>wrong country</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td>DE</td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
<tr class="table-even-row">
<td colspan="13">
Errors:
<ul class="errors">
<li>postal address -- country: Value D is not allowed. Allowed values are: AF, AX, AL, DZ, AS, AD, AO, AI, ...
</ul>
</td>
</tr>
    <tr class="table-odd-row">
      <td></td>
      <td>country ISO code</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td>AT</td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
<BLANKLINE>
    <tr class="table-even-row">
      <td></td>
      <td>not enough fields</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td>DE</td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
<tr class="table-even-row">
<td colspan="13">
Errors:
<ul class="errors">
<li>home page address: Not enough data fields in row.</li>
<li>person: Not enough data fields in row.</li>
<li>postal address: Not enough data fields in row.</li>
</ul>
</td>
</tr>
    <tr class="table-odd-row">
      <td></td>
      <td>nice</td>
      <td>2006-06-06</td>
      <td></td>
      <td>my r e a l l y   long, …</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td>CH</td>
      <td></td>
      <td>r6@ab.info</td>
      <td>http://www.r6.sf.net</td>
    </tr>
 </tbody>
</table>...


As there are errors, there is no `next` button:

>>> from icemac.addressbook.testing import get_submit_control_names
>>> get_submit_control_names(browser)
['form.buttons.back']

Selecting the `back` button shows that the selected mapping has been kept:

>>> browser.getControl('Back').click()
>>> browser.getControl('last name').displayValue
['last_name (wrong date, wrong e-mail)']
>>> browser.getControl('birth date').displayValue
['birth_date (1999-09-09, 1981)']
>>> browser.getControl('notes', index=0).displayValue
['pnotes']
>>> browser.getControl('e-mail address').displayValue
['e_mail_addr (i@me@de)']
>>> browser.getControl('country').displayValue
['countries']
>>> browser.getControl('URL').displayValue
['www']
>>> browser.getControl('Next').click()

As the user can't go further from the review step he could upload another import file or abort the import right now by selecting any link outside the importer. None of the data rows got imported as there were errors:

>>> browser.getLink('Person list').click()
>>> browser.url
'http://localhost/++skin++AddressBook/ab/@@index.html'
>>> print browser.contents
<!DOCTYPE ...
...There are no persons entered yet, click on "Add person" to create one...