Beispiel #1
0
def test_array_field():
    s_f = StringField()
    n_f = NumberField()
    field = ArrayField(Var({
        'role_1': s_f,
        'role_2': n_f,
    }))
    schema = field.get_schema(role='role_1')
    assert schema['items'] == s_f.get_schema()

    schema = field.get_schema(role='role_2')
    assert schema['items'] == n_f.get_schema()

    schema = field.get_schema()
    assert 'items' not in schema

    _ = lambda value: Var({'role_1': value})
    field = ArrayField(s_f,
                       min_items=_(1),
                       max_items=_(2),
                       unique_items=_(True),
                       additional_items=_(True))
    assert field.get_schema() == {
        'type': 'array',
        'items': s_f.get_schema(),
    }
    assert field.get_schema(role='role_1') == {
        'type': 'array',
        'items': s_f.get_schema(),
        'minItems': 1,
        'maxItems': 2,
        'uniqueItems': True,
        'additionalItems': True,
    }
Beispiel #2
0
def test_array_field():
    f = ArrayField(items=())
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    assert list(e.value.steps) == [FieldStep(f), AttributeStep('items')]

    f = ArrayField(items=(
        Var({'role_x': StringField()}),
        Var({'role_x': IntField()}),
    ))
    role = 'role_y'
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema(role='role_y')
    assert list(e.value.steps) == [
        FieldStep(f, role=role),
        AttributeStep('items', role=role)
    ]

    f = ArrayField(items=(None, None))
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    assert list(
        e.value.steps) == [FieldStep(f),
                           AttributeStep('items'),
                           ItemStep(0)]

    f = ArrayField(items=object())
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    assert list(e.value.steps) == [FieldStep(f), AttributeStep('items')]

    f = ArrayField(additional_items=object())
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    assert list(
        e.value.steps) == [FieldStep(f),
                           AttributeStep('additional_items')]

    f = ArrayField(items=FieldStub())
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert e.message == FieldStub.ERROR_MESSAGE
    assert list(e.steps) == [FieldStep(f), AttributeStep('items')]

    f = ArrayField(items=(FieldStub(), ))
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert e.message == FieldStub.ERROR_MESSAGE
    assert list(e.steps) == [FieldStep(f), AttributeStep('items'), ItemStep(0)]

    f = ArrayField(additional_items=FieldStub())
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert e.message == FieldStub.ERROR_MESSAGE
    assert list(e.steps) == [FieldStep(f), AttributeStep('additional_items')]
Beispiel #3
0
    class Task(Document):
        class Options(object):
            title = 'Task'
            description = 'A task.'
            definition_id = 'task'

        id = IntField(required=Var({'response': True}))
        name = StringField(required=True, min_length=5)
        type = StringField(required=True, enum=['TYPE_1', 'TYPE_2'])
        created_at = DateTimeField(required=True)
        author = Var({'response': DocumentField(User)})
Beispiel #4
0
def test_var():
    value_1 = object()
    value_2 = object()
    value_3 = object()
    var = Var([
        ('role_1', value_1),
        ('role_2', value_2),
        (not_('role_3'), value_3),
    ])
    assert len(var.values) == 3
    for matcher, value in var.values:
        assert callable(matcher)
        assert type(value) == object

    assert var.resolve('role_1') == Resolution(value_1, 'role_1')
    assert var.resolve('role_2') == Resolution(value_2, 'role_2')
    assert var.resolve('default') == Resolution(value_3, 'default')

    var = Var([
        (not_('role_3'), value_3),
        ('role_1', value_1),
        ('role_2', value_2),
    ])
    assert var.resolve('role_1') == Resolution(value_3, 'role_1')
    assert var.resolve('role_2') == Resolution(value_3, 'role_2')
    assert var.resolve('default') == Resolution(value_3, 'default')
    assert var.resolve('role_3') == Resolution(None, 'role_3')

    var = Var([
        ('role_1', value_1),
        ('role_2', value_2),
    ], propagate='role_2')
    assert callable(var.propagate)
Beispiel #5
0
def test_helpers():
    when = lambda *args: Var({
        not_(*args): False
    }, default=True)

    assert when(RESPONSE_ROLE).resolve(RESPONSE_ROLE).value
    assert not when(RESPONSE_ROLE).resolve(REQUEST_ROLE).value
