13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
14 # details. |
14 # details. |
15 # |
15 # |
16 # You should have received a copy of the GNU Lesser General Public License along |
16 # You should have received a copy of the GNU Lesser General Public License along |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
|
18 |
|
19 from logilab.common.decorators import clear_cache |
|
20 |
18 from cubicweb.devtools import init_test_database |
21 from cubicweb.devtools import init_test_database |
19 from cubicweb.devtools.repotest import BasePlannerTC, test_plan |
22 from cubicweb.devtools.repotest import BasePlannerTC, test_plan |
20 |
23 |
21 class _SetGenerator(object): |
24 class _SetGenerator(object): |
22 """singleton to easily create set using "s[0]" or "s[0,1,2]" for instance |
25 """singleton to easily create set using "s[0]" or "s[0,1,2]" for instance |
43 |
46 |
44 class FakeCardSource(AbstractSource): |
47 class FakeCardSource(AbstractSource): |
45 uri = 'ccc' |
48 uri = 'ccc' |
46 support_entities = {'Card': True, 'Note': True, 'State': True} |
49 support_entities = {'Card': True, 'Note': True, 'State': True} |
47 support_relations = {'in_state': True, 'multisource_rel': True, 'multisource_inlined_rel': True, |
50 support_relations = {'in_state': True, 'multisource_rel': True, 'multisource_inlined_rel': True, |
48 'multisource_crossed_rel': True} |
51 'multisource_crossed_rel': True,} |
49 dont_cross_relations = set(('fiche', 'state_of')) |
52 dont_cross_relations = set(('fiche', 'state_of')) |
50 cross_relations = set(('multisource_crossed_rel',)) |
53 cross_relations = set(('multisource_crossed_rel',)) |
51 |
54 |
52 def syntax_tree_search(self, *args, **kwargs): |
55 def syntax_tree_search(self, *args, **kwargs): |
53 return [] |
56 return [] |
1024 ('FetchStep', |
1029 ('FetchStep', |
1025 [('Any X,XT WHERE X title XT, X is Card', [{'X': 'Card', 'XT': 'String'}])], |
1030 [('Any X,XT WHERE X title XT, X is Card', [{'X': 'Card', 'XT': 'String'}])], |
1026 [self.cards, self.system], None, {'X': 'table1.C0', 'X.title': 'table1.C1', 'XT': 'table1.C1'}, []), |
1031 [self.cards, self.system], None, {'X': 'table1.C0', 'X.title': 'table1.C1', 'XT': 'table1.C1'}, []), |
1027 ('OneFetchStep', |
1032 ('OneFetchStep', |
1028 [('Any X,XT,U WHERE X owned_by U?, X title XT, X is Card', |
1033 [('Any X,XT,U WHERE X owned_by U?, X title XT, X is Card', |
1029 [{'X': 'Card', 'XT': 'String'}])], |
1034 [{'X': 'Card', 'U': 'CWUser', 'XT': 'String'}])], |
1030 None, None, [self.system], {'L': 'table0.C1', |
1035 None, None, [self.system], {'L': 'table0.C1', |
1031 'U': 'table0.C0', |
1036 'U': 'table0.C0', |
1032 'X': 'table1.C0', |
1037 'X': 'table1.C0', |
1033 'X.title': 'table1.C1', |
1038 'X.title': 'table1.C1', |
1034 'XT': 'table1.C1'}, []) |
1039 'XT': 'table1.C1'}, []) |
1434 [{'T': 'String', 'X': 'Bookmark'}])], |
1439 [{'T': 'String', 'X': 'Bookmark'}])], |
1435 [self.system], {}, {'N': 'table0.C1', 'X': 'table0.C0', 'X.name': 'table0.C1'}, []), |
1440 [self.system], {}, {'N': 'table0.C1', 'X': 'table0.C0', 'X.name': 'table0.C1'}, []), |
1436 ('FetchStep', |
1441 ('FetchStep', |
1437 [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])], |
1442 [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])], |
1438 [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []), |
1443 [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []), |
1439 ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser', |
1444 ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser, A is IN(Bookmark, Tag)', |
1440 [{'A': 'Bookmark', 'B': 'CWUser', 'C': 'String'}, |
1445 [{'A': 'Bookmark', 'B': 'CWUser', 'C': 'String'}, |
1441 {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])], |
1446 {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])], |
1442 None, None, [self.system], |
1447 None, None, [self.system], |
1443 {'A': 'table0.C0', |
1448 {'A': 'table0.C0', |
1444 'B': 'table1.C0', 'B.login': 'table1.C1', |
1449 'B': 'table1.C0', 'B.login': 'table1.C1', |
1468 'X.title': 'table0.C1'}, []), |
1473 'X.title': 'table0.C1'}, []), |
1469 ]), |
1474 ]), |
1470 ('FetchStep', |
1475 ('FetchStep', |
1471 [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])], |
1476 [('Any B,C WHERE B login C, B is CWUser', [{'B': 'CWUser', 'C': 'String'}])], |
1472 [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []), |
1477 [self.ldap, self.system], None, {'B': 'table1.C0', 'B.login': 'table1.C1', 'C': 'table1.C1'}, []), |
1473 ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser', |
1478 ('OneFetchStep', [('DISTINCT Any B,C ORDERBY C WHERE A created_by B, B login C, EXISTS(B owned_by 5), B is CWUser, A is IN(Card, Tag)', |
1474 [{'A': 'Card', 'B': 'CWUser', 'C': 'String'}, |
1479 [{'A': 'Card', 'B': 'CWUser', 'C': 'String'}, |
1475 {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])], |
1480 {'A': 'Tag', 'B': 'CWUser', 'C': 'String'}])], |
1476 None, None, [self.system], |
1481 None, None, [self.system], |
1477 {'A': 'table0.C0', |
1482 {'A': 'table0.C0', |
1478 'B': 'table1.C0', 'B.login': 'table1.C1', |
1483 'B': 'table1.C0', 'B.login': 'table1.C1', |
1534 {'x': 999999,}) |
1539 {'x': 999999,}) |
1535 |
1540 |
1536 def test_crossed_relation_eid_2_needattr(self): |
1541 def test_crossed_relation_eid_2_needattr(self): |
1537 repo._type_source_cache[999999] = ('Note', 'cards', 999999) |
1542 repo._type_source_cache[999999] = ('Note', 'cards', 999999) |
1538 self._test('Any Y,T WHERE X eid %(x)s, X multisource_crossed_rel Y, Y type T', |
1543 self._test('Any Y,T WHERE X eid %(x)s, X multisource_crossed_rel Y, Y type T', |
1539 [('FetchStep', [('Any Y,T WHERE Y type T, Y is Note', [{'T': 'String', 'Y': 'Note'}])], |
1544 [('OneFetchStep', [('Any Y,T WHERE 999999 multisource_crossed_rel Y, Y type T, Y is Note', |
1540 [self.cards, self.system], None, |
1545 [{'T': 'String', 'Y': 'Note'}])], |
1541 {'T': 'table0.C1', 'Y': 'table0.C0', 'Y.type': 'table0.C1'}, []), |
1546 None, None, [self.cards, self.system], {}, |
1542 ('UnionStep', None, None, |
1547 []), |
1543 [('OneFetchStep', [('Any Y,T WHERE 999999 multisource_crossed_rel Y, Y type T, Y is Note', |
1548 ], |
1544 [{'T': 'String', 'Y': 'Note'}])], |
|
1545 None, None, [self.cards], None, |
|
1546 []), |
|
1547 ('OneFetchStep', [('Any Y,T WHERE 999999 multisource_crossed_rel Y, Y type T, Y is Note', |
|
1548 [{'T': 'String', 'Y': 'Note'}])], |
|
1549 None, None, [self.system], |
|
1550 {'T': 'table0.C1', 'Y': 'table0.C0', 'Y.type': 'table0.C1'}, |
|
1551 [])] |
|
1552 )], |
|
1553 {'x': 999999,}) |
1549 {'x': 999999,}) |
1554 |
1550 |
1555 def test_crossed_relation_eid_not_1(self): |
1551 def test_crossed_relation_eid_not_1(self): |
1556 repo._type_source_cache[999999] = ('Note', 'system', 999999) |
1552 repo._type_source_cache[999999] = ('Note', 'system', 999999) |
1557 self._test('Any Y WHERE X eid %(x)s, NOT X multisource_crossed_rel Y', |
1553 self._test('Any Y WHERE X eid %(x)s, NOT X multisource_crossed_rel Y', |
1754 # ('OneFetchStep', [('DISTINCT Any X,%s WHERE X is CWUser' % activatedeid, |
1750 # ('OneFetchStep', [('DISTINCT Any X,%s WHERE X is CWUser' % activatedeid, |
1755 # [{'X': 'CWUser'}])], |
1751 # [{'X': 'CWUser'}])], |
1756 # None, None, [self.system], {}, []), |
1752 # None, None, [self.system], {}, []), |
1757 # ]), |
1753 # ]), |
1758 # ]) |
1754 # ]) |
|
1755 |
|
1756 def test_ldap_user_related_to_invariant_and_dont_cross_rel(self): |
|
1757 self.repo._type_source_cache[999999] = ('Note', 'cards', 999999) |
|
1758 self.cards.dont_cross_relations.add('created_by') |
|
1759 try: |
|
1760 self._test('Any X,XL WHERE E eid %(x)s, E created_by X, X login XL', |
|
1761 [('FetchStep', [('Any X,XL WHERE X login XL, X is CWUser', |
|
1762 [{'X': 'CWUser', 'XL': 'String'}])], |
|
1763 [self.ldap, self.system], None, |
|
1764 {'X': 'table0.C0', 'X.login': 'table0.C1', 'XL': 'table0.C1'}, |
|
1765 []), |
|
1766 ('OneFetchStep', |
|
1767 [('Any X,XL WHERE 999999 created_by X, X login XL, X is CWUser', |
|
1768 [{'X': 'CWUser', 'XL': 'String'}])], |
|
1769 None, None, |
|
1770 [self.system], |
|
1771 {'X': 'table0.C0', 'X.login': 'table0.C1', 'XL': 'table0.C1'}, |
|
1772 [])], |
|
1773 {'x': 999999}) |
|
1774 finally: |
|
1775 self.cards.dont_cross_relations.remove('created_by') |
|
1776 |
|
1777 def test_ambigous_cross_relation(self): |
|
1778 self.repo._type_source_cache[999999] = ('Note', 'cards', 999999) |
|
1779 self.cards.support_relations['see_also'] = True |
|
1780 self.cards.cross_relations.add('see_also') |
|
1781 try: |
|
1782 self._test('Any X,AA ORDERBY AA WHERE E eid %(x)s, E see_also X, X modification_date AA', |
|
1783 [('AggrStep', |
|
1784 'SELECT table0.C0, table0.C1 FROM table0 ORDER BY table0.C1', |
|
1785 None, |
|
1786 [('FetchStep', |
|
1787 [('Any X,AA WHERE 999999 see_also X, X modification_date AA, X is Note', |
|
1788 [{'AA': 'Datetime', 'X': 'Note'}])], [self.cards, self.system], {}, |
|
1789 {'AA': 'table0.C1', 'X': 'table0.C0', |
|
1790 'X.modification_date': 'table0.C1'}, |
|
1791 []), |
|
1792 ('FetchStep', |
|
1793 [('Any X,AA WHERE 999999 see_also X, X modification_date AA, X is Bookmark', |
|
1794 [{'AA': 'Datetime', 'X': 'Bookmark'}])], |
|
1795 [self.system], {}, |
|
1796 {'AA': 'table0.C1', 'X': 'table0.C0', |
|
1797 'X.modification_date': 'table0.C1'}, |
|
1798 [])])], |
|
1799 {'x': 999999}) |
|
1800 finally: |
|
1801 del self.cards.support_relations['see_also'] |
|
1802 self.cards.cross_relations.remove('see_also') |
1759 |
1803 |
1760 # non regression tests #################################################### |
1804 # non regression tests #################################################### |
1761 |
1805 |
1762 def test_nonregr1(self): |
1806 def test_nonregr1(self): |
1763 self._test('Any X, Y WHERE X copain Y, X login "syt", Y login "cochon"', |
1807 self._test('Any X, Y WHERE X copain Y, X login "syt", Y login "cochon"', |
1871 {'n': 999999}) |
1915 {'n': 999999}) |
1872 |
1916 |
1873 def test_nonregr8(self): |
1917 def test_nonregr8(self): |
1874 repo._type_source_cache[999999] = ('Note', 'cards', 999999) |
1918 repo._type_source_cache[999999] = ('Note', 'cards', 999999) |
1875 self._test('Any X,Z WHERE X eid %(x)s, X multisource_rel Y, Z concerne X', |
1919 self._test('Any X,Z WHERE X eid %(x)s, X multisource_rel Y, Z concerne X', |
1876 [('FetchStep', [('Any WHERE 999999 multisource_rel Y, Y is Note', [{'Y': 'Note'}])], |
1920 [('FetchStep', [('Any 999999 WHERE 999999 multisource_rel Y, Y is Note', |
1877 [self.cards], None, {}, []), |
1921 [{'Y': 'Note'}])], |
|
1922 [self.cards], |
|
1923 None, {u'%(x)s': 'table0.C0'}, |
|
1924 []), |
1878 ('OneFetchStep', [('Any 999999,Z WHERE Z concerne 999999, Z is Affaire', |
1925 ('OneFetchStep', [('Any 999999,Z WHERE Z concerne 999999, Z is Affaire', |
1879 [{'Z': 'Affaire'}])], |
1926 [{'Z': 'Affaire'}])], |
1880 None, None, [self.system], {}, [])], |
1927 None, None, [self.system], |
|
1928 {u'%(x)s': 'table0.C0'}, []), |
|
1929 ], |
1881 {'x': 999999}) |
1930 {'x': 999999}) |
1882 |
1931 |
1883 def test_nonregr9(self): |
1932 def test_nonregr9(self): |
1884 repo._type_source_cache[999999] = ('Note', 'cards', 999999) |
1933 repo._type_source_cache[999999] = ('Note', 'cards', 999999) |
1885 repo._type_source_cache[999998] = ('Note', 'cards', 999998) |
1934 repo._type_source_cache[999998] = ('Note', 'cards', 999998) |