diff --git a/rhodecode/apps/admin/tests/test_admin_defaults.py b/rhodecode/apps/admin/tests/test_admin_defaults.py --- a/rhodecode/apps/admin/tests/test_admin_defaults.py +++ b/rhodecode/apps/admin/tests/test_admin_defaults.py @@ -41,7 +41,7 @@ def route_path(name, params=None, **kwar @pytest.mark.usefixtures("app") -class TestDefaultsController(object): +class TestDefaultsView(object): def test_index(self, autologin_user): response = self.app.get(route_path('admin_defaults_repositories')) diff --git a/rhodecode/lib/base.py b/rhodecode/lib/base.py --- a/rhodecode/lib/base.py +++ b/rhodecode/lib/base.py @@ -608,10 +608,20 @@ def add_events_routes(config): def bootstrap_request(**kwargs): import pyramid.testing - request = pyramid.testing.DummyRequest(**kwargs) - request.application_url = kwargs.pop('application_url', 'http://example.com') - request.host = kwargs.pop('host', 'example.com:80') - request.domain = kwargs.pop('domain', 'example.com') + + class TestRequest(pyramid.testing.DummyRequest): + application_url = kwargs.pop('application_url', 'http://example.com') + host = kwargs.pop('host', 'example.com:80') + domain = kwargs.pop('domain', 'example.com') + + class TestDummySession(pyramid.testing.DummySession): + def save(*arg, **kw): + pass + + request = TestRequest(**kwargs) + request.session = TestDummySession() config = pyramid.testing.setUp(request=request) add_events_routes(config) + return request + diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py --- a/rhodecode/lib/helpers.py +++ b/rhodecode/lib/helpers.py @@ -60,7 +60,6 @@ from webhelpers.html.tags import auto_di submit, text, password, textarea, title, ul, xml_declaration, radio from webhelpers.html.tools import auto_link, button_to, highlight, \ js_obfuscate, mail_to, strip_links, strip_tags, tag_re -from webhelpers.pylonslib import Flash as _Flash from webhelpers.text import chop_at, collapse, convert_accented_entities, \ convert_misc_entities, lchop, plural, rchop, remove_formatting, \ replace_whitespace, urlify, truncate, wrap_paragraphs @@ -661,19 +660,48 @@ class _Message(object): return escape(safe_unicode(self.message)) -class Flash(_Flash): +class Flash(object): + # List of allowed categories. If None, allow any category. + categories = ["warning", "notice", "error", "success"] + + # Default category if none is specified. + default_category = "notice" + + def __init__(self, session_key="flash", categories=None, + default_category=None): + """ + Instantiate a ``Flash`` object. + + ``session_key`` is the key to save the messages under in the user's + session. - def pop_messages(self, request=None): - """Return all accumulated messages and delete them from the session. + ``categories`` is an optional list which overrides the default list + of categories. + + ``default_category`` overrides the default category used for messages + when none is specified. + """ + self.session_key = session_key + if categories is not None: + self.categories = categories + if default_category is not None: + self.default_category = default_category + if self.categories and self.default_category not in self.categories: + raise ValueError( + "unrecognized default category %r" % (self.default_category,)) + + def pop_messages(self, session=None, request=None): + """ + Return all accumulated messages and delete them from the session. The return value is a list of ``Message`` objects. """ messages = [] - if request: + if not session: + if not request: + request = get_current_request() session = request.session - else: - from pylons import session # Pop the 'old' pylons flash messages. They are tuples of the form # (category, message) @@ -692,9 +720,9 @@ class Flash(_Flash): session.save() return messages - def json_alerts(self, request=None): + def json_alerts(self, session=None, request=None): payloads = [] - messages = flash.pop_messages(request=request) + messages = flash.pop_messages(session=session, request=request) if messages: for message in messages: subdata = {} @@ -715,6 +743,18 @@ class Flash(_Flash): }) return json.dumps(payloads) + def __call__(self, message, category=None, ignore_duplicate=False, + session=None, request=None): + + if not session: + if not request: + request = get_current_request() + session = request.session + + session.flash( + message, queue=category, allow_duplicate=not ignore_duplicate) + + flash = Flash() #============================================================================== diff --git a/rhodecode/templates/base/root.mako b/rhodecode/templates/base/root.mako --- a/rhodecode/templates/base/root.mako +++ b/rhodecode/templates/base/root.mako @@ -120,7 +120,7 @@ c.template_context['default_user'] = { - + ## avoide escaping the %N diff --git a/rhodecode/tests/__init__.py b/rhodecode/tests/__init__.py --- a/rhodecode/tests/__init__.py +++ b/rhodecode/tests/__init__.py @@ -28,27 +28,16 @@ from os.path import join as jn from tempfile import _RandomNameSequence -from paste.deploy import loadapp -from paste.script.appinstall import SetupCommand +from pylons import url -import pylons -import pylons.test -from pylons import config, url -from pylons.i18n.translation import _get_translator -from pylons.util import ContextObj - -from routes.util import URLGenerator from nose.plugins.skip import SkipTest import pytest -from rhodecode import is_windows -from rhodecode.config.routing import ADMIN_PREFIX -from rhodecode.model.meta import Session from rhodecode.model.db import User from rhodecode.lib import auth from rhodecode.lib import helpers as h from rhodecode.lib.helpers import flash, link_to -from rhodecode.lib.utils2 import safe_unicode, safe_str +from rhodecode.lib.utils2 import safe_str log = logging.getLogger(__name__) @@ -117,6 +106,7 @@ try: import ldap ldap_lib_installed = True except ImportError: + ldap = None # means that python-ldap is not installed pass @@ -196,18 +186,18 @@ def login_user(app, username=TEST_USER_A return login_user_session(app, username, password)['rhodecode_user'] -def assert_session_flash(response=None, msg=None, category=None, no_=None): +def assert_session_flash(response, msg=None, category=None, no_=None): """ Assert on a flash message in the current session. - :param msg: Required. The expected message. Will be evaluated if a + :param response: Response from give calll, it will contain flash + messages or bound session with them. + :param msg: The expected message. Will be evaluated if a :class:`LazyString` is passed in. - :param response: Optional. For functional testing, pass in the response - object. Otherwise don't pass in any value. :param category: Optional. If passed, the message category will be checked as well. - :param no_: Optional. If passed, the message will be checked to NOT be in the - flash session + :param no_: Optional. If passed, the message will be checked to NOT + be in the flash session """ if msg is None and no_ is None: raise ValueError("Parameter msg or no_ is required.") @@ -215,7 +205,8 @@ def assert_session_flash(response=None, if msg and no_: raise ValueError("Please specify either msg or no_, but not both") - messages = flash.pop_messages() + session = response.get_session_from_response() + messages = flash.pop_messages(session=session) msg = _eval_if_lazy(msg) assert messages, 'unable to find message `%s` in empty flash list' % msg @@ -242,14 +233,6 @@ def _eval_if_lazy(value): return value.eval() if hasattr(value, 'eval') else value -def assert_session_flash_is_empty(response): - assert 'flash' in response.session, 'Response session has no flash key' - - msg = 'flash messages are present in session:%s' % \ - response.session['flash'][0] - pytest.fail(safe_str(msg)) - - def no_newline_id_generator(test_name): """ Generates a test name without spaces or newlines characters. Used for diff --git a/rhodecode/tests/plugin.py b/rhodecode/tests/plugin.py --- a/rhodecode/tests/plugin.py +++ b/rhodecode/tests/plugin.py @@ -1669,8 +1669,8 @@ def request_stub(): """ Stub request object. """ - request = pyramid.testing.DummyRequest() - request.scheme = 'https' + from rhodecode.lib.base import bootstrap_request + request = bootstrap_request(scheme='https') return request