def test_allow_null():
    class AllowNullSerializer(ChoiceSerializer):
        choice_text = serializers.CharField(allow_null=True)

    result = SchemaProcessor(AllowNullSerializer(), {}).get_schema()
    assert len(result['properties']['choice_text']['type']) == 2
    assert 'null' in result['properties']['choice_text']['type']
def test_serializer_no_title():
    class NoTitleSerializer(ChoiceSerializer):
        def __init__(self, **kwargs):
            super().__init__(label='', **kwargs)

    result = SchemaProcessor(NoTitleSerializer(), {}).get_schema()
    assert result['title'] == ''
def test_choice_schema_dependency_key_error():
    class SchemaKeyErrorDependencySerializer(ChoiceSerializer):
        choice_text = serializers.CharField(style={
            DEPENDENCY_SIMPLE_KEY: 'votes',
            DEPENDENCY_OVERRIDE_KEY: {}
        })

    with pytest.raises(KeyError):
        SchemaProcessor(SchemaKeyErrorDependencySerializer(), {}).get_schema()
def test_default():
    new_default = 'default'

    class DefaultSerializer(ChoiceSerializer):
        choice_text = serializers.CharField(default=new_default)

    result = SchemaProcessor(DefaultSerializer(), {}).get_schema()
    assert result['properties']['choice_text']['default'] == new_default
    assert 'choice_text' not in result['required']
def test_choice_schema_dynamic_dependency_non_enum_field():
    class SchemaDynamicDependencySerializer(ChoiceSerializer):
        choice_text = serializers.CharField(
            style={DEPENDENCY_DYNAMIC_KEY: {
                'yes': ['votes'],
                'no': None
            }}, )

    with pytest.raises(KeyError):
        SchemaProcessor(SchemaDynamicDependencySerializer(), {}).get_schema()
def test_field_label():
    new_label = 'test_label'

    class LabelSerializer(ChoiceSerializer):
        choice_text = serializers.CharField(label=new_label)

    result = SchemaProcessor(LabelSerializer(), {}).get_schema()
    assert result['properties']['choice_text']['title'] == new_label

    result = ColumnProcessor(LabelSerializer(), {}).get_schema()
    assert result[0]['title'] == new_label
def test_choice_schema_simple_unidirectional_dependency(dependencies):
    class SchemaSimpleUnidirectionalDependencySerializer(ChoiceSerializer):
        choice_text = serializers.CharField(
            style={DEPENDENCY_SIMPLE_KEY: dependencies})

    result = SchemaProcessor(SchemaSimpleUnidirectionalDependencySerializer(),
                             {}).get_schema()
    assert 'votes' not in result['required']
    assert 'votes' in result['dependencies']['choice_text']
    ui_result = UiSchemaProcessor(
        SchemaSimpleUnidirectionalDependencySerializer(), {}).get_ui_schema()
    assert DEPENDENCY_SIMPLE_KEY not in ui_result['votes']
def test_read_only():
    class ReadOnlySerializer(ChoiceSerializer):
        choice_text = serializers.CharField(read_only=True)

    result = SchemaProcessor(ReadOnlySerializer(), {}).get_schema()
    assert 'choice_text' not in result['properties']

    result = UiSchemaProcessor(ReadOnlySerializer(), {}).get_ui_schema()
    assert 'choice_text' not in result

    result = ColumnProcessor(ReadOnlySerializer(), {}).get_schema()
    assert not any(d['key'] == 'choice_text' for d in result)
def test_field_hidden_label():
    new_label = 'test_label'
    style_dict = {'ui:options': {'label': False}}

    class LabelSerializer(ChoiceSerializer):
        choice_text = serializers.CharField(label=new_label, style=style_dict)

    result = SchemaProcessor(LabelSerializer(), {}).get_schema()
    assert result['properties']['choice_text']['title'] == new_label

    result = UiSchemaProcessor(LabelSerializer(), {}).get_ui_schema()
    assert result['choice_text'] == style_dict
def test_choice_schema_dynamic_dependency_bad_enum_key_in_style():
    class SchemaDynamicDependencySerializer(ChoiceSerializer):
        choice_text = serializers.ChoiceField(
            choices=(('yes', 'Yes'), ('no', 'No')),
            style={DEPENDENCY_DYNAMIC_KEY: {
                'yes': ['votes'],
                'test': None
            }},
        )

    with pytest.raises(KeyError):
        SchemaProcessor(SchemaDynamicDependencySerializer(), {}).get_schema()
def test_extra_field_type(custom_field_type_expected_schema):
    class CustomFieldTypeSerializer(ChoiceSerializer):
        image_field = serializers.ImageField(required=True)
        uuid_field = serializers.UUIDField(required=True)

    result = SchemaProcessor(CustomFieldTypeSerializer(), {},
                             extra_types={
                                 'UUIDField': {
                                     'type': 'uuid'
                                 }
                             }).get_schema()
    assert result['properties'] == custom_field_type_expected_schema
def test_choice_schema_override():
    title_override = 'Override'

    class SchemaOverrideSerializer(ChoiceSerializer):
        choice_text = serializers.CharField(style={
            SCHEMA_OVERRIDE_KEY: {
                'type': 'string',
                'title': title_override
            }
        })

    result = SchemaProcessor(SchemaOverrideSerializer(), {}).get_schema()
    assert result['properties']['choice_text']['title'] == title_override
def test_choice_custom_widget_and_type():
    new_widget = 'CustomWidget'
    new_type = 'CustomType'

    class CustomWidgetSerializer(ChoiceSerializer):
        choice_text = serializers.CharField(style={
            'ui:widget': new_widget,
            'schema:type': new_type
        })

    result = SchemaProcessor(CustomWidgetSerializer(), {}).get_schema()
    assert result['properties']['choice_text']['type'] == new_type

    result = UiSchemaProcessor(CustomWidgetSerializer(), {}).get_ui_schema()
    assert result['choice_text']['ui:widget'] == new_widget