Beispiel #6
0
 class User(Document):
     login = StringField()
     friends = ArrayField(
         Var({
             'db_role': db_role_friends_field,
             'request_role': request_role_friends_field,
         }))
Beispiel #7
0
def test_not_field():
    for f in [NotField(object()), NotField(Var({'role_x': object()}))]:
        with pytest.raises(SchemaGenerationException) as e:
            f.get_schema()
        e = e.value
        assert 'not a BaseField' in e.message
        assert list(e.steps) == [FieldStep(f), AttributeStep('field')]
Beispiel #8
0
 class Message(Document):
     with Scope(DB_ROLE) as db:
         db.uuid = StringField(required=True)
     created_at = IntField(
         required=when_not(PARTIAL_RESPONSE_ROLE, REQUEST_ROLE))
     text = StringField(required=when_not(PARTIAL_RESPONSE_ROLE))
     field_that_is_never_present = Var(
         {'NEVER': StringField(required=True)})
Beispiel #9
0
def test_keyword_of_fields(field_cls):
    f = field_cls(object())
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert 'not a list or a tuple' in e.message
    assert list(e.steps) == [FieldStep(f), AttributeStep('fields')]

    f = field_cls([])
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert 'empty' in e.message
    assert list(e.steps) == [FieldStep(f), AttributeStep('fields')]

    f = field_cls([object()])
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert 'not resolvable' in e.message
    assert list(
        e.steps) == [FieldStep(f),
                     AttributeStep('fields'),
                     ItemStep(0)]

    role = 'role_x'
    f = field_cls([Var({role: object()})])
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema(role=role)
    e = e.value
    assert 'not a BaseField' in e.message
    assert list(e.steps) == [
        FieldStep(f, role),
        AttributeStep('fields', role),
        ItemStep(0, role)
    ]

    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert 'empty' in e.message
    assert list(e.steps) == [FieldStep(f), AttributeStep('fields')]

    # test nested field errors
    f = field_cls([FieldStub()])
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert e.message == FieldStub.ERROR_MESSAGE
    assert list(
        e.steps) == [FieldStep(f),
                     AttributeStep('fields'),
                     ItemStep(0)]
Beispiel #10
0
def test_keyword_of_fields(keyword, field_cls):
    s_f = StringField()
    n_f = NumberField()
    i_f = IntField()
    field = field_cls([n_f, Var({'role_1': s_f}), Var({'role_2': i_f})])
    assert field.get_schema() == {keyword: [n_f.get_schema()]}
    assert field.get_schema(role='role_1') == {
        keyword: [n_f.get_schema(), s_f.get_schema()]
    }
    assert field.get_schema(role='role_2') == {
        keyword: [n_f.get_schema(), i_f.get_schema()]
    }

    field = field_cls(
        Var(
            {
                'role_1': [n_f,
                           Var({'role_1': s_f}),
                           Var({'role_2': i_f})],
                'role_2': [Var({'role_2': i_f})],
            },
            propagate='role_1'))
    assert field.get_schema() == {keyword: []}
    assert field.get_schema(role='role_1') == {
        keyword: [n_f.get_schema(), s_f.get_schema()]
    }
    assert field.get_schema(role='role_2') == {keyword: []}
Beispiel #11
0
def test_keyword_of_fields(keyword, field_cls):
    s_f = StringField()
    n_f = NumberField()
    i_f = IntField()
    field = field_cls([n_f, Var({'role_1': s_f}), Var({'role_2': i_f})])
    assert s(field.get_schema()) == {keyword: [n_f.get_schema()]}
    assert s(field.get_schema(role='role_1')) == {
        keyword: [n_f.get_schema(), s_f.get_schema()]
    }
    assert s(field.get_schema(role='role_2')) == {
        keyword: [n_f.get_schema(), i_f.get_schema()]
    }

    field = field_cls(
        Var(
            {
                'role_1': [n_f,
                           Var({'role_1': s_f}),
                           Var({'role_2': i_f})],
                'role_2': [Var({'role_2': i_f})],
            },
            propagate='role_1'))
    assert s(field.get_schema(role='role_1')) == {
        keyword: [n_f.get_schema(), s_f.get_schema()]
    }
    with pytest.raises(SchemaGenerationException):
        field.get_schema(role='role_2')
