Ejemplo n.º 1
0
def get_item_form(name, request, renderers=None, validators=None, values=None):
    """Will return a form for the given item

    :name: Name of the form
    :request: Current request
    :renderers: Dictionary of external renderers which should be used
                for renderering some form elements.
    :validators: List of external formbar validators which should be
                 added to the form for validation
    :values: Dictionary with external values to prefill the form or add
    addional values for rule evaluation.
    :returns: Form
    """
    if renderers is None:
        renderers = {}
    if validators is None:
        validators = []
    if values is None:
        values = {}
    item = get_item_from_request(request)
    renderers = add_renderers(renderers)
    clazz = request.context.__model__
    name = request.session.get("%s.form" % clazz) or name

    # handle blobforms
    if isinstance(item, Blobform):
        # TODO: Why not use the get_form_config method here. This can
        # handle Blobforms and usual form configs. () <2014-08-26 22:21>

        item, formconfig = get_blobform_config(request, item, name)
    else:
        formconfig = get_form_config(item, name)

    form = Form(formconfig,
                item,
                request.db,
                translate=request.translate,
                renderers=renderers,
                change_page_callback={
                    'url': 'set_current_form_page',
                    'item': clazz.__tablename__,
                    'itemid': item.id
                },
                request=request,
                csrf_token=request.session.get_csrf_token(),
                eval_url=get_eval_url(),
                url_prefix=get_app_url(request),
                locale=locale_negotiator(request),
                values=values,
                timezone=get_timezone(request),
                dependencies=create_dependencies(request))
    # Add validators
    for validator in validators:
        form.add_validator(validator)
    return form
Ejemplo n.º 2
0
def get_item_form(name, request, renderers=None, validators=None, values=None):
    """Will return a form for the given item

    :name: Name of the form
    :request: Current request
    :renderers: Dictionary of external renderers which should be used
                for renderering some form elements.
    :validators: List of external formbar validators which should be
                 added to the form for validation
    :values: Dictionary with external values to prefill the form or add
    addional values for rule evaluation.
    :returns: Form
    """
    if renderers is None:
        renderers = {}
    if validators is None:
        validators = []
    if values is None:
        values = {}
    item = get_item_from_request(request)
    renderers = add_renderers(renderers)
    clazz = request.context.__model__
    name = request.session.get("%s.form" % clazz) or name

    ## handle blobforms
    if isinstance(item, Blobform):
        # TODO: Why not use the get_form_config method here. This can
        # handle Blobforms and usual form configs. () <2014-08-26 22:21>

        item, formconfig = get_blobform_config(request, item, name)
    else:
        formconfig = get_form_config(item, name)

    form = Form(formconfig, item, request.db,
                translate=request.translate,
                renderers=renderers,
                change_page_callback={'url': 'set_current_form_page',
                                      'item': clazz.__tablename__,
                                      'itemid': item.id},
                request=request,
                csrf_token=request.session.get_csrf_token(),
                eval_url=get_eval_url(),
                url_prefix=get_app_url(request),
                locale=locale_negotiator(request),
                values=values)
    # Add validators
    for validator in validators:
        form.add_validator(validator)
    return form
Ejemplo n.º 3
0
def changepassword(request):
    """Method to change the users password by the user. The user user
    musst provide his old and the new pasword. Users are only allowed to
    change their own password."""

    # Check authentification
    # As this view has now security configured it is
    # generally callable by all users. For this reason we first check if
    # the user is authenticated. If the user is not authenticated the
    # raise an 401 (unauthorized) exception.
    if not request.user:
        raise HTTPUnauthorized

    clazz = User
    _ = request.translate
    rvalue = {}
    # Load the item return 400 if the item can not be found.
    id = request.matchdict.get('id')
    factory = clazz.get_item_factory()
    try:
        item = factory.load(id, request.db)
        # Check authorisation
        # User are only allowed to set their own password.
        if item.id != request.user.id:
            raise HTTPForbidden()
    except sa.orm.exc.NoResultFound:
        raise HTTPBadRequest()

    form = Form(get_form_config(item, 'changepassword'),
                item, request.db, translate=_,
                renderers={},
                change_page_callback={'url': 'set_current_form_page',
                                      'item': clazz.__tablename__,
                                      'itemid': id},
                request=request, csrf_token=request.session.get_csrf_token())

    if request.POST:
        mapping = {'item': item}
        # Do extra validation which is not handled by formbar.
        # Is the provided old password correct?
        validator = Validator('oldpassword',
                              _('The given password is not correct'),
                              check_password)
        pw_len_validator = Validator('password',
                                     _('Password must be at least 12 '
                                       'characters long.'),
                                     password_minlength_validator)
        pw_nonchar_validator = Validator('password',
                                         _('Password must contain at least 2 '
                                           'non-letters.'),
                                         password_nonletter_validator)

        form.add_validator(validator)
        form.add_validator(pw_len_validator)
        form.add_validator(pw_nonchar_validator)
        if form.validate(request.params):
            form.save()
            # Actually save the password. This is not done in the form
            # as the password needs to be encrypted.
            encrypt_password_callback(request, item)
            msg = _('Changed password for "${item}" successfull.',
                    mapping=mapping)
            log.info(msg)
            request.session.flash(msg, 'success')
            route_name = get_action_routename(item, 'changepassword')
            url = request.route_path(route_name, id=item.id)
            # Invalidate cache
            invalidate_cache()
            return HTTPFound(location=url)
        else:
            msg = _('Error on changing the password for '
                    '"${item}".', mapping=mapping)
            log.info(msg)
            request.session.flash(msg, 'error')

    rvalue['clazz'] = clazz
    rvalue['item'] = item
    rvalue['form'] = form.render(page=get_current_form_page(clazz, request))
    return rvalue