def test_choice_schema_override_dependency(
        choice_conditional_dependency_votes):
    class SchemaOverrideDependencySerializer(ChoiceSerializer):
        choice_text = serializers.CharField(
            style={
                DEPENDENCY_OVERRIDE_KEY: choice_conditional_dependency_votes
            })

    result = SchemaProcessor(SchemaOverrideDependencySerializer(),
                             {}).get_schema()
    # Since override doesn't do any processing this may result in a bad schema.
    assert 'votes' in result['properties']
    assert result['dependencies'] == {
        'choice_text': choice_conditional_dependency_votes
    }
def test_choice_schema_conditional_dependency(
        choice_conditional_dependency_votes):
    class SchemaConditionalDependencySerializer(ChoiceSerializer):
        choice_text = serializers.CharField(
            style={DEPENDENCY_CONDITIONAL_KEY: ['votes']})

    result = SchemaProcessor(SchemaConditionalDependencySerializer(),
                             {}).get_schema()
    assert 'votes' not in result['required']
    assert 'votes' not in result['properties']
    assert result['dependencies'] == {
        'choice_text': choice_conditional_dependency_votes
    }
    ui_result = UiSchemaProcessor(SchemaConditionalDependencySerializer(),
                                  {}).get_ui_schema()
    assert DEPENDENCY_CONDITIONAL_KEY not in ui_result['choice_text']
def test_choice_schema_dynamic_dependency(choice_dynamic_dependency_votes):
    class SchemaDynamicDependencySerializer(ChoiceSerializer):
        choice_text = serializers.ChoiceField(
            choices=(('yes', 'Yes'), ('no', 'No')),
            style={DEPENDENCY_DYNAMIC_KEY: {
                'yes': ['votes'],
                'no': None
            }},
        )
        votes = serializers.IntegerField()

    result = SchemaProcessor(SchemaDynamicDependencySerializer(),
                             {}).get_schema()
    assert result['dependencies'] == choice_dynamic_dependency_votes
    ui_result = UiSchemaProcessor(SchemaDynamicDependencySerializer(),
                                  {}).get_ui_schema()
    assert DEPENDENCY_DYNAMIC_KEY not in ui_result['choice_text']
def test_validation_schema():
    class MinSizeImageValidator:
        message = _('Image is too small, must be 1KB minimum.')
        code = 'image_min_1KB'

        def __call__(self, value):
            min_size = 1024  # 1KB
            if value.size < min_size:
                raise serializers.ValidationError(self.message, code=self.code)

    class CustomValidationSerializer(ChoiceSerializer):
        char_text = serializers.CharField(min_length=5, max_length=10)
        int_field = serializers.IntegerField(min_value=3, max_value=7)
        regex_field = serializers.RegexField(regex=r'^[a-zA-Z]+$',
                                             required=True)
        image_field = serializers.ImageField(
            required=True, validators=[MinSizeImageValidator])
        list_field = serializers.ListField(
            child=serializers.IntegerField(min_value=0, max_value=100),
            min_length=1,
            max_length=5,
            allow_empty=True,
        )

    result = SchemaProcessor(CustomValidationSerializer(), {}).get_schema()

    assert result['properties']['regex_field']['pattern'] == '^[a-zA-Z]+$'
    assert result['properties']['char_text']['maxLength'] == 10
    assert result['properties']['char_text']['minLength'] == 5
    assert result['properties']['int_field']['maximum'] == 7
    assert result['properties']['int_field']['minimum'] == 3
    assert result['properties']['list_field']['maxLength'] == 5
    assert result['properties']['list_field']['minLength'] == 1
    assert result['properties']['list_field']['required'] is False

    ui_result = UiSchemaProcessor(CustomValidationSerializer(),
                                  {}).get_ui_schema()

    assert 'ui:custom-validators' not in ui_result['char_text']
    assert ui_result['image_field']['ui:custom-validators'] == [{
        'code':
        'image_min_1KB',
        'message':
        'Image is too small, must be 1KB minimum.'
    }]
def test_choice_schema_simple_dynamic_dependencies(
        choice_dynamic_dependency_votes):
    class SchemaSimpleDynamicDependencySerializer(ChoiceSerializer):
        choice_text = serializers.ChoiceField(
            choices=(('yes', 'Yes'), ('no', 'No')),
            style={DEPENDENCY_DYNAMIC_KEY: {
                'yes': ['votes'],
                'no': None
            }},
        )
        votes = serializers.IntegerField()
        conditional = serializers.IntegerField(
            style={DEPENDENCY_SIMPLE_KEY: ['votes']})

    result = SchemaProcessor(SchemaSimpleDynamicDependencySerializer(),
                             {}).get_schema()
    assert 'votes' in result['properties']
    assert 'votes' in result['dependencies']['conditional']
    assert (result['dependencies']['choice_text'] ==
            choice_dynamic_dependency_votes['choice_text'])
def test_required():
    class RequiredSerializer(ChoiceSerializer):
        choice_text = serializers.CharField(required=False)

    result = SchemaProcessor(RequiredSerializer(), {}).get_schema()
    assert 'choice_text' not in result['required']
def test_serializer_title(class_name, form_name):
    ChoiceSerializer.__name__ = class_name

    result = SchemaProcessor(ChoiceSerializer(), {}).get_schema()
    assert result['title'] == form_name
def test_question_and_choice_retrieve_schema(
    question_and_choice_retrieve_expected_schema, ):
    result = SchemaProcessor(QuestionSerializer(), {}).get_schema()
    assert result == question_and_choice_retrieve_expected_schema