Beispiel #1
0
 def inner(mapping, context=None):
     register = context
     if not isinstance(mapping, dict):
         raise t.DataError("value is not a dict", value=mapping)
     checked_mapping = {}
     errors = {}
     for key, value in mapping.items():
         pair_errors = {}
         try:
             checked_key = key_trafaret.check(key, context=register)
         except t.DataError as err:
             pair_errors['key'] = err
             checked_key = None
         try:
             if checked_key:
                 register.push(path)
                 register.push(checked_key)
             schema = json_schema.check(value, context=register)
         except t.DataError as err:
             pair_errors['value'] = err
         else:
             register.save_schema(schema)
         finally:
             if checked_key:
                 register.pop()
                 register.pop()
         if pair_errors:
             errors[key] = t.DataError(error=pair_errors)
         else:
             checked_mapping[checked_key] = schema
     if errors:
         raise t.DataError(error=errors)
     return checked_mapping
Beispiel #2
0
def test_nested_dataerror_value():
    error = t.DataError(
        error={
            0:
            t.DataError(error='Wait for good value',
                        value='BAD ONE',
                        code='bad_value')
        },
        code='some_elements_going_mad',
    )
    assert error.as_dict() == {0: 'Wait for good value'}
    assert error.as_dict(value=True) == {
        0: "Wait for good value, got 'BAD ONE'"
    }
    assert error.to_struct() == {
        'code': 'some_elements_going_mad',
        'nested': {
            0: {
                'code': 'bad_value',
                'message': 'Wait for good value',
            }
        },
    }
    assert error.to_struct(value=True) == {
        'code': 'some_elements_going_mad',
        'nested': {
            0: {
                'code': 'bad_value',
                'message': "Wait for good value, got 'BAD ONE'",
            }
        },
    }
Beispiel #3
0
    def process_payment(self):
        status = http.OK
        data = self.order.details
        data['status'] = 'OK'
        try:
            option_id = session.pop('valid_option', None)
            carts = self.order.goods.filter_by(price_option_id=option_id)
            if carts.count() != self.order.goods.count():
                raise t.DataError({'voucher': _('Invalid price option')})

            redemption = self.__redeem(voucher=data['voucher'],
                                       security=data['code'],
                                       deal=data['deal'])
            if redemption.status_code != http.OK:
                raise t.DataError({'voucher': _('Invalid voucher')})
            else:
                self.order.mark_paid()
                data.update(self.order.as_dict())
        except t.DataError as e:
            status = http.BAD_REQUEST
            data.update({
                'message': 'ERROR',
                'errors': e.as_dict(),
                'status': 'ERR'
            })

        return jsonify_status_code(data, status)
Beispiel #4
0
class TestCall(unittest.TestCase):

    TRAFARET = T.Dict({
        T.Key("call_dict", optional=True):
        # The following is the ordered dict because we want to obey order
        # in the error messages. Otherwise, it could be normal dict as well
        T.Call(lambda _: T.DataError({
            "anything": "bad idea",
            "bad": "another bad idea",
        })),
        T.Key("call_str", optional=True):
        T.Call(lambda _: T.DataError("some error")),
    })

    def test_call_dict(self):
        self.assertEqual(
            get_err(self.TRAFARET, u"""
            call_dict: "hello"
        """),
            dedent(u"""\
            config.yaml:2: call_dict.anything: bad idea
            config.yaml:2: call_dict.bad: another bad idea
        """))

    def test_call_str(self):
        self.assertEqual(
            get_err(self.TRAFARET, u"""
            call_str: "hello"
        """),
            dedent(u"""\
            config.yaml:2: call_str: some error
              -> 'hello'
        """))
Beispiel #5
0
def ensure_callback_args(value):
    callback = value.get("callback")
    if not callback:
        return value

    kwargs = value.get("callback_args", {})
    callback_params = set(kwargs) | {"context"}

    sig = signature(callback)

    required_params = {
        name
        for name, param in sig.parameters.items()
        if param.default is param.empty and param.kind != 2
    }
    missed_params = required_params - callback_params

    if missed_params:
        raise t.DataError("Missed parameters for %s: %s" %
                          (callback, ", ".join(missed_params)))

    all_params = {
        name
        for name, param in sig.parameters.items()
        if param.kind != 2  # ignore vararg
    }
    unknown_params = callback_params - all_params

    if unknown_params:
        raise t.DataError("Unexpected parameters for %s: %s" %
                          (callback, ", ".join(unknown_params)))

    return value
