def setup(self):
     super(TestMGORMProvider, self).setup()
     self.provider = MingProvider(User.__mongometa__.session)
     Department(_id=1, name='Marketing')
     Department(_id=2, name='Accounting')
     DocumentCategory(_id=1, department_id=1, name='Brochure')
     DocumentCategory(_id=2, department_id=1, name='Flyer')
     DocumentCategory(_id=3, department_id=2, name='Balance Sheet')
     #session.add(DocumentRating(user_id=1, document_id=1, rating=5))
     session.flush_all()
     #session.close_all()
     self.asdf_user_id = self.provider.get_obj(User, {
         'user_name': 'asdf'
     })._id
Beispiel #2
0
 def setup(self):
     super(TestMGORMProvider, self).setup()
     self.provider = MingProvider(User.__mongometa__.session)
     Department(_id=1, name='Marketing')
     Department(_id=2, name='Accounting')
     DocumentCategory(_id=1, department_id=1, name='Brochure')
     DocumentCategory(_id=2, department_id=1, name='Flyer')
     DocumentCategory(_id=3, department_id=2, name='Balance Sheet')
     #session.add(DocumentRating(user_id=1, document_id=1, rating=5))
     session.flush_all()
     #session.close_all()
     self.asdf_user_id = self.provider.get_obj(User, {'user_name': 'asdf'})._id
Beispiel #3
0
 def _configure_provider(self):
     if tg.config.get('use_sqlalchemy', False):
         log.info('Configuring resetpassword for SQLAlchemy')
         from sprox.sa.provider import SAORMProvider
         self._provider = SAORMProvider(session=DBSession)
     elif tg.config.get('use_ming', False):
         log.info('Configuring resetpassword for Ming')
         from sprox.mg.provider import MingProvider
         self._provider = MingProvider(DBSession)
     else:
         raise ValueError(
             'resetpassword should be used with sqlalchemy or ming')
Beispiel #4
0
 def _configure_provider(self):
     if tg.config.get('use_sqlalchemy'):
         log.info('Configuring %s for SQLAlchemy' % TGAPP_NAME)
         from sprox.sa.provider import SAORMProvider
         self._provider = SAORMProvider(session=DBSession)
     elif tg.config.get('use_ming'):
         log.info('Configuring %s for Ming' % TGAPP_NAME)
         from sprox.mg.provider import MingProvider
         self._provider = MingProvider(DBSession)
     else:
         raise ValueError('%s should be used with sqlalchemy or ming' %
                          TGAPP_NAME)
Beispiel #5
0
def configure_models():
    global provider

    if tg.config.get('use_sqlalchemy', False):
        log.info('Configuring TgappPermissions for SQLAlchemy')
        from sprox.sa.provider import SAORMProvider
        provider = SAORMProvider(session=DBSession, engine=False)
    elif tg.config.get('use_ming', False):
        log.info('Configuring TgappPermissions for Ming')
        from sprox.mg.provider import MingProvider
        provider = MingProvider(DBSession)
    else:
        raise ValueError(
            'TgappPermissions should be used with sqlalchemy or ming')
Beispiel #6
0
def configure_models():
    global provider, MailModel, TemplateTranslation

    if tg.config.get('use_sqlalchemy', False):
        log.info('Configuring MailTemplates for SQLAlchemy')
        from mailtemplates.model.sqla.models import MailModel, TemplateTranslation
        from sprox.sa.provider import SAORMProvider
        provider = SAORMProvider(session=DBSession, engine=False)
    elif tg.config.get('use_ming', False):
        log.info('Configuring MailTemplates for Ming')
        from mailtemplates.model.ming.models import MailModel, TemplateTranslation
        from sprox.mg.provider import MingProvider
        provider = MingProvider(DBSession)
    else:
        raise ValueError('MailTemplates should be used with sqlalchemy or ming')
Beispiel #7
0
def configure_models():
    global provider, ProfileActivation

    if tg.config.get('use_sqlalchemy', False):
        log.info('Configuring tgapp-userprofile for SQLAlchemy')
        from userprofile.model.sqla.models import ProfileActivation
        from sprox.sa.provider import SAORMProvider
        provider = SAORMProvider(session=DBSession, engine=False)
    elif tg.config.get('use_ming', False):
        log.info('Configuring tgapp-userprofile for Ming')
        from userprofile.model.ming.models import ProfileActivation
        from sprox.mg.provider import MingProvider
        provider = MingProvider(DBSession)
    else:
        raise ValueError(
            'tgapp-userprofile should be used with sqlalchemy or ming')
Beispiel #8
0
def configure_models():
    global provider, Category, CategoryImage

    if tg.config.get('use_sqlalchemy', False):
        log.info('Configuring TgappCategories for SQLAlchemy')
        from tgappcategories.model.sqla.models import Category, CategoryImage
        from sprox.sa.provider import SAORMProvider
        provider = SAORMProvider(session=DBSession, engine=False)
    elif tg.config.get('use_ming', False):
        log.info('Configuring TgappCategories for Ming')
        from tgappcategories.model.ming.models import Category, CategoryImage
        from sprox.mg.provider import MingProvider
        provider = MingProvider(DBSession)
    else:
        raise ValueError(
            'TgappCategories should be used with sqlalchemy or ming')
Beispiel #9
0
def configure_models():
    global provider, Comment, CommentVote, DeclarativeBase

    if tg.config.get('use_sqlalchemy', False):
        log.info('Configuring TGComments for SQLAlchemy')
        from sqlalchemy.ext.declarative import declarative_base
        DeclarativeBase = declarative_base()
        from tgcomments.model.sqla.models import Comment, CommentVote
        from sprox.sa.provider import SAORMProvider
        provider = SAORMProvider(session=DBSession, engine=False)
    elif tg.config.get('use_ming', False):
        log.info('Configuring TGComments for Ming')
        from tgcomments.model.ming.models import Comment, CommentVote
        from sprox.mg.provider import MingProvider
        provider = MingProvider(DBSession)
    else:
        raise ValueError('TGComments should be used with sqlalchemy or ming')
