server/test/unittest_migractions.py
branchtls-sprint
changeset 1787 71c143c0ada3
parent 1398 5fe84a5f7035
child 1977 606923dff11b
equal deleted inserted replaced
1786:eccd1885d42e 1787:71c143c0ada3
    17     Repository.get_versions = get_versions
    17     Repository.get_versions = get_versions
    18 
    18 
    19 def teardown_module(*args):
    19 def teardown_module(*args):
    20     Repository.get_versions = orig_get_versions
    20     Repository.get_versions = orig_get_versions
    21 
    21 
    22     
    22 
    23 class MigrationCommandsTC(RepositoryBasedTC):
    23 class MigrationCommandsTC(RepositoryBasedTC):
    24     copy_schema = True
    24     copy_schema = True
    25     
    25 
    26     def setUp(self):
    26     def setUp(self):
    27         if not hasattr(self, '_repo'):
    27         if not hasattr(self, '_repo'):
    28             # first initialization
    28             # first initialization
    29             repo = self.repo # set by the RepositoryBasedTC metaclass
    29             repo = self.repo # set by the RepositoryBasedTC metaclass
    30             # force to read schema from the database
    30             # force to read schema from the database
    41         self.mh = ServerMigrationHelper(self.repo.config, migrschema,
    41         self.mh = ServerMigrationHelper(self.repo.config, migrschema,
    42                                         repo=self.repo, cnx=self.cnx,
    42                                         repo=self.repo, cnx=self.cnx,
    43                                         interactive=False)
    43                                         interactive=False)
    44         assert self.cnx is self.mh._cnx
    44         assert self.cnx is self.mh._cnx
    45         assert self.session is self.mh.session, (self.session.id, self.mh.session.id)
    45         assert self.session is self.mh.session, (self.session.id, self.mh.session.id)
    46         
    46 
    47     def test_add_attribute_int(self):
    47     def test_add_attribute_int(self):
    48         self.failIf('whatever' in self.schema)
    48         self.failIf('whatever' in self.schema)
    49         paraordernum = self.mh.rqlexec('Any O WHERE X name "Note", RT name "para", RDEF from_entity X, RDEF relation_type RT, RDEF ordernum O')[0][0]
    49         paraordernum = self.mh.rqlexec('Any O WHERE X name "Note", RT name "para", RDEF from_entity X, RDEF relation_type RT, RDEF ordernum O')[0][0]
    50         self.mh.cmd_add_attribute('Note', 'whatever')
    50         self.mh.cmd_add_attribute('Note', 'whatever')
    51         self.failUnless('whatever' in self.schema)
    51         self.failUnless('whatever' in self.schema)
    71         # test created column is actually a varchar(64)
    71         # test created column is actually a varchar(64)
    72         notesql = self.mh.sqlexec("SELECT sql FROM sqlite_master WHERE type='table' and name='%sNote'" % SQL_PREFIX)[0][0]
    72         notesql = self.mh.sqlexec("SELECT sql FROM sqlite_master WHERE type='table' and name='%sNote'" % SQL_PREFIX)[0][0]
    73         fields = dict(x.strip().split()[:2] for x in notesql.split('(', 1)[1].rsplit(')', 1)[0].split(','))
    73         fields = dict(x.strip().split()[:2] for x in notesql.split('(', 1)[1].rsplit(')', 1)[0].split(','))
    74         self.assertEquals(fields['%sshortpara' % SQL_PREFIX], 'varchar(64)')
    74         self.assertEquals(fields['%sshortpara' % SQL_PREFIX], 'varchar(64)')
    75         self.mh.rollback()
    75         self.mh.rollback()
    76         
    76 
    77     def test_add_datetime_with_default_value_attribute(self):
    77     def test_add_datetime_with_default_value_attribute(self):
    78         self.failIf('mydate' in self.schema)
    78         self.failIf('mydate' in self.schema)
    79         self.mh.cmd_add_attribute('Note', 'mydate')
    79         self.mh.cmd_add_attribute('Note', 'mydate')
    80         self.failUnless('mydate' in self.schema)
    80         self.failUnless('mydate' in self.schema)
    81         self.assertEquals(self.schema['mydate'].subjects(), ('Note', ))
    81         self.assertEquals(self.schema['mydate'].subjects(), ('Note', ))
    86         d1 = self.mh.rqlexec('Any D WHERE X eid %(x)s, X mydate D', {'x': eid1}, 'x')[0][0]
    86         d1 = self.mh.rqlexec('Any D WHERE X eid %(x)s, X mydate D', {'x': eid1}, 'x')[0][0]
    87         d2 = self.mh.rqlexec('Any D WHERE X eid %(x)s, X mydate D', {'x': eid2}, 'x')[0][0]
    87         d2 = self.mh.rqlexec('Any D WHERE X eid %(x)s, X mydate D', {'x': eid2}, 'x')[0][0]
    88         self.assertEquals(d1, date.today())
    88         self.assertEquals(d1, date.today())
    89         self.assertEquals(d2, testdate)
    89         self.assertEquals(d2, testdate)
    90         self.mh.rollback()
    90         self.mh.rollback()
    91             
    91 
    92     def test_rename_attribute(self):
    92     def test_rename_attribute(self):
    93         self.failIf('civility' in self.schema)
    93         self.failIf('civility' in self.schema)
    94         eid1 = self.mh.rqlexec('INSERT Personne X: X nom "lui", X sexe "M"')[0][0]
    94         eid1 = self.mh.rqlexec('INSERT Personne X: X nom "lui", X sexe "M"')[0][0]
    95         eid2 = self.mh.rqlexec('INSERT Personne X: X nom "l\'autre", X sexe NULL')[0][0]
    95         eid2 = self.mh.rqlexec('INSERT Personne X: X nom "l\'autre", X sexe NULL')[0][0]
    96         self.mh.cmd_rename_attribute('Personne', 'sexe', 'civility')
    96         self.mh.cmd_rename_attribute('Personne', 'sexe', 'civility')
   119             t1 = self.mh.rqlexec('Any N WHERE T transition_of ET, ET name "%s", T name N' %
   119             t1 = self.mh.rqlexec('Any N WHERE T transition_of ET, ET name "%s", T name N' %
   120                                  etype)[0][0]
   120                                  etype)[0][0]
   121             self.assertEquals(t1, "baz")
   121             self.assertEquals(t1, "baz")
   122         gn = self.mh.rqlexec('Any GN WHERE T require_group G, G name GN, T eid %s' % baz)[0][0]
   122         gn = self.mh.rqlexec('Any GN WHERE T require_group G, G name GN, T eid %s' % baz)[0][0]
   123         self.assertEquals(gn, 'managers')
   123         self.assertEquals(gn, 'managers')
   124         
   124 
   125     def test_add_entity_type(self):
   125     def test_add_entity_type(self):
   126         self.failIf('Folder2' in self.schema)
   126         self.failIf('Folder2' in self.schema)
   127         self.failIf('filed_under2' in self.schema)
   127         self.failIf('filed_under2' in self.schema)
   128         self.mh.cmd_add_entity_type('Folder2')
   128         self.mh.cmd_add_entity_type('Folder2')
   129         self.failUnless('Folder2' in self.schema)
   129         self.failUnless('Folder2' in self.schema)
   135                            'filed_under2', 'has_text', 'identity', 'is', 'is_instance_of',
   135                            'filed_under2', 'has_text', 'identity', 'is', 'is_instance_of',
   136                            'modification_date', 'name', 'owned_by'])
   136                            'modification_date', 'name', 'owned_by'])
   137         self.assertEquals([str(rs) for rs in self.schema['Folder2'].object_relations()],
   137         self.assertEquals([str(rs) for rs in self.schema['Folder2'].object_relations()],
   138                           ['filed_under2', 'identity'])
   138                           ['filed_under2', 'identity'])
   139         self.assertEquals(sorted(str(e) for e in self.schema['filed_under2'].subjects()),
   139         self.assertEquals(sorted(str(e) for e in self.schema['filed_under2'].subjects()),
   140                           ['Affaire', 'Card', 'Division', 'Email', 'EmailThread', 'File', 
   140                           ['Affaire', 'Card', 'Division', 'Email', 'EmailThread', 'File',
   141                            'Folder2', 'Image', 'Note', 'Personne', 'Societe', 'SubDivision'])
   141                            'Folder2', 'Image', 'Note', 'Personne', 'Societe', 'SubDivision'])
   142         self.assertEquals(self.schema['filed_under2'].objects(), ('Folder2',))
   142         self.assertEquals(self.schema['filed_under2'].objects(), ('Folder2',))
   143         eschema = self.schema.eschema('Folder2')
   143         eschema = self.schema.eschema('Folder2')
   144         for cstr in eschema.constraints('name'):
   144         for cstr in eschema.constraints('name'):
   145             self.failUnless(hasattr(cstr, 'eid'))
   145             self.failUnless(hasattr(cstr, 'eid'))
   162     def test_add_relation_type(self):
   162     def test_add_relation_type(self):
   163         self.mh.cmd_add_entity_type('Folder2', auto=False)
   163         self.mh.cmd_add_entity_type('Folder2', auto=False)
   164         self.mh.cmd_add_relation_type('filed_under2')
   164         self.mh.cmd_add_relation_type('filed_under2')
   165         self.failUnless('filed_under2' in self.schema)
   165         self.failUnless('filed_under2' in self.schema)
   166         self.assertEquals(sorted(str(e) for e in self.schema['filed_under2'].subjects()),
   166         self.assertEquals(sorted(str(e) for e in self.schema['filed_under2'].subjects()),
   167                           ['Affaire', 'Card', 'Division', 'Email', 'EmailThread', 'File', 
   167                           ['Affaire', 'Card', 'Division', 'Email', 'EmailThread', 'File',
   168                            'Folder2', 'Image', 'Note', 'Personne', 'Societe', 'SubDivision'])
   168                            'Folder2', 'Image', 'Note', 'Personne', 'Societe', 'SubDivision'])
   169         self.assertEquals(self.schema['filed_under2'].objects(), ('Folder2',))
   169         self.assertEquals(self.schema['filed_under2'].objects(), ('Folder2',))
   170 
   170 
   171 
   171 
   172     def test_drop_relation_type(self):
   172     def test_drop_relation_type(self):
   176         self.mh.cmd_drop_relation_type('filed_under2')
   176         self.mh.cmd_drop_relation_type('filed_under2')
   177         self.failIf('filed_under2' in self.schema)
   177         self.failIf('filed_under2' in self.schema)
   178 
   178 
   179     def test_add_relation_definition(self):
   179     def test_add_relation_definition(self):
   180         self.mh.cmd_add_relation_definition('Societe', 'in_state', 'State')
   180         self.mh.cmd_add_relation_definition('Societe', 'in_state', 'State')
   181         self.assertEquals(sorted(self.schema['in_state'].subjects()),
   181         self.assertEquals(sorted(str(x) for x in self.schema['in_state'].subjects()),
   182                           ['Affaire', 'Division', 'CWUser', 'Note', 'Societe', 'SubDivision'])
   182                           ['Affaire', 'CWUser', 'Division', 'Note', 'Societe', 'SubDivision'])
   183         self.assertEquals(self.schema['in_state'].objects(), ('State',))
   183         self.assertEquals(self.schema['in_state'].objects(), ('State',))
   184 
   184 
   185     def test_add_relation_definition_nortype(self):
   185     def test_add_relation_definition_nortype(self):
   186         self.mh.cmd_add_relation_definition('Personne', 'concerne2', 'Affaire')
   186         self.mh.cmd_add_relation_definition('Personne', 'concerne2', 'Affaire')
   187         self.assertEquals(self.schema['concerne2'].subjects(),
   187         self.assertEquals(self.schema['concerne2'].subjects(),
   193         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()), ['Affaire', 'Personne'])
   193         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()), ['Affaire', 'Personne'])
   194         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()), ['Affaire', 'Division', 'Note', 'Societe', 'SubDivision'])
   194         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()), ['Affaire', 'Division', 'Note', 'Societe', 'SubDivision'])
   195         self.mh.cmd_drop_relation_definition('Personne', 'concerne', 'Affaire')
   195         self.mh.cmd_drop_relation_definition('Personne', 'concerne', 'Affaire')
   196         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()), ['Affaire'])
   196         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()), ['Affaire'])
   197         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()), ['Division', 'Note', 'Societe', 'SubDivision'])
   197         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()), ['Division', 'Note', 'Societe', 'SubDivision'])
   198         
   198 
   199     def test_drop_relation_definition_with_specialization(self):
   199     def test_drop_relation_definition_with_specialization(self):
   200         self.failUnless('concerne' in self.schema)
   200         self.failUnless('concerne' in self.schema)
   201         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()), ['Affaire', 'Personne'])
   201         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()), ['Affaire', 'Personne'])
   202         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()), ['Affaire', 'Division', 'Note', 'Societe', 'SubDivision'])
   202         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()), ['Affaire', 'Division', 'Note', 'Societe', 'SubDivision'])
   203         self.mh.cmd_drop_relation_definition('Affaire', 'concerne', 'Societe')
   203         self.mh.cmd_drop_relation_definition('Affaire', 'concerne', 'Societe')
   204         self.mh.cmd_drop_relation_definition('None', 'concerne', 'Societe')
   204         self.mh.cmd_drop_relation_definition('None', 'concerne', 'Societe')
   205         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()), ['Affaire', 'Personne'])
   205         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].subjects()), ['Affaire', 'Personne'])
   206         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()), ['Affaire', 'Note'])
   206         self.assertEquals(sorted(str(e) for e in self.schema['concerne'].objects()), ['Affaire', 'Note'])
   207         
   207 
   208     def test_drop_relation_definition2(self):
   208     def test_drop_relation_definition2(self):
   209         self.failUnless('evaluee' in self.schema)
   209         self.failUnless('evaluee' in self.schema)
   210         self.mh.cmd_drop_relation_definition('Personne', 'evaluee', 'Note')
   210         self.mh.cmd_drop_relation_definition('Personne', 'evaluee', 'Note')
   211         self.failUnless('evaluee' in self.schema)
   211         self.failUnless('evaluee' in self.schema)
   212         self.assertEquals(sorted(self.schema['evaluee'].subjects()),
   212         self.assertEquals(sorted(self.schema['evaluee'].subjects()),
   213                           ['Division', 'CWUser', 'Societe', 'SubDivision'])
   213                           ['CWUser', 'Division', 'Societe', 'SubDivision'])
   214         self.assertEquals(sorted(self.schema['evaluee'].objects()),
   214         self.assertEquals(sorted(self.schema['evaluee'].objects()),
   215                           ['Note'])
   215                           ['Note'])
   216 
   216 
   217     def test_rename_relation(self):
   217     def test_rename_relation(self):
   218         self.skip('implement me')
   218         self.skip('implement me')
   227             card = rschema.rproperty('Affaire', 'Societe', 'cardinality')
   227             card = rschema.rproperty('Affaire', 'Societe', 'cardinality')
   228             self.assertEquals(card, '?*')
   228             self.assertEquals(card, '?*')
   229         finally:
   229         finally:
   230             self.mh.cmd_change_relation_props('Affaire', 'concerne', 'Societe',
   230             self.mh.cmd_change_relation_props('Affaire', 'concerne', 'Societe',
   231                                               cardinality='**')
   231                                               cardinality='**')
   232             
   232 
   233     def test_change_relation_props_final(self):
   233     def test_change_relation_props_final(self):
   234         rschema = self.schema['adel']
   234         rschema = self.schema['adel']
   235         card = rschema.rproperty('Personne', 'String', 'fulltextindexed')
   235         card = rschema.rproperty('Personne', 'String', 'fulltextindexed')
   236         self.assertEquals(card, False)
   236         self.assertEquals(card, False)
   237         try:
   237         try:
   253 #                     'nom', 'prenom', 'civility', 'promo', 'ass', 'adel', 'titre',
   253 #                     'nom', 'prenom', 'civility', 'promo', 'ass', 'adel', 'titre',
   254 #                     'web', 'tel', 'fax', 'datenaiss', 'test']
   254 #                     'web', 'tel', 'fax', 'datenaiss', 'test']
   255 #         self.assertEquals([rs.type for rs in migrschema['Personne'].ordered_relations() if rs.is_final()],
   255 #         self.assertEquals([rs.type for rs in migrschema['Personne'].ordered_relations() if rs.is_final()],
   256 #                           expected)
   256 #                           expected)
   257         migrschema['Personne'].description = 'blabla bla'
   257         migrschema['Personne'].description = 'blabla bla'
   258         migrschema['titre'].description = 'usually a title' 
   258         migrschema['titre'].description = 'usually a title'
   259         migrschema['titre']._rproperties[('Personne', 'String')]['description'] = 'title for this person'
   259         migrschema['titre']._rproperties[('Personne', 'String')]['description'] = 'title for this person'
   260 #         rinorderbefore = cursor.execute('Any O,N WHERE X is CWAttribute, X relation_type RT, RT name N,'
   260 #         rinorderbefore = cursor.execute('Any O,N WHERE X is CWAttribute, X relation_type RT, RT name N,'
   261 #                                         'X from_entity FE, FE name "Personne",'
   261 #                                         'X from_entity FE, FE name "Personne",'
   262 #                                         'X ordernum O ORDERBY O')
   262 #                                         'X ordernum O ORDERBY O')
   263 #         expected = [u'creation_date', u'modification_date', u'nom', u'prenom',
   263 #         expected = [u'creation_date', u'modification_date', u'nom', u'prenom',
   264 #                     u'sexe', u'promo', u'titre', u'adel', u'ass', u'web', u'tel',
   264 #                     u'sexe', u'promo', u'titre', u'adel', u'ass', u'web', u'tel',
   265 #                     u'fax', u'datenaiss', u'test', u'description']
   265 #                     u'fax', u'datenaiss', u'test', u'description']
   266 #        self.assertListEquals(rinorderbefore, map(list, zip([0, 0]+range(1, len(expected)), expected)))
   266 #        self.assertListEquals(rinorderbefore, map(list, zip([0, 0]+range(1, len(expected)), expected)))
   267         
   267 
   268         self.mh.cmd_synchronize_schema(commit=False)
   268         self.mh.cmd_sync_schema_props_perms(commit=False)
   269         
   269 
   270         self.assertEquals(cursor.execute('Any D WHERE X name "Personne", X description D')[0][0],
   270         self.assertEquals(cursor.execute('Any D WHERE X name "Personne", X description D')[0][0],
   271                           'blabla bla')
   271                           'blabla bla')
   272         self.assertEquals(cursor.execute('Any D WHERE X name "titre", X description D')[0][0],
   272         self.assertEquals(cursor.execute('Any D WHERE X name "titre", X description D')[0][0],
   273                           'usually a title')
   273                           'usually a title')
   274         self.assertEquals(cursor.execute('Any D WHERE X relation_type RT, RT name "titre",'
   274         self.assertEquals(cursor.execute('Any D WHERE X relation_type RT, RT name "titre",'
   298         self.assertEquals(eexpr.reverse_delete_permission, [])
   298         self.assertEquals(eexpr.reverse_delete_permission, [])
   299         self.assertEquals(eexpr.reverse_update_permission, [])
   299         self.assertEquals(eexpr.reverse_update_permission, [])
   300         # no more rqlexpr to delete and add para attribute
   300         # no more rqlexpr to delete and add para attribute
   301         self.failIf(self._rrqlexpr_rset('add', 'para'))
   301         self.failIf(self._rrqlexpr_rset('add', 'para'))
   302         self.failIf(self._rrqlexpr_rset('delete', 'para'))
   302         self.failIf(self._rrqlexpr_rset('delete', 'para'))
   303         # new rql expr to add ecrit_par relation        
   303         # new rql expr to add ecrit_par relation
   304         rexpr = self._rrqlexpr_entity('add', 'ecrit_par')
   304         rexpr = self._rrqlexpr_entity('add', 'ecrit_par')
   305         self.assertEquals(rexpr.expression,
   305         self.assertEquals(rexpr.expression,
   306                           'O require_permission P, P name "add_note", '
   306                           'O require_permission P, P name "add_note", '
   307                           'U in_group G, P require_group G')
   307                           'U in_group G, P require_group G')
   308         self.assertEquals([rt.name for rt in rexpr.reverse_add_permission], ['ecrit_par'])
   308         self.assertEquals([rt.name for rt in rexpr.reverse_add_permission], ['ecrit_par'])
   331         #   * 2 new (Note add, ecrit_par add)
   331         #   * 2 new (Note add, ecrit_par add)
   332         # remaining orphan rql expr which should be deleted at commit (composite relation)
   332         # remaining orphan rql expr which should be deleted at commit (composite relation)
   333         self.assertEquals(len(cursor.execute('RQLExpression X WHERE NOT ET1 read_permission X, NOT ET2 add_permission X, '
   333         self.assertEquals(len(cursor.execute('RQLExpression X WHERE NOT ET1 read_permission X, NOT ET2 add_permission X, '
   334                                              'NOT ET3 delete_permission X, NOT ET4 update_permission X')), 8+1)
   334                                              'NOT ET3 delete_permission X, NOT ET4 update_permission X')), 8+1)
   335         # finally
   335         # finally
   336         self.assertEquals(len(cursor.execute('RQLExpression X')), nbrqlexpr_start + 1 + 2) 
   336         self.assertEquals(len(cursor.execute('RQLExpression X')), nbrqlexpr_start + 1 + 2)
   337                           
   337 
   338         self.mh.rollback()
   338         self.mh.rollback()
   339 
   339 
   340     def _erqlexpr_rset(self, action, ertype):
   340     def _erqlexpr_rset(self, action, ertype):
   341         rql = 'RQLExpression X WHERE ET is CWEType, ET %s_permission X, ET name %%(name)s' % action
   341         rql = 'RQLExpression X WHERE ET is CWEType, ET %s_permission X, ET name %%(name)s' % action
   342         return self.mh.rqlcursor.execute(rql, {'name': ertype})
   342         return self.mh.rqlcursor.execute(rql, {'name': ertype})
   349         return self.mh.rqlcursor.execute(rql, {'name': ertype})
   349         return self.mh.rqlcursor.execute(rql, {'name': ertype})
   350     def _rrqlexpr_entity(self, action, ertype):
   350     def _rrqlexpr_entity(self, action, ertype):
   351         rset = self._rrqlexpr_rset(action, ertype)
   351         rset = self._rrqlexpr_rset(action, ertype)
   352         self.assertEquals(len(rset), 1)
   352         self.assertEquals(len(rset), 1)
   353         return rset.get_entity(0, 0)
   353         return rset.get_entity(0, 0)
   354     
   354 
   355     def test_set_size_constraint(self):
   355     def test_set_size_constraint(self):
   356         # existing previous value
   356         # existing previous value
   357         try:
   357         try:
   358             self.mh.cmd_set_size_constraint('CWEType', 'name', 128)
   358             self.mh.cmd_set_size_constraint('CWEType', 'name', 128)
   359         finally:
   359         finally:
   376                 self.mh.cmd_remove_cube('email')
   376                 self.mh.cmd_remove_cube('email')
   377                 # file was there because it's an email dependancy, should have been removed
   377                 # file was there because it's an email dependancy, should have been removed
   378                 cubes.remove('email')
   378                 cubes.remove('email')
   379                 cubes.remove('file')
   379                 cubes.remove('file')
   380                 self.assertEquals(set(self.config.cubes()), cubes)
   380                 self.assertEquals(set(self.config.cubes()), cubes)
   381                 for ertype in ('Email', 'EmailThread', 'EmailPart', 'File', 'Image', 
   381                 for ertype in ('Email', 'EmailThread', 'EmailPart', 'File', 'Image',
   382                                'sender', 'in_thread', 'reply_to', 'data_format'):
   382                                'sender', 'in_thread', 'reply_to', 'data_format'):
   383                     self.failIf(ertype in schema, ertype)
   383                     self.failIf(ertype in schema, ertype)
   384                 self.assertEquals(sorted(schema['see_also']._rproperties.keys()),
   384                 self.assertEquals(sorted(schema['see_also']._rproperties.keys()),
   385                                   sorted([('Folder', 'Folder'),
   385                                   sorted([('Folder', 'Folder'),
   386                                           ('Bookmark', 'Bookmark'),
   386                                           ('Bookmark', 'Bookmark'),
   400         finally:
   400         finally:
   401             self.mh.cmd_add_cube('email')
   401             self.mh.cmd_add_cube('email')
   402             cubes.add('email')
   402             cubes.add('email')
   403             cubes.add('file')
   403             cubes.add('file')
   404             self.assertEquals(set(self.config.cubes()), cubes)
   404             self.assertEquals(set(self.config.cubes()), cubes)
   405             for ertype in ('Email', 'EmailThread', 'EmailPart', 'File', 'Image', 
   405             for ertype in ('Email', 'EmailThread', 'EmailPart', 'File', 'Image',
   406                            'sender', 'in_thread', 'reply_to', 'data_format'):
   406                            'sender', 'in_thread', 'reply_to', 'data_format'):
   407                 self.failUnless(ertype in schema, ertype)
   407                 self.failUnless(ertype in schema, ertype)
   408             self.assertEquals(sorted(schema['see_also']._rproperties.keys()),
   408             self.assertEquals(sorted(schema['see_also']._rproperties.keys()),
   409                               sorted([('EmailThread', 'EmailThread'), ('Folder', 'Folder'),
   409                               sorted([('EmailThread', 'EmailThread'), ('Folder', 'Folder'),
   410                                       ('Bookmark', 'Bookmark'),
   410                                       ('Bookmark', 'Bookmark'),
   424             # trick: overwrite self.maxeid to avoid deletion of just reintroduced
   424             # trick: overwrite self.maxeid to avoid deletion of just reintroduced
   425             #        types (and their associated tables!)
   425             #        types (and their associated tables!)
   426             self.maxeid = self.execute('Any MAX(X)')[0][0]
   426             self.maxeid = self.execute('Any MAX(X)')[0][0]
   427             # why this commit is necessary is unclear to me (though without it
   427             # why this commit is necessary is unclear to me (though without it
   428             # next test may fail complaining of missing tables
   428             # next test may fail complaining of missing tables
   429             self.commit() 
   429             self.commit()
   430 
   430 
   431     def test_set_state(self):
   431     def test_set_state(self):
   432         user = self.session.user
   432         user = self.session.user
   433         self.set_debug(True)
       
   434         self.mh.set_state(user.eid, 'deactivated')
   433         self.mh.set_state(user.eid, 'deactivated')
   435         user.clear_related_cache('in_state', 'subject')
   434         user.clear_related_cache('in_state', 'subject')
   436         try:
   435         self.assertEquals(user.state, 'deactivated')
   437             self.assertEquals(user.state, 'deactivated')
   436 
   438         finally:
       
   439             self.set_debug(False)
       
   440         
       
   441 if __name__ == '__main__':
   437 if __name__ == '__main__':
   442     unittest_main()
   438     unittest_main()