Beispiel #6
0
 def check(value):
     errors = {}
     for name in names:
         if name not in value:
             errors[name] = t.DataError('%s is required' % name)
     if errors:
         return t.DataError(errors)
     return value
Beispiel #7
0
 def test_nested_dataerror_value(self):
     error = t.DataError(
         error={
             0: t.DataError(error='Wait for good value', value='BAD ONE')
         })
     self.assertEqual(error.as_dict(), {0: 'Wait for good value'})
     self.assertEqual(error.as_dict(value=True),
                      {0: "Wait for good value, got 'BAD ONE'"})
Beispiel #8
0
def check_headers(headers):
    if not isinstance(headers, dict):
        return t.DataError('value is not a dict')

    headers = dict((k.lower(), v) for k, v in headers.items())
    for item in ('fs-signature', 'fs-timestamp'):
        if item.lower() not in headers:
            return t.DataError('{} header is missing'.format(item))
    return headers
Beispiel #9
0
def test_as_dict():
    exc = t.DataError()
    resp = as_dict(exc)
    assert isinstance(resp, dict)

    exc = t.DataError()
    assert isinstance(exc.as_dict("boom"), str)

    resp = as_dict(exc, 'boom')
    assert isinstance(resp, dict)
Beispiel #10
0
 def check_(value):
     if (first in value) ^ (second in value):
         key = first if first in value else second
         yield first, t.catch_error(trafaret, value[key]), (key,)
     elif first in value and second in value:
         yield first, t.DataError(error=f'correct only if {second} is not defined'), (first,)
         yield second, t.DataError(error=f'correct only if {first} is not defined'), (second,)
     else:
         yield first, t.DataError(error=f'is required if {second} is not defined'), (first,)
         yield second, t.DataError(error=f'is required if {first} is not defined'), (second,)
Beispiel #11
0
 def _cmp_pwd(self, value):
     password, confirmation = (value.pop('password', None),
                               value.pop('confirmation', None))
     if password:
         if len(password) < 6:
             return t.DataError({
                 'password':
                 _("Passwords should be more than 6 symbols length")
             })
         if password != confirmation:
             return t.DataError(
                 {'confirmation': _("Passwords doesn't match")})
         value['password'] = encrypt_password(password)
     return value
Beispiel #12
0
 def check_(value):
     first, second = None, None
     if name in value:
         first = value[name]
     else:
         yield name, t.DataError('is required'), (name,)
     if confirm_name in value:
         second = value[confirm_name]
     else:
         yield confirm_name, t.DataError('is required'), (confirm_name,)
     if not (first and second):
         return
     yield name, t.catch_error(trafaret, first), (name,)
     yield confirm_name, t.catch_error(trafaret, second), (confirm_name,)
     if first != second:
         yield confirm_name, t.DataError(f'must be equal to {name}'), (confirm_name,)
    def test_call(self):
        a_three = lambda val: val if val == 3 else t.DataError('not a 3')
        tt = construct([a_three])
        self.assertEqual(tt([3, 3, 3]), [3, 3, 3])

        with self.assertRaises(t.DataError):
            tt([5])