Ejemplo n.º 4
0
Archivo: auth.py Proyecto: toirl/ringo
def register_user(request):
    settings = request.registry.settings
    if not is_registration_enabled(settings):
        raise exc.exception_response(503)
    handle_history(request)
    _ = request.translate
    config = Config(load(get_path_to_form_config('auth.xml')))
    form_config = config.get_form('register_user')
    form = Form(form_config, csrf_token=request.session.get_csrf_token(),
                translate=_)
    # Do extra validation which is not handled by formbar.
    # Is the login unique?
    login_unique_validator = Validator('login',
                                       _('There is already a user with this '
                                         'name'),
                                       is_login_unique)
    pw_len_validator = Validator('pass',
                                 _('Password must be at least 12 characters '
                                   'long.'),
                                 password_minlength_validator)
    pw_nonchar_validator = Validator('pass',
                                     _('Password must contain at least 2 '
                                       'non-letters.'),
                                     password_nonletter_validator)
    form.add_validator(login_unique_validator)
    form.add_validator(pw_len_validator)
    form.add_validator(pw_nonchar_validator)
    registration_complete = False
    if request.POST:
        if form.validate(request.params):
            # 1. Create user. Do not activate him. Default role is user.
            ufac = User.get_item_factory()
            user = ufac.create(None, form.data)
            # Set login from formdata
            user.login = form.data['login']
            # Encrypt password and save
            user.password = encrypt_password(form.data['pass'])
            # Deactivate the user. To activate the user needs to confirm
            # with the activation link
            user.activated = False
            atoken = str(uuid.uuid4())
            user.activation_token = atoken
            # Set profile data
            user.profile[0].email = form.data['_email']

            # 2. Set user group
            gfac = Usergroup.get_item_factory()
            default_grps = settings.get("auth.register_user_default_groups",
                                        str(USER_GROUP_ID))
            for gid in [int(id) for id in default_grps.split(",")]:
                group = gfac.load(gid)
                user.groups.append(group)

            # 3. Set user role
            rfac = Role.get_item_factory()
            default_roles = settings.get("auth.register_user_default_roles",
                                         str(USER_ROLE_ID))
            for rid in [int(id) for id in default_roles.split(",")]:
                role = rfac.load(rid)
                user.roles.append(role)
            # Set default user group.
            request.db.add(user)

            # 4. Send confirmation email. The user will be activated
            #    after the user clicks on the confirmation link
            mailer = Mailer(request)
            recipient = user.profile[0].email
            subject = _('Confirm user registration')
            values = {'url': request.route_url('confirm_user', token=atoken),
                      'app_name': get_app_title(),
                      'email': settings['mail.default_sender'],
                      '_': _}
            mail = Mail([recipient],
                        subject,
                        template="register_user",
                        values=values)
            mailer.send(mail)

            msg = _("User has been created and a confirmation mail was sent"
                    " to the users email adress. Please check your email.")
            request.session.flash(msg, 'success')
            registration_complete = True
    return {'form': form.render(), 'complete': registration_complete}