Beispiel #12
0
def test_base_field():
    _ = lambda value: Var({'role_1': value})
    field = BaseSchemaField(default=_(lambda: 1), enum=_(lambda: [1, 2, 3]), title=_('Title'),
                            description=_('Description'))
    schema = field._update_schema_with_common_fields({})
    assert schema == {}

    schema = field._update_schema_with_common_fields(schema, role='role_1')
    assert schema == {
        'title': 'Title',
        'description': 'Description',
        'enum': [1, 2, 3],
        'default': 1,
    }
Beispiel #13
0
def test_string_field():
    _ = lambda value: Var({'role_1': value})
    field = StringField(format=_('date-time'),
                        min_length=_(1),
                        max_length=_(2))
    assert field.get_schema() == {'type': 'string'}
    assert field.get_schema(role='role_1') == {
        'type': 'string',
        'format': 'date-time',
        'minLength': 1,
        'maxLength': 2,
    }

    with pytest.raises(ValueError) as e:
        StringField(pattern=_('('))
    assert str(e.value) == 'Invalid regular expression: unbalanced parenthesis'
Beispiel #14
0
def test_var():
    value_1 = object()
    value_2 = object()
    value_3 = object()
    var = Var([
        ('role_1', value_1),
        ('role_2', value_2),
        (not_('role_3'), value_3),
    ])
    assert var.resolve('role_1') == Resolution(value_1, 'role_1')
    assert var.resolve('role_2') == Resolution(value_2, 'role_2')
    assert var.resolve('default') == Resolution(value_3, 'default')

    var = Var([
        (not_('role_3'), value_3),
        ('role_1', value_1),
        ('role_2', value_2),
    ])
    assert var.resolve('role_1') == Resolution(value_3, 'role_1')
    assert var.resolve('role_2') == Resolution(value_3, 'role_2')
    assert var.resolve('default') == Resolution(value_3, 'default')
    assert var.resolve('role_3') == Resolution(None, 'role_3')
Beispiel #15
0
def test_dict_field():
    s_f = StringField()
    _ = lambda value: Var({'role_1': value})
    field = DictField(properties=Var(
        {
            'role_1': {
                'name': Var({'role_1': s_f})
            },
            'role_2': {
                'name': Var({'role_2': s_f})
            },
        },
        propagate='role_1'),
                      pattern_properties=Var(
                          {
                              'role_1': {
                                  '.*': Var({'role_1': s_f})
                              },
                              'role_2': {
                                  '.*': Var({'role_2': s_f})
                              },
                          },
                          propagate='role_1'),
                      additional_properties=_(s_f),
                      min_properties=_(1),
                      max_properties=_(2))
    assert s(field.get_schema()) == s({'type': 'object'})
    assert s(field.get_schema(role='role_1')) == s({
        'type':
        'object',
        'properties': {
            'name': s_f.get_schema(),
        },
        'patternProperties': {
            '.*': s_f.get_schema(),
        },
        'additionalProperties':
        s_f.get_schema(),
        'minProperties':
        1,
        'maxProperties':
        2,
    })
    assert s(field.get_schema(role='role_2')) == s({
        'type': 'object',
        'properties': {},
        'patternProperties': {},
    })
Beispiel #16
0
def test_var():
    value_1 = object()
    value_2 = object()
    value_3 = object()
    var = Var([
        ('role_1', value_1),
        ('role_2', value_2),
        (Not('role_3'), value_3),
    ])
    assert var.resolve('role_1') == value_1
    assert var.resolve('role_2') == value_2
    assert var.resolve('default') == value_3

    var = Var([
        (Not('role_3'), value_3),
        ('role_1', value_1),
        ('role_2', value_2),
    ])
    assert var.resolve('role_1') == value_3
    assert var.resolve('role_2') == value_3
    assert var.resolve('default') == value_3
    assert var.resolve('role_3') is None