Beispiel #14
0
    def test_keys_subset(self):
        cmp_pwds = lambda x: {
            'pwd':
            x['pwd']
            if x.get('pwd') == x.get('pwd1') else t.DataError('Not equal')
        }
        d = t.Dict({KeysSubset('pwd', 'pwd1'): cmp_pwds, 'key1': t.String})

        res = d.check({'pwd': 'a', 'pwd1': 'a', 'key1': 'b'}).keys()
        self.assertEqual(list(sorted(res)), ['key1', 'pwd'])

        res = extract_error(d.check, {'pwd': 'a', 'pwd1': 'c', 'key1': 'b'})
        self.assertEqual(res, {'pwd': 'Not equal'})

        res = extract_error(d.check, {'pwd': 'a', 'pwd1': None, 'key1': 'b'})
        self.assertEqual(res, {'pwd': 'Not equal'})

        get_values = (lambda d, keys: [d[k] for k in keys if k in d])
        join = (lambda d: {'name': ' '.join(get_values(d, ['name', 'last']))})
        res = t.Dict({
            KeysSubset('name', 'last'): join
        }).check({
            'name': 'Adam',
            'last': 'Smith'
        })
        self.assertEqual(res, {'name': 'Adam Smith'})

        res = t.Dict({KeysSubset(): t.Dict({'a': t.Any})}).check({'a': 3})
        self.assertEqual(res, {'a': 3})
Beispiel #15
0
def cast_interval(value):
    r"""Casts interval value into `datetime.timedelta` instance.

    If value is `int`, returned `timedelta` get constructed from a given
    by the value`s seconds.

    If value is `str`, then it get converted into seconds according the rules:

    - ``\d+s`` - time delta in seconds. Example: ``10s`` for 10 seconds;
    - ``\d+m`` - time delta in minutes. Example: ``42m`` for 42 minutes;
    - ``\d+h`` - time delta in hours. Example: ``1h`` for 1 hour;
    - ``\d+d`` - time delta in days. Example: ``10d`` for 10 days.

    :param str | int | datetime.timedelta value: An interval value.
    :rtype: datetime.timedelta
    """
    if isinstance(value, str):
        match = re.match(r"^(-)?(\d+)([dhms])$", value)
        if match is not None:
            has_neg_sign, value, unit = match.groups()
            value = int(value)
            value *= {
                # fmt: off
                "s": 1,
                "m": 60,
                "h": 60 * 60,
                "d": 60 * 60 * 24,
                # fmt: on
            }[unit]
            value *= -1 if has_neg_sign else 1
    if isinstance(value, int):
        value = datetime.timedelta(seconds=value)
    elif not isinstance(value, datetime.timedelta):
        raise t.DataError("invalid interval value %s" % value)
    return value
Beispiel #16
0
def validate_schema(schema, context=None):
    # we use `context` to provide register to deep schemas
    if context is None or isinstance(context, Register):
        register = context or Register()
        schema_name = schema.get('$id') or uuid4().urn
        schema_register = register.reg_schema(schema_name)
    elif isinstance(context, SchemaRegister):
        schema_register = context
    else:
        ValueError('You need to provide Register instance to json_schema and nothing else')

    touched_names = set()
    errors = {}
    keywords_checks = []
    format_transform = t.Any
    for key in all_keywords:
        for k, v, names in key(schema, context=schema_register):
            if isinstance(v, t.DataError):
                errors[k] = v
            else:
                if k == 'format':
                    format_transform = v
                keywords_checks.append(v)
            touched_names = touched_names.union(names)
    schema_keys = set(schema.keys())
    for key in schema_keys - touched_names:
        errors[key] = '%s is not allowed key' % key
    if errors:
        raise t.DataError(errors)
    schema_trafaret = All(keywords_checks) & format_transform
    return schema_trafaret
Beispiel #17
0
    def post(self):
        data = self.clean(g.request_json)

        if not User.is_unique(data['email']):
            raise t.DataError({'email': _("This email is already taken")})

        register_user(email=data['email'], password=data.get('password', '*'))
        return self._get_response()
Beispiel #18
0
    def transform(value):
        assert isinstance(value, dict)

        data = value.copy()
        if data.get(main) != data.get(extra):
            return t.DataError(error={main: msg})
        data.pop(extra, None)
        return data
def check_for_class_callback_collisions(value):
    if "class" in value:
        if "callback" in value or "callback_args" in value:
            raise t.DataError(
                "when `class` specified, there should be no"
                " `callback` and `callback_args`"
            )
    return value
