def __new__(cls, *args):
        class_name, parents, attrs = args

        if not parents:
            return type.__new__(cls, class_name, parents, attrs)

        options = Options(class_name, attrs)
        generated_schema = cls._gen_schema(options.model, options)
        options.single = generated_schema.single
        options.list = generated_schema.list

        return type(class_name, (),
                    dict(generated_schema.to_attrs(), _meta=options))
def test_validator_wrong():
    from mongoengine import Document, StringField

    class Test(Document):
        parent = StringField()

    with pytest.raises(Exception) as e_info:
        Options('TestSchema', {'model': Test, 'validator': True})

    assert str(e_info.value) == "'validator' attribute must be callable."

    with pytest.raises(Exception) as e_info:
        Options('TestSchema', {'model': Test, 'validator': lambda x: x})

    assert str(e_info.value) == (
        "The 'validator' attribute must be a callable that accepts four arguments: "
        "model, fields, query, special_params")
def test_options_no_model():
    with pytest.raises(Exception) as e_info:
        Options('TestSchema', {})

    assert str(
        e_info.value
    ) == 'Failed to generate schema {}, model attribute was not given.'.format(
        'TestSchema')
def test_mutate_not_static():
    from mongoengine import Document

    class Test(Document):
        pass

    with pytest.raises(Exception) as e_info:
        Options('TestSchema', {'model': Test, 'mutate': 'To fails'})

    assert str(e_info.value) == 'Failed to generate schema {}, mutate method must ' \
                                'be a method with the decorator staticmethod.'.format('TestSchema')
    def _gen_schema(cls, model, options=None):
        """ This function is responsible for generate the graphene schema and memoize it """
        options = Options(model.__name__ + 'Schema',
                          {'model': model}) if not options else options

        MongoSchemaMeta._generated_schemas.update({
            model:
            ModelSchema(model, options.mongo_fields, options.mutate,
                        options.validator)
        })
        return MongoSchemaMeta._generated_schemas[model]
def test_mongoengine_field_references_self():
    from mongoengine import Document, ReferenceField

    class Test(Document):
        parent = ReferenceField('self')

    with pytest.raises(Exception) as e_info:
        Options('TestSchema', {'model': Test})

    assert str(e_info.value) == "It was not possible to generate schema for {} because the field {} is a " \
                                "ReferenceField to self and this is not supported yet."\
                                .format("TestSchema", 'parent')
def test_mongoengine_field_not_implemented():
    from mongoengine import FileField, Document

    class Test(Document):
        field_error = FileField()

    with pytest.raises(Exception) as e_info:
        Options('TestSchema', {'model': Test})

    assert str(e_info.value) == "It was not possible to generate schema for {} because the " \
                                "field {} is of the type {}, and that field is not supported yet." \
                                .format("Test", 'field_error', FileField)
def test_mongoengine_list_of_field_field_not_implemented():
    from graphene_mongodb.operators import list_fields
    from mongoengine import FileField, Document

    for list_type in list_fields:

        class Test(Document):
            field_error = list_type(FileField())

        with pytest.raises(Exception) as e_info:
            Options('TestSchema', {'model': Test})

        assert str(e_info.value) == "It was not possible to generate schema for {} because the " \
                                    "field {} is a List of the type {}, and that field is not supported yet."\
                                    .format("Test", 'field_error', type(Test.field_error.field))
def test_mutate_wrong_number_arguments():
    from mongoengine import Document

    class Test(Document):
        pass

    def mutate():
        pass

    with pytest.raises(Exception) as e_info:
        Options('TestSchema', {'model': Test, 'mutate': staticmethod(mutate)})

    assert str(e_info.value) == 'Failed to generate schema {}, mutate method must accept two params. ' \
                                'The first is the arguments passed to mutate in query, for instance: ' \
                                'username:"******". Second is the context of the application, if it is flask, ' \
                                'will be flask global request.'.format('TestSchema')
def test_not_mongoengine_document():
    with pytest.raises(Exception) as e_info:
        Options('TestSchema', {'model': False})

    assert str(e_info.value) == 'Failed to generate schema {}, model must be ' \
                                'a subclass of mongoengine.Document.'.format('TestSchema')