Beispiel #17
0
def test_var():
    value_1 = object()
    value_2 = object()
    value_3 = object()
    var = Var([
        ('role_1', value_1),
        ('role_2', value_2),
        (not_('role_3'), value_3),
    ])
    assert var.resolve('role_1') == Resolution(value_1, 'role_1')
    assert var.resolve('role_2') == Resolution(value_2, 'role_2')
    assert var.resolve('default') == Resolution(value_3, 'default')

    var = Var([
        (not_('role_3'), value_3),
        ('role_1', value_1),
        ('role_2', value_2),
    ])
    assert var.resolve('role_1') == Resolution(value_3, 'role_1')
    assert var.resolve('role_2') == Resolution(value_3, 'role_2')
    assert var.resolve('default') == Resolution(value_3, 'default')
    assert var.resolve('role_3') == Resolution(None, 'role_3')
Beispiel #18
0
 class Options(object):
     definition_id = Var({'role_1': 'a'})
Beispiel #19
0
 class User(Document):
     id = Var({'response': IntField(required=True)})
     login = StringField(required=True)
Beispiel #20
0
 class A(Document):
     id = Var({'response': StringField(required=True)})
     b = DocumentField(B)
Beispiel #21
0
 class B(Document):
     name = Var({
         'response': StringField(required=True),
         'request': StringField(),
     })
Beispiel #22
0
def test_not_field():
    s_f = StringField()
    field = NotField(Var({'role_1': s_f}))
    assert field.get_schema() == {'not': {}}
    assert field.get_schema(role='role_1') == {'not': s_f.get_schema()}
Beispiel #23
0
def test_dict_field():
    f = DictField(properties={'a': object()})
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert 'not resolvable' in e.message
    assert list(
        e.steps) == [FieldStep(f),
                     AttributeStep('properties'),
                     ItemStep('a')]

    f = DictField(pattern_properties={'a.*': object()})
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert 'not resolvable' in e.message
    assert list(e.steps) == [
        FieldStep(f),
        AttributeStep('pattern_properties'),
        ItemStep('a.*')
    ]

    f = DictField(additional_properties=object())
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert 'not a BaseField or a bool' in e.message
    assert list(
        e.steps) == [FieldStep(f),
                     AttributeStep('additional_properties')]

    f = DictField(properties={'a': FieldStub()})
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert e.message == FieldStub.ERROR_MESSAGE
    assert list(
        e.steps) == [FieldStep(f),
                     AttributeStep('properties'),
                     ItemStep('a')]

    f = DictField(pattern_properties={'a.*': FieldStub()})
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert e.message == FieldStub.ERROR_MESSAGE
    assert list(e.steps) == [
        FieldStep(f),
        AttributeStep('pattern_properties'),
        ItemStep('a.*')
    ]

    f = DictField(additional_properties=FieldStub())
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert e.message == FieldStub.ERROR_MESSAGE
    assert list(
        e.steps) == [FieldStep(f),
                     AttributeStep('additional_properties')]

    for kwarg_value in (object(), Var({'role_x': object()})):
        for kwarg in ('properties', 'pattern_properties'):
            f = DictField(**{kwarg: kwarg_value})
            with pytest.raises(SchemaGenerationException) as e:
                f.get_schema(role='role_x')
            e = e.value
            assert 'not a dict' in e.message
            assert list(e.steps) == [
                FieldStep(f, role='role_x'),
                AttributeStep(kwarg, role='role_x')
            ]

        f = DictField(additional_properties=kwarg_value)
        with pytest.raises(SchemaGenerationException) as e:
            f.get_schema(role='role_x')
        e = e.value
        assert 'not a BaseField or a bool' in e.message
        assert list(e.steps) == [
            FieldStep(f, role='role_x'),
            AttributeStep('additional_properties', role='role_x')
        ]

    f = DictField(pattern_properties={'((((': StringField()})
    with pytest.raises(SchemaGenerationException) as e:
        f.get_schema()
    e = e.value
    assert 'unbalanced parenthesis' in e.message
    assert list(e.steps) == [FieldStep(f), AttributeStep('pattern_properties')]