Beispiel #20
0
 def get_schema(self, ref):
     if ref.startswith('#'):  # local reference
         if ref not in self.schemas:
             # TODO detect on build
             raise t.DataError('Bad reference `%s` in JSON schema' % ref)
         return self.schemas.get(ref)
     else:
         return self.register().get_schema(ref)
Beispiel #21
0
    def test_call(self):
        a_three = lambda val: val if val == 3 else t.DataError('not a 3',
                                                               code='not_a_3')
        tt = construct([a_three])
        assert tt([3, 3, 3]) == [3, 3, 3]

        with pytest.raises(t.DataError):
            tt([5])
Beispiel #22
0
def strong_password(string):
    """Check that ``string`` is strong enough password"""
    if (any(char.isdigit() for char in string) and any(char.islower()
                                                       for char in string)
            and any(char.isupper() for char in string)
            and any(char in punctuation for char in string)):
        return string
    else:
        raise t.DataError('Password is not strong enough')
Beispiel #23
0
 def transform(self, value, context=None):
     errors = []
     for trafaret in self.trafarets:
         res = t.catch_error(trafaret, value, context=context)
         if isinstance(res, t.DataError):
             errors.append(res)
         else:
             return value
     raise t.DataError(errors)
Beispiel #24
0
 def check(data):
     for v in data:
         try:
             trafaret(v)
         except t.DataError:
             pass
         else:
             return data
     raise t.DataError('Array does not contains any value that completes test')
Beispiel #25
0
 def check_(value):
     if (first in value) ^ (second in value):
         key = first if first in value else second
         yield first, t.catch_error(trafaret, value[key]), (key, )
     elif first in value and second in value:
         yield first, t.DataError(
             error='correct only if {} is not defined'.format(second)), (
                 first, )
         yield second, t.DataError(
             error='correct only if {} is not defined'.format(first)), (
                 second, )
     else:
         yield first, t.DataError(
             error='is required if {} is not defined'.format('second')), (
                 first, )
         yield second, t.DataError(
             error='is required if {} is not defined'.format('first')), (
                 second, )
Beispiel #26
0
    def _authenticate(self, data_dict):
        user = security.datastore.find_user(email=data_dict['email'])

        if verify_password(data_dict.get('password'), user.password):
            login_user(user)
        else:
            raise t.DataError(
                {'email': "Can't find anyone with this credentials"})

        return data_dict
Beispiel #27
0
def test_dataerror_value():
    error = t.DataError(error='Wait for good value',
                        value='BAD ONE',
                        code='bad_value')
    assert error.as_dict() == 'Wait for good value'
    assert error.as_dict(value=True) == "Wait for good value, got 'BAD ONE'"
    assert error.to_struct() == {
        'code': 'bad_value',
        'message': 'Wait for good value',
    }
Beispiel #28
0
 def test_dataerror_value(self):
     error = t.DataError(error='Wait for good value', value='BAD ONE')
     self.assertEqual(
         error.as_dict(),
         'Wait for good value'
     )
     self.assertEqual(
         error.as_dict(value=True),
         "Wait for good value, got 'BAD ONE'"
     )
Beispiel #29
0
 def check_and_return(self, value, context=None):
     try:
         return self.to_enum_func(value, self.converter)
     except ValueError:
         raise trf.DataError(
             "Incorrect value `{val}`. Possible variants: {possible_vals}".format(
                 val=value,
                 possible_vals=", ".join(e.name for e in self.converter),
             ),
             value=value,
             trafaret=self,
         )
Beispiel #30
0
 def check_(value):
     first, second = None, None
     if name in value:
         first = value[name]
         yield name, t.catch_error(trafaret, first), (name, )
     else:
         yield name, t.DataError('is required',
                                 code=codes.REQUIRED), (name, )
     if confirm_name in value:
         second = value[confirm_name]
         yield confirm_name, t.catch_error(trafaret,
                                           second), (confirm_name, )
     else:
         yield confirm_name, t.DataError(
             'is required', code=codes.REQUIRED), (confirm_name, )
     if not (first and second):
         return
     if first != second:
         yield (confirm_name,
                t.DataError('must be equal to {}'.format(name),
                            code=codes.MUST_BE_EQUAL), (confirm_name, ))