Beispiel #10
0
class TestMGORMProvider(SproxTest):
    def setup(self):
        super(TestMGORMProvider, self).setup()
        self.provider = MingProvider(User.__mongometa__.session)
        Department(_id=1, name='Marketing')
        Department(_id=2, name='Accounting')
        DocumentCategory(_id=1, department_id=1, name='Brochure')
        DocumentCategory(_id=2, department_id=1, name='Flyer')
        DocumentCategory(_id=3, department_id=2, name='Balance Sheet')
        #session.add(DocumentRating(user_id=1, document_id=1, rating=5))
        session.flush_all()
        #session.close_all()
        self.asdf_user_id = self.provider.get_obj(User, {'user_name': 'asdf'})._id

    def test_get_field_widget_args(self):
        eq_(self.provider.get_field_widget_args(User, 'groups', User.groups), {'nullable': True, 'provider':self.provider})

    def test_get_fields_with_func(self):
        eq_(self.provider.get_fields(lambda: Town), ['_id', 'users', 'name'])

    def test_isbinary_related(self):
        assert not self.provider.is_binary(User, 'groups')

    def test_isbinary(self):
        assert self.provider.is_binary(File, 'data')

    def test_is_query_not_a_query(self):
        assert self.provider.is_query(File, None) == False

    def test_binary_create(self):
        fs = "fake_content"

        values = {'data':fs}
        self.provider.create(File, values)
        session.flush()

    def test_binary_update(self):
        fs = "fake_content"

        values = {'data':fs}
        entity = self.provider.create(File, values)

        session.flush()
        values = {'data':fs, '_id':entity._id}
        self.provider.update(File, values)

    def test_get_entity(self):
        entity = self.provider.get_entity('User')
        assert entity == User, entity

    def test_get_entities(self):
        entities = self.provider.get_entities()
        assert set(entities) == set(['Town', 'GroupPermission', 'Group', 'Permission', 'DocumentCategoryReference',
                'SproxTestClass', 'DocumentCategoryTag', 'DocumentCategoryTagAssignment', 'User', 'File', 'TGMMUser',
                'DocumentCategory', 'Department', 'Document', 'MappedClass', 'Example', 'UserGroup', 'UnrelatedDocument'])

    @raises(KeyError)
    def test_get_entity_non_matching_engine(self):
        entity = self.provider.get_entity('OtherClass')


    def test_get_primary_fields(self):
        fields = self.provider.get_primary_fields(User)
        eq_(fields, ['_id'])

    # expected failure; need compound primary key support
    @raises(AssertionError)
    def test_get_primary_fields_multi(self):
        fields = self.provider.get_primary_fields(DocumentCategory)
        eq_(fields, ['document_category_id', 'department_id'])

    def test_get_primary_field_function(self):
        field = self.provider.get_primary_field(lambda: User)
        eq_(field, '_id')

    def test_get_view_field_name_defaults_substring(self):
        field = self.provider.get_view_field_name(Permission, None)
        eq_(field, 'permission_name')

    def test_get_view_field_name_with_title(self):
        """
        if it exists, orm provider should use the 'title' info attribute to
        determine the title column
        """
        field = self.provider.get_view_field_name(User, ['name'])
        eq_(field, 'display_name')

    def test_get_view_field_name_not_found(self):
        field = self.provider.get_view_field_name(Group, [])
        assert field in self.provider.get_fields(Group)

    def test_get_dropdown_options_oneof(self):
        options = self.provider.get_dropdown_options(Example, 'oneof')
        eq_(set(options), set(set([('three', 'three'), ('one', 'one'), ('two', 'two')])))

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_fieldtype(self):
        class BadClass(object):
            pass
        bc = BadClass()
        options = self.provider.get_dropdown_options(BadClass, None)

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_type(self):
        options = self.provider.get_dropdown_options(Example, 'int_')

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_field(self):
        options = self.provider.get_dropdown_options(User, 'town_id')

    def test_get_dropdown_options_fk(self):
        options = self.provider.get_dropdown_options(User, 'town')
        for _id, name in options:
            town = Town.query.find({'name':name}).first()
            assert str(town._id) == str(_id)

    def test_get_dropdown_options_fk_multi(self):
        options = self.provider.get_dropdown_options(Document, 'category')
        eq_(set(options), set((('1', 'Brochure'), ('2', 'Flyer'), ('3', 'Balance Sheet'))))

    # expected failure; need many-to-many support
    @raises(AssertionError)
    def test_get_dropdown_options_join(self):
        options = self.provider.get_dropdown_options(User, 'groups')
        eq_(options, [('1', '0'), ('2', '1'), ('3', '2'), ('4', '3'), ('5', '4')])

    # expected failure; need many-to-many support
    @raises(AssertionError)
    def test_get_dropdown_options_join_2(self):
        options = self.provider.get_dropdown_options(Group, 'users')
        eq_(options, [(1, '*****@*****.**'),])

    def test_get_relations(self):
        relations = self.provider.get_relations(User)
        eq_(relations, ['town', 'groups'])

    def test_dictify(self):
        d = self.provider.dictify(self.user)
        eq_(d['user_name'], 'asdf')

    def test_dictify_limit_fields(self):
        d = self.provider.dictify(self.user, fields=['user_name'])
        eq_(d['user_name'], 'asdf')
        eq_(list(d.keys()), ['user_name'])

    def test_dictify_omit_fields(self):
        d = self.provider.dictify(self.user, omit_fields=['password', '_password'])
        assert 'password' not in list(d.keys())
        assert '_password' not in list(d.keys())
        assert 'user_name' in list(d.keys())

    def test_dictify_none(self):
        d = self.provider.dictify(None)
        eq_(d, {})

    # expected failure; ming does not yet support writing into RelationProperties
    @raises(TypeError)
    def test_create(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', 'groups':[1,4], 'town':2}
        new_user = self.provider.create(User, params)
        assert q_user == new_user

    def test_create_blank__id(self):
        params = {'user_name':'asdf3', 'password':'******', 'email_address':'*****@*****.**', '_id':''}
        new_user = self.provider.create(User, params)
        q_user = self.provider.get(User, {'user_name':'asdf3'})
        assert q_user is not None

    # expected failure; needs many-to-many support
    @raises(InvalidId)
    def test_create_many_to_one_multi(self):
        params = {'category': '1/1'}
        new_ref = self.provider.create(DocumentCategoryReference, params)
        q_ref = self.session.query(DocumentCategoryReference).get(1)
        assert new_ref == q_ref

    # expected failure; needs many-to-many support
    @raises(InvalidId)
    def test_create_many_to_many_multi(self):
        params = {'categories': ['1/1', '1/2']}
        new_ratingref = self.provider.create(DocumentCategoryTag, params)
        q_ratingref = self.session.query(DocumentCategoryTag).get(1)
        assert new_ratingref == q_ratingref

    def test_query(self):
        r = self.provider.query(User, limit=20, offset=0)
        eq_(len(r), 2)

    def test_query_offset_None(self):
        r = self.provider.query(User, limit=20, offset=None)
        eq_(len(r), 2)

    def test_query_with_offset(self):
        r = self.provider.query(User, offset=10)
        eq_(len(r), 2)

    def test_query_limit_None(self):
        r = self.provider.query(User, limit=None, offset=None)
        eq_(len(r), 2)

    def test_query_limit(self):
        count, r = self.provider.query(User, limit=1)
        eq_(len(r), 1)

    def test_query_sort_asc(self):
        cnt, r = self.provider.query(Town, order_by="name")
        eq_([t.name for t in r], ['Arvada', 'Boulder', 'Denver', 'Golden'])

    def test_query_sort_desc(self):
        cnt, r = self.provider.query(Town, order_by="name", desc=True)
        eq_([t.name for t in r], ['Golden', 'Denver', 'Boulder', 'Arvada'])

    def test_query_filters(self):
        cnt, r = self.provider.query(Town, filters={'name':'Golden'})
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_id_by_string(self):
        cnt, r = self.provider.query(Town, filters={'name':'Golden'})
        golden_id = str(r[0]._id)

        cnt, r = self.provider.query(Town, filters={'_id':golden_id})
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_id_by_objectid(self):
        cnt, r = self.provider.query(Town, filters={'name':'Golden'})
        golden_id = r[0]._id

        cnt, r = self.provider.query(Town, filters={'_id':golden_id})
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_substring(self):
        cnt, r = self.provider.query(Town, filters={'name':'old'}, substring_filters=['name'])
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_substring_escaping(self):
        cnt, r = self.provider.query(Town, filters={'name':'o.*l.*d'}, substring_filters=['name'])
        eq_(r, []), r

    def test_query_filters_substring_related(self):
        cnt, r = self.provider.query(Town, filters={'users':'this_does_not_work'}, substring_filters=['users'])
        eq_(r, []), r

    def test_query_filters_substring_insensitive(self):
        cnt, r = self.provider.query(Town, filters={'name':'gold'}, substring_filters=['name'])
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_substring_disabled(self):
        cnt, r = self.provider.query(Town, filters={'name':'old'}, substring_filters=[])
        eq_(r, [])

    def test_query_filters_substring_notstring(self):
        cnt, towns = self.provider.query(Town)
        cnt, r = self.provider.query(Town, filters={'_id':towns[0]._id}, substring_filters=['_id'])
        eq_([t.name for t in r], [towns[0].name])
        cnt, r = self.provider.query(Town, filters={'_id':'this_is_the_id'}, substring_filters=['_id'])
        eq_(r, [])

    # expected failure; needs updatable RelationProperty
    @raises(TypeError)
    def test_update(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', 'groups':[1,4], 'town':2}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_simple(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_datetime(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = datetime.utcnow().replace(microsecond=0)
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')
        eq_(q_user.created, params['created'])

    def test_update_sprox_id(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', 'sprox_id': 'xyz'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_method(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', '_method': 'xyz'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_extra_keys(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', 'extraneous': 'xyz'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_omit_fieds(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params, omit_fields=['email_address'])
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_create_one_to_many_relation(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', 'extraneous': 'xyz'}
        new_user = self.provider.create(User, params)
        session.flush()

        #One-To-Many relations are not writable in Ming, we ensure that we do not have a crash when one is set
        new_town = self.provider.create(Town, {'users':[new_user._id]})
        assert new_town.users == []

    @raises(TypeError)
    def test_relation_fields_invalid(self):
        self.provider.relation_fields(User, "_id")

    def test_relation_fields_tgmm(self):
        relation_fields = self.provider.relation_fields(TGMMUser, 'groups')
        assert relation_fields == []

    # expected failure; needs updatable RelationProperty
    @raises(TypeError)
    def test_update_omit(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', 'groups':[1,4], 'town':2}
        new_user = self.provider.create(User, params)

        params = {}
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = 2
        new_user = self.provider.update(User, params, omit_fields=['email_address', 'groups'])
        q_user = self.session.query(User).get(2)

        eq_(q_user.email_address, '*****@*****.**')
        eq_([group.group_id for group in q_user.groups], [1,4])

    def test_get_default_values(self):
        assert {} == self.provider.get_default_values(User, {})

    def test_get(self):
        user = self.provider.get(User, params={'_id': self.asdf_user_id})
        eq_(user['user_name'], 'asdf')

    def test_delete(self):
        user = self.provider.delete(User, params={'_id': self.asdf_user_id})
        session.flush()
        users = User.query.find().all()
        assert len(users) == 0

    def test_create_with_DateTime(self):
        self.provider.create(Document, dict(edited='2011-03-30 12:21:21'))

    def test_create_with_int(self):
        self.provider.create(UnrelatedDocument, dict(number=5))

    def test_create_with_bool(self):
        self.provider.create(UnrelatedDocument, dict(enabled=True))

    def test_create_with_str_bool(self):
        self.provider.create(UnrelatedDocument, dict(enabled='true'))

    def test_create_relationships_with_wacky_relation(self):
        obj = Group.query.find().first()
        user = User.query.find().first()
        self.provider.update(Group, {'_id':obj._id, 'users':[user._id]})
        assert user._id == obj.users[0].user_id

    def test_create_relationships_remove_groups(self):
        obj = Group.query.find().first()
        self.provider.update(User, {'_id':self.user._id, 'groups':[]})
        assert user not in obj.users

    def test_create_relationships_change_town(self):
        town = Town.query.find({'name':'Arvada'}).first()

        self.user.town = town
        self.session.flush()

        self.provider.update(User, {'_id':self.user._id, 'town':Town.query.find({'name':'Denver'}).first()})
        assert self.user.town.name == 'Denver'

    def test_tgmanymany_create(self):
        count, groups = self.provider.query(Group, limit=1)
        params = {'user_name':'mmuser', 'groups':[groups[0]]}
        new_user = self.provider.create(TGMMUser, params)

        assert new_user.groups[0].group_name == groups[0].group_name
        assert new_user._groups[0] == groups[0].group_name

    def test_tgmanymany_update(self):
        params = {'user_name':'mmuser', 'groups':[]}
        new_user = self.provider.create(TGMMUser, params)

        assert len(new_user.groups) == 0
        count, groups = self.provider.query(Group, limit=1)
        self.provider.update(TGMMUser, {'_id':new_user._id, 'groups':[groups[0]]})

        new_user = self.provider.get_obj(TGMMUser, {'_id':new_user._id})
        assert len(new_user.groups) == 1
        assert new_user.groups[0].group_name == groups[0].group_name
        assert new_user._groups[0] == groups[0].group_name
Beispiel #11
0
class TestMGORMProvider(SproxTest):
    def setup(self):
        super(TestMGORMProvider, self).setup()
        self.provider = MingProvider(User.__mongometa__.session)
        Department(_id=1, name='Marketing')
        Department(_id=2, name='Accounting')
        DocumentCategory(_id=1, department_id=1, name='Brochure')
        DocumentCategory(_id=2, department_id=1, name='Flyer')
        DocumentCategory(_id=3, department_id=2, name='Balance Sheet')
        #session.add(DocumentRating(user_id=1, document_id=1, rating=5))
        session.flush_all()
        #session.close_all()
        self.asdf_user_id = self.provider.get_obj(User, {'user_name': 'asdf'})._id

    def test_get_field_widget_args(self):
        eq_(self.provider.get_field_widget_args(User, 'groups', User.groups), {'nullable': True, 'provider':self.provider})

    def test_get_fields_with_func(self):
        eq_(sorted(self.provider.get_fields(lambda: Town)), sorted(['country', '_id', 'users', 'name']))

    def test_isbinary_related(self):
        assert not self.provider.is_binary(User, 'groups')

    def test_isbinary(self):
        assert self.provider.is_binary(File, 'data')

    def test_is_query_not_a_query(self):
        assert self.provider.is_query(File, None) == False

    def test_binary_create(self):
        fs = b"fake_content"

        values = {'data':fs}
        self.provider.create(File, values)
        session.flush()

    def test_binary_update(self):
        fs = b"fake_content"

        values = {'data':fs}
        entity = self.provider.create(File, values)

        session.flush()
        values = {'data':fs, '_id':entity._id}
        self.provider.update(File, values)

    def test_get_entity(self):
        entity = self.provider.get_entity('User')
        assert entity == User, entity

    def test_get_entities(self):
        entities = list(self.provider.get_entities())
        assert set(entities) == set(['Town', 'GroupPermission', 'Group', 'Permission', 'DocumentCategoryReference',
                'SproxTestClass', 'DocumentCategoryTag', 'DocumentCategoryTagAssignment', 'User', 'File', 'TGMMUser',
                'DocumentCategory', 'Department', 'Document', 'MappedClass', 'Example', 'UnrelatedDocument',
                'ModelWithRequired', 'NestedModel']), entities

    @raises(KeyError)
    def test_get_entity_non_matching_engine(self):
        entity = self.provider.get_entity('OtherClass')

    def test_get_primary_fields(self):
        fields = self.provider.get_primary_fields(User)
        eq_(fields, ['_id'])

    # expected failure; need compound primary key support
    @raises(AssertionError)
    def test_get_primary_fields_multi(self):
        fields = self.provider.get_primary_fields(DocumentCategory)
        eq_(fields, ['document_category_id', 'department_id'])

    def test_get_primary_field_function(self):
        field = self.provider.get_primary_field(lambda: User)
        eq_(field, '_id')

    def test_get_view_field_name_defaults_substring(self):
        field = self.provider.get_view_field_name(Permission, ['name'])
        eq_(field, 'permission_name')

    def test_get_view_field_name_with_title(self):
        """
        if it exists, orm provider should use the 'title' info attribute to
        determine the title column
        """
        field = self.provider.get_view_field_name(User, ['name'])
        eq_(field, 'display_name')

    def test_get_view_field_name_not_found(self):
        field = self.provider.get_view_field_name(Group, [])
        assert field in self.provider.get_fields(Group)

    def test_get_view_field_name_for_subdocument(self):
        doc = self.provider.create(Document, dict(metadata=[{'name': 'author',
                                                             'value': 'Philip K Dick'},
                                                            {'name': 'year',
                                                             'value': '1968'}]))

        class DocumentsFiller(TableFiller):
            __model__ = Document
        tf = DocumentsFiller(self.provider.session)

        names = tf._get_list_data_value(Document, doc.metadata)
        assert names == 'author, year', names

    def test_get_view_field_name_for_unknown_objects(self):
        first_list_value = {'name': 'author', 'value': 'Philip K Dick'}

        doc = self.provider.create(Document, dict(metadata=[first_list_value,
                                                            {'name': 'year',
                                                             'value': '1968'}]))

        entry = doc.metadata[0]
        suggested_name = self.provider.get_view_field_name(entry.__class__, ['name'])
        value = str(getattr(entry, suggested_name))
        assert value == str(first_list_value)

    def test_get_dropdown_options_oneof(self):
        options = self.provider.get_dropdown_options(Example, 'oneof')
        eq_(set(options), set(set([('three', 'three'), ('one', 'one'), ('two', 'two')])))

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_fieldtype(self):
        class BadClass(object):
            pass
        bc = BadClass()
        options = self.provider.get_dropdown_options(BadClass, None)

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_type(self):
        options = self.provider.get_dropdown_options(Example, 'int_')

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_field(self):
        options = self.provider.get_dropdown_options(User, 'town_id')

    def test_get_dropdown_options_fk(self):
        options = self.provider.get_dropdown_options(User, 'town')
        for _id, name in options:
            town = Town.query.find({'name':name}).first()
            assert str(town._id) == str(_id)

    def test_get_dropdown_options_fk_multi(self):
        options = self.provider.get_dropdown_options(Document, 'category')
        eq_(set(options), set((('1', 'Brochure'), ('2', 'Flyer'), ('3', 'Balance Sheet'))))

    # expected failure; need many-to-many support
    @raises(AssertionError)
    def test_get_dropdown_options_join(self):
        options = self.provider.get_dropdown_options(User, 'groups')
        eq_(options, [('1', '0'), ('2', '1'), ('3', '2'), ('4', '3'), ('5', '4')])

    # expected failure; need many-to-many support
    @raises(AssertionError)
    def test_get_dropdown_options_join_2(self):
        options = self.provider.get_dropdown_options(Group, 'users')
        eq_(options, [(1, '*****@*****.**'),])

    def test_get_relations(self):
        relations = self.provider.get_relations(User)
        eq_(sorted(relations), sorted(['town', 'groups']))

    def test_dictify(self):
        d = self.provider.dictify(self.user)
        eq_(d['user_name'], 'asdf')

    def test_dictify_limit_fields(self):
        d = self.provider.dictify(self.user, fields=['user_name'])
        eq_(d['user_name'], 'asdf')
        eq_(list(d.keys()), ['user_name'])

    def test_dictify_omit_fields(self):
        d = self.provider.dictify(self.user, omit_fields=['password', '_password'])
        assert 'password' not in list(d.keys())
        assert '_password' not in list(d.keys())
        assert 'user_name' in list(d.keys())

    def test_dictify_none(self):
        d = self.provider.dictify(None)
        eq_(d, {})

    # expected failure; groups and town relation values should be an ObjectId
    @raises(TypeError)
    def test_create(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**',
                  'groups':[1,4], 'town':2}
        new_user = self.provider.create(User, params)

    def test_create_blank__id(self):
        params = {'user_name':'asdf3', 'password':'******', 'email_address':'*****@*****.**', '_id':''}
        new_user = self.provider.create(User, params)
        q_user = self.provider.get(User, {'user_name':'asdf3'})
        assert q_user is not None

    # expected failure; needs many-to-many support
    @raises(InvalidId)
    def test_create_many_to_one_multi(self):
        params = {'category': '1/1'}
        new_ref = self.provider.create(DocumentCategoryReference, params)
        q_ref = self.session.query(DocumentCategoryReference).get(1)
        assert new_ref == q_ref

    # expected failure; needs many-to-many support
    @raises(InvalidId)
    def test_create_many_to_many_multi(self):
        params = {'categories': ['1/1', '1/2']}
        new_ratingref = self.provider.create(DocumentCategoryTag, params)
        q_ratingref = self.session.query(DocumentCategoryTag).get(1)
        assert new_ratingref == q_ratingref

    def test_create_with_required(self):
        new_doc = self.provider.create(ModelWithRequired, dict(value='Hello'))
        q_user = self.provider.get(ModelWithRequired, {'value': 'Hello'})    
        assert q_user is not None

    def test_create_none_int(self):
        new_doc = self.provider.create(UnrelatedDocument, dict(number=None, enabled=None))
        assert new_doc.number is None, new_doc
        assert new_doc.enabled is None, new_doc
        assert new_doc._id is not None, new_doc

    @raises(S.Invalid)  # Expect failure, missing field
    def test_create_with_missing_required(self):
        new_doc = self.provider.create(ModelWithRequired, dict())

    def test_query(self):
        r = self.provider.query(User, limit=20, offset=0)
        eq_(len(r), 2)

    def test_query_offset_None(self):
        r = self.provider.query(User, limit=20, offset=None)
        eq_(len(r), 2)

    def test_query_with_offset(self):
        r = self.provider.query(User, offset=10)
        eq_(len(r), 2)

    def test_query_limit_None(self):
        r = self.provider.query(User, limit=None, offset=None)
        eq_(len(r), 2)

    def test_query_limit(self):
        count, r = self.provider.query(User, limit=1)
        eq_(len(r), 1)

    def test_query_sort_asc(self):
        cnt, r = self.provider.query(Town, order_by="name")
        eq_([t.name for t in r], ['Arvada', 'Boulder', 'Denver', 'Golden', 'Torino'])

    def test_query_sort_desc(self):
        cnt, r = self.provider.query(Town, order_by="name", desc=True)
        eq_([t.name for t in r], ['Torino', 'Golden', 'Denver', 'Boulder', 'Arvada'])

    def test_query_sort_multi_asc(self):
        cnt, r = self.provider.query(Town, order_by=["name", 'country'])
        eq_([t.name for t in r], ['Arvada', 'Boulder', 'Denver', 'Golden', 'Torino'])

        cnt, r = self.provider.query(Town, order_by=['country', "name"])
        eq_([t.name for t in r], ['Torino', 'Arvada', 'Boulder', 'Denver', 'Golden'])

    def test_query_sort_multi_desc(self):
        cnt, r = self.provider.query(Town, order_by=["name", 'country'], desc=True)
        eq_([t.name for t in r], ['Torino', 'Golden', 'Denver', 'Boulder', 'Arvada'])

        cnt, r = self.provider.query(Town, order_by=['country', "name"], desc=[True, False])
        eq_([t.name for t in r], ['Arvada', 'Boulder', 'Denver', 'Golden', 'Torino'])

    def test_query_sort_related(self):
        cnt, r = self.provider.query(DocumentCategory, order_by=['department'], related_field_names=['name'])
        eq_([t.department.name for t in r], ['Accounting', 'Marketing', 'Marketing'])

        cnt, r = self.provider.query(DocumentCategory, order_by=['department'],
                                     related_field_names=['name'], desc=True)
        eq_([t.department.name for t in r], ['Marketing', 'Marketing', 'Accounting'])

    def test_query_sort_related_many(self):
        g1 = self.provider.create(Group, {'group_name': 'Alpha'})
        g2 = self.provider.create(Group, {'group_name': 'Beta'})
        g3 = self.provider.create(Group, {'group_name': 'Zeta'})

        u1 = self.provider.create(User, {'user_name': 'User3', 'groups':[g1]})
        u2 = self.provider.create(User, {'user_name': 'User1', 'groups':[g2]})
        u3 = self.provider.create(User, {'user_name': 'User2', 'groups':[g3]})

        cnt, r = self.provider.query(User, order_by=['groups'], related_field_names=['group_name'])
        eq_([u.user_name for u in r], ['asdf', 'User3', 'User1', 'User2'])

        cnt, r = self.provider.query(User, order_by=['groups'], 
                                     related_field_names=['group_name'], desc=True)
        eq_([u.user_name for u in r], ['User2', 'User1', 'User3', 'asdf'])

        u4 = self.provider.create(User, {'user_name': 'User0', 'groups':[g2, g1]})
        cnt, r = self.provider.query(User, order_by=['groups'], related_field_names=['group_name'])
        eq_([u.user_name for u in r], ['asdf', 'User3', 'User0','User1', 'User2'])
        cnt, r = self.provider.query(User, order_by=['groups'], 
                                     related_field_names=['group_name'], desc=True)
        eq_([u.user_name for u in r], ['User2', 'User1', 'User0', 'User3', 'asdf'])

    def test_query_filters(self):
        cnt, r = self.provider.query(Town, filters={'name':'Golden'})
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_id_by_string(self):
        cnt, r = self.provider.query(Town, filters={'name':'Golden'})
        golden_id = str(r[0]._id)

        cnt, r = self.provider.query(Town, filters={'_id':golden_id})
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_id_by_objectid(self):
        cnt, r = self.provider.query(Town, filters={'name':'Golden'})
        golden_id = r[0]._id

        cnt, r = self.provider.query(Town, filters={'_id':golden_id})
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_substring(self):
        cnt, r = self.provider.query(Town, filters={'name':'old'}, substring_filters=['name'])
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_substring_escaping(self):
        cnt, r = self.provider.query(Town, filters={'name':'o.*l.*d'}, substring_filters=['name'])
        eq_(r, []), r

    def test_query_filters_substring_related(self):
        cnt, r = self.provider.query(Town, filters={'users':'this_does_not_work'}, substring_filters=['users'])
        eq_(r, []), r

    def test_query_filters_substring_insensitive(self):
        cnt, r = self.provider.query(Town, filters={'name':'gold'}, substring_filters=['name'])
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_substring_disabled(self):
        cnt, r = self.provider.query(Town, filters={'name':'old'}, substring_filters=[])
        eq_(r, [])

    def test_query_filters_substring_notstring(self):
        cnt, towns = self.provider.query(Town)
        cnt, r = self.provider.query(Town, filters={'_id':towns[0]._id}, substring_filters=['_id'])
        eq_([t.name for t in r], [towns[0].name])
        cnt, r = self.provider.query(Town, filters={'_id':'this_is_the_id'}, substring_filters=['_id'])
        eq_(r, [])

    def test_query_filters_relations_search_many2one(self):
        cnt, r = self.provider.query(User, filters={'town': 'Arvada'},
                                     search_related=True)
        assert cnt == 1, r
        assert r[0].email_address == '*****@*****.**', r

    def test_query_filters_relations_search_many2many(self):
        cnt, r = self.provider.query(Group, filters={'users': '*****@*****.**'},
                                     search_related=True)
        assert cnt == 1, r
        assert r[0].group_name == '4', r

    def test_query_filters_relations_search_one2many(self):
        cnt, r = self.provider.query(Town, filters={'users': '*****@*****.**'},
                                     search_related=True)
        assert cnt == 1, r
        assert r[0].name == 'Arvada', r

    def test_query_filters_relations_substring_search_many2one(self):
        cnt, r = self.provider.query(User, filters={'town': 'Arv'},
                                     search_related=True, substring_filters=['town'])
        assert cnt == 1, r
        assert r[0].email_address == '*****@*****.**', r

    def test_query_filters_relations_substring_search_many2many(self):
        cnt, r = self.provider.query(Group, filters={'users': 'asdf'},
                                     search_related=True, substring_filters=['users'])
        assert cnt == 1, r
        assert r[0].group_name == '4', r

    def test_query_filters_relations_substring_search_one2many(self):
        cnt, r = self.provider.query(Town, filters={'users': 'asdf'},
                                     search_related=True, substring_filters=['users'])
        assert cnt == 1, r
        assert r[0].name == 'Arvada', r

    def test_query_filters_relations_search_nonstring(self):
        cnt, r = self.provider.query(Town, filters={'name': 'Arvada'})
        town = r[0]

        cnt, r = self.provider.query(User, filters={'town': town._id},
                                     search_related=True)
        assert cnt == 1, r
        assert r[0].email_address == '*****@*****.**', r

    def test_query_filters_relations_search_empty(self):
        cnt, r = self.provider.query(Town, filters={'users': ''},
                                     search_related=True)
        assert cnt == 5, r

    def test_update_related(self):
        __, cities = self.provider.query(Town)

        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', 'town':cities[0]}
        new_user = self.provider.create(User, params)
        session.flush()
        eq_(new_user.town.name, cities[0].name)

        params['town'] = cities[1]
        params['_id'] = new_user._id
        new_user = self.provider.update(User, params)
        session.flush()
        
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.town.name, cities[1].name)
        eq_(q_user.town.name, cities[1].name)

    def test_update_none(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**'}
        new_user = self.provider.create(User, params)
        session.flush()
        
        params['email_address'] = '*****@*****.**'
        params['email_address'] = None
        params['created'] = None
        params['_id'] = new_user._id
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, None)
        eq_(q_user.email_address, None)

    def test_update_simple(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_datetime(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = datetime.utcnow().replace(microsecond=0)
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')
        eq_(q_user.created, params['created'])

    def test_update_sprox_id(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', 'sprox_id': 'xyz'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_method(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', '_method': 'xyz'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_extra_keys(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', 'extraneous': 'xyz'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_omit_fieds(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**'}
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params, omit_fields=['email_address'])
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_create_one_to_many_relation(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**', 'extraneous': 'xyz'}
        new_user = self.provider.create(User, params)
        session.flush()

        #One-To-Many relations are now writable in Ming, check that it correctly changed the relation
        new_town = self.provider.create(Town, {'users':[new_user._id]})
        assert len(new_town.users) == 1
        assert new_town.users[0]._id == new_user._id

    @raises(TypeError)
    def test_relation_fields_invalid(self):
        self.provider.relation_fields(User, "_id")

    def test_relation_fields_tgmm(self):
        relation_fields = self.provider.relation_fields(TGMMUser, 'groups')
        assert relation_fields == []

    def test_update_omit(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**'}
        new_user = self.provider.create(User, params)

        params = {}
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        new_user = self.provider.update(User, params, omit_fields=['email_address'])
        q_user = User.query.get(_id=new_user._id)

        eq_(q_user.email_address, '*****@*****.**')
        eq_(q_user.created, datetime(2008, 3, 30, 12, 21, 21))

    # expected failure; related ID should be an ObjectId
    @raises(TypeError)
    def test_update_relationship(self):
        params = {'user_name':'asdf2', 'password':'******', 'email_address':'*****@*****.**'}
        new_user = self.provider.create(User, params)

        self.provider.update(User, {'_id': new_user._id, 'groups': [1, 4]})

    def test_get_default_values(self):
        assert {} == self.provider.get_default_values(User, {})

    def test_get(self):
        user = self.provider.get(User, params={'_id': self.asdf_user_id})
        eq_(user['user_name'], 'asdf')
    
    def test_get_valid_object_id(self):
        user = self.provider.get_obj(User, params={'_id': self.asdf_user_id})
        eq_(user['user_name'], 'asdf')
   
    def test_get_object_id_casting(self):
        user = self.provider.get_obj(User, params={'_id': str(self.asdf_user_id)})
        eq_(user['user_name'], 'asdf')

    def test_get_invalid_object_id(self):
        user = self.provider.get_obj(User, params={'_id': "1"})
        assert user is None

    def test_get_values_casting(self):
        val = self.provider._cast_value_for_type(S.Int, None)
        assert val is None

        val = self.provider._cast_value_for_type(S.Array(S.Int), '1234')
        assert val == [1234], val

        val = self.provider._cast_value_for_type(S.Object({'num': S.Int}), {'num': '1234'})
        assert val == {'num': 1234}, val

        val = self.provider._cast_value_for_type(S.Array(S.Object(dict(value=s.Int))), [{'value':'1234'}])
        assert val == [{'value': 1234}], val

    def test_delete(self):
        self.provider.delete(User, params={'_id': self.asdf_user_id})
        session.flush()
        users = User.query.find().all()
        assert len(users) == 0
        # Tests twice for idempotence
        self.provider.delete(User, params={'_id': self.asdf_user_id})
        session.flush()
        users = User.query.find().all()
        assert len(users) == 0

    def test_create_with_DateTime(self):
        self.provider.create(Document, dict(edited='2011-03-30 12:21:21'))

    def test_create_with_int(self):
        self.provider.create(UnrelatedDocument, dict(number=5))

    def test_create_with_bool(self):
        self.provider.create(UnrelatedDocument, dict(enabled=True))

    def test_create_with_str_bool(self):
        self.provider.create(UnrelatedDocument, dict(enabled='true'))

    def test_create_relationships_with_wacky_relation(self):
        obj = Group.query.find().first()
        user = User.query.find().first()
        self.provider.update(Group, {'_id':obj._id, 'users': [user._id]})
        assert user._id == obj.users[0]._id

    def test_create_relationships_remove_groups(self):
        obj = Group.query.find().first()
        self.provider.update(User, {'_id':self.user._id, 'groups':[]})
        assert user not in obj.users

    def test_create_relationships_change_town(self):
        town = Town.query.find({'name':'Arvada'}).first()

        self.user.town = town
        self.session.flush()

        self.provider.update(User, {'_id':self.user._id, 'town':Town.query.find({'name':'Denver'}).first()})
        assert self.user.town.name == 'Denver'

    def test_tgmanymany_create(self):
        count, groups = self.provider.query(Group, limit=1)
        params = {'user_name':'mmuser', 'groups':[groups[0]]}
        new_user = self.provider.create(TGMMUser, params)

        assert new_user.groups[0].group_name == groups[0].group_name
        assert new_user._groups[0] == groups[0].group_name

    def test_tgmanymany_update(self):
        params = {'user_name':'mmuser', 'groups':[]}
        new_user = self.provider.create(TGMMUser, params)

        assert len(new_user.groups) == 0
        count, groups = self.provider.query(Group, limit=1)
        self.provider.update(TGMMUser, {'_id':new_user._id, 'groups':[groups[0]]})

        new_user = self.provider.get_obj(TGMMUser, {'_id':new_user._id})
        assert len(new_user.groups) == 1
        assert new_user.groups[0].group_name == groups[0].group_name
        assert new_user._groups[0] == groups[0].group_name
Beispiel #12
0
class TestMGORMProvider(SproxTest):
    def setup(self):
        super(TestMGORMProvider, self).setup()
        self.provider = MingProvider(User.__mongometa__.session)
        Department(_id=1, name=u'Marketing')
        Department(_id=2, name=u'Accounting')
        DocumentCategory(_id=1, department_id=1, name=u'Brochure')
        DocumentCategory(_id=2, department_id=1, name=u'Flyer')
        DocumentCategory(_id=3, department_id=2, name=u'Balance Sheet')
        #session.add(DocumentRating(user_id=1, document_id=1, rating=5))
        session.flush_all()
        #session.close_all()
        self.asdf_user_id = self.provider.get_obj(User, {'user_name': 'asdf'})._id

    def test_get_field_widget_args(self):
        eq_(self.provider.get_field_widget_args(User, 'groups', User.groups), {'nullable': True, 'provider':self.provider})

    def test_get_fields_with_func(self):
        eq_(self.provider.get_fields(lambda: Town), ['_id', 'name'])

    def test_isbinary_related(self):
        assert not self.provider.is_binary(User, 'groups')

    def test_binary_create(self):
        fs = "fake_content"

        values = {'data':fs}
        self.provider.create(File, values)
        session.flush()

    def test_binary_update(self):
        fs = "fake_content"

        values = {'data':fs}
        entity = self.provider.create(File, values)

        session.flush()
        values = {'data':fs, '_id':entity._id}
        self.provider.update(File, values)

    def test_get_entity(self):
        entity = self.provider.get_entity('User')
        assert entity == User, entity

    def test_get_entities(self):
        entities = self.provider.get_entities()
        assert set(entities) == set(['Town', 'GroupPermission', 'Group', 'Permission', 'DocumentCategoryReference',
                'SproxTestClass', 'DocumentCategoryTag', 'DocumentCategoryTagAssignment', 'User', 'File',
                'DocumentCategory', 'Department', 'Document', 'MappedClass', 'Example', 'UserGroup'])

    @raises(KeyError)
    def test_get_entity_non_matching_engine(self):
        entity = self.provider.get_entity('OtherClass')


    def test_get_primary_fields(self):
        fields = self.provider.get_primary_fields(User)
        eq_(fields, ['_id'])

    # expected failure; need compound primary key support
    @raises(AssertionError)
    def test_get_primary_fields_multi(self):
        fields = self.provider.get_primary_fields(DocumentCategory)
        eq_(fields, ['document_category_id', 'department_id'])

    def test_get_primary_field_function(self):
        field = self.provider.get_primary_field(lambda: User)
        eq_(field, '_id')

    def test_get_view_field_name_defaults_substring(self):
        field = self.provider.get_view_field_name(Permission, None)
        eq_(field, 'permission_name')

    def test_get_view_field_name_with_title(self):
        """
        if it exists, orm provider should use the 'title' info attribute to
        determine the title column
        """
        field = self.provider.get_view_field_name(User, ['name'])
        eq_(field, 'display_name')

    def test_get_view_field_name_not_found(self):
        field = self.provider.get_view_field_name(Group, [])
        assert field in self.provider.get_fields(Group)

    def test_get_dropdown_options_oneof(self):
        options = self.provider.get_dropdown_options(Example, 'oneof')
        eq_(set(options), set(set([('three', 'three'), ('one', 'one'), ('two', 'two')])))

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_fieldtype(self):
        class BadClass(object):
            pass
        bc = BadClass()
        options = self.provider.get_dropdown_options(BadClass, None)

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_type(self):
        options = self.provider.get_dropdown_options(Example, 'int_')

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_field(self):
        options = self.provider.get_dropdown_options(User, 'town_id')

    def test_get_dropdown_options_fk(self):
        options = self.provider.get_dropdown_options(User, 'town')
        eq_(set(options), set((('1', u'Arvada'), ('2', u'Denver'), ('3', u'Golden'), ('4', u'Boulder'))))

    def test_get_dropdown_options_fk_multi(self):
        options = self.provider.get_dropdown_options(Document, 'category')
        eq_(set(options), set((('1', u'Brochure'), ('2', u'Flyer'), ('3', u'Balance Sheet'))))

    # expected failure; need many-to-many support
    @raises(AssertionError)
    def test_get_dropdown_options_join(self):
        options = self.provider.get_dropdown_options(User, 'groups')
        eq_(options, [('1', u'0'), ('2', u'1'), ('3', u'2'), ('4', u'3'), ('5', u'4')])

    # expected failure; need many-to-many support
    @raises(AssertionError)
    def test_get_dropdown_options_join_2(self):
        options = self.provider.get_dropdown_options(Group, 'users')
        eq_(options, [(1, u'*****@*****.**'),])

    def test_get_relations(self):
        relations = self.provider.get_relations(User)
        eq_(relations, ['town', 'groups'])

    def test_dictify(self):
        d = self.provider.dictify(self.user)
        eq_(d['user_name'], 'asdf')

    def test_dictify_limit_fields(self):
        d = self.provider.dictify(self.user, fields=['user_name'])
        eq_(d['user_name'], 'asdf')
        eq_(d.keys(), ['user_name'])

    def test_dictify_omit_fields(self):
        d = self.provider.dictify(self.user, omit_fields=['password', '_password'])
        assert 'password' not in d.keys()
        assert '_password' not in d.keys()
        assert 'user_name' in d.keys()

    def test_dictify_none(self):
        d = self.provider.dictify(None)
        eq_(d, {})

    # expected failure; ming does not yet support writing into RelationProperties
    @raises(TypeError)
    def test_create(self):
        params = {'user_name':u'asdf2', 'password':u'asdf2', 'email_address':u'*****@*****.**', 'groups':[1,4], 'town':2}
        new_user = self.provider.create(User, params)
        q_user = self.session.query(User).get(2)
        assert q_user == new_user

    # expected failure; needs many-to-many support
    @raises(InvalidId)
    def test_create_many_to_one_multi(self):
        params = {'category': '1/1'}
        new_ref = self.provider.create(DocumentCategoryReference, params)
        q_ref = self.session.query(DocumentCategoryReference).get(1)
        assert new_ref == q_ref

    # expected failure; needs many-to-many support
    @raises(InvalidId)
    def test_create_many_to_many_multi(self):
        params = {'categories': ['1/1', '1/2']}
        new_ratingref = self.provider.create(DocumentCategoryTag, params)
        q_ratingref = self.session.query(DocumentCategoryTag).get(1)
        assert new_ratingref == q_ratingref

    def test_query(self):
        r = self.provider.query(User, limit=20, offset=0)
        eq_(len(r), 2)

    def test_query_offset_None(self):
        r = self.provider.query(User, limit=20, offset=None)
        eq_(len(r), 2)

    def test_query_with_offset(self):
        r = self.provider.query(User, offset=10)
        eq_(len(r), 2)

    def test_query_limit_None(self):
        r = self.provider.query(User, limit=None, offset=None)
        eq_(len(r), 2)

    def test_query_limit(self):
        count, r = self.provider.query(User, limit=1)
        eq_(len(r), 1)

    def test_query_sort_asc(self):
        cnt, r = self.provider.query(Town, order_by="name")
        eq_([t.name for t in r], [u'Arvada', u'Boulder', u'Denver', u'Golden'])

    def test_query_sort_desc(self):
        cnt, r = self.provider.query(Town, order_by="name", desc=True)
        eq_([t.name for t in r], [u'Golden', u'Denver', u'Boulder', u'Arvada'])

    # expected failure; needs updatable RelationProperty
    @raises(TypeError)
    def test_update(self):
        params = {'user_name':u'asdf2', 'password':u'asdf2', 'email_address':u'*****@*****.**', 'groups':[1,4], 'town':2}
        new_user = self.provider.create(User, params)
        params['email_address'] = u'*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, u'*****@*****.**')
        eq_(q_user.email_address, u'*****@*****.**')

    def test_update_simple(self):
        params = {'user_name':u'asdf2', 'password':u'asdf2', 'email_address':u'*****@*****.**'}
        new_user = self.provider.create(User, params)
        params['email_address'] = u'*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, u'*****@*****.**')
        eq_(q_user.email_address, u'*****@*****.**')

    def test_update_sprox_id(self):
        params = {'user_name':u'asdf2', 'password':u'asdf2', 'email_address':u'*****@*****.**', 'sprox_id': 'xyz'}
        new_user = self.provider.create(User, params)
        params['email_address'] = u'*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, u'*****@*****.**')
        eq_(q_user.email_address, u'*****@*****.**')

    def test_update_method(self):
        params = {'user_name':u'asdf2', 'password':u'asdf2', 'email_address':u'*****@*****.**', '_method': 'xyz'}
        new_user = self.provider.create(User, params)
        params['email_address'] = u'*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, u'*****@*****.**')
        eq_(q_user.email_address, u'*****@*****.**')

    def test_update_extra_keys(self):
        params = {'user_name':u'asdf2', 'password':u'asdf2', 'email_address':u'*****@*****.**', 'extraneous': 'xyz'}
        new_user = self.provider.create(User, params)
        params['email_address'] = u'*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({ "_id": new_user._id }).first()
        eq_(new_user.email_address, u'*****@*****.**')
        eq_(q_user.email_address, u'*****@*****.**')

    @raises(TypeError)
    def test_relation_fields_invalid(self):
        self.provider.relation_fields(User, "_id")

    # expected failure; needs updatable RelationProperty
    @raises(TypeError)
    def test_update_omit(self):
        params = {'user_name':u'asdf2', 'password':u'asdf2', 'email_address':u'*****@*****.**', 'groups':[1,4], 'town':2}
        new_user = self.provider.create(User, params)

        params = {}
        params['email_address'] = u'*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['user_id'] = 2
        new_user = self.provider.update(User, params, omit_fields=['email_address', 'groups'])
        q_user = self.session.query(User).get(2)

        eq_(q_user.email_address, u'*****@*****.**')
        eq_([group.group_id for group in q_user.groups], [1,4])

    def test_get_default_values(self):
        assert {} == self.provider.get_default_values(User, {})

    def test_get(self):
        user = self.provider.get(User, params={'_id': self.asdf_user_id})
        eq_(user['user_name'], 'asdf')

    def test_delete(self):
        user = self.provider.delete(User, params={'_id': self.asdf_user_id})
        session.flush()
        users = User.query.find().all()
        assert len(users) == 0

    def test_create_with_unicode_cast_to_int(self):
        self.provider.create(User, dict(user_id=u'34', user_name=u'something'))

    def test_create_with_DateTime(self):
        self.provider.create(Document, dict(edited='2011-03-30 12:21:21'))

    # expected failure; need many-to-many support and writing into RelationProperty
    @raises(TypeError)
    def test_create_relationships_with_wacky_relation(self):
        obj = Group.query.find().first()
        user = User.query.find().first()
        params = {'_id':obj._id, 'users':user}
        self.provider.update(Group, params)
        assert user in obj.users

    # expected failure; ming does not yet support writing into RelationProperties
    @raises(TypeError)
    def test_create_relationships_remove_groups(self):
        obj = Group.query.find().first()
        obj.users.append(self.user)
        self.provider.update(User, {'user_id':self.user.user_id, 'groups':[]})
        session.flush()
        user = User.query.find().get(1)
        assert user not in obj.users

    # expected failure; ming does not yet support writing into RelationProperties
    @raises(TypeError)
    def test_create_relationships_remove_town(self):
        town = Town.query.find().first()

        self.user.town = town
        self.session.flush()

        self.provider.update(User, {'user_id':self.user.user_id, 'town':None})
        assert self.user.town is None
 def get_provider(self, entity=None, hint=None, **hints):
     #TODO cache
     return MingProvider(entity.__mongometa__.session)
class TestMGORMProvider(SproxTest):
    def setup(self):
        super(TestMGORMProvider, self).setup()
        self.provider = MingProvider(User.__mongometa__.session)
        Department(_id=1, name='Marketing')
        Department(_id=2, name='Accounting')
        DocumentCategory(_id=1, department_id=1, name='Brochure')
        DocumentCategory(_id=2, department_id=1, name='Flyer')
        DocumentCategory(_id=3, department_id=2, name='Balance Sheet')
        #session.add(DocumentRating(user_id=1, document_id=1, rating=5))
        session.flush_all()
        #session.close_all()
        self.asdf_user_id = self.provider.get_obj(User, {
            'user_name': 'asdf'
        })._id

    def test_get_field_widget_args(self):
        eq_(self.provider.get_field_widget_args(User, 'groups', User.groups), {
            'nullable': True,
            'provider': self.provider
        })

    def test_get_fields_with_func(self):
        eq_(sorted(self.provider.get_fields(lambda: Town)),
            sorted(['country', '_id', 'users', 'name']))

    def test_isbinary_related(self):
        assert not self.provider.is_binary(User, 'groups')

    def test_isbinary(self):
        assert self.provider.is_binary(File, 'data')

    def test_is_query_not_a_query(self):
        assert self.provider.is_query(File, None) == False

    def test_binary_create(self):
        fs = b"fake_content"

        values = {'data': fs}
        self.provider.create(File, values)
        session.flush()

    def test_binary_update(self):
        fs = b"fake_content"

        values = {'data': fs}
        entity = self.provider.create(File, values)

        session.flush()
        values = {'data': fs, '_id': entity._id}
        self.provider.update(File, values)

    def test_get_entity(self):
        entity = self.provider.get_entity('User')
        assert entity == User, entity

    def test_get_entities(self):
        entities = list(self.provider.get_entities())
        assert set(entities) == set([
            'Town', 'GroupPermission', 'Group', 'Permission',
            'DocumentCategoryReference', 'SproxTestClass',
            'DocumentCategoryTag', 'DocumentCategoryTagAssignment', 'User',
            'File', 'TGMMUser', 'DocumentCategory', 'Department', 'Document',
            'MappedClass', 'Example', 'UnrelatedDocument', 'ModelWithRequired',
            'NestedModel'
        ]), entities

    @raises(KeyError)
    def test_get_entity_non_matching_engine(self):
        entity = self.provider.get_entity('OtherClass')

    def test_get_primary_fields(self):
        fields = self.provider.get_primary_fields(User)
        eq_(fields, ['_id'])

    # expected failure; need compound primary key support
    @raises(AssertionError)
    def test_get_primary_fields_multi(self):
        fields = self.provider.get_primary_fields(DocumentCategory)
        eq_(fields, ['document_category_id', 'department_id'])

    def test_get_primary_field_function(self):
        field = self.provider.get_primary_field(lambda: User)
        eq_(field, '_id')

    def test_get_view_field_name_defaults_substring(self):
        field = self.provider.get_view_field_name(Permission, ['name'])
        eq_(field, 'permission_name')

    def test_get_view_field_name_with_title(self):
        """
        if it exists, orm provider should use the 'title' info attribute to
        determine the title column
        """
        field = self.provider.get_view_field_name(User, ['name'])
        eq_(field, 'display_name')

    def test_get_view_field_name_not_found(self):
        field = self.provider.get_view_field_name(Group, [])
        assert field in self.provider.get_fields(Group)

    def test_get_view_field_name_for_subdocument(self):
        doc = self.provider.create(
            Document,
            dict(metadata=[{
                'name': 'author',
                'value': 'Philip K Dick'
            }, {
                'name': 'year',
                'value': '1968'
            }]))

        class DocumentsFiller(TableFiller):
            __model__ = Document

        tf = DocumentsFiller(self.provider.session)

        names = tf._get_list_data_value(Document, doc.metadata)
        assert names == 'author, year', names

    def test_get_view_field_name_for_unknown_objects(self):
        first_list_value = {'name': 'author', 'value': 'Philip K Dick'}

        doc = self.provider.create(
            Document,
            dict(
                metadata=[first_list_value, {
                    'name': 'year',
                    'value': '1968'
                }]))

        entry = doc.metadata[0]
        suggested_name = self.provider.get_view_field_name(
            entry.__class__, ['name'])
        value = str(getattr(entry, suggested_name))
        assert value == str(first_list_value)

    def test_get_dropdown_options_oneof(self):
        options = self.provider.get_dropdown_options(Example, 'oneof')
        eq_(set(options),
            set(set([('three', 'three'), ('one', 'one'), ('two', 'two')])))

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_fieldtype(self):
        class BadClass(object):
            pass

        bc = BadClass()
        options = self.provider.get_dropdown_options(BadClass, None)

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_type(self):
        options = self.provider.get_dropdown_options(Example, 'int_')

    @raises(NotImplementedError)
    def test_get_dropdown_options_bad_field(self):
        options = self.provider.get_dropdown_options(User, 'town_id')

    def test_get_dropdown_options_fk(self):
        options = self.provider.get_dropdown_options(User, 'town')
        for _id, name in options:
            town = Town.query.find({'name': name}).first()
            assert str(town._id) == str(_id)

    def test_get_dropdown_options_fk_multi(self):
        options = self.provider.get_dropdown_options(Document, 'category')
        eq_(set(options),
            set((('1', 'Brochure'), ('2', 'Flyer'), ('3', 'Balance Sheet'))))

    # expected failure; need many-to-many support
    @raises(AssertionError)
    def test_get_dropdown_options_join(self):
        options = self.provider.get_dropdown_options(User, 'groups')
        eq_(options, [('1', '0'), ('2', '1'), ('3', '2'), ('4', '3'),
                      ('5', '4')])

    # expected failure; need many-to-many support
    @raises(AssertionError)
    def test_get_dropdown_options_join_2(self):
        options = self.provider.get_dropdown_options(Group, 'users')
        eq_(options, [
            (1, '*****@*****.**'),
        ])

    def test_get_relations(self):
        relations = self.provider.get_relations(User)
        eq_(sorted(relations), sorted(['town', 'groups']))

    def test_dictify(self):
        d = self.provider.dictify(self.user)
        eq_(d['user_name'], 'asdf')

    def test_dictify_limit_fields(self):
        d = self.provider.dictify(self.user, fields=['user_name'])
        eq_(d['user_name'], 'asdf')
        eq_(list(d.keys()), ['user_name'])

    def test_dictify_omit_fields(self):
        d = self.provider.dictify(self.user,
                                  omit_fields=['password', '_password'])
        assert 'password' not in list(d.keys())
        assert '_password' not in list(d.keys())
        assert 'user_name' in list(d.keys())

    def test_dictify_none(self):
        d = self.provider.dictify(None)
        eq_(d, {})

    # expected failure; groups and town relation values should be an ObjectId
    @raises(TypeError)
    def test_create(self):
        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**',
            'groups': [1, 4],
            'town': 2
        }
        new_user = self.provider.create(User, params)

    def test_create_blank__id(self):
        params = {
            'user_name': 'asdf3',
            'password': '******',
            'email_address': '*****@*****.**',
            '_id': ''
        }
        new_user = self.provider.create(User, params)
        q_user = self.provider.get(User, {'user_name': 'asdf3'})
        assert q_user is not None

    # expected failure; needs many-to-many support
    @raises(InvalidId)
    def test_create_many_to_one_multi(self):
        params = {'category': '1/1'}
        new_ref = self.provider.create(DocumentCategoryReference, params)
        q_ref = self.session.query(DocumentCategoryReference).get(1)
        assert new_ref == q_ref

    # expected failure; needs many-to-many support
    @raises(InvalidId)
    def test_create_many_to_many_multi(self):
        params = {'categories': ['1/1', '1/2']}
        new_ratingref = self.provider.create(DocumentCategoryTag, params)
        q_ratingref = self.session.query(DocumentCategoryTag).get(1)
        assert new_ratingref == q_ratingref

    def test_create_with_required(self):
        new_doc = self.provider.create(ModelWithRequired, dict(value='Hello'))
        q_user = self.provider.get(ModelWithRequired, {'value': 'Hello'})
        assert q_user is not None

    def test_create_none_int(self):
        new_doc = self.provider.create(UnrelatedDocument,
                                       dict(number=None, enabled=None))
        assert new_doc.number is None, new_doc
        assert new_doc.enabled is None, new_doc
        assert new_doc._id is not None, new_doc

    @raises(S.Invalid)  # Expect failure, missing field
    def test_create_with_missing_required(self):
        new_doc = self.provider.create(ModelWithRequired, dict())

    def test_query(self):
        r = self.provider.query(User, limit=20, offset=0)
        eq_(len(r), 2)

    def test_query_offset_None(self):
        r = self.provider.query(User, limit=20, offset=None)
        eq_(len(r), 2)

    def test_query_with_offset(self):
        r = self.provider.query(User, offset=10)
        eq_(len(r), 2)

    def test_query_limit_None(self):
        r = self.provider.query(User, limit=None, offset=None)
        eq_(len(r), 2)

    def test_query_limit(self):
        count, r = self.provider.query(User, limit=1)
        eq_(len(r), 1)

    def test_query_sort_asc(self):
        cnt, r = self.provider.query(Town, order_by="name")
        eq_([t.name for t in r],
            ['Arvada', 'Boulder', 'Denver', 'Golden', 'Torino'])

    def test_query_sort_desc(self):
        cnt, r = self.provider.query(Town, order_by="name", desc=True)
        eq_([t.name for t in r],
            ['Torino', 'Golden', 'Denver', 'Boulder', 'Arvada'])

    def test_query_sort_multi_asc(self):
        cnt, r = self.provider.query(Town, order_by=["name", 'country'])
        eq_([t.name for t in r],
            ['Arvada', 'Boulder', 'Denver', 'Golden', 'Torino'])

        cnt, r = self.provider.query(Town, order_by=['country', "name"])
        eq_([t.name for t in r],
            ['Torino', 'Arvada', 'Boulder', 'Denver', 'Golden'])

    def test_query_sort_multi_desc(self):
        cnt, r = self.provider.query(Town,
                                     order_by=["name", 'country'],
                                     desc=True)
        eq_([t.name for t in r],
            ['Torino', 'Golden', 'Denver', 'Boulder', 'Arvada'])

        cnt, r = self.provider.query(Town,
                                     order_by=['country', "name"],
                                     desc=[True, False])
        eq_([t.name for t in r],
            ['Arvada', 'Boulder', 'Denver', 'Golden', 'Torino'])

    def test_query_sort_related(self):
        cnt, r = self.provider.query(DocumentCategory,
                                     order_by=['department'],
                                     related_field_names=['name'])
        eq_([t.department.name for t in r],
            ['Accounting', 'Marketing', 'Marketing'])

        cnt, r = self.provider.query(DocumentCategory,
                                     order_by=['department'],
                                     related_field_names=['name'],
                                     desc=True)
        eq_([t.department.name for t in r],
            ['Marketing', 'Marketing', 'Accounting'])

    def test_query_sort_related_many(self):
        g1 = self.provider.create(Group, {'group_name': 'Alpha'})
        g2 = self.provider.create(Group, {'group_name': 'Beta'})
        g3 = self.provider.create(Group, {'group_name': 'Zeta'})

        u1 = self.provider.create(User, {'user_name': 'User3', 'groups': [g1]})
        u2 = self.provider.create(User, {'user_name': 'User1', 'groups': [g2]})
        u3 = self.provider.create(User, {'user_name': 'User2', 'groups': [g3]})

        cnt, r = self.provider.query(User,
                                     order_by=['groups'],
                                     related_field_names=['group_name'])
        eq_([u.user_name for u in r], ['asdf', 'User3', 'User1', 'User2'])

        cnt, r = self.provider.query(User,
                                     order_by=['groups'],
                                     related_field_names=['group_name'],
                                     desc=True)
        eq_([u.user_name for u in r], ['User2', 'User1', 'User3', 'asdf'])

        u4 = self.provider.create(User, {
            'user_name': 'User0',
            'groups': [g2, g1]
        })
        cnt, r = self.provider.query(User,
                                     order_by=['groups'],
                                     related_field_names=['group_name'])
        eq_([u.user_name for u in r],
            ['asdf', 'User3', 'User0', 'User1', 'User2'])
        cnt, r = self.provider.query(User,
                                     order_by=['groups'],
                                     related_field_names=['group_name'],
                                     desc=True)
        eq_([u.user_name for u in r],
            ['User2', 'User1', 'User0', 'User3', 'asdf'])

    def test_query_filters(self):
        cnt, r = self.provider.query(Town, filters={'name': 'Golden'})
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_id_by_string(self):
        cnt, r = self.provider.query(Town, filters={'name': 'Golden'})
        golden_id = str(r[0]._id)

        cnt, r = self.provider.query(Town, filters={'_id': golden_id})
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_id_by_objectid(self):
        cnt, r = self.provider.query(Town, filters={'name': 'Golden'})
        golden_id = r[0]._id

        cnt, r = self.provider.query(Town, filters={'_id': golden_id})
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_substring(self):
        cnt, r = self.provider.query(Town,
                                     filters={'name': 'old'},
                                     substring_filters=['name'])
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_substring_escaping(self):
        cnt, r = self.provider.query(Town,
                                     filters={'name': 'o.*l.*d'},
                                     substring_filters=['name'])
        eq_(r, []), r

    def test_query_filters_substring_related(self):
        cnt, r = self.provider.query(Town,
                                     filters={'users': 'this_does_not_work'},
                                     substring_filters=['users'])
        eq_(r, []), r

    def test_query_filters_substring_insensitive(self):
        cnt, r = self.provider.query(Town,
                                     filters={'name': 'gold'},
                                     substring_filters=['name'])
        eq_([t.name for t in r], ['Golden']), r

    def test_query_filters_substring_disabled(self):
        cnt, r = self.provider.query(Town,
                                     filters={'name': 'old'},
                                     substring_filters=[])
        eq_(r, [])

    def test_query_filters_substring_notstring(self):
        cnt, towns = self.provider.query(Town)
        cnt, r = self.provider.query(Town,
                                     filters={'_id': towns[0]._id},
                                     substring_filters=['_id'])
        eq_([t.name for t in r], [towns[0].name])
        cnt, r = self.provider.query(Town,
                                     filters={'_id': 'this_is_the_id'},
                                     substring_filters=['_id'])
        eq_(r, [])

    def test_query_filters_relations_search_many2one(self):
        cnt, r = self.provider.query(User,
                                     filters={'town': 'Arvada'},
                                     search_related=True)
        assert cnt == 1, r
        assert r[0].email_address == '*****@*****.**', r

    def test_query_filters_relations_search_many2many(self):
        cnt, r = self.provider.query(Group,
                                     filters={'users': '*****@*****.**'},
                                     search_related=True)
        assert cnt == 1, r
        assert r[0].group_name == '4', r

    def test_query_filters_relations_search_one2many(self):
        cnt, r = self.provider.query(Town,
                                     filters={'users': '*****@*****.**'},
                                     search_related=True)
        assert cnt == 1, r
        assert r[0].name == 'Arvada', r

    def test_query_filters_relations_substring_search_many2one(self):
        cnt, r = self.provider.query(User,
                                     filters={'town': 'Arv'},
                                     search_related=True,
                                     substring_filters=['town'])
        assert cnt == 1, r
        assert r[0].email_address == '*****@*****.**', r

    def test_query_filters_relations_substring_search_many2many(self):
        cnt, r = self.provider.query(Group,
                                     filters={'users': 'asdf'},
                                     search_related=True,
                                     substring_filters=['users'])
        assert cnt == 1, r
        assert r[0].group_name == '4', r

    def test_query_filters_relations_substring_search_one2many(self):
        cnt, r = self.provider.query(Town,
                                     filters={'users': 'asdf'},
                                     search_related=True,
                                     substring_filters=['users'])
        assert cnt == 1, r
        assert r[0].name == 'Arvada', r

    def test_query_filters_relations_search_nonstring(self):
        cnt, r = self.provider.query(Town, filters={'name': 'Arvada'})
        town = r[0]

        cnt, r = self.provider.query(User,
                                     filters={'town': town._id},
                                     search_related=True)
        assert cnt == 1, r
        assert r[0].email_address == '*****@*****.**', r

    def test_query_filters_relations_search_empty(self):
        cnt, r = self.provider.query(Town,
                                     filters={'users': ''},
                                     search_related=True)
        assert cnt == 5, r

    def test_update_related(self):
        __, cities = self.provider.query(Town)

        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**',
            'town': cities[0]
        }
        new_user = self.provider.create(User, params)
        session.flush()
        eq_(new_user.town.name, cities[0].name)

        params['town'] = cities[1]
        params['_id'] = new_user._id
        new_user = self.provider.update(User, params)
        session.flush()

        q_user = User.query.find({"_id": new_user._id}).first()
        eq_(new_user.town.name, cities[1].name)
        eq_(q_user.town.name, cities[1].name)

    def test_update_none(self):
        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**'
        }
        new_user = self.provider.create(User, params)
        session.flush()

        params['email_address'] = '*****@*****.**'
        params['email_address'] = None
        params['created'] = None
        params['_id'] = new_user._id
        new_user = self.provider.update(User, params)
        q_user = User.query.find({"_id": new_user._id}).first()
        eq_(new_user.email_address, None)
        eq_(q_user.email_address, None)

    def test_update_simple(self):
        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**'
        }
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({"_id": new_user._id}).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_datetime(self):
        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**'
        }
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = datetime.utcnow().replace(microsecond=0)
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({"_id": new_user._id}).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')
        eq_(q_user.created, params['created'])

    def test_update_sprox_id(self):
        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**',
            'sprox_id': 'xyz'
        }
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({"_id": new_user._id}).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_method(self):
        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**',
            '_method': 'xyz'
        }
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({"_id": new_user._id}).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_extra_keys(self):
        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**',
            'extraneous': 'xyz'
        }
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User, params)
        q_user = User.query.find({"_id": new_user._id}).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_update_omit_fieds(self):
        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**'
        }
        new_user = self.provider.create(User, params)
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        session.flush()
        new_user = self.provider.update(User,
                                        params,
                                        omit_fields=['email_address'])
        q_user = User.query.find({"_id": new_user._id}).first()
        eq_(new_user.email_address, '*****@*****.**')
        eq_(q_user.email_address, '*****@*****.**')

    def test_create_one_to_many_relation(self):
        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**',
            'extraneous': 'xyz'
        }
        new_user = self.provider.create(User, params)
        session.flush()

        #One-To-Many relations are now writable in Ming, check that it correctly changed the relation
        new_town = self.provider.create(Town, {'users': [new_user._id]})
        assert len(new_town.users) == 1
        assert new_town.users[0]._id == new_user._id

    @raises(TypeError)
    def test_relation_fields_invalid(self):
        self.provider.relation_fields(User, "_id")

    def test_relation_fields_tgmm(self):
        relation_fields = self.provider.relation_fields(TGMMUser, 'groups')
        assert relation_fields == []

    def test_update_omit(self):
        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**'
        }
        new_user = self.provider.create(User, params)

        params = {}
        params['email_address'] = '*****@*****.**'
        params['created'] = '2008-3-30 12:21:21'
        params['_id'] = new_user._id
        new_user = self.provider.update(User,
                                        params,
                                        omit_fields=['email_address'])
        q_user = User.query.get(_id=new_user._id)

        eq_(q_user.email_address, '*****@*****.**')
        eq_(q_user.created, datetime(2008, 3, 30, 12, 21, 21))

    # expected failure; related ID should be an ObjectId
    @raises(TypeError)
    def test_update_relationship(self):
        params = {
            'user_name': 'asdf2',
            'password': '******',
            'email_address': '*****@*****.**'
        }
        new_user = self.provider.create(User, params)

        self.provider.update(User, {'_id': new_user._id, 'groups': [1, 4]})

    def test_get_default_values(self):
        assert {} == self.provider.get_default_values(User, {})

    def test_get(self):
        user = self.provider.get(User, params={'_id': self.asdf_user_id})
        eq_(user['user_name'], 'asdf')

    def test_get_valid_object_id(self):
        user = self.provider.get_obj(User, params={'_id': self.asdf_user_id})
        eq_(user['user_name'], 'asdf')

    def test_get_object_id_casting(self):
        user = self.provider.get_obj(User,
                                     params={'_id': str(self.asdf_user_id)})
        eq_(user['user_name'], 'asdf')

    def test_get_invalid_object_id(self):
        user = self.provider.get_obj(User, params={'_id': "1"})
        assert user is None

    def test_get_values_casting(self):
        val = self.provider._cast_value_for_type(S.Int, None)
        assert val is None

        val = self.provider._cast_value_for_type(S.Array(S.Int), '1234')
        assert val == [1234], val

        val = self.provider._cast_value_for_type(S.Object({'num': S.Int}),
                                                 {'num': '1234'})
        assert val == {'num': 1234}, val

        val = self.provider._cast_value_for_type(
            S.Array(S.Object(dict(value=s.Int))), [{
                'value': '1234'
            }])
        assert val == [{'value': 1234}], val

    def test_delete(self):
        self.provider.delete(User, params={'_id': self.asdf_user_id})
        session.flush()
        users = User.query.find().all()
        assert len(users) == 0
        # Tests twice for idempotence
        self.provider.delete(User, params={'_id': self.asdf_user_id})
        session.flush()
        users = User.query.find().all()
        assert len(users) == 0

    def test_create_with_DateTime(self):
        self.provider.create(Document, dict(edited='2011-03-30 12:21:21'))

    def test_create_with_int(self):
        self.provider.create(UnrelatedDocument, dict(number=5))

    def test_create_with_bool(self):
        self.provider.create(UnrelatedDocument, dict(enabled=True))

    def test_create_with_str_bool(self):
        self.provider.create(UnrelatedDocument, dict(enabled='true'))

    def test_create_relationships_with_wacky_relation(self):
        obj = Group.query.find().first()
        user = User.query.find().first()
        self.provider.update(Group, {'_id': obj._id, 'users': [user._id]})
        assert user._id == obj.users[0]._id

    def test_create_relationships_remove_groups(self):
        obj = Group.query.find().first()
        self.provider.update(User, {'_id': self.user._id, 'groups': []})
        assert user not in obj.users

    def test_create_relationships_change_town(self):
        town = Town.query.find({'name': 'Arvada'}).first()

        self.user.town = town
        self.session.flush()

        self.provider.update(
            User, {
                '_id': self.user._id,
                'town': Town.query.find({
                    'name': 'Denver'
                }).first()
            })
        assert self.user.town.name == 'Denver'

    def test_tgmanymany_create(self):
        count, groups = self.provider.query(Group, limit=1)
        params = {'user_name': 'mmuser', 'groups': [groups[0]]}
        new_user = self.provider.create(TGMMUser, params)

        assert new_user.groups[0].group_name == groups[0].group_name
        assert new_user._groups[0] == groups[0].group_name

    def test_tgmanymany_update(self):
        params = {'user_name': 'mmuser', 'groups': []}
        new_user = self.provider.create(TGMMUser, params)

        assert len(new_user.groups) == 0
        count, groups = self.provider.query(Group, limit=1)
        self.provider.update(TGMMUser, {
            '_id': new_user._id,
            'groups': [groups[0]]
        })

        new_user = self.provider.get_obj(TGMMUser, {'_id': new_user._id})
        assert len(new_user.groups) == 1
        assert new_user.groups[0].group_name == groups[0].group_name
        assert new_user._groups[0] == groups[0].group_name