Beispiel #24
0
def test_var():
    value_1 = object()
    value_2 = object()
    value_3 = object()
    var = Var([
        ('role_1', value_1),
        ('role_2', value_2),
        (not_('role_3'), value_3),
    ])
    assert len(var.values) == 3
    for matcher, value in var.values:
        assert callable(matcher)
        assert type(value) == object

    assert var.resolve('role_1') == Resolution(value_1, 'role_1')
    assert var.resolve('role_2') == Resolution(value_2, 'role_2')
    assert var.resolve('default') == Resolution(value_3, 'default')

    var = Var([
        (not_('role_3'), value_3),
        ('role_1', value_1),
        ('role_2', value_2),
    ])
    assert var.resolve('role_1') == Resolution(value_3, 'role_1')
    assert var.resolve('role_2') == Resolution(value_3, 'role_2')
    assert var.resolve('default') == Resolution(value_3, 'default')
    assert var.resolve('role_3') == Resolution(None, 'role_3')

    var = Var([
        ('role_1', value_1),
        ('role_2', value_2),
    ], propagate='role_2')
    assert callable(var.propagate)
Beispiel #25
0
 class A(Document):
     a = Var({'role_1': DocumentField('self')})
Beispiel #26
0
def test_scopes_basics():
    when_not = lambda *args: Var({all_but(*args): True}, default=False)

    when = lambda *args: Var({all_but(*args): False}, default=True)

    class Message(Document):
        with Scope(DB_ROLE) as db:
            db.uuid = StringField(required=True)
        created_at = IntField(
            required=when_not(PARTIAL_RESPONSE_ROLE, REQUEST_ROLE))
        text = StringField(required=when_not(PARTIAL_RESPONSE_ROLE))

    class User(Document):
        class Options(object):
            roles_to_propagate = all_but(PARTIAL_RESPONSE_ROLE)

        with Scope(DB_ROLE) as db:
            db._id = StringField(required=True)
            db.version = StringField(required=True)
        with Scope(lambda r: r.startswith(RESPONSE_ROLE) or r == REQUEST_ROLE
                   ) as response:
            response.id = StringField(required=when_not(PARTIAL_RESPONSE_ROLE))
        with Scope(all_but(REQUEST_ROLE)) as request:
            request.messages = ArrayField(
                DocumentField(Message),
                required=when_not(PARTIAL_RESPONSE_ROLE))

    schema = User.get_schema(role=DB_ROLE)
    sort_required_keys(schema)
    expected_required = sorted(['_id', 'version', 'messages'])
    expected_properties = {
        '_id': {
            'type': 'string'
        },
        'version': {
            'type': 'string'
        },
        'messages': {
            'type': 'array',
            'items': {
                'type': 'object',
                'additionalProperties': False,
                'properties': {
                    'created_at': {
                        'type': 'integer'
                    },
                    'text': {
                        'type': 'string'
                    },
                    'uuid': {
                        'type': 'string'
                    }
                },
                'required': sorted(['uuid', 'created_at', 'text']),
            },
        },
    }
    assert schema['required'] == expected_required
    assert schema['properties'] == expected_properties

    schema = User.get_schema(role=REQUEST_ROLE)
    sort_required_keys(schema)
    expected_required = sorted(['id'])
    expected_properties = {
        'id': {
            'type': 'string'
        },
    }
    assert schema['required'] == expected_required
    assert schema['properties'] == expected_properties

    schema = User.get_schema(role=RESPONSE_ROLE)
    sort_required_keys(schema)
    expected_required = sorted(['id', 'messages'])
    expected_properties = {
        'id': {
            'type': 'string'
        },
        'messages': {
            'type': 'array',
            'items': {
                'type': 'object',
                'additionalProperties': False,
                'properties': {
                    'created_at': {
                        'type': 'integer'
                    },
                    'text': {
                        'type': 'string'
                    },
                },
                'required': sorted(['created_at', 'text']),
            },
        },
    }
    assert schema['required'] == expected_required
    assert schema['properties'] == expected_properties

    schema = User.get_schema(role=PARTIAL_RESPONSE_ROLE)
    sort_required_keys(schema)
    expected_properties = {
        'id': {
            'type': 'string'
        },
        'messages': {
            'type': 'array',
            'items': {
                'type': 'object',
                'additionalProperties': False,
                'properties': {
                    'created_at': {
                        'type': 'integer'
                    },
                    'text': {
                        'type': 'string'
                    },
                },
                'required': sorted(['created_at', 'text']),
            },
        },
    }
    assert 'required' not in schema
    assert schema['properties'] == expected_properties
