예제 #1
0
 def __init__(self):
     super(GetNewAddressesRequestFilter, self).__init__(
         {
             # Everything except ``seed`` is optional.
             'checksum':
             f.Type(bool) | f.Optional(default=False),
             'count':
             f.Type(int) | f.Min(1),
             'index':
             f.Type(int) | f.Min(0) | f.Optional(default=0),
             'securityLevel':
             f.Type(int)
             | f.Min(1)
             | f.Max(self.MAX_SECURITY_LEVEL)
             | f.Optional(default=AddressGenerator.DEFAULT_SECURITY_LEVEL),
             'seed':
             f.Required | Trytes(result_type=Seed),
         },
         allow_missing_keys={
             'checksum',
             'count',
             'index',
             'securityLevel',
         },
     )
예제 #2
0
    def test_mapper_chained_with_mapper(self):
        """
        Chaining two FilterMappers together has basically the same
        effect as combining their Filters.

        Generally, combining two FilterMappers into a single instance
        is much easier to read/maintain than chaining them, but in
        a few cases it may be unavoidable (for example, if you need
        each FilterMapper to handle extra and/or missing keys
        differently).
        """
        fm1 = f.FilterMapper(
            {
                'id': f.Int | f.Min(1),
            },
            allow_missing_keys=True,
            allow_extra_keys=True,
        )

        fm2 = f.FilterMapper(
            {
                'id': f.Required | f.Max(256),
                'subject': f.NotEmpty | f.MaxLength(16),
            },
            allow_missing_keys=False,
            allow_extra_keys=False,
        )

        self.filter_type = lambda: fm1 | fm2

        self.assertFilterPasses(
            {
                'id': '42',
                'subject': 'Hello, world!',
            },
            {
                'id': 42,
                'subject': 'Hello, world!',
            },
        )

        self.assertFilterErrors(
            {},
            {
                # ``fm1`` allows missing keys, so it sets 'id' to
                # ``None``.
                # However, ``fm2`` does not allow ``None`` for 'id'
                # (because of the ``Required`` filter).
                'id': [f.Required.CODE_EMPTY],

                # `fm1` does not care about `subject`, but `fm2`
                # expects it to be there.
                'subject': [f.FilterMapper.CODE_MISSING_KEY],
            },
            expected_value={
                'id': None,
                'subject': None,
            },
        )
예제 #3
0
    def test_implicit_chain(self):
        """
        Chaining two filters together creates a FilterChain.
        """
        self.filter_type = lambda: f.Int | f.Max(3)

        self.assertFilterPasses('1', 1)
        self.assertFilterErrors('4', [f.Max.CODE_TOO_BIG])
예제 #4
0
    def test_success_filter_map(self):
        """
        Applying a :py:class:`f.FilterMap` to the values in a namedtuple
        after converting (success case).
        """
        self.filter_type = lambda: f.NamedTuple(
            Color,
            {
                # For whatever reason, we decide not to filter ``r``.
                'g': f.Required | f.Int | f.Min(0) | f.Max(255),
                'b': f.Required | f.Int | f.Min(0) | f.Max(255),
            })

        self.assertFilterPasses(
            ('64.0', '128', 192.0),
            Color('64.0', 128, 192),
        )
예제 #5
0
def SecurityLevel():
    """
    Generates a filter chain for validating a security level.

    :return:
        :py:class:`filters.FilterChain` object.
    """
    return (f.Type(int) | f.Min(1) | f.Max(3)
            | f.Optional(default=AddressGenerator.DEFAULT_SECURITY_LEVEL))
예제 #6
0
    def test_fail_filter_map(self):
        """
        Applying a :py:class:`f.FilterMap` to the values in a namedtuple
        after converting (failure case).
        """
        self.filter_type = lambda: f.NamedTuple(
            Color,
            {
                # For whatever reason, we decide not to filter ``r``.
                'g': f.Required | f.Int | f.Min(0) | f.Max(255),
                'b': f.Required | f.Int | f.Min(0) | f.Max(255),
            })

        self.assertFilterErrors(
            ['NaN', None, (42, )],
            {
                'g': [f.Required.CODE_EMPTY],
                'b': [f.Decimal.CODE_INVALID],
            },
        )
예제 #7
0
 def __init__(self):
     super(GetBalancesRequestFilter, self).__init__(
         {
             'addresses':
             f.Required | f.Array | f.FilterRepeater(
                 f.Required | AddressNoChecksum()
                 | f.Unicode(encoding='ascii', normalize=False), ),
             'threshold':
             f.Type(int) | f.Min(0) | f.Max(100) | f.Optional(default=100),
         },
         allow_missing_keys={
             'threshold',
         },
     )
예제 #8
0
 def __init__(self):
     super(GetBalancesRequestFilter, self).__init__(
         {
             'addresses':
             (f.Required
              | f.Array
              | f.FilterRepeater(f.Required | Trytes(result_type=Address))),
             'threshold': (f.Type(int)
                           | f.Min(0)
                           | f.Max(100)
                           | f.Optional(default=100)),
         },
         allow_missing_keys={
             'threshold',
         },
     )
예제 #9
0
 def test_pass_default(self):
     """
     The incoming value does not match any of the switch cases, but
     we defined a default filter.
     """
     self.assertFilterPasses(
         self._filter(
             {
                 'name': 'negative',
                 'value': -42
             },
             getter=lambda value: value['name'],
             cases={
                 'positive': f.FilterMapper({'value': f.Int | f.Min(0)}),
             },
             default=f.FilterMapper({'value': f.Int | f.Max(0)}),
         ), )