23 from six.moves.urllib.parse import urlsplit, urlunsplit, urljoin, parse_qs |
23 from six.moves.urllib.parse import urlsplit, urlunsplit, urljoin, parse_qs |
24 |
24 |
25 import lxml |
25 import lxml |
26 |
26 |
27 from logilab.common.testlib import unittest_main |
27 from logilab.common.testlib import unittest_main |
28 from logilab.common.decorators import monkeypatch |
|
29 |
28 |
30 from cubicweb import Binary, NoSelectableObject, ValidationError, transaction as tx |
29 from cubicweb import Binary, NoSelectableObject, ValidationError, transaction as tx |
31 from cubicweb.schema import RRQLExpression |
30 from cubicweb.schema import RRQLExpression |
32 from cubicweb.predicates import is_instance |
31 from cubicweb.predicates import is_instance |
33 from cubicweb.devtools.testlib import CubicWebTC |
32 from cubicweb.devtools.testlib import CubicWebTC |
35 from cubicweb.devtools.httptest import CubicWebServerTC |
34 from cubicweb.devtools.httptest import CubicWebServerTC |
36 from cubicweb.utils import json_dumps |
35 from cubicweb.utils import json_dumps |
37 from cubicweb.uilib import rql_for_eid |
36 from cubicweb.uilib import rql_for_eid |
38 from cubicweb.web import Redirect, RemoteCallFailed, http_headers, formfields as ff |
37 from cubicweb.web import Redirect, RemoteCallFailed, http_headers, formfields as ff |
39 from cubicweb.web.views.autoform import get_pending_inserts, get_pending_deletes |
38 from cubicweb.web.views.autoform import get_pending_inserts, get_pending_deletes |
40 from cubicweb.web.views.basecontrollers import JSonController, xhtmlize, jsonize |
|
41 from cubicweb.web.views.ajaxcontroller import ajaxfunc, AjaxFunction |
39 from cubicweb.web.views.ajaxcontroller import ajaxfunc, AjaxFunction |
42 from cubicweb.server.session import Connection |
40 from cubicweb.server.session import Connection |
43 from cubicweb.server.hook import Hook, Operation |
41 from cubicweb.server.hook import Hook, Operation |
44 |
42 |
45 |
43 |
758 |
756 |
759 def test_nonregr_rollback_on_validation_error(self): |
757 def test_nonregr_rollback_on_validation_error(self): |
760 with self.admin_access.web_request(url='edit') as req: |
758 with self.admin_access.web_request(url='edit') as req: |
761 p = self.create_user(req, u"doe") |
759 p = self.create_user(req, u"doe") |
762 # do not try to skip 'primary_email' for this test |
760 # do not try to skip 'primary_email' for this test |
763 old_skips = p.__class__.skip_copy_for |
761 old_skips = p.__class__.cw_skip_copy_for |
764 p.__class__.skip_copy_for = () |
762 p.__class__.cw_skip_copy_for = () |
765 try: |
763 try: |
766 e = req.create_entity('EmailAddress', address=u'doe@doe.com') |
764 e = req.create_entity('EmailAddress', address=u'doe@doe.com') |
767 req.execute('SET P use_email E, P primary_email E WHERE P eid %(p)s, E eid %(e)s', |
765 req.execute('SET P use_email E, P primary_email E WHERE P eid %(p)s, E eid %(e)s', |
768 {'p' : p.eid, 'e' : e.eid}) |
766 {'p' : p.eid, 'e' : e.eid}) |
769 req.form = {'eid': 'X', |
767 req.form = {'eid': 'X', |
784 req.form['vid'] = 'copy' |
782 req.form['vid'] = 'copy' |
785 self.app_handle_request(req, 'view') |
783 self.app_handle_request(req, 'view') |
786 rset = req.execute('CWUser P WHERE P surname "Boom"') |
784 rset = req.execute('CWUser P WHERE P surname "Boom"') |
787 self.assertEqual(len(rset), 0) |
785 self.assertEqual(len(rset), 0) |
788 finally: |
786 finally: |
789 p.__class__.skip_copy_for = old_skips |
787 p.__class__.cw_skip_copy_for = old_skips |
790 |
788 |
791 def test_regr_inlined_forms(self): |
789 def test_regr_inlined_forms(self): |
792 with self.admin_access.web_request() as req: |
790 with self.admin_access.web_request() as req: |
793 self.schema['described_by_test'].inlined = False |
791 self.schema['described_by_test'].inlined = False |
794 try: |
792 try: |
1018 pass |
1016 pass |
1019 self.assertEqual(cm.exception.status, 400) |
1017 self.assertEqual(cm.exception.status, 400) |
1020 self.assertEqual(cm.exception.reason, 'no foo method') |
1018 self.assertEqual(cm.exception.reason, 'no foo method') |
1021 |
1019 |
1022 |
1020 |
1023 class JSonControllerTC(AjaxControllerTC): |
|
1024 # NOTE: this class performs the same tests as AjaxController but with |
|
1025 # deprecated 'json' controller (i.e. check backward compatibility) |
|
1026 tested_controller = 'json' |
|
1027 |
|
1028 def setUp(self): |
|
1029 super(JSonControllerTC, self).setUp() |
|
1030 self.exposed_remote_funcs = [fname for fname in dir(JSonController) |
|
1031 if fname.startswith('js_')] |
|
1032 |
|
1033 def tearDown(self): |
|
1034 super(JSonControllerTC, self).tearDown() |
|
1035 for funcname in dir(JSonController): |
|
1036 # remove functions added dynamically during tests |
|
1037 if funcname.startswith('js_') and funcname not in self.exposed_remote_funcs: |
|
1038 delattr(JSonController, funcname) |
|
1039 |
|
1040 def test_monkeypatch_jsoncontroller(self): |
|
1041 with self.assertRaises(RemoteCallFailed): |
|
1042 with self.remote_calling('foo'): |
|
1043 pass |
|
1044 @monkeypatch(JSonController) |
|
1045 def js_foo(self): |
|
1046 return u'hello' |
|
1047 with self.remote_calling('foo') as (res, _): |
|
1048 self.assertEqual(res, b'hello') |
|
1049 |
|
1050 def test_monkeypatch_jsoncontroller_xhtmlize(self): |
|
1051 with self.assertRaises(RemoteCallFailed): |
|
1052 with self.remote_calling('foo'): |
|
1053 pass |
|
1054 @monkeypatch(JSonController) |
|
1055 @xhtmlize |
|
1056 def js_foo(self): |
|
1057 return u'hello' |
|
1058 with self.remote_calling('foo') as (res, _): |
|
1059 self.assertEqual(b'<div>hello</div>', res) |
|
1060 |
|
1061 def test_monkeypatch_jsoncontroller_jsonize(self): |
|
1062 with self.assertRaises(RemoteCallFailed): |
|
1063 with self.remote_calling('foo'): |
|
1064 pass |
|
1065 @monkeypatch(JSonController) |
|
1066 @jsonize |
|
1067 def js_foo(self): |
|
1068 return 12 |
|
1069 with self.remote_calling('foo') as (res, _): |
|
1070 self.assertEqual(res, b'12') |
|
1071 |
|
1072 def test_monkeypatch_jsoncontroller_stdfunc(self): |
|
1073 @monkeypatch(JSonController) |
|
1074 @jsonize |
|
1075 def js_reledit_form(self): |
|
1076 return 12 |
|
1077 with self.remote_calling('reledit_form') as (res, _): |
|
1078 self.assertEqual(res, b'12') |
|
1079 |
|
1080 |
|
1081 class UndoControllerTC(CubicWebTC): |
1021 class UndoControllerTC(CubicWebTC): |
1082 |
1022 |
1083 def setUp(self): |
1023 def setUp(self): |
1084 # Force undo feature to be turned on |
1024 # Force undo feature to be turned on |
1085 Connection.undo_actions = property(lambda self: True, lambda self, v:None) |
1025 Connection.undo_actions = property(lambda self: True, lambda self, v:None) |