25 from os.path import dirname, join, abspath |
25 from os.path import dirname, join, abspath |
26 from math import log |
26 from math import log |
27 from contextlib import contextmanager |
27 from contextlib import contextmanager |
28 from inspect import isgeneratorfunction |
28 from inspect import isgeneratorfunction |
29 from itertools import chain |
29 from itertools import chain |
30 from warnings import warn |
|
31 |
30 |
32 from six import binary_type, text_type, string_types, reraise |
31 from six import binary_type, text_type, string_types, reraise |
33 from six.moves import range |
32 from six.moves import range |
34 from six.moves.urllib.parse import urlparse, parse_qs, unquote as urlunquote |
33 from six.moves.urllib.parse import urlparse, parse_qs, unquote as urlunquote |
35 |
34 |
37 |
36 |
38 from logilab.common.testlib import Tags, nocoverage |
37 from logilab.common.testlib import Tags, nocoverage |
39 from logilab.common.debugger import Debugger |
38 from logilab.common.debugger import Debugger |
40 from logilab.common.umessage import message_from_string |
39 from logilab.common.umessage import message_from_string |
41 from logilab.common.decorators import cached, classproperty, clear_cache, iclassmethod |
40 from logilab.common.decorators import cached, classproperty, clear_cache, iclassmethod |
42 from logilab.common.deprecation import deprecated, class_deprecated |
41 from logilab.common.deprecation import class_deprecated |
43 from logilab.common.shellutils import getlogin |
42 from logilab.common.shellutils import getlogin |
44 |
43 |
45 from cubicweb import (ValidationError, NoSelectableObject, AuthenticationError, |
44 from cubicweb import (ValidationError, NoSelectableObject, AuthenticationError, |
46 BadConnectionId) |
45 BadConnectionId) |
47 from cubicweb import cwconfig, devtools, repoapi, server, web |
46 from cubicweb import cwconfig, devtools, repoapi, server, web |
450 Do not forget to set the cls.test_db_id value to enable caching of the |
449 Do not forget to set the cls.test_db_id value to enable caching of the |
451 result. |
450 result. |
452 """ |
451 """ |
453 |
452 |
454 # user / session management ############################################### |
453 # user / session management ############################################### |
455 |
|
456 @deprecated('[3.19] explicitly use RepoAccess object in test instead') |
|
457 def user(self, req=None): |
|
458 """return the application schema""" |
|
459 if req is None: |
|
460 return self.request().user |
|
461 else: |
|
462 return req.user |
|
463 |
454 |
464 @iclassmethod # XXX turn into a class method |
455 @iclassmethod # XXX turn into a class method |
465 def create_user(self, req, login=None, groups=('users',), password=None, |
456 def create_user(self, req, login=None, groups=('users',), password=None, |
466 email=None, commit=True, **kwargs): |
457 email=None, commit=True, **kwargs): |
467 """create and return a new user entity""" |
458 """create and return a new user entity""" |
669 raise |
660 raise |
670 |
661 |
671 publisher.error_handler = raise_error_handler |
662 publisher.error_handler = raise_error_handler |
672 return publisher |
663 return publisher |
673 |
664 |
674 @deprecated('[3.19] use the .remote_calling method') |
|
675 def remote_call(self, fname, *args): |
|
676 """remote json call simulation""" |
|
677 dump = json.dumps |
|
678 args = [dump(arg) for arg in args] |
|
679 req = self.request(fname=fname, pageid='123', arg=args) |
|
680 ctrl = self.vreg['controllers'].select('ajax', req) |
|
681 return ctrl.publish(), req |
|
682 |
|
683 @contextmanager |
665 @contextmanager |
684 def remote_calling(self, fname, *args, **kwargs): |
666 def remote_calling(self, fname, *args, **kwargs): |
685 """remote json call simulation""" |
667 """remote json call simulation""" |
686 args = [json.dumps(arg) for arg in args] |
668 args = [json.dumps(arg) for arg in args] |
687 with self.admin_access.web_request(fname=fname, pageid='123', arg=args, **kwargs) as req: |
669 with self.admin_access.web_request(fname=fname, pageid='123', arg=args, **kwargs) as req: |
688 ctrl = self.vreg['controllers'].select('ajax', req) |
670 ctrl = self.vreg['controllers'].select('ajax', req) |
689 yield ctrl.publish(), req |
671 yield ctrl.publish(), req |
690 |
672 |
691 def app_handle_request(self, req, path=None): |
673 def app_handle_request(self, req): |
692 if path is not None: |
|
693 warn('[3.24] path argument got removed from app_handle_request parameters, ' |
|
694 'give it to the request constructor', DeprecationWarning) |
|
695 if req.relative_path(False) != path: |
|
696 req._url = path |
|
697 return self.app.core_handle(req) |
674 return self.app.core_handle(req) |
698 |
|
699 @deprecated("[3.15] app_handle_request is the new and better way" |
|
700 " (beware of small semantic changes)") |
|
701 def app_publish(self, *args, **kwargs): |
|
702 return self.app_handle_request(*args, **kwargs) |
|
703 |
675 |
704 def ctrl_publish(self, req, ctrl='edit', rset=None): |
676 def ctrl_publish(self, req, ctrl='edit', rset=None): |
705 """call the publish method of the edit controller""" |
677 """call the publish method of the edit controller""" |
706 ctrl = self.vreg['controllers'].select(ctrl, req, appli=self.app) |
678 ctrl = self.vreg['controllers'].select(ctrl, req, appli=self.app) |
707 try: |
679 try: |
749 form[eid_param('_cw_entity_fields', entity.eid)] = ','.join(entity_fields) |
721 form[eid_param('_cw_entity_fields', entity.eid)] = ','.join(entity_fields) |
750 if fields: |
722 if fields: |
751 form['_cw_fields'] = ','.join(sorted(fields)) |
723 form['_cw_fields'] = ','.join(sorted(fields)) |
752 return form |
724 return form |
753 |
725 |
754 @deprecated('[3.19] use .admin_request_from_url instead') |
|
755 def req_from_url(self, url): |
|
756 """parses `url` and builds the corresponding CW-web request |
|
757 |
|
758 req.form will be setup using the url's query string |
|
759 """ |
|
760 req = self.request(url=url) |
|
761 if isinstance(url, text_type): |
|
762 url = url.encode(req.encoding) # req.setup_params() expects encoded strings |
|
763 querystring = urlparse(url)[-2] |
|
764 params = parse_qs(querystring) |
|
765 req.setup_params(params) |
|
766 return req |
|
767 |
|
768 @contextmanager |
726 @contextmanager |
769 def admin_request_from_url(self, url): |
727 def admin_request_from_url(self, url): |
770 """parses `url` and builds the corresponding CW-web request |
728 """parses `url` and builds the corresponding CW-web request |
771 |
729 |
772 req.form will be setup using the url's query string |
730 req.form will be setup using the url's query string |
841 req._url = path |
799 req._url = path |
842 self.app_handle_request(req) |
800 self.app_handle_request(req) |
843 self.assertTrue(300 <= req.status_out < 400, req.status_out) |
801 self.assertTrue(300 <= req.status_out < 400, req.status_out) |
844 location = req.get_response_header('location') |
802 location = req.get_response_header('location') |
845 return self._parse_location(req, location) |
803 return self._parse_location(req, location) |
846 |
|
847 @deprecated("[3.15] expect_redirect_handle_request is the new and better way" |
|
848 " (beware of small semantic changes)") |
|
849 def expect_redirect_publish(self, *args, **kwargs): |
|
850 return self.expect_redirect_handle_request(*args, **kwargs) |
|
851 |
804 |
852 def set_auth_mode(self, authmode, anonuser=None): |
805 def set_auth_mode(self, authmode, anonuser=None): |
853 self.set_option('auth-mode', authmode) |
806 self.set_option('auth-mode', authmode) |
854 self.set_option('anonymous-user', anonuser) |
807 self.set_option('anonymous-user', anonuser) |
855 if anonuser is None: |
808 if anonuser is None: |