Ejemplo n.º 5
0
def register_user(request):
    settings = request.registry.settings
    if not is_registration_enabled(settings):
        raise exc.exception_response(503)
    _ = request.translate
    config = Config(load(get_path_to_form_config('auth.xml')))
    form_config = config.get_form('register_user')
    form = Form(form_config,
                csrf_token=request.session.get_csrf_token(),
                translate=_)
    # Do extra validation which is not handled by formbar.
    # Is the login unique?
    login_unique_validator = Validator(
        'login', _('There is already a user with this '
                   'name'), is_login_unique)
    pw_len_validator = Validator(
        'pass', _('Password must be at least 12 characters '
                  'long.'), password_minlength_validator)
    pw_nonchar_validator = Validator(
        'pass', _('Password must contain at least 2 '
                  'non-letters.'), password_nonletter_validator)
    form.add_validator(login_unique_validator)
    form.add_validator(pw_len_validator)
    form.add_validator(pw_nonchar_validator)
    registration_complete = False
    if request.POST:
        if form.validate(request.params):
            # 1. Create user. Do not activate him. Default role is user.
            ufac = User.get_item_factory()
            user = ufac.create(None, form.data)
            # Set login from formdata
            user.login = form.data['login']
            # Encrypt password and save
            user.password = encrypt_password(form.data['pass'])
            # Deactivate the user. To activate the user needs to confirm
            # with the activation link
            user.activated = False
            atoken = str(uuid.uuid4())
            user.activation_token = atoken
            # Set profile data
            user.profile[0].email = form.data['_email']

            # 2. Set user group
            gfac = Usergroup.get_item_factory()
            default_grps = settings.get("auth.register_user_default_groups",
                                        str(USER_GROUP_ID))
            for gid in [int(id) for id in default_grps.split(",")]:
                group = gfac.load(gid)
                user.groups.append(group)

            # 3. Set user role
            rfac = Role.get_item_factory()
            default_roles = settings.get("auth.register_user_default_roles",
                                         str(USER_ROLE_ID))
            for rid in [int(id) for id in default_roles.split(",")]:
                role = rfac.load(rid)
                user.roles.append(role)
            # Set default user group.
            request.db.add(user)

            # 4. Send confirmation email. The user will be activated
            #    after the user clicks on the confirmation link
            mailer = Mailer(request)
            recipient = user.profile[0].email
            subject = _('Confirm user registration')
            values = {
                'url': request.route_url('confirm_user', token=atoken),
                'app_name': get_app_title(),
                'email': settings['mail.default_sender'],
                'login': user.login,
                '_': _
            }
            mail = Mail([recipient],
                        subject,
                        template="register_user",
                        values=values)
            mailer.send(mail)

            msg = _("User has been created and a confirmation mail was sent"
                    " to the users email adress. Please check your email.")
            request.session.flash(msg, 'success')
            registration_complete = True
    return {'form': form.render(), 'complete': registration_complete}
Ejemplo n.º 6
0
def changepassword(request):
    """Method to change the users password by the user. The user user
    musst provide his old and the new pasword. Users are only allowed to
    change their own password."""

    # Check authentification
    # As this view has now security configured it is
    # generally callable by all users. For this reason we first check if
    # the user is authenticated. If the user is not authenticated the
    # raise an 401 (unauthorized) exception.
    if not request.user:
        raise HTTPUnauthorized

    clazz = User
    handle_history(request)
    handle_params(request)
    _ = request.translate
    rvalue = {}
    # Load the item return 400 if the item can not be found.
    id = request.matchdict.get('id')
    factory = clazz.get_item_factory()
    try:
        item = factory.load(id, request.db)
        # Check authorisation
        # User are only allowed to set their own password.
        if item.id != request.user.id:
            raise HTTPForbidden()
    except sa.orm.exc.NoResultFound:
        raise HTTPBadRequest()

    form = Form(get_form_config(item, 'changepassword'),
                item, request.db, translate=_,
                renderers={},
                change_page_callback={'url': 'set_current_form_page',
                                      'item': clazz.__tablename__,
                                      'itemid': id},
                request=request, csrf_token=request.session.get_csrf_token())

    if request.POST:
        mapping = {'item': item}
        # Do extra validation which is not handled by formbar.
        # Is the provided old password correct?
        validator = Validator('oldpassword',
                              _('The given password is not correct'),
                              check_password)
        pw_len_validator = Validator('password',
                                     _('Password must be at least 12 '
                                       'characters long.'),
                                     password_minlength_validator)
        pw_nonchar_validator = Validator('password',
                                         _('Password must contain at least 2 '
                                           'non-letters.'),
                                         password_nonletter_validator)

        form.add_validator(validator)
        form.add_validator(pw_len_validator)
        form.add_validator(pw_nonchar_validator)
        if form.validate(request.params):
            form.save()
            # Actually save the password. This is not done in the form
            # as the password needs to be encrypted.
            encrypt_password_callback(request, item)
            msg = _('Changed password for "${item}" successfull.',
                    mapping=mapping)
            log.info(msg)
            request.session.flash(msg, 'success')
            route_name = get_action_routename(item, 'changepassword')
            url = request.route_path(route_name, id=item.id)
            # Invalidate cache
            invalidate_cache()
            return HTTPFound(location=url)
        else:
            msg = _('Error on changing the password for '
                    '"${item}".', mapping=mapping)
            log.info(msg)
            request.session.flash(msg, 'error')

    rvalue['clazz'] = clazz
    rvalue['item'] = item
    rvalue['form'] = form.render(page=get_current_form_page(clazz, request))
    return rvalue
