server/test/unittest_msplanner.py
branchstable
changeset 3315 59220b704562
parent 3240 8604a15995d1
child 3293 69c0ba095536
child 3587 5b3725f315fc
equal deleted inserted replaced
3298:caef98aa4a98 3315:59220b704562
    41     cross_relations = set(('multisource_crossed_rel',))
    41     cross_relations = set(('multisource_crossed_rel',))
    42 
    42 
    43     def syntax_tree_search(self, *args, **kwargs):
    43     def syntax_tree_search(self, *args, **kwargs):
    44         return []
    44         return []
    45 
    45 
    46 X_ALL_SOLS = sorted([{'X': 'Affaire'}, {'X': 'Basket'}, {'X': 'Bookmark'},
    46 X_ALL_SOLS = sorted([{'X': 'Affaire'}, {'X': 'BaseTransition'}, {'X': 'Basket'},
       
    47                      {'X': 'Bookmark'}, {'X': 'CWAttribute'}, {'X': 'CWCache'},
       
    48                      {'X': 'CWConstraint'}, {'X': 'CWConstraintType'}, {'X': 'CWEType'},
       
    49                      {'X': 'CWGroup'}, {'X': 'CWPermission'}, {'X': 'CWProperty'},
       
    50                      {'X': 'CWRType'}, {'X': 'CWRelation'}, {'X': 'CWUser'},
    47                      {'X': 'Card'}, {'X': 'Comment'}, {'X': 'Division'},
    51                      {'X': 'Card'}, {'X': 'Comment'}, {'X': 'Division'},
    48                      {'X': 'CWCache'}, {'X': 'CWConstraint'}, {'X': 'CWConstraintType'},
    52                      {'X': 'Email'}, {'X': 'EmailAddress'}, {'X': 'EmailPart'},
    49                      {'X': 'CWEType'}, {'X': 'CWAttribute'}, {'X': 'CWGroup'},
    53                      {'X': 'EmailThread'}, {'X': 'ExternalUri'}, {'X': 'File'},
    50                      {'X': 'CWRelation'}, {'X': 'CWPermission'}, {'X': 'CWProperty'},
    54                      {'X': 'Folder'}, {'X': 'Image'}, {'X': 'Note'},
    51                      {'X': 'CWRType'}, {'X': 'CWUser'}, {'X': 'Email'},
    55                      {'X': 'Personne'}, {'X': 'RQLExpression'}, {'X': 'Societe'},
    52                      {'X': 'EmailAddress'}, {'X': 'EmailPart'}, {'X': 'EmailThread'},
    56                      {'X': 'State'}, {'X': 'SubDivision'}, {'X': 'SubWorkflowExitPoint'},
    53                      {'X': 'ExternalUri'},
    57                      {'X': 'Tag'}, {'X': 'TrInfo'}, {'X': 'Transition'},
    54                      {'X': 'File'}, {'X': 'Folder'}, {'X': 'Image'},
    58                      {'X': 'Workflow'}, {'X': 'WorkflowTransition'}])
    55                      {'X': 'Note'}, {'X': 'Personne'}, {'X': 'RQLExpression'},
       
    56                      {'X': 'Societe'}, {'X': 'State'}, {'X': 'SubDivision'},
       
    57                      {'X': 'Tag'}, {'X': 'TrInfo'}, {'X': 'Transition'}])
       
    58 
    59 
    59 
    60 
    60 # keep cnx so it's not garbage collected and the associated session is closed
    61 # keep cnx so it's not garbage collected and the associated session is closed
    61 repo, cnx = init_test_database('sqlite')
    62 repo, cnx = init_test_database('sqlite')
    62 
    63 
   345 
   346 
   346 class MSPlannerTC(BaseMSPlannerTC):
   347 class MSPlannerTC(BaseMSPlannerTC):
   347 
   348 
   348     def setUp(self):
   349     def setUp(self):
   349         BaseMSPlannerTC.setUp(self)
   350         BaseMSPlannerTC.setUp(self)
   350         self.planner = MSPlanner(self.o.schema, self.o._rqlhelper)
   351         self.planner = MSPlanner(self.o.schema, self.repo.vreg.rqlhelper)
   351 
   352 
   352     _test = test_plan
   353     _test = test_plan
   353 
   354 
   354     def test_simple_system_only(self):
   355     def test_simple_system_only(self):
   355         """retrieve entities only supported by the system source
   356         """retrieve entities only supported by the system source
   768                       ('OneFetchStep',
   769                       ('OneFetchStep',
   769                        [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is Basket',
   770                        [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is Basket',
   770                          [{'X': 'Basket'}]),
   771                          [{'X': 'Basket'}]),
   771                         ('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser',
   772                         ('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser',
   772                          [{'X': 'CWUser'}]),
   773                          [{'X': 'CWUser'}]),
   773                         ('Any X WHERE X has_text "bla", X is IN(Card, Comment, Division, Email, EmailThread, File, Folder, Image, Note, Personne, Societe, State, SubDivision, Tag, Transition)',
   774                         ('Any X WHERE X has_text "bla", X is IN(BaseTransition, Card, Comment, Division, Email, EmailThread, File, Folder, Image, Note, Personne, Societe, State, SubDivision, Tag, Transition, Workflow, WorkflowTransition)',
   774                          [{'X': 'Card'}, {'X': 'Comment'}, {'X': 'Division'},
   775                          [{'X': 'BaseTransition'}, {'X': 'Card'}, {'X': 'Comment'},
   775                           {'X': 'Email'}, {'X': 'EmailThread'}, {'X': 'File'},
   776                           {'X': 'Division'}, {'X': 'Email'}, {'X': 'EmailThread'},
   776                           {'X': 'Folder'}, {'X': 'Image'}, {'X': 'Note'},
   777                           {'X': 'File'}, {'X': 'Folder'}, {'X': 'Image'},
   777                           {'X': 'Personne'}, {'X': 'Societe'}, {'X': 'State'},
   778                           {'X': 'Note'}, {'X': 'Personne'}, {'X': 'Societe'},
   778                           {'X': 'SubDivision'}, {'X': 'Tag'}, {'X': 'Transition'}]),],
   779                           {'X': 'State'}, {'X': 'SubDivision'}, {'X': 'Tag'},
       
   780                           {'X': 'Transition'}, {'X': 'Workflow'}, {'X': 'WorkflowTransition'}]),],
   779                        None, None, [self.system], {}, []),
   781                        None, None, [self.system], {}, []),
   780                       ])
   782                       ])
   781                      ])
   783                      ])
   782 
   784 
   783     def test_security_has_text_limit_offset(self):
   785     def test_security_has_text_limit_offset(self):
   791                          ('FetchStep', [('Any X WHERE X has_text "bla", (EXISTS(X owned_by 5)) OR ((((EXISTS(D concerne C?, C owned_by 5, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by 5, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by 5, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by 5, X identity J, E is Note, J is Affaire))), X is Affaire',
   793                          ('FetchStep', [('Any X WHERE X has_text "bla", (EXISTS(X owned_by 5)) OR ((((EXISTS(D concerne C?, C owned_by 5, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by 5, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by 5, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by 5, X identity J, E is Note, J is Affaire))), X is Affaire',
   792                                             [{'C': 'Division', 'E': 'Note', 'D': 'Affaire', 'G': 'SubDivision', 'F': 'Societe', 'I': 'Affaire', 'H': 'Affaire', 'J': 'Affaire', 'X': 'Affaire'}])],
   794                                             [{'C': 'Division', 'E': 'Note', 'D': 'Affaire', 'G': 'SubDivision', 'F': 'Societe', 'I': 'Affaire', 'H': 'Affaire', 'J': 'Affaire', 'X': 'Affaire'}])],
   793                           [self.system], {'E': 'table1.C0'}, {'X': 'table0.C0'}, []),
   795                           [self.system], {'E': 'table1.C0'}, {'X': 'table0.C0'}, []),
   794                          ('FetchStep',
   796                          ('FetchStep',
   795                           [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is Basket',
   797                           [('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is Basket',
   796                          [{'X': 'Basket'}]),
   798                             [{'X': 'Basket'}]),
   797                         ('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser',
   799                            ('Any X WHERE X has_text "bla", EXISTS(X owned_by 5), X is CWUser',
   798                          [{'X': 'CWUser'}]),
   800                             [{'X': 'CWUser'}]),
   799                         ('Any X WHERE X has_text "bla", X is IN(Card, Comment, Division, Email, EmailThread, File, Folder, Image, Note, Personne, Societe, State, SubDivision, Tag, Transition)',
   801                            ('Any X WHERE X has_text "bla", X is IN(BaseTransition, Card, Comment, Division, Email, EmailThread, File, Folder, Image, Note, Personne, Societe, State, SubDivision, Tag, Transition, Workflow, WorkflowTransition)',
   800                          [{'X': 'Card'}, {'X': 'Comment'}, {'X': 'Division'},
   802                             [{'X': 'BaseTransition'}, {'X': 'Card'}, {'X': 'Comment'},
   801                           {'X': 'Email'}, {'X': 'EmailThread'}, {'X': 'File'},
   803                              {'X': 'Division'}, {'X': 'Email'}, {'X': 'EmailThread'},
   802                           {'X': 'Folder'}, {'X': 'Image'}, {'X': 'Note'},
   804                              {'X': 'File'}, {'X': 'Folder'}, {'X': 'Image'},
   803                           {'X': 'Personne'}, {'X': 'Societe'}, {'X': 'State'},
   805                              {'X': 'Note'}, {'X': 'Personne'}, {'X': 'Societe'},
   804                           {'X': 'SubDivision'}, {'X': 'Tag'}, {'X': 'Transition'}]),],
   806                              {'X': 'State'}, {'X': 'SubDivision'}, {'X': 'Tag'},
       
   807                              {'X': 'Transition'}, {'X': 'Workflow'}, {'X': 'WorkflowTransition'}])],
   805                           [self.system], {}, {'X': 'table0.C0'}, []),
   808                           [self.system], {}, {'X': 'table0.C0'}, []),
   806                          ]),
   809                          ]),
   807                     ('OneFetchStep',
   810                     ('OneFetchStep',
   808                      [('Any X LIMIT 10 OFFSET 10',
   811                      [('Any X LIMIT 10 OFFSET 10',
   809                        [{'X': 'Affaire'}, {'X': 'Basket'}, {'X': 'Card'},
   812                        [{'X': 'Affaire'}, {'X': 'BaseTransition'}, {'X': 'Basket'},
   810                         {'X': 'Comment'}, {'X': 'Division'}, {'X': 'CWUser'},
   813                         {'X': 'CWUser'}, {'X': 'Card'}, {'X': 'Comment'},
   811                         {'X': 'Email'}, {'X': 'EmailThread'}, {'X': 'File'},
   814                         {'X': 'Division'}, {'X': 'Email'}, {'X': 'EmailThread'},
   812                         {'X': 'Folder'}, {'X': 'Image'}, {'X': 'Note'},
   815                         {'X': 'File'}, {'X': 'Folder'}, {'X': 'Image'},
   813                         {'X': 'Personne'}, {'X': 'Societe'}, {'X': 'State'},
   816                         {'X': 'Note'}, {'X': 'Personne'}, {'X': 'Societe'},
   814                         {'X': 'SubDivision'}, {'X': 'Tag'}, {'X': 'Transition'}])],
   817                         {'X': 'State'}, {'X': 'SubDivision'}, {'X': 'Tag'},
       
   818                         {'X': 'Transition'}, {'X': 'Workflow'}, {'X': 'WorkflowTransition'}])],
   815                      10, 10, [self.system], {'X': 'table0.C0'}, [])
   819                      10, 10, [self.system], {'X': 'table0.C0'}, [])
   816                      ])
   820                      ])
   817 
   821 
   818     def test_security_user(self):
   822     def test_security_user(self):
   819         """a guest user trying to see another user: EXISTS(X owned_by U) is automatically inserted"""
   823         """a guest user trying to see another user: EXISTS(X owned_by U) is automatically inserted"""
   872                         ('UnionFetchStep',
   876                         ('UnionFetchStep',
   873                          [('FetchStep', [('Any X WHERE X is IN(Card, Note, State)',
   877                          [('FetchStep', [('Any X WHERE X is IN(Card, Note, State)',
   874                                           [{'X': 'Card'}, {'X': 'Note'}, {'X': 'State'}])],
   878                                           [{'X': 'Card'}, {'X': 'Note'}, {'X': 'State'}])],
   875                            [self.cards, self.system], {}, {'X': 'table0.C0'}, []),
   879                            [self.cards, self.system], {}, {'X': 'table0.C0'}, []),
   876                           ('FetchStep',
   880                           ('FetchStep',
   877                            [('Any X WHERE X is IN(Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Image, Personne, RQLExpression, Societe, SubDivision, Tag, TrInfo, Transition)',
   881                            [('Any X WHERE X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Image, Personne, RQLExpression, Societe, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)',
   878                              sorted([{'X': 'Bookmark'}, {'X': 'Comment'}, {'X': 'Division'},
   882                              [{'X': 'BaseTransition'}, {'X': 'Bookmark'},
   879                                       {'X': 'CWCache'}, {'X': 'CWConstraint'}, {'X': 'CWConstraintType'},
   883                               {'X': 'CWAttribute'}, {'X': 'CWCache'},
   880                                       {'X': 'CWEType'}, {'X': 'CWAttribute'}, {'X': 'CWGroup'},
   884                               {'X': 'CWConstraint'}, {'X': 'CWConstraintType'},
   881                                       {'X': 'CWRelation'}, {'X': 'CWPermission'}, {'X': 'CWProperty'},
   885                               {'X': 'CWEType'}, {'X': 'CWGroup'},
   882                                       {'X': 'CWRType'}, {'X': 'Email'}, {'X': 'EmailAddress'},
   886                               {'X': 'CWPermission'}, {'X': 'CWProperty'},
   883                                       {'X': 'EmailPart'}, {'X': 'EmailThread'}, {'X': 'ExternalUri'}, {'X': 'File'},
   887                               {'X': 'CWRType'}, {'X': 'CWRelation'},
   884                                       {'X': 'Folder'}, {'X': 'Image'}, {'X': 'Personne'},
   888                               {'X': 'Comment'}, {'X': 'Division'},
   885                                       {'X': 'RQLExpression'}, {'X': 'Societe'}, {'X': 'SubDivision'},
   889                               {'X': 'Email'}, {'X': 'EmailAddress'},
   886                                       {'X': 'Tag'}, {'X': 'TrInfo'}, {'X': 'Transition'}]))],
   890                               {'X': 'EmailPart'}, {'X': 'EmailThread'},
       
   891                               {'X': 'ExternalUri'}, {'X': 'File'},
       
   892                               {'X': 'Folder'}, {'X': 'Image'},
       
   893                               {'X': 'Personne'}, {'X': 'RQLExpression'},
       
   894                               {'X': 'Societe'}, {'X': 'SubDivision'},
       
   895                               {'X': 'SubWorkflowExitPoint'}, {'X': 'Tag'},
       
   896                               {'X': 'TrInfo'}, {'X': 'Transition'},
       
   897                               {'X': 'Workflow'}, {'X': 'WorkflowTransition'}])],
   887                            [self.system], {}, {'X': 'table0.C0'}, []),
   898                            [self.system], {}, {'X': 'table0.C0'}, []),
   888                           ]),
   899                           ]),
   889                         ('FetchStep', [('Any X WHERE EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
   900                         ('FetchStep', [('Any X WHERE EXISTS(X owned_by 5), X is CWUser', [{'X': 'CWUser'}])],
   890                          [self.system], {'X': 'table2.C0'}, {'X': 'table0.C0'}, []),
   901                          [self.system], {'X': 'table2.C0'}, {'X': 'table0.C0'}, []),
   891                         ('FetchStep', [('Any X WHERE (EXISTS(X owned_by 5)) OR ((((EXISTS(D concerne C?, C owned_by 5, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by 5, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by 5, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by 5, X identity J, E is Note, J is Affaire))), X is Affaire',
   902                         ('FetchStep', [('Any X WHERE (EXISTS(X owned_by 5)) OR ((((EXISTS(D concerne C?, C owned_by 5, C type "X", X identity D, C is Division, D is Affaire)) OR (EXISTS(H concerne G?, G owned_by 5, G type "X", X identity H, G is SubDivision, H is Affaire))) OR (EXISTS(I concerne F?, F owned_by 5, F type "X", X identity I, F is Societe, I is Affaire))) OR (EXISTS(J concerne E?, E owned_by 5, X identity J, E is Note, J is Affaire))), X is Affaire',
   897                     ])
   908                     ])
   898 
   909 
   899     def test_security_complex_aggregat2(self):
   910     def test_security_complex_aggregat2(self):
   900         # use a guest user
   911         # use a guest user
   901         self.session = self._user_session()[1]
   912         self.session = self._user_session()[1]
       
   913         X_ET_ALL_SOLS = []
       
   914         for s in X_ALL_SOLS:
       
   915             ets = {'ET': 'CWEType'}
       
   916             ets.update(s)
       
   917             X_ET_ALL_SOLS.append(ets)
   902         self._test('Any ET, COUNT(X) GROUPBY ET ORDERBY ET WHERE X is ET',
   918         self._test('Any ET, COUNT(X) GROUPBY ET ORDERBY ET WHERE X is ET',
   903                    [('FetchStep', [('Any X WHERE X is IN(Card, Note, State)',
   919                    [('FetchStep', [('Any X WHERE X is IN(Card, Note, State)',
   904                                     [{'X': 'Card'}, {'X': 'Note'}, {'X': 'State'}])],
   920                                     [{'X': 'Card'}, {'X': 'Note'}, {'X': 'State'}])],
   905                      [self.cards, self.system], None, {'X': 'table1.C0'}, []),
   921                      [self.cards, self.system], None, {'X': 'table1.C0'}, []),
   906                     ('FetchStep', [('Any E WHERE E type "X", E is Note', [{'E': 'Note'}])],
   922                     ('FetchStep', [('Any E WHERE E type "X", E is Note', [{'E': 'Note'}])],
   921                       ('FetchStep', [('Any ET,X WHERE X is ET, EXISTS(X owned_by 5), ET is CWEType, X is CWUser',
   937                       ('FetchStep', [('Any ET,X WHERE X is ET, EXISTS(X owned_by 5), ET is CWEType, X is CWUser',
   922                                       [{'ET': 'CWEType', 'X': 'CWUser'}])],
   938                                       [{'ET': 'CWEType', 'X': 'CWUser'}])],
   923                        [self.system], {'X': 'table3.C0'}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
   939                        [self.system], {'X': 'table3.C0'}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
   924                       # extra UnionFetchStep could be avoided but has no cost, so don't care
   940                       # extra UnionFetchStep could be avoided but has no cost, so don't care
   925                       ('UnionFetchStep',
   941                       ('UnionFetchStep',
   926                        [('FetchStep', [('Any ET,X WHERE X is ET, ET is CWEType, X is IN(Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Image, Personne, RQLExpression, Societe, SubDivision, Tag, TrInfo, Transition)',
   942                        [('FetchStep', [('Any ET,X WHERE X is ET, ET is CWEType, X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, Comment, Division, Email, EmailAddress, EmailPart, EmailThread, ExternalUri, File, Folder, Image, Personne, RQLExpression, Societe, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)',
   927                                         [{'X': 'Bookmark', 'ET': 'CWEType'}, {'X': 'Comment', 'ET': 'CWEType'},
   943                                         [{'X': 'BaseTransition', 'ET': 'CWEType'},
   928                                          {'X': 'Division', 'ET': 'CWEType'}, {'X': 'CWCache', 'ET': 'CWEType'},
   944                                          {'X': 'Bookmark', 'ET': 'CWEType'}, {'X': 'CWAttribute', 'ET': 'CWEType'},
   929                                          {'X': 'CWConstraint', 'ET': 'CWEType'}, {'X': 'CWConstraintType', 'ET': 'CWEType'},
   945                                          {'X': 'CWCache', 'ET': 'CWEType'}, {'X': 'CWConstraint', 'ET': 'CWEType'},
   930                                          {'X': 'CWEType', 'ET': 'CWEType'}, {'X': 'CWAttribute', 'ET': 'CWEType'},
   946                                          {'X': 'CWConstraintType', 'ET': 'CWEType'}, {'X': 'CWEType', 'ET': 'CWEType'},
   931                                          {'X': 'CWGroup', 'ET': 'CWEType'}, {'X': 'CWRelation', 'ET': 'CWEType'},
   947                                          {'X': 'CWGroup', 'ET': 'CWEType'}, {'X': 'CWPermission', 'ET': 'CWEType'},
   932                                          {'X': 'CWPermission', 'ET': 'CWEType'}, {'X': 'CWProperty', 'ET': 'CWEType'},
   948                                          {'X': 'CWProperty', 'ET': 'CWEType'}, {'X': 'CWRType', 'ET': 'CWEType'},
   933                                          {'X': 'CWRType', 'ET': 'CWEType'}, {'X': 'Email', 'ET': 'CWEType'},
   949                                          {'X': 'CWRelation', 'ET': 'CWEType'}, {'X': 'Comment', 'ET': 'CWEType'},
       
   950                                          {'X': 'Division', 'ET': 'CWEType'}, {'X': 'Email', 'ET': 'CWEType'},
   934                                          {'X': 'EmailAddress', 'ET': 'CWEType'}, {'X': 'EmailPart', 'ET': 'CWEType'},
   951                                          {'X': 'EmailAddress', 'ET': 'CWEType'}, {'X': 'EmailPart', 'ET': 'CWEType'},
   935                                          {'X': 'EmailThread', 'ET': 'CWEType'},
   952                                          {'X': 'EmailThread', 'ET': 'CWEType'}, {'X': 'ExternalUri', 'ET': 'CWEType'},
   936                                          {'ET': 'CWEType', 'X': 'ExternalUri'},
   953                                          {'X': 'File', 'ET': 'CWEType'}, {'X': 'Folder', 'ET': 'CWEType'},
   937                                          {'X': 'File', 'ET': 'CWEType'},
   954                                          {'X': 'Image', 'ET': 'CWEType'}, {'X': 'Personne', 'ET': 'CWEType'},
   938                                          {'X': 'Folder', 'ET': 'CWEType'}, {'X': 'Image', 'ET': 'CWEType'},
   955                                          {'X': 'RQLExpression', 'ET': 'CWEType'}, {'X': 'Societe', 'ET': 'CWEType'},
   939                                          {'X': 'Personne', 'ET': 'CWEType'}, {'X': 'RQLExpression', 'ET': 'CWEType'},
   956                                          {'X': 'SubDivision', 'ET': 'CWEType'}, {'X': 'SubWorkflowExitPoint', 'ET': 'CWEType'},
   940                                          {'X': 'Societe', 'ET': 'CWEType'}, {'X': 'SubDivision', 'ET': 'CWEType'},
       
   941                                          {'X': 'Tag', 'ET': 'CWEType'}, {'X': 'TrInfo', 'ET': 'CWEType'},
   957                                          {'X': 'Tag', 'ET': 'CWEType'}, {'X': 'TrInfo', 'ET': 'CWEType'},
   942                                          {'X': 'Transition', 'ET': 'CWEType'}])],
   958                                          {'X': 'Transition', 'ET': 'CWEType'}, {'X': 'Workflow', 'ET': 'CWEType'},
       
   959                                          {'X': 'WorkflowTransition', 'ET': 'CWEType'}])],
   943                          [self.system], {}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
   960                          [self.system], {}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
   944                         ('FetchStep',
   961                         ('FetchStep',
   945                          [('Any ET,X WHERE X is ET, ET is CWEType, X is IN(Card, Note, State)',
   962                          [('Any ET,X WHERE X is ET, ET is CWEType, X is IN(Card, Note, State)',
   946                            [{'ET': 'CWEType', 'X': 'Card'},
   963                            [{'ET': 'CWEType', 'X': 'Card'},
   947                             {'ET': 'CWEType', 'X': 'Note'},
   964                             {'ET': 'CWEType', 'X': 'Note'},
   948                             {'ET': 'CWEType', 'X': 'State'}])],
   965                             {'ET': 'CWEType', 'X': 'State'}])],
   949                          [self.system], {'X': 'table1.C0'}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
   966                          [self.system], {'X': 'table1.C0'}, {'ET': 'table0.C0', 'X': 'table0.C1'}, []),
   950                         ]),
   967                         ]),
   951                     ]),
   968                     ]),
   952                     ('OneFetchStep',
   969                     ('OneFetchStep',
   953                      [('Any ET,COUNT(X) GROUPBY ET ORDERBY ET',
   970                      [('Any ET,COUNT(X) GROUPBY ET ORDERBY ET', X_ET_ALL_SOLS)],
   954                        sorted([{'ET': 'CWEType', 'X': 'Affaire'}, {'ET': 'CWEType', 'X': 'Basket'},
       
   955                                {'ET': 'CWEType', 'X': 'Bookmark'}, {'ET': 'CWEType', 'X': 'Card'},
       
   956                                {'ET': 'CWEType', 'X': 'Comment'}, {'ET': 'CWEType', 'X': 'Division'},
       
   957                                {'ET': 'CWEType', 'X': 'CWCache'}, {'ET': 'CWEType', 'X': 'CWConstraint'},
       
   958                                {'ET': 'CWEType', 'X': 'CWConstraintType'}, {'ET': 'CWEType', 'X': 'CWEType'},
       
   959                                {'ET': 'CWEType', 'X': 'CWAttribute'}, {'ET': 'CWEType', 'X': 'CWGroup'},
       
   960                                {'ET': 'CWEType', 'X': 'CWRelation'}, {'ET': 'CWEType', 'X': 'CWPermission'},
       
   961                                {'ET': 'CWEType', 'X': 'CWProperty'}, {'ET': 'CWEType', 'X': 'CWRType'},
       
   962                                {'ET': 'CWEType', 'X': 'CWUser'}, {'ET': 'CWEType', 'X': 'Email'},
       
   963                                {'ET': 'CWEType', 'X': 'EmailAddress'}, {'ET': 'CWEType', 'X': 'EmailPart'},
       
   964                                {'ET': 'CWEType', 'X': 'EmailThread'},
       
   965                                {'ET': 'CWEType', 'X': 'ExternalUri'},
       
   966                                {'ET': 'CWEType', 'X': 'File'},
       
   967                                {'ET': 'CWEType', 'X': 'Folder'}, {'ET': 'CWEType', 'X': 'Image'},
       
   968                                {'ET': 'CWEType', 'X': 'Note'}, {'ET': 'CWEType', 'X': 'Personne'},
       
   969                                {'ET': 'CWEType', 'X': 'RQLExpression'}, {'ET': 'CWEType', 'X': 'Societe'},
       
   970                                {'ET': 'CWEType', 'X': 'State'}, {'ET': 'CWEType', 'X': 'SubDivision'},
       
   971                                {'ET': 'CWEType', 'X': 'Tag'}, {'ET': 'CWEType', 'X': 'TrInfo'},
       
   972                                {'ET': 'CWEType', 'X': 'Transition'}]))],
       
   973                      None, None, [self.system], {'ET': 'table0.C0', 'X': 'table0.C1'}, [])
   971                      None, None, [self.system], {'ET': 'table0.C0', 'X': 'table0.C1'}, [])
   974                     ])
   972                     ])
   975 
   973 
   976     def test_security_3sources(self):
   974     def test_security_3sources(self):
   977         # use a guest user
   975         # use a guest user
  1705                        [{'X': 'CWUser', 'Y': 'CWUser'}])],
  1703                        [{'X': 'CWUser', 'Y': 'CWUser'}])],
  1706                      None, None, [self.system], {'X': 'table0.C0', 'Y': 'table1.C0'}, [])
  1704                      None, None, [self.system], {'X': 'table0.C0', 'Y': 'table1.C0'}, [])
  1707                     ])
  1705                     ])
  1708 
  1706 
  1709     def test_nonregr2(self):
  1707     def test_nonregr2(self):
       
  1708         self.session.user.fire_transition('deactivate')
  1710         treid = self.session.user.latest_trinfo().eid
  1709         treid = self.session.user.latest_trinfo().eid
  1711         self._test('Any X ORDERBY D DESC WHERE E eid %(x)s, E wf_info_for X, X modification_date D',
  1710         self._test('Any X ORDERBY D DESC WHERE E eid %(x)s, E wf_info_for X, X modification_date D',
  1712                    [('FetchStep', [('Any X,D WHERE X modification_date D, X is Note',
  1711                    [('FetchStep', [('Any X,D WHERE X modification_date D, X is Note',
  1713                                     [{'X': 'Note', 'D': 'Datetime'}])],
  1712                                     [{'X': 'Note', 'D': 'Datetime'}])],
  1714                      [self.cards, self.system], None, {'X': 'table0.C0', 'X.modification_date': 'table0.C1', 'D': 'table0.C1'}, []),
  1713                      [self.cards, self.system], None, {'X': 'table0.C0', 'X.modification_date': 'table0.C1', 'D': 'table0.C1'}, []),
  1960         self._test('Any X WHERE X eid %(x)s, X owned_by U, U eid %(u)s',
  1959         self._test('Any X WHERE X eid %(x)s, X owned_by U, U eid %(u)s',
  1961                    [('OneFetchStep', [('Any 999998 WHERE 999998 owned_by 999999', [{}])],
  1960                    [('OneFetchStep', [('Any 999998 WHERE 999998 owned_by 999999', [{}])],
  1962                      None, None, [self.system], {}, [])],
  1961                      None, None, [self.system], {}, [])],
  1963                    {'x': 999998, 'u': 999999})
  1962                    {'x': 999998, 'u': 999999})
  1964 
  1963 
  1965     def test_nonregr_identity_no_source_access(self):
  1964     def test_nonregr_identity_no_source_access_1(self):
  1966         repo._type_source_cache[999999] = ('CWUser', 'ldap', 999998)
  1965         repo._type_source_cache[999999] = ('CWUser', 'ldap', 999998)
  1967         self._test('Any S WHERE S identity U, S eid %(s)s, U eid %(u)s',
  1966         self._test('Any S WHERE S identity U, S eid %(s)s, U eid %(u)s',
  1968                    [('OneFetchStep', [('Any 999999 WHERE 999999 identity 999999', [{}])],
  1967                    [('OneFetchStep', [('Any 999999 WHERE 999999 identity 999999', [{}])],
  1969                      None, None, [self.system], {}, [])],
  1968                      None, None, [self.system], {}, [])],
  1970                    {'s': 999999, 'u': 999999})
  1969                    {'s': 999999, 'u': 999999})
  1971 
  1970 
       
  1971     def test_nonregr_identity_no_source_access_2(self):
       
  1972         repo._type_source_cache[999999] = ('EmailAddress', 'system', 999999)
       
  1973         repo._type_source_cache[999998] = ('CWUser', 'ldap', 999998)
       
  1974         self._test('Any X WHERE O use_email X, ((EXISTS(O identity U)) OR (EXISTS(O in_group G, G name IN("managers", "staff")))) OR (EXISTS(O in_group G2, U in_group G2, NOT G2 name "users")), X eid %(x)s, U eid %(u)s',
       
  1975                    [('OneFetchStep', [('Any 999999 WHERE O use_email 999999, ((EXISTS(O identity 999998)) OR (EXISTS(O in_group G, G name IN("managers", "staff")))) OR (EXISTS(O in_group G2, 999998 in_group G2, NOT G2 name "users"))',
       
  1976                                        [{'G': 'CWGroup', 'G2': 'CWGroup', 'O': 'CWUser'}])],
       
  1977                      None, None, [self.system], {}, [])],
       
  1978                    {'x': 999999, 'u': 999998})
       
  1979 
       
  1980 
  1972 class MSPlannerTwoSameExternalSourcesTC(BasePlannerTC):
  1981 class MSPlannerTwoSameExternalSourcesTC(BasePlannerTC):
  1973     """test planner related feature on a 3-sources repository:
  1982     """test planner related feature on a 3-sources repository:
  1974 
  1983 
  1975     * 2 rql sources supporting Card
  1984     * 2 rql sources supporting Card
  1976     """
  1985     """
  1978 
  1987 
  1979     def setUp(self):
  1988     def setUp(self):
  1980         self.setup()
  1989         self.setup()
  1981         self.add_source(FakeCardSource, 'cards')
  1990         self.add_source(FakeCardSource, 'cards')
  1982         self.add_source(FakeCardSource, 'cards2')
  1991         self.add_source(FakeCardSource, 'cards2')
  1983         self.planner = MSPlanner(self.o.schema, self.o._rqlhelper)
  1992         self.planner = MSPlanner(self.o.schema, self.repo.vreg.rqlhelper)
  1984         assert repo.sources_by_uri['cards2'].support_relation('multisource_crossed_rel')
  1993         assert repo.sources_by_uri['cards2'].support_relation('multisource_crossed_rel')
  1985         assert 'multisource_crossed_rel' in repo.sources_by_uri['cards2'].cross_relations
  1994         assert 'multisource_crossed_rel' in repo.sources_by_uri['cards2'].cross_relations
  1986         assert repo.sources_by_uri['cards'].support_relation('multisource_crossed_rel')
  1995         assert repo.sources_by_uri['cards'].support_relation('multisource_crossed_rel')
  1987         assert 'multisource_crossed_rel' in repo.sources_by_uri['cards'].cross_relations
  1996         assert 'multisource_crossed_rel' in repo.sources_by_uri['cards'].cross_relations
  1988     _test = test_plan
  1997     _test = test_plan
  2131     repo = repo
  2140     repo = repo
  2132 
  2141 
  2133     def setUp(self):
  2142     def setUp(self):
  2134         self.setup()
  2143         self.setup()
  2135         self.add_source(FakeVCSSource, 'vcs')
  2144         self.add_source(FakeVCSSource, 'vcs')
  2136         self.planner = MSPlanner(self.o.schema, self.o._rqlhelper)
  2145         self.planner = MSPlanner(self.o.schema, self.repo.vreg.rqlhelper)
  2137     _test = test_plan
  2146     _test = test_plan
  2138 
  2147 
  2139     def test_multisource_inlined_rel_skipped(self):
  2148     def test_multisource_inlined_rel_skipped(self):
  2140         self._test('Any MAX(VC) '
  2149         self._test('Any MAX(VC) '
  2141                    'WHERE VC multisource_inlined_rel R2, R para %(branch)s, VC in_state S, S name "published", '
  2150                    'WHERE VC multisource_inlined_rel R2, R para %(branch)s, VC in_state S, S name "published", '