Beispiel #27
0
def test_scopes_basics():
    when_not = lambda *args: Var({not_(*args): True}, default=False)

    class Message(Document):
        with Scope(DB_ROLE) as db:
            db.uuid = StringField(required=True)
        created_at = IntField(
            required=when_not(PARTIAL_RESPONSE_ROLE, REQUEST_ROLE))
        text = StringField(required=when_not(PARTIAL_RESPONSE_ROLE))
        field_that_is_never_present = Var(
            {'NEVER': StringField(required=True)})

    class User(Document):
        class Options(object):
            roles_to_propagate = not_(PARTIAL_RESPONSE_ROLE)

        with Scope(DB_ROLE) as db:
            db._id = StringField(required=True)
            db.version = StringField(required=True)
        with Scope(lambda r: r.startswith(RESPONSE_ROLE) or r == REQUEST_ROLE
                   ) as response:
            response.id = StringField(required=when_not(PARTIAL_RESPONSE_ROLE))
        with Scope(not_(REQUEST_ROLE)) as not_request:
            not_request.messages = ArrayField(
                DocumentField(Message),
                required=when_not(PARTIAL_RESPONSE_ROLE))

    resolution = Message.resolve_field('text')
    assert resolution.value == Message.text
    assert resolution.role == DEFAULT_ROLE

    resolution = Message.resolve_field('field_that_is_never_present')
    assert resolution.value is None
    assert resolution.role == DEFAULT_ROLE

    resolution = Message.resolve_field('non-existent')
    assert resolution.value is None
    assert resolution.role == DEFAULT_ROLE

    schema = User.get_schema(role=DB_ROLE)
    expected_required = sorted(['_id', 'version', 'messages'])
    expected_properties = {
        '_id': {
            'type': 'string'
        },
        'version': {
            'type': 'string'
        },
        'messages': {
            'type': 'array',
            'items': {
                'type': 'object',
                'additionalProperties': False,
                'properties': {
                    'created_at': {
                        'type': 'integer'
                    },
                    'text': {
                        'type': 'string'
                    },
                    'uuid': {
                        'type': 'string'
                    }
                },
                'required': sorted(['uuid', 'created_at', 'text']),
            },
        },
    }
    assert sorted(schema['required']) == expected_required
    assert sort_required_keys(
        schema['properties']) == sort_required_keys(expected_properties)
    assert dict(User.resolve_and_iter_fields(DB_ROLE)) == {
        '_id': User.db._id,
        'version': User.db.version,
        'messages': User.not_request.messages,
    }

    schema = User.get_schema(role=REQUEST_ROLE)
    expected_required = sorted(['id'])
    expected_properties = {
        'id': {
            'type': 'string'
        },
    }
    assert sorted(schema['required']) == expected_required
    assert sort_required_keys(
        schema['properties']) == sort_required_keys(expected_properties)
    assert dict(User.resolve_and_iter_fields(REQUEST_ROLE)) == {
        'id': User.response.id,
    }

    schema = User.get_schema(role=RESPONSE_ROLE)
    expected_required = sorted(['id', 'messages'])
    expected_properties = {
        'id': {
            'type': 'string'
        },
        'messages': {
            'type': 'array',
            'items': {
                'type': 'object',
                'additionalProperties': False,
                'properties': {
                    'created_at': {
                        'type': 'integer'
                    },
                    'text': {
                        'type': 'string'
                    },
                },
                'required': sorted(['created_at', 'text']),
            },
        },
    }
    assert sorted(schema['required']) == expected_required
    assert sort_required_keys(
        schema['properties']) == sort_required_keys(expected_properties)
    assert dict(User.resolve_and_iter_fields(RESPONSE_ROLE)) == {
        'id': User.response.id,
        'messages': User.not_request.messages,
    }

    schema = User.get_schema(role=PARTIAL_RESPONSE_ROLE)
    expected_properties = {
        'id': {
            'type': 'string'
        },
        'messages': {
            'type': 'array',
            'items': {
                'type': 'object',
                'additionalProperties': False,
                'properties': {
                    'created_at': {
                        'type': 'integer'
                    },
                    'text': {
                        'type': 'string'
                    },
                },
                'required': sorted(['created_at', 'text']),
            },
        },
    }
    assert 'required' not in schema
    assert sort_required_keys(
        schema['properties']) == sort_required_keys(expected_properties)
    assert dict(Message.resolve_and_iter_fields(PARTIAL_RESPONSE_ROLE)) == {
        'created_at': Message.created_at,
        'text': Message.text,
    }