Ejemplo n.º 7
0
def register_user(request):
    settings = request.registry.settings
    if not is_registration_enabled(settings):
        raise exc.exception_response(503)
    handle_history(request)
    _ = request.translate
    config = Config(load(get_path_to_form_config('auth.xml', 'ringo')))
    form_config = config.get_form('register_user')
    form = Form(form_config, csrf_token=request.session.get_csrf_token(),
                translate=_)
    # Do extra validation which is not handled by formbar.
    # Is the login unique?
    validator = Validator('login',
                          'There is already a user with this name',
                          is_login_unique)
    form.add_validator(validator)
    if request.POST:
        if form.validate(request.params):
            # 1. Create user. Do not activate him. Default role is user.
            ufac = User.get_item_factory()
            user = ufac.create(None, form.data)
            # Set login from formdata
            user.login = form.data['login']
            # Encrypt password and save
            user.password = encrypt_password(form.data['pass'])
            # Deactivate the user. To activate the user needs to confirm
            # with the activation link
            user.activated = False
            atoken = str(uuid.uuid4())
            user.activation_token = atoken
            # Set profile data
            user.profile[0].email = form.data['_email']

            # 2. Set user group
            gfac = Usergroup.get_item_factory()
            group = gfac.load(USER_GROUP_ID)
            user.groups.append(group)

            # 3. Set user role
            rfac = Role.get_item_factory()
            role = rfac.load(USER_ROLE_ID)
            user.roles.append(role)
            # Set default user group.
            request.db.add(user)

            # 4. Send confirmation email. The user will be activated
            #    after the user clicks on the confirmation link
            mailer = Mailer(request)
            recipient = user.profile[0].email
            subject = _('Confirm user registration')
            values = {'url': request.route_url('confirm_user', token=atoken),
                      'app_name': get_app_title(),
                      'email': settings['mail.default_sender'],
                      '_': _}
            mail = Mail([recipient], subject, template="register_user", values=values)
            mailer.send(mail)

            target_url = request.route_path('login')
            headers = forget(request)
            msg = _("User has been created and a confirmation mail was sent"
                    " to the users email adress. Please check your email.")
            request.session.flash(msg, 'success')
            return HTTPFound(location=target_url, headers=headers)
    return {'form': form.render()}
Ejemplo n.º 8
0
class TestFormValidation(unittest.TestCase):

    def setUp(self):
        tree = load(os.path.join(test_dir, 'form.xml'))
        config = Config(tree)
        form_config = config.get_form('customform')
        self.form = Form(form_config)

    def test_form_init(self):
        pass

    def test_form_unknown_field(self):
        values = {'unknown': 'test', 'integer': '15', 'date': '1998-02-01'}
        self.form.validate(values)
        # Check that the unknown field has been filtered out as it was
        # not part of the form.
        self.assertEqual(self.form.data.has_key('unknown'), False)

    def test_form_validate_fail(self):
        values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'}
        self.assertEqual(self.form.validate(values), False)

    def test_form_validate_fail_checkvalues(self):
        values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'}
        self.assertEqual(self.form.validate(values), False)
        self.assertEqual(self.form.submitted_data['integer'], '15')
        self.assertEqual(self.form.submitted_data['date'], '1998-02-01')

    def test_form_validate_ok(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'}
        validator = Validator('integer',
                              'Error message',
                              external_validator)
        self.form.add_validator(validator)
        self.assertEqual(self.form.validate(values), True)

    def test_form_validate_ext_validator_fail(self):
        values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'}
        validator = Validator('integer',
                              'Error message',
                              external_validator)
        self.form.add_validator(validator)
        self.assertEqual(self.form.validate(values), False)

    def test_form_validate_ext_validator_ok(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'}
        self.assertEqual(self.form.validate(values), True)

    def test_form_deserialize_int(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'}
        self.form.validate(values)
        self.assertEqual(self.form.data['integer'], 16)

    def test_form_deserialize_float(self):
        values = {'default': 'test', 'integer': '16',
                  'date': '1998-02-01', 'float': '87.5'}
        self.assertEqual(self.form.validate(values), True)
        self.assertEqual(self.form.data['float'], 87.5)

    def test_form_deserialize_date(self):
        values = {'default': 'test', 'integer': '16',
                  'float': '87.5', 'date': '1998-02-01'}
        self.form.validate(values)
        self.assertEqual(self.form.data['date'], datetime.date(1998, 2, 1))

    def test_form_deserialize_string(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99'}
        self.form.validate(values)
        self.assertEqual(self.form.data['default'], 'test')

    def test_form_deserialize_time(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'time': '00:12:11'}
        self.form.validate(values)
        self.assertEqual(self.form.data['time'], 731)

    def test_form_deserialize_interval(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '00:12:11'}
        self.form.validate(values)
        self.assertEqual(self.form.data['interval'], datetime.timedelta(0, 731))

    def test_form_convert_interval_ok(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '01:12'}
        self.form.validate(values)
        self.assertEqual(self.form.data['interval'], datetime.timedelta(hours=1, minutes=12))
    
    def test_form_convert_interval_false(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '00:12:11'}
        self.form.validate(values)
        self.assertEqual(self.form.data['interval'] == datetime.timedelta(1), False)
    
    def test_form_convert_interval_mm_ok(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01', 'float': '99', 'interval': '12'}
        self.form.validate(values)
        self.assertEqual(self.form.data['interval'], datetime.timedelta(minutes=12))
    
    def test_form_save(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'}
        self.assertEqual(self.form.validate(values), True)

    def test_form_warnings(self):
        values = {'select': '2', 'default': 'test', 'integer': '16', 'date': '1998-02-01'}
        self.form.validate(values)
        warnings = self.form.get_warnings()
        self.assertEqual(len(warnings), 2)

    def test_form_save_without_validation(self):
        self.assertRaises(StateError, self.form.save)

    def test_form_fields(self):
        self.assertEqual(len(self.form.fields.values()), 9)

    def test_form_field_select_options(self):
        selfield = self.form.get_field('select')
        self.assertEqual(len(selfield.get_options()), 4)

    def test_generated_rules(self):
        num_rules = 0
        fields = self.form.fields
        for field in fields:
            num_rules += len(self.form.get_field(field).get_rules())
        self.assertEqual(num_rules, 5)

    def test_generated_warning_rules(self):
        num_rules = 0
        fields = self.form.fields
        for fieldname in fields:
            field = self.form.get_field(fieldname)
            rules = [r for r in field.get_rules() if r.triggers=="warning"]
            num_rules += len(rules)
        self.assertEqual(num_rules, 2)

    def test_generated_error_rules(self):
        num_rules = 0
        fields = self.form.fields
        for fieldname in fields:
            field = self.form.get_field(fieldname)
            rules = [r for r in field.get_rules() if r.triggers=="error"]
            num_rules += len(rules)
        self.assertEqual(num_rules, 3)
Ejemplo n.º 9
0
class TestFormValidation(unittest.TestCase):
    def setUp(self):
        tree = load(os.path.join(test_dir, 'form.xml'))
        config = Config(tree)
        form_config = config.get_form('customform')
        self.form = Form(form_config)

    def test_form_init(self):
        pass

    def test_form_unknown_field(self):
        values = {'unknown': 'test', 'integer': '15', 'date': '1998-02-01'}
        self.form.validate(values)
        # Check that the unknown field has been filtered out as it was
        # not part of the form.
        self.assertEqual(self.form.data.has_key('unknown'), False)

    def test_form_validate_fail(self):
        values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'}
        self.assertEqual(self.form.validate(values), False)

    def test_form_validate_fail_checkvalues(self):
        values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'}
        self.assertEqual(self.form.validate(values), False)
        self.assertEqual(self.form.submitted_data['integer'], '15')
        self.assertEqual(self.form.submitted_data['date'], '1998-02-01')

    def test_form_validate_ok(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'}
        validator = Validator('integer', 'Error message', external_validator)
        self.form.add_validator(validator)
        self.assertEqual(self.form.validate(values), True)

    def test_form_validate_ext_validator_fail(self):
        values = {'default': 'test', 'integer': '15', 'date': '1998-02-01'}
        validator = Validator('integer', 'Error message', external_validator)
        self.form.add_validator(validator)
        self.assertEqual(self.form.validate(values), False)

    def test_form_validate_ext_validator_ok(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'}
        self.assertEqual(self.form.validate(values), True)

    def test_form_deserialize_int(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'}
        self.form.validate(values)
        self.assertEqual(self.form.data['integer'], 16)

    def test_form_deserialize_float(self):
        values = {
            'default': 'test',
            'integer': '16',
            'date': '1998-02-01',
            'float': '87.5'
        }
        self.assertEqual(self.form.validate(values), True)
        self.assertEqual(self.form.data['float'], 87.5)

    def test_form_deserialize_date(self):
        values = {
            'default': 'test',
            'integer': '16',
            'float': '87.5',
            'date': '1998-02-01'
        }
        self.form.validate(values)
        self.assertEqual(self.form.data['date'], datetime.date(1998, 2, 1))

    def test_form_deserialize_string(self):
        values = {
            'default': 'test',
            'integer': '16',
            'date': '1998-02-01',
            'float': '99'
        }
        self.form.validate(values)
        self.assertEqual(self.form.data['default'], 'test')

    def test_form_deserialize_time(self):
        values = {
            'default': 'test',
            'integer': '16',
            'date': '1998-02-01',
            'float': '99',
            'time': '00:12:11'
        }
        self.form.validate(values)
        self.assertEqual(self.form.data['time'], 731)

    def test_form_deserialize_interval(self):
        values = {
            'default': 'test',
            'integer': '16',
            'date': '1998-02-01',
            'float': '99',
            'interval': '00:12:11'
        }
        self.form.validate(values)
        self.assertEqual(self.form.data['interval'],
                         datetime.timedelta(0, 731))

    def test_form_convert_interval_ok(self):
        values = {
            'default': 'test',
            'integer': '16',
            'date': '1998-02-01',
            'float': '99',
            'interval': '01:12'
        }
        self.form.validate(values)
        self.assertEqual(self.form.data['interval'],
                         datetime.timedelta(hours=1, minutes=12))

    def test_form_convert_interval_false(self):
        values = {
            'default': 'test',
            'integer': '16',
            'date': '1998-02-01',
            'float': '99',
            'interval': '00:12:11'
        }
        self.form.validate(values)
        self.assertEqual(self.form.data['interval'] == datetime.timedelta(1),
                         False)

    def test_form_convert_interval_mm_ok(self):
        values = {
            'default': 'test',
            'integer': '16',
            'date': '1998-02-01',
            'float': '99',
            'interval': '12'
        }
        self.form.validate(values)
        self.assertEqual(self.form.data['interval'],
                         datetime.timedelta(minutes=12))

    def test_form_save(self):
        values = {'default': 'test', 'integer': '16', 'date': '1998-02-01'}
        self.assertEqual(self.form.validate(values), True)

    def test_form_warnings(self):
        values = {
            'select': '2',
            'default': 'test',
            'integer': '16',
            'date': '1998-02-01'
        }
        self.form.validate(values)
        warnings = self.form.get_warnings()
        self.assertEqual(len(warnings), 2)

    def test_form_save_without_validation(self):
        self.assertRaises(StateError, self.form.save)

    def test_form_fields(self):
        self.assertEqual(len(self.form.fields.values()), 9)

    def test_form_field_select_options(self):
        selfield = self.form.get_field('select')
        self.assertEqual(len(selfield.get_options()), 4)

    def test_generated_rules(self):
        num_rules = 0
        fields = self.form.fields
        for field in fields:
            num_rules += len(self.form.get_field(field).get_rules())
        self.assertEqual(num_rules, 5)

    def test_generated_warning_rules(self):
        num_rules = 0
        fields = self.form.fields
        for fieldname in fields:
            field = self.form.get_field(fieldname)
            rules = [r for r in field.get_rules() if r.triggers == "warning"]
            num_rules += len(rules)
        self.assertEqual(num_rules, 2)

    def test_generated_error_rules(self):
        num_rules = 0
        fields = self.form.fields
        for fieldname in fields:
            field = self.form.get_field(fieldname)
            rules = [r for r in field.get_rules() if r.triggers == "error"]
            num_rules += len(rules)
        self.assertEqual(num_rules, 3)