TurboGears2-2.3.7/0000755000076500000240000000000012607177763013755 5ustar amolstaff00000000000000TurboGears2-2.3.7/PKG-INFO0000644000076500000240000000323012607177763015050 0ustar amolstaff00000000000000Metadata-Version: 1.1 Name: TurboGears2 Version: 2.3.7 Summary: Next generation TurboGears Home-page: http://www.turbogears.org/ Author: Mark Ramm, Christopher Perkins, Jonathan LaCour, Rick Copland, Alberto Valverde, Michael Pedersen, Alessandro Molina, and the TurboGears community Author-email: mark.ramm@gmail.com, alberto@toscat.net, m.pedersen@icelus.org, amol@turbogears.org License: MIT Description: TurboGears brings together a best of breed python tools to create a flexible, full featured, and easy to use web framework. TurboGears 2 provides an integrated and well tested set of tools for everything you need to build dynamic, database driven applications. It provides a full range of tools for front end javascript develeopment, back database development and everything in between: * dynamic javascript powered widgets (ToscaWidgets2) * automatic JSON generation from your controllers * powerful, designer friendly XHTML based templating (Genshi) * object or route based URL dispatching * powerful Object Relational Mappers (SQLAlchemy) The latest development version is available in the `TurboGears Git repositories`_. .. _TurboGears Git repositories: https://github.com/TurboGears Keywords: turbogears Platform: UNKNOWN Classifier: Intended Audience :: Developers Classifier: Environment :: Web Environment Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Internet :: WWW/HTTP :: WSGI TurboGears2-2.3.7/README.rst0000644000076500000240000000220512413576166015436 0ustar amolstaff00000000000000TurboGears ============== .. image:: https://travis-ci.org/TurboGears/tg2.png?branch=development :target: https://travis-ci.org/TurboGears/tg2 .. image:: https://coveralls.io/repos/TurboGears/tg2/badge.png?branch=development :target: https://coveralls.io/r/TurboGears/tg2?branch=development .. image:: https://pypip.in/v/TurboGears2/badge.png :target: https://pypi.python.org/pypi/TurboGears2 .. image:: https://pypip.in/d/TurboGears2/badge.png :target: https://pypi.python.org/pypi/TurboGears2 TurboGears is a hybrid web framework able to act both as a Full Stack framework or as a Microframework. TurboGears helps you get going fast and gets out of your way when you want it! Support and Documentation ---------------------------- See the `TurboGears website `_ to get a quick overview of the framework or visit the `TurboGears Documentation `_ License ----------- TurboGears is licensed under an MIT-style license (see LICENSE.txt). Other incorporated projects may be licensed under different licenses. All licenses allow for non-commercial and commercial use. TurboGears2-2.3.7/setup.cfg0000644000076500000240000000040212607177763015572 0ustar amolstaff00000000000000[aliases] release = egg_info -RDb "" sdist bdist_egg register upload [nosetests] exclude = who_testutil verbosity = 2 detailed-errors = 1 with-coverage = true cover-erase = true cover-package = tg [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 TurboGears2-2.3.7/setup.py0000644000076500000240000000546012607177564015473 0ustar amolstaff00000000000000import os here = os.path.abspath(os.path.dirname(__file__)) exec(compile(open(os.path.join(here, 'tg', 'release.py')).read(), 'release.py', 'exec'), globals(), locals()) from setuptools import find_packages, setup import sys py_version = sys.version_info[:2] if py_version < (2, 6): raise RuntimeError('TurboGears2 requires Python 2.6 or better') if py_version[0] == 3 and py_version < (3, 2): raise RuntimeError('When using Python3 TurboGears2 requires at least Python3.2') test_requirements = ['nose', 'zope.sqlalchemy >= 0.4', 'repoze.who', 'repoze.who.plugins.sa >= 1.0.1', 'Genshi >= 0.5.1', 'Mako', 'WebTest < 2.0', 'routes', 'backlash >= 0.0.7', 'sqlalchemy', 'raven < 4.1.0', 'formencode>=1.3.0a1', 'tw2.forms', 'Beaker', 'Kajiki >= 0.4.4', 'routes'] if py_version == (3, 2): # jinja2 2.7 is incompatible with Python 3.2 test_requirements.append('jinja2 < 2.7') # coverage 4.0 is incompatible with Python 3.2 test_requirements.append('coverage < 4.0') else: test_requirements.append('jinja2') test_requirements.append('coverage') if py_version != (3, 2): # Ming is not compatible with Python3.2 test_requirements.append('ming > 0.5.0') if py_version[0] == 2: test_requirements.extend(['TurboKid >= 1.0.4', 'tgming', 'tw.forms']) install_requires=[ 'WebOb >= 1.2', 'crank >= 0.7.3, < 0.8', 'repoze.lru' ] if py_version == (3, 2): # markupsafe 0.16 is incompatible with Python 3.2 install_requires.append('MarkupSafe < 0.16') else: install_requires.append('MarkupSafe') setup( name='TurboGears2', version=version, description=description, long_description=long_description, classifiers=[ 'Intended Audience :: Developers', 'Environment :: Web Environment', 'Programming Language :: Python :: 3', 'Programming Language :: Python', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Internet :: WWW/HTTP :: WSGI', ], keywords='turbogears', author=author, author_email=email, url=url, license=license, packages=find_packages(exclude=['ez_setup', 'examples']), include_package_data=True, zip_safe=False, install_requires=install_requires, extras_require={ # Used by Travis and Coverage due to setup.py nosetests # causing a coredump when used with coverage 'testing':test_requirements, }, test_suite='nose.collector', tests_require = test_requirements, entry_points=''' ''' ) TurboGears2-2.3.7/tests/0000755000076500000240000000000012607177763015117 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/__init__.py0000644000076500000240000000000012413576166017211 0ustar amolstaff00000000000000TurboGears2-2.3.7/tests/base.py0000644000076500000240000000663712555020522016375 0ustar amolstaff00000000000000# -*- coding: utf-8 -*- import os, shutil from unittest import TestCase from tg.appwrappers.caching import CacheApplicationWrapper from tg.appwrappers.errorpage import ErrorPageApplicationWrapper from tg.appwrappers.i18n import I18NApplicationWrapper from tg.appwrappers.identity import IdentityApplicationWrapper from tg.appwrappers.session import SessionApplicationWrapper try: from xmlrpclib import loads, dumps except ImportError: from xmlrpc.client import loads, dumps import warnings from tg.support.registry import Registry, RegistryManager from webtest import TestApp import tg from tg import tmpl_context, request_local from tg.configuration import milestones from tg.wsgiapp import TemplateContext, TGApp, RequestLocals from tg.controllers import TGController from .test_stack.baseutils import ControllerWrap, FakeRoutes, default_config data_dir = os.path.dirname(os.path.abspath(__file__)) session_dir = os.path.join(data_dir, 'session') cache_dir = os.path.join(data_dir, 'cache') def setup_session_dir(): if not os.path.exists(session_dir): os.makedirs(session_dir) def teardown_session_dir(): shutil.rmtree(session_dir, ignore_errors=True) def make_app(controller_klass=None, environ=None, config_options=None, with_errors=False): """Creates a `TestApp` instance.""" if controller_klass is None: controller_klass = TGController tg.config['renderers'] = default_config['renderers'] tg.config['rendering_engines_options'] = default_config['rendering_engines_options'] config = default_config.copy() config['application_wrappers'] = [ I18NApplicationWrapper, IdentityApplicationWrapper, CacheApplicationWrapper, SessionApplicationWrapper ] if with_errors: config['errorpage.enabled'] = True config['errorpage.status_codes'] = [403, 404] config['application_wrappers'].append(ErrorPageApplicationWrapper) config['session.enabled'] = True config['session.data_dir'] = session_dir config['cache.enabled'] = True config['cache.cache_dir'] = cache_dir if config_options is not None: config.update(config_options) app = TGApp(config=config) app.controller_classes['root'] = ControllerWrap(controller_klass) app = FakeRoutes(app) app = RegistryManager(app) return TestApp(app) class TestWSGIController(TestCase): def setUp(self): tmpl_options = {} tmpl_options['genshi.search_path'] = ['tests'] self._tgl = RequestLocals() self._tgl.tmpl_context = TemplateContext() request_local.context._push_object(self._tgl) # Mark configuration milestones as passed as # test sets up a fake configuration milestones._reach_all() warnings.simplefilter("ignore") tg.config.push_process_config(default_config) warnings.resetwarnings() setup_session_dir() def tearDown(self): request_local.context._pop_object(self._tgl) tg.config.pop_process_config() teardown_session_dir() # Reset milestones milestones._reset_all() def get_response(self, **kargs): url = kargs.pop('_url', '/') self.environ['tg.routes_dict'].update(kargs) return self.app.get(url, extra_environ=self.environ) def post_response(self, **kargs): url = kargs.pop('_url', '/') return self.app.post(url, extra_environ=self.environ, params=kargs) TurboGears2-2.3.7/tests/fixtures/0000755000076500000240000000000012607177763016770 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/fixtures/__init__.py0000644000076500000240000000011612413576166021072 0ustar amolstaff00000000000000"""TG developers may use this package to store fixtures for the test suite""" TurboGears2-2.3.7/tests/fixtures/model.py0000644000076500000240000000310012413576166020427 0ustar amolstaff00000000000000"""A fake application's model objects""" from datetime import datetime from zope.sqlalchemy import ZopeTransactionExtension from sqlalchemy import Table, ForeignKey, Column from sqlalchemy.orm import scoped_session, sessionmaker, relation, backref, \ synonym from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.types import String, Unicode, UnicodeText, Integer, DateTime, \ Boolean, Float # Global session manager. DBSession() returns the session object # appropriate for the current web request. maker = sessionmaker(autoflush=True, autocommit=False, extension=ZopeTransactionExtension()) DBSession = scoped_session(maker) # By default, the data model is defined with SQLAlchemy's declarative # extension, but if you need more control, you can switch to the traditional # method. DeclarativeBase = declarative_base() # Global metadata. # The default metadata is the one from the declarative base. metadata = DeclarativeBase.metadata def init_model(engine): """Call me before using any of the tables or classes in the model.""" DBSession.configure(bind=engine) class Group(DeclarativeBase): """An ultra-simple group definition. """ __tablename__ = 'tg_group' group_id = Column(Integer, autoincrement=True, primary_key=True) group_name = Column(Unicode(16), unique=True) display_name = Column(Unicode(255)) created = Column(DateTime, default=datetime.now) def __repr__(self): return '' % self.group_name TurboGears2-2.3.7/tests/test_balanced_session.py0000644000076500000240000000570312413576166022024 0ustar amolstaff00000000000000from tg.configuration.sqla.balanced_session import BalancedSession, UsingEngineContext, force_request_engine from tg.util import Bunch from tg.wsgiapp import RequestLocals from tg import request_local import tg class TestBalancedSession(object): def setup(self): locals = RequestLocals() locals.request = Bunch() locals.app_globals = Bunch() locals.config = Bunch({'tg.app_globals':locals.app_globals, 'balanced_engines': {'all':{'master':'master', 'slave1':'slave1', 'slave2':'slave2'}, 'master':'master', 'slaves':{'slave1':'slave1', 'slave2':'slave2'}}}) #Register Global objects request_local.config._push_object(locals.config) request_local.context._push_object(locals) self.locals = locals self.session = BalancedSession() locals.config['DBSession'] = self.session def teardown(self): request_local.config._pop_object() request_local.context._pop_object() def test_disabled_balancing(self): tg.config['balanced_engines'] = None tg.app_globals['sa_engine'] = 'DEFAULT_ENGINE' assert self.session.get_bind() == 'DEFAULT_ENGINE' def test_disabled_balancing_out_of_request(self): request_local.context._pop_object() tg.config['balanced_engines'] = None tg.config['tg.app_globals']['sa_engine'] = 'DEFAULT_ENGINE' assert self.session.get_bind() == 'DEFAULT_ENGINE' request_local.context._push_object(self.locals) def test_master_on_flush(self): self.session._flushing = True assert self.session.get_bind() == 'master' def test_master_out_of_request(self): request_local.context._pop_object() assert self.session.get_bind() == 'master' request_local.context._push_object(self.locals) def test_pick_slave(self): assert self.session.get_bind().startswith('slave') def test_with_context(self): with self.session.using_engine('master'): assert self.session.get_bind() == 'master' assert self.session.get_bind().startswith('slave') def test_forced_engine(self): force_request_engine('slave2') assert self.session.get_bind() == 'slave2' def test_with_explicit_context(self): class FakeThreadedSession: def __init__(self, real_session): self.sess = real_session def __call__(self): return self.sess self.locals.config['DBSession'] = FakeThreadedSession(self.session) with UsingEngineContext('master'): assert self.session.get_bind() == 'master' assert self.session.get_bind().startswith('slave') TurboGears2-2.3.7/tests/test_caching.py0000644000076500000240000004312512607177564020130 0ustar amolstaff00000000000000# -*- coding: utf-8 -*- """ Test cases for TG caching. See: http://turbogears.org/2.1/docs/main/Caching.html For more details. """ import tg from tg.controllers import TGController from tg.decorators import expose, cached from tg.caching import create_cache_key, cached_property, beaker_cache from tg.controllers.util import etag_cache from tg import cache from tests.base import TestWSGIController, make_app, setup_session_dir, teardown_session_dir def setup(): setup_session_dir() def teardown(): teardown_session_dir() # a variable used to represent state held outside the controllers mockdb = {} class MockTime: """ A very simple class to mock the time module. This lets us slide time around to fake expiry in beaker.container. """ mock_time = 0 def time(self): return self.mock_time def set_time(self, v): self.mock_time = v mocktime = MockTime() import beaker.container beaker.container.time = mocktime class TestCachedProperty(object): def setup(self): class FakeObject(object): def __init__(self): self.v = 0 @cached_property def value(self): self.v += 1 return self.v self.FakeObjectClass = FakeObject def test_cached_property(self): o = self.FakeObjectClass() for i in range(10): assert o.value == 1 def test_cached_property_on_class(self): assert isinstance(self.FakeObjectClass.value, cached_property) class SimpleCachingController(TGController): """ Pylons supports a mechanism for arbitrary caches that can be allocated within controllers. Each cache value has a creation function associated with it that is called to retrieve it's results. """ @expose() def simple(self, a): c = cache.get_cache("BasicTGController.index") x = c.get_value(key=a, createfunc=lambda: "cached %s" % a, type="memory", expiretime=3600) return x def createfunc(self): return "cached %s" % mockdb['expiry'] @expose() def expiry(self, a): mockdb['expiry'] = a # inject a value into the context c = cache.get_cache("BasicTGController.index") x = c.get_value(key='test', createfunc=self.createfunc, type="memory", expiretime=100) return x class TestSimpleCaching(TestWSGIController): def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.baseenviron = {} self.app = make_app(SimpleCachingController, self.baseenviron) def test_simple_cache(self): """ test that caches get different results for different cache keys. """ resp = self.app.get('/simple/', params={'a':'foo'}) assert resp.body.decode('ascii') == 'cached foo' resp = self.app.get('/simple/', params={'a':'bar'}) assert resp.body.decode('ascii') == 'cached bar' resp = self.app.get('/simple/', params={'a':'baz'}) assert resp.body.decode('ascii') == 'cached baz' def test_expiry(self): """ test that values expire from a single cache key. """ mocktime.set_time(0) resp = self.app.get('/expiry/', params={'a':'foo1'}) assert resp.body.decode('ascii') == 'cached foo1' mocktime.set_time(1) resp = self.app.get('/expiry/', params={'a':'foo2'}) assert resp.body.decode('ascii') == 'cached foo1' mocktime.set_time(200) # wind clock past expiry resp = self.app.get('/expiry/', params={'a':'foo2'}) assert resp.body.decode('ascii') == 'cached foo2' class DecoratorController(TGController): @cached(expire=100, type='memory') @expose() def simple(self): return "cached %s" % mockdb['DecoratorController.simple'] class TestDecoratorCaching(TestWSGIController): """ Test that the decorators function. """ def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.baseenviron = {} self.app = make_app(DecoratorController, self.baseenviron) def test_simple(self): """ Test expiry of cached results for decorated functions. """ mocktime.set_time(0) mockdb['DecoratorController.simple'] = 'foo1' resp = self.app.get('/simple/') assert resp.body.decode('ascii') == 'cached foo1' mocktime.set_time(1) mockdb['DecoratorController.simple'] = 'foo2' resp = self.app.get('/simple/') assert resp.body.decode('ascii') == 'cached foo1' mocktime.set_time(200) mockdb['DecoratorController.simple'] = 'foo2' resp = self.app.get('/simple/') assert resp.body.decode('ascii') == 'cached foo2' class EtagController(TGController): @expose() def etagged(self, etag): etag_cache(etag) return "bar" class TestEtagCaching(TestWSGIController): """ A simple mechanism is provided to set the etag header for returned results. """ def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.app = make_app(EtagController) def test_etags(self): """ Test that the etag in the response headers is the one we expect. """ resp = self.app.get('/etagged/', params={'etag':'foo'}) assert resp.etag == 'foo', resp.etag resp = self.app.get('/etagged/', params={'etag':'bar'}) assert resp.etag == 'bar', resp.etag def test_304(self): resp = self.app.get('/etagged/', params={'etag':'foo'}, headers={'if-none-match': '"foo"'}) assert "304" in resp.status, resp class SessionTouchController(TGController): @expose() def session_get(self): if tg.session.accessed(): return 'ACCESSED' else: return 'NOTOUCH' class TestSessionTouch(TestWSGIController): def test_prova(self): app = make_app(SessionTouchController, config_options={ 'i18n.no_session_touch': False, 'i18n.enabled': True }) assert 'ACCESSED' in app.get('/session_get') def test_avoid_touch(self): app = make_app(SessionTouchController, config_options={ 'i18n.no_session_touch': True, 'i18n.enabled': True }) assert 'NOTOUCH' in app.get('/session_get') class CustomSessionController(TGController): @expose('json') def session_init(self): tg.session['counter'] = 0 tg.session.save() get_session = tg.request.environ['beaker.get_session'] other_sess = get_session() other_sess['counter'] = 0 other_sess.save() return dict(session_id=other_sess.id) @expose('json') def session_get(self, session_id): tg.session['counter'] -= 1 tg.session.save() get_session = tg.request.environ['beaker.get_session'] other_sess = get_session(session_id) other_sess['counter'] +=1 other_sess.save() return dict(tg_session_counter=tg.session['counter'], other_session_counter=other_sess['counter']) class TestMultipleSessions(TestWSGIController): def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.app = make_app(CustomSessionController, config_options={ 'session.key': 'test_app' }) def test_multiple_sessions_work(self): resp = self.app.get('/session_init') session_id = resp.json['session_id'] counters = self.app.get('/session_get', dict(session_id=session_id)).json assert counters['tg_session_counter'] == -1, counters assert counters['other_session_counter'] == 1, counters counters = self.app.get('/session_get', dict(session_id=session_id)).json assert counters['tg_session_counter'] == -2, counters assert counters['other_session_counter'] == 2, counters def disable_cache(wrapped): def wrapper(*args, **kws): tg.config['cache.enabled'] = False x = wrapped(*args, **kws) tg.config['cache.enabled'] = True return x return wrapper class CachedController(TGController): CALL_COUNT = 0 @expose() @cached(key=None) def none_key(self): CachedController.CALL_COUNT += 1 return 'Counter=%s' % CachedController.CALL_COUNT @expose() @cached() def no_options(self): CachedController.CALL_COUNT += 1 return 'Counter=%s' % CachedController.CALL_COUNT @expose() @cached(key='arg') def specified_cache_key(self, arg): CachedController.CALL_COUNT += 1 return 'Counter=%s' % CachedController.CALL_COUNT @expose() @cached(key=['arg1', 'arg2']) def specified_cache_key_args(self, arg1, arg2): CachedController.CALL_COUNT += 1 return 'Counter=%s' % CachedController.CALL_COUNT @expose() @cached(query_args=True) def cache_with_args(self, arg): CachedController.CALL_COUNT += 1 return 'Counter=%s' % CachedController.CALL_COUNT @expose() @disable_cache @cached() def disabled_cache(self): CachedController.CALL_COUNT += 1 return 'Counter=%s' % CachedController.CALL_COUNT @expose() @cached(invalidate_on_startup=True) def invalidate_on_startup(self): CachedController.CALL_COUNT += 1 return 'Counter=%s' % CachedController.CALL_COUNT @expose() def clear_cache(self): curcache = tg.cache.get_cache('tests.test_caching.CachedController') curcache.clear() return '' @expose() @cached() def req_cache_key(self, arg=None): return '%s ~ %s' % (tg.request.caching.namespace, tg.request.caching.key) class BeakerCacheController(TGController): # For backward compatibility CALL_COUNT = 0 @expose() @beaker_cache(key=None) def none_key(self): BeakerCacheController.CALL_COUNT += 1 return 'Counter=%s' % BeakerCacheController.CALL_COUNT @expose() @beaker_cache() def no_options(self): BeakerCacheController.CALL_COUNT += 1 return 'Counter=%s' % BeakerCacheController.CALL_COUNT @expose() @beaker_cache(key='arg') def specified_cache_key(self, arg): BeakerCacheController.CALL_COUNT += 1 return 'Counter=%s' % BeakerCacheController.CALL_COUNT @expose() @beaker_cache(key=['arg1', 'arg2']) def specified_cache_key_args(self, arg1, arg2): BeakerCacheController.CALL_COUNT += 1 return 'Counter=%s' % BeakerCacheController.CALL_COUNT @expose() @beaker_cache(query_args=True) def cache_with_args(self, arg): BeakerCacheController.CALL_COUNT += 1 return 'Counter=%s' % BeakerCacheController.CALL_COUNT @expose() @disable_cache @beaker_cache() def disabled_cache(self): BeakerCacheController.CALL_COUNT += 1 return 'Counter=%s' % BeakerCacheController.CALL_COUNT @expose() @beaker_cache(invalidate_on_startup=True) def invalidate_on_startup(self): BeakerCacheController.CALL_COUNT += 1 return 'Counter=%s' % BeakerCacheController.CALL_COUNT class TestCacheTouch(TestWSGIController): CACHED_CONTROLLER = CachedController def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.app = make_app(self.CACHED_CONTROLLER) def setUp(self): super(TestCacheTouch, self).setUp() self.app.get('/clear_cache') def test_none_key(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/none_key') assert 'Counter=1' in r r = self.app.get('/none_key') assert 'Counter=1' in r def test_invalidate_on_startup(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/invalidate_on_startup') assert 'Counter=1' in r r = self.app.get('/invalidate_on_startup') assert 'Counter=2' in r def test_no_options(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/no_options') assert 'Counter=1' in r r = self.app.get('/no_options') assert 'Counter=1' in r def test_specified_cache_key(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/specified_cache_key?arg=0') assert 'Counter=1' in r r = self.app.get('/specified_cache_key?arg=x') assert 'Counter=2' in r r = self.app.get('/specified_cache_key?arg=x') assert 'Counter=2' in r r = self.app.get('/specified_cache_key/x') assert 'Counter=2' in r def test_specified_cache_key_args(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/specified_cache_key_args?arg1=x&arg2=y') assert 'Counter=1' in r r = self.app.get('/specified_cache_key_args?arg1=x&arg2=y') assert 'Counter=1' in r r = self.app.get('/specified_cache_key_args?arg1=x&arg2=z') assert 'Counter=2' in r r = self.app.get('/specified_cache_key_args/x/y') assert 'Counter=1' in r def test_cache_with_args(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/cache_with_args?arg=x') assert 'Counter=1' in r, r r = self.app.get('/cache_with_args?arg=x') assert 'Counter=1' in r, r r = self.app.get('/cache_with_args/x') assert 'Counter=1' in r def test_different_cache_key(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/specified_cache_key?arg=x') assert 'Counter=1' in r r = self.app.get('/specified_cache_key?arg=y') assert 'Counter=2' in r r = self.app.get('/specified_cache_key/z') assert 'Counter=3' in r def test_request_caching_info(self): r = self.app.get('/req_cache_key') assert 'tests.test_caching.CachedController ~ req_cache_key' in r r = self.app.get('/req_cache_key?arg=5') assert 'tests.test_caching.CachedController ~ req_cache_key arg=5' in r def test_cache_key_instance_method(self): class Something(object): def method(self, arg): return arg o = Something() namespace, key = create_cache_key(o.method) assert namespace == 'tests.test_caching.Something' assert key == 'method' def test_cache_key_function(self): def method(self, arg): return arg namespace, key = create_cache_key(method) assert namespace == 'tests.test_caching' assert key == 'method' def test_disable_cache(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/disabled_cache') assert 'Counter=1' in r r = self.app.get('/disabled_cache') assert 'Counter=2' in r class TestBeakerCacheTouch(TestWSGIController): CACHED_CONTROLLER = BeakerCacheController def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.app = make_app(self.CACHED_CONTROLLER) def test_none_key(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/none_key') assert 'Counter=1' in r r = self.app.get('/none_key') assert 'Counter=1' in r def test_invalidate_on_startup(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/invalidate_on_startup') assert 'Counter=1' in r r = self.app.get('/invalidate_on_startup') assert 'Counter=2' in r def test_no_options(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/no_options') assert 'Counter=1' in r r = self.app.get('/no_options') assert 'Counter=1' in r def test_specified_cache_key(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/specified_cache_key?arg=x') assert 'Counter=1' in r r = self.app.get('/specified_cache_key?arg=x') assert 'Counter=1' in r def test_specified_cache_key_args(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/specified_cache_key_args?arg1=x&arg2=y') assert 'Counter=1' in r r = self.app.get('/specified_cache_key_args?arg1=x&arg2=y') assert 'Counter=1' in r r = self.app.get('/specified_cache_key_args?arg1=x&arg2=z') assert 'Counter=2' in r def test_cache_with_args(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/cache_with_args?arg=x') assert 'Counter=1' in r, r r = self.app.get('/cache_with_args?arg=x') assert 'Counter=1' in r, r def test_different_cache_key(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/specified_cache_key?arg=x') assert 'Counter=1' in r r = self.app.get('/specified_cache_key?arg=y') assert 'Counter=2' in r def test_cache_key_instance_method(self): class Something(object): def method(self, arg): return arg o = Something() namespace, key = create_cache_key(o.method) assert namespace == 'tests.test_caching.Something' assert key == 'method' def test_cache_key_function(self): def method(self, arg): return arg namespace, key = create_cache_key(method) assert namespace == 'tests.test_caching' assert key == 'method' def test_disable_cache(self): self.CACHED_CONTROLLER.CALL_COUNT = 0 r = self.app.get('/disabled_cache') assert 'Counter=1' in r r = self.app.get('/disabled_cache') assert 'Counter=2' in r TurboGears2-2.3.7/tests/test_config_milestones.py0000644000076500000240000000617312413576166022241 0ustar amolstaff00000000000000from nose.tools import raises from tg._compat import im_self from tg.configuration.milestones import _ConfigMilestoneTracker, config_ready from tg.configuration.utils import GlobalConfigurable, TGConfigError class Action: called = 0 def __call__(self): self.called += 1 class TestMilestones(object): def setup(self): self.milestone = _ConfigMilestoneTracker('test_milestone') def test_multiple_registration(self): a = Action() self.milestone.register(a) self.milestone.register(a) self.milestone.register(a) self.milestone.reach() assert a.called == 1 def test_register_after_reach(self): a = Action() self.milestone.reach() self.milestone.register(a) assert a.called == 1 def test_call_all(self): a = Action() a2 = Action() a3 = Action() self.milestone.register(a) self.milestone.register(a2) self.milestone.register(a3) self.milestone.reach() assert a.called == a2.called == a3.called == 1 def test_register_func_unique(self): called = [] def f(): called.append(True) self.milestone.register(f) self.milestone.register(f) self.milestone.reach() assert len(called) == 1 class TemporaryGlobalConfigurable(GlobalConfigurable): pass class TestGlobalConfigurable(object): def setup(self): config_ready._reset() def teardown(self): for action in config_ready._keep_on_reset[:]: default_object = im_self(action) if default_object and isinstance(default_object, TemporaryGlobalConfigurable): config_ready._keep_on_reset.remove(action) config_ready._reset() @raises(NotImplementedError) def test_requires_configure_implementation(self): class NoConfig(TemporaryGlobalConfigurable): CONFIG_NAMESPACE = 'fake.' default_object = NoConfig.create_global() config_ready.reach() @raises(TGConfigError) def test_requires_namespace(self): class NoNameSpace(TemporaryGlobalConfigurable): def configure(self, **options): return options default_object = NoNameSpace.create_global() config_ready.reach() def test_gets_configured_on_config_ready(self): class Configurable(TemporaryGlobalConfigurable): CONFIG_NAMESPACE = 'fake.' _CONFIGURED = [] def configure(self, **options): self._CONFIGURED.append(True) default_object = Configurable.create_global() config_ready.reach() assert len(Configurable._CONFIGURED) == 1 def test_keeps_on_milestone_reset(self): class Configurable(TemporaryGlobalConfigurable): CONFIG_NAMESPACE = 'fake.' _CONFIGURED = [] def configure(self, **options): self._CONFIGURED.append(True) default_object = Configurable.create_global() config_ready.reach() config_ready._reset() config_ready.reach() assert len(Configurable._CONFIGURED) == 2TurboGears2-2.3.7/tests/test_configuration.py0000644000076500000240000022425612607177564021411 0ustar amolstaff00000000000000""" Testing for TG2 Configuration """ from nose import SkipTest from nose.tools import eq_, raises import atexit, sys, os from datetime import datetime from sqlalchemy.orm import scoped_session from sqlalchemy.orm import sessionmaker from ming import Session from ming.orm import ThreadLocalORMSession from tg.configuration.hooks import _TGGlobalHooksNamespace from tg.appwrappers.errorpage import ErrorPageApplicationWrapper from tg.appwrappers.mingflush import MingApplicationWrapper from tg.appwrappers.transaction_manager import TransactionApplicationWrapper from tg.util import Bunch from tg.configuration import AppConfig, config from tg.configuration.app_config import TGConfigError, defaults as app_config_defaults from tg.configuration.auth import _AuthenticationForgerPlugin from tg.configuration.auth.metadata import _AuthMetadataAuthenticator from tg.configuration.utils import coerce_config, coerce_options from tg.configuration import milestones from tg.support.converters import asint, asbool import tg.i18n from tg import TGController, expose, response, request, abort from tests.base import setup_session_dir, teardown_session_dir from webtest import TestApp from tg.renderers.base import RendererFactory from tg.wsgiapp import TGApp from tg._compat import PY3 def setup(): milestones._reset_all() setup_session_dir() def teardown(): milestones._reset_all() teardown_session_dir() class PackageWithModel: __name__ = 'tests' __file__ = __file__ def __init__(self): self.model = self.ModelClass() self.model.DBSession = self.model.FakeDBSession() class ModelClass: class FakeDBSession: def remove(self): self.DBSESSION_REMOVED=True @classmethod def init_model(package, engine): pass class lib: class app_globals: class Globals: pass PackageWithModel.__name__ = 'tests' class UncopiableList(list): """ This is to test configuration methods that make a copy of a list to modify it, using this we can check how it has been modified """ def __copy__(self): return self class FakeTransaction: def get(self): return self def begin(self): self.aborted = False self.doomed = False def abort(self): self.aborted = True def commit(self): self.aborted = False def _retryable(self, *args): return True note = _retryable def isDoomed(self): return self.doomed def doom(self): self.doomed = True from tg.configuration.auth import TGAuthMetadata class ApplicationAuthMetadata(TGAuthMetadata): def get_user(self, identity, userid): return {'name':'None'} class ApplicationAuthMetadataWithAuthentication(TGAuthMetadata): def authenticate(self, environ, identity): return 1 def get_user(self, identity, userid): return {'name':'None'} class AtExitTestException(Exception): pass class TestPylonsConfigWrapper: def setup(self): self.config = config def test_create(self): pass def test_getitem(self): expected_keys = ['global_conf', 'use_sqlalchemy', 'package', 'tg.app_globals', 'call_on_shutdown'] for key in expected_keys: self.config[key] @raises(KeyError) def test_getitem_bad(self): self.config['no_such_key'] def test_setitem(self): self.config['no_such_key'] = 'something' def test_delattr(self): del self.config.use_sqlalchemy eq_(hasattr(self.config, 'use_sqlalchemy'), False) self.config.use_sqlalchemy = True @raises(AttributeError) def test_delattr_bad(self): del self.config.i_dont_exist def test_keys(self): k = self.config.keys() assert 'tg.app_globals' in k def test_coerce_config(): opts = {'ming.connection.max_pool_size': '5'} conf = coerce_config(opts, 'ming.connection.', {'max_pool_size':asint}) assert conf['max_pool_size'] == 5 assert opts['ming.connection.max_pool_size'] == '5' def test_coerce_options(): opts = {'connection': 'false'} conf = coerce_options(opts, {'connection': asbool}) assert conf['connection'] is False assert opts['connection'] == 'false' class TestAppConfig: def __init__(self): self.fake_package = PackageWithModel def setup(self): milestones._reset_all() self.config = AppConfig() # set up some required paths and config settings # FIXME: these seem to be needed so that # other tests don't suffer - but that's a nasty # side-effect. setup for those tests actually needs # fixing. self.config['package'] = self.fake_package self.config['paths']['root'] = 'test' self.config['paths']['controllers'] = 'test.controllers' self.config['paths']['static_files'] = "test" self.config["tg.app_globals"] = Bunch() self.config["use_sqlalchemy"] = False self.config["global_conf"] = Bunch() self.config["render_functions"] = Bunch() self.config['session.secret'] = 'some_secret' self.config._init_config({'cache_dir':'/tmp'}, {}) def teardown(self): #This is here to avoid that other tests keep using the forced controller config.pop('tg.root_controller', None) milestones._reset_all() tg.hooks = _TGGlobalHooksNamespace() # Reset hooks def test_get_root(self): current_root_module = self.config['paths']['root'] assert self.config._get_root_module() == 'tests.controllers.root', self.config._get_root_module() self.config['paths']['root'] = None assert self.config._get_root_module() == None, self.config._get_root_module() self.config['paths']['root'] = current_root_module def test_lang_can_be_changed_by_ini(self): conf = AppConfig(minimal=True) conf._init_config({'lang':'ru'}, {}) assert config['lang'] == 'ru' def test_create_minimal_app(self): class RootController(TGController): @expose() def test(self): return 'HI!' conf = AppConfig(minimal=True, root_controller=RootController()) app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') #This is here to avoid that other tests keep using the forced controller config.pop('tg.root_controller') def test_minimal_app_with_sqlalchemy(self): class RootController(TGController): @expose() def test(self): return 'HI!' DBSession = scoped_session(sessionmaker(autoflush=True, autocommit=False)) def init_model(engine): DBSession.configure(bind=engine) conf = AppConfig(minimal=True, root_controller=RootController()) conf['use_sqlalchemy'] = True conf['sqlalchemy.url'] = 'sqlite://' conf['model'] = Bunch(DBSession=DBSession, init_model=init_model) app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') @raises(TGConfigError) def test_sqlalchemy_without_models(self): class RootController(TGController): @expose() def test(self): return 'HI!' conf = AppConfig(minimal=True, root_controller=RootController()) conf['use_sqlalchemy'] = True conf['sqlalchemy.url'] = 'sqlite://' app = conf.make_wsgi_app() def test_minimal_app_with_ming(self): class RootController(TGController): @expose() def test(self): return 'HI!' mainsession = Session() DBSession = ThreadLocalORMSession(mainsession) def init_model(engine): mainsession.bind = engine conf = AppConfig(minimal=True, root_controller=RootController()) conf['use_ming'] = True conf['ming.url'] = 'mim://' conf['model'] = Bunch(init_model=init_model, DBSession=DBSession) app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') @raises(TGConfigError) def test_ming_without_models(self): class RootController(TGController): @expose() def test(self): return 'HI!' DBSession = scoped_session(sessionmaker(autoflush=True, autocommit=False)) def init_model(engine): DBSession.configure(bind=engine) conf = AppConfig(minimal=True, root_controller=RootController()) conf['use_ming'] = True conf['ming.url'] = 'mim://' app = conf.make_wsgi_app() def test_enable_routes(self): conf = AppConfig(minimal=True) conf.enable_routes = True app = conf.make_wsgi_app() a = TGApp() assert a.enable_routes == True config.pop('routes.map') config.pop('enable_routes') def test_create(self): pass def test_setup_helpers_and_globals(self): self.config.setup_helpers_and_globals() def test_setup_sa_auth_backend(self): class ConfigWithSetupAuthBackend(self.config.__class__): called = [] def setup_sa_auth_backend(self): self.called.append(True) conf = ConfigWithSetupAuthBackend() conf.setup_auth() assert len(ConfigWithSetupAuthBackend.called) >= 1 def test_setup_jinja_without_package(self): class RootController(TGController): @expose() def test(self): return 'HI!' conf = AppConfig(minimal=True, root_controller=RootController()) conf.renderers = ['jinja'] app = conf.make_wsgi_app() def test_setup_sqlalchemy(self): class RootController(TGController): @expose() def test(self): return 'HI!' package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_sqlalchemy = True conf['sqlalchemy.url'] = 'sqlite://' app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') assert package.model.DBSession.DBSESSION_REMOVED def test_custom_transaction_manager(self): class CustomAppConfig(AppConfig): def add_tm_middleware(self, app): self.did_perform_custom_tm = True return app class RootController(TGController): @expose() def test(self): return 'HI!' package = PackageWithModel() conf = CustomAppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_sqlalchemy = True conf.use_transaction_manager = True conf['sqlalchemy.url'] = 'sqlite://' app = conf.make_wsgi_app() # Check the custom manager got configured assert conf.did_perform_custom_tm == True # The transaction manager wrapper should not have been enabled. tgapp = TGApp() wrapper = tgapp.wrapped_dispatch while wrapper != tgapp.dispatch: assert not isinstance(wrapper, TransactionApplicationWrapper) wrapper = wrapper.next_handler def test_sqlalchemy_commit_veto(self): class RootController(TGController): @expose() def test(self): return 'HI!' @expose() def crash(self): raise Exception('crash') @expose() def forbidden(self): response.status = 403 return 'FORBIDDEN' @expose() def notfound(self): response.status = 404 return 'NOTFOUND' def custom_commit_veto(environ, status, headers): if status.startswith('404'): return True return False fake_transaction = FakeTransaction() import transaction prev_transaction_manager = transaction.manager transaction.manager = fake_transaction package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_sqlalchemy = True conf['tm.enabled'] = True conf['tm.commit_veto'] = custom_commit_veto conf['sqlalchemy.url'] = 'sqlite://' app = conf.make_wsgi_app() app = TestApp(app) assert hasattr(conf, 'use_transaction_manager') is False app.get('/test') assert fake_transaction.aborted == False try: app.get('/crash') except: pass assert fake_transaction.aborted == True app.get('/forbidden', status=403) assert fake_transaction.aborted == False app.get('/notfound', status=404) assert fake_transaction.aborted == True transaction.manager = prev_transaction_manager def test_sqlalchemy_doom(self): fake_transaction = FakeTransaction() import transaction prev_transaction_manager = transaction.manager transaction.manager = fake_transaction class RootController(TGController): @expose() def test(self): fake_transaction.doom() return 'HI!' package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_sqlalchemy = True conf['tm.enabled'] = True conf['sqlalchemy.url'] = 'sqlite://' app = conf.make_wsgi_app() app = TestApp(app) assert hasattr(conf, 'use_transaction_manager') is False app.get('/test') assert fake_transaction.aborted == True transaction.manager = prev_transaction_manager def test_sqlalchemy_retry(self): fake_transaction = FakeTransaction() import transaction prev_transaction_manager = transaction.manager transaction.manager = fake_transaction from transaction.interfaces import TransientError class RootController(TGController): attempts = [] @expose() def test(self): self.attempts.append(True) if len(self.attempts) == 3: return 'HI!' raise TransientError() package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_sqlalchemy = True conf['tm.enabled'] = True conf['sqlalchemy.url'] = 'sqlite://' conf['tm.attempts'] = 3 app = conf.make_wsgi_app() app = TestApp(app) assert hasattr(conf, 'use_transaction_manager') is False resp = app.get('/test') assert 'HI' in resp transaction.manager = prev_transaction_manager def test_old_sqlalchemy_commit_veto(self): class RootController(TGController): @expose() def test(self): return 'HI!' @expose() def crash(self): raise Exception('crash') @expose() def forbidden(self): response.status = 403 return 'FORBIDDEN' @expose() def notfound(self): response.status = 404 return 'NOTFOUND' def custom_commit_veto(environ, status, headers): if status.startswith('404'): return True return False fake_transaction = FakeTransaction() import transaction prev_transaction_manager = transaction.manager transaction.manager = fake_transaction package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_sqlalchemy = True conf.use_transaction_manager = True conf['sqlalchemy.url'] = 'sqlite://' conf.commit_veto = custom_commit_veto app = conf.make_wsgi_app() app = TestApp(app) app.get('/test') assert fake_transaction.aborted == False try: app.get('/crash') except: pass assert fake_transaction.aborted == True app.get('/forbidden', status=403) assert fake_transaction.aborted == False app.get('/notfound', status=404) assert fake_transaction.aborted == True transaction.manager = prev_transaction_manager def test_old_sqlalchemy_doom(self): fake_transaction = FakeTransaction() import transaction prev_transaction_manager = transaction.manager transaction.manager = fake_transaction class RootController(TGController): @expose() def test(self): fake_transaction.doom() return 'HI!' package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_sqlalchemy = True conf.use_transaction_manager = True conf['sqlalchemy.url'] = 'sqlite://' app = conf.make_wsgi_app() app = TestApp(app) app.get('/test') assert fake_transaction.aborted == True transaction.manager = prev_transaction_manager def test_old_sqlalchemy_retry(self): fake_transaction = FakeTransaction() import transaction prev_transaction_manager = transaction.manager transaction.manager = fake_transaction from transaction.interfaces import TransientError class RootController(TGController): attempts = [] @expose() def test(self): self.attempts.append(True) if len(self.attempts) == 3: return 'HI!' raise TransientError() package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_sqlalchemy = True conf.use_transaction_manager = True conf['sqlalchemy.url'] = 'sqlite://' conf['tm.attempts'] = 3 app = conf.make_wsgi_app() app = TestApp(app) resp = app.get('/test') assert 'HI' in resp transaction.manager = prev_transaction_manager def test_old_sqlalchemy_is_disabled_when_missing(self): class RootController(TGController): @expose() def test(self): return 'HI!' package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_sqlalchemy = False conf.use_transaction_manager = True app = conf.make_wsgi_app() assert conf.use_transaction_manager is False def test_setup_sqla_persistance(self): config['sqlalchemy.url'] = 'sqlite://' self.config.use_sqlalchemy = True self.config.package = PackageWithModel() self.config.setup_persistence() self.config.use_sqlalchemy = False def test_setup_sqla_balanced(self): config['sqlalchemy.master.url'] = 'sqlite://' config['sqlalchemy.slaves.slave1.url'] = 'sqlite://' self.config.use_sqlalchemy = True self.config.package = PackageWithModel() self.config.setup_persistence() self.config.use_sqlalchemy = False config.pop('sqlalchemy.master.url') config.pop('sqlalchemy.slaves.slave1.url') @raises(TGConfigError) def test_setup_sqla_balanced_prevent_slave_named_master(self): config['sqlalchemy.master.url'] = 'sqlite://' config['sqlalchemy.slaves.master.url'] = 'sqlite://' self.config.use_sqlalchemy = True self.config.package = PackageWithModel() try: self.config.setup_persistence() except: raise finally: self.config.use_sqlalchemy = False config.pop('sqlalchemy.master.url') config.pop('sqlalchemy.slaves.master.url') @raises(TGConfigError) def test_setup_sqla_balanced_no_slaves(self): config['sqlalchemy.master.url'] = 'sqlite://' self.config.use_sqlalchemy = True self.config.package = PackageWithModel() try: self.config.setup_persistence() except: raise finally: self.config.use_sqlalchemy = False config.pop('sqlalchemy.master.url') def test_setup_ming_persistance(self): class RootController(TGController): @expose() def test(self): return 'HI!' package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_ming = True conf['ming.url'] = 'mim://' conf['ming.db'] = 'inmemdb' app = conf.make_wsgi_app() tgapp = app.application while not isinstance(tgapp, TGApp): tgapp = tgapp.app ming_handler = tgapp.wrapped_dispatch while ming_handler != tgapp.dispatch: if isinstance(ming_handler, MingApplicationWrapper): break ming_handler = ming_handler.next_handler assert isinstance(ming_handler, MingApplicationWrapper), ming_handler class FakeMingSession(object): actions = [] def flush_all(self): self.actions.append('FLUSH') def close_all(self): self.actions.append('CLOSE') ming_handler.ThreadLocalODMSession = FakeMingSession() app = TestApp(app) resp = app.get('/test') assert 'HI' in resp assert ming_handler.ThreadLocalODMSession.actions == ['FLUSH'] def test_setup_ming_persistance_closes_on_failure(self): class RootController(TGController): @expose() def test(self): raise Exception('CRASH!') package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_ming = True conf['ming.url'] = 'mim://' conf['ming.db'] = 'inmemdb' app = conf.make_wsgi_app() tgapp = app.application while not isinstance(tgapp, TGApp): tgapp = tgapp.app ming_handler = tgapp.wrapped_dispatch while ming_handler != tgapp.dispatch: if isinstance(ming_handler, MingApplicationWrapper): break ming_handler = ming_handler.next_handler assert isinstance(ming_handler, MingApplicationWrapper), ming_handler class FakeMingSession(object): actions = [] def flush_all(self): self.actions.append('FLUSH') def close_all(self): self.actions.append('CLOSE') ming_handler.ThreadLocalODMSession = FakeMingSession() app = TestApp(app) try: app.get('/test', status=500) except: assert ming_handler.ThreadLocalODMSession.actions == ['CLOSE'] else: assert False, 'Should have raised exception' def test_setup_ming_persistance_with_url_alone(self): package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=None) conf.package = package conf.model = package.model conf.use_ming = True conf['ming.url'] = 'mim://inmemdb' app = conf.make_wsgi_app() assert app is not None dstore = config['tg.app_globals'].ming_datastore dstore_name = dstore.name # Looks like ming has empty dstore.name when using MIM. assert dstore_name == '', dstore def test_setup_ming_persistance_with_url_and_db(self): package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=None) conf.package = package conf.model = package.model conf.use_ming = True conf['ming.url'] = 'mim://inmemdb' conf['ming.db'] = 'realinmemdb' app = conf.make_wsgi_app() assert app is not None dstore = config['tg.app_globals'].ming_datastore dstore_name = dstore.name assert dstore_name == 'realinmemdb', dstore def test_setup_ming_persistance_advanced_options(self): package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=None) conf.package = package conf.model = package.model conf.use_ming = True conf['ming.url'] = 'mim://inmemdb' conf['ming.connection.read_preference'] = 'PRIMARY' app = conf.make_wsgi_app() assert app is not None def test_setup_ming_persistance_replica_set(self): if sys.version_info[:2] == (2, 6): raise SkipTest() package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=None) conf.package = package conf.model = package.model conf.use_ming = True conf['ming.url'] = 'mongodb://localhost:27017,localhost:27018/testdb?replicaSet=test' conf['ming.db'] = '' app = conf.make_wsgi_app() assert app is not None expected_url = 'mongodb://localhost:27017,localhost:27018/?replicaSet=test' expected_db = 'testdb' dstore = config['tg.app_globals'].ming_datastore assert expected_db == dstore.name, dstore.name assert expected_url == dstore.bind._conn_args[0], dstore.bind._conn_args def test_setup_mig_persistance_replica_set_option(self): package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=None) conf.package = package conf.model = package.model conf.use_ming = True conf['ming.url'] = 'mongodb://localhost:27017,localhost:27018/testdb' conf['ming.connection.replicaSet'] = 'test' conf['ming.db'] = '' app = conf.make_wsgi_app() assert app is not None expected_url = 'mongodb://localhost:27017,localhost:27018/' expected_db = 'testdb' dstore = config['tg.app_globals'].ming_datastore assert expected_db == dstore.name, dstore.name assert expected_url == dstore.bind._conn_args[0], dstore.bind._conn_args assert 'test' == dstore.bind._conn_kwargs.get('replicaSet'), dstore.bind._conn_kwargs def test_add_auth_middleware(self): class Dummy:pass self.config.sa_auth.dbsession = Dummy() self.config.sa_auth.user_class = Dummy self.config.sa_auth.group_class = Dummy self.config.sa_auth.permission_class = Dummy self.config.sa_auth.cookie_secret = 'dummy' self.config.sa_auth.password_encryption_method = 'sha' self.config.setup_auth() self.config.add_auth_middleware(None, None) def test_add_static_file_middleware(self): self.config.add_static_file_middleware(None) def test_setup_sqla_auth(self): if PY3: raise SkipTest() class RootController(TGController): @expose() def test(self): return str(request.environ) package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.use_sqlalchemy = True conf.auth_backend = 'sqlalchemy' conf['sa_auth'] = {'authmetadata': ApplicationAuthMetadata(), 'dbsession': None, 'user_class': None, 'cookie_secret': '12345'} conf['sqlalchemy.url'] = 'sqlite://' app = conf.make_wsgi_app() app = TestApp(app) resp = app.get('/test') assert 'repoze.who.plugins' in resp, resp self.config.auth_backend = None def test_setup_ming_auth(self): self.config.auth_backend = 'ming' self.config.setup_auth() assert 'sa_auth' in config self.config.auth_backend = None def test_deprecated_register_hooks(self): def dummy(*args): pass milestones.config_ready._reset() milestones.environment_loaded._reset() self.config.register_hook('startup', dummy) self.config.register_hook('shutdown', dummy) self.config.register_hook('controller_wrapper', dummy) for hook_name in ('before_validate', 'before_call', 'before_render', 'after_render', 'before_render_call', 'after_render_call', 'before_config', 'after_config'): self.config.register_hook(hook_name, dummy) milestones.config_ready.reach() milestones.environment_loaded.reach() for hooks in ('before_validate', 'before_call', 'before_render', 'after_render', 'before_render_call', 'after_render_call', 'before_config', 'after_config', 'startup', 'shutdown'): assert tg.hooks._hooks[hooks] assert self.config.controller_wrappers @raises(TGConfigError) def test_missing_secret(self): self.config.auth_backend = 'sqlalchemy' config.pop('session.secret', None) self.config.setup_auth() def test_sessions_enabled(self): class RootController(TGController): @expose('json') def test(self): try: tg.session['counter'] += 1 except KeyError: tg.session['counter'] = 0 tg.session.save() return dict(counter=tg.session['counter']) conf = AppConfig(minimal=True, root_controller=RootController()) conf['session.enabled'] = True app = conf.make_wsgi_app() app = TestApp(app) resp = app.get('/test') assert resp.json['counter'] == 0, resp resp = app.get('/test') assert resp.json['counter'] == 1, resp def test_backware_compatible_sessions_enabled(self): class RootController(TGController): @expose('json') def test(self): try: tg.session['counter'] += 1 except KeyError: tg.session['counter'] = 0 tg.session.save() return dict(counter=tg.session['counter']) conf = AppConfig(minimal=True, root_controller=RootController()) conf['session.enabled'] = False conf['use_session_middleware'] = True app = conf.make_wsgi_app() app = TestApp(app) resp = app.get('/test') assert resp.json['counter'] == 0, resp resp = app.get('/test') assert resp.json['counter'] == 1, resp def test_caching_enabled(self): class RootController(TGController): @expose('json') def test(self): cache = tg.cache.get_cache('test_caching_enabled') now = cache.get_value('test_cache_key', createfunc=datetime.utcnow) return dict(now=now) conf = AppConfig(minimal=True, root_controller=RootController()) conf['cache.enabled'] = True app = conf.make_wsgi_app() app = TestApp(app) resp = app.get('/test') now = resp.json['now'] for x in range(20): resp = app.get('/test') assert resp.json['now'] == now, (resp, now) def test_backward_compatible_caching_enabled(self): class RootController(TGController): @expose('json') def test(self): cache = tg.cache.get_cache('test_caching_enabled') now = cache.get_value('test_cache_key', createfunc=datetime.utcnow) return dict(now=now) conf = AppConfig(minimal=True, root_controller=RootController()) conf['cache.enabled'] = False conf['use_cache_middleware'] = True app = conf.make_wsgi_app() app = TestApp(app) resp = app.get('/test') now = resp.json['now'] for x in range(20): resp = app.get('/test') assert resp.json['now'] == now, (resp, now) def test_controler_wrapper_setup(self): orig_caller = self.config.controller_caller self.config.controller_wrappers = [] self.config._setup_controller_wrappers() assert config['controller_caller'] == orig_caller def controller_wrapper(caller): def call(*args, **kw): return caller(*args, **kw) return call orig_caller = self.config.controller_caller self.config.controller_wrappers = [controller_wrapper] self.config._setup_controller_wrappers() assert config['controller_caller'].__name__ == controller_wrapper(orig_caller).__name__ def test_backward_compatible_controler_wrapper_setup(self): orig_caller = self.config.controller_caller self.config.controller_wrappers = [] self.config._setup_controller_wrappers() assert config['controller_caller'] == orig_caller def controller_wrapper(app_config, caller): def call(*args, **kw): return caller(*args, **kw) return call orig_caller = self.config.controller_caller self.config.controller_wrappers = [controller_wrapper] self.config._setup_controller_wrappers() deprecated_wrapper = config['controller_caller'].wrapper assert deprecated_wrapper.__name__ == controller_wrapper(self.config, orig_caller).__name__ def test_global_controller_wrapper(self): milestones._reset_all() class RootController(TGController): @expose() def test(self): return 'HI!' wrapper_has_been_visited = [] def controller_wrapper(caller): def call(*args, **kw): wrapper_has_been_visited.append(True) return caller(*args, **kw) return call conf = AppConfig(minimal=True, root_controller=RootController()) conf.register_hook('controller_wrapper', controller_wrapper) conf.package = PackageWithModel() app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') assert wrapper_has_been_visited[0] is True def test_backward_compatible_global_controller_wrapper(self): milestones._reset_all() class RootController(TGController): @expose() def test(self): return 'HI!' wrapper_has_been_visited = [] def controller_wrapper(app_config, caller): def call(*args, **kw): wrapper_has_been_visited.append(True) return caller(*args, **kw) return call def controller_wrapper2(app_config, caller): def call(controller, remainder, params): wrapper_has_been_visited.append(True) return caller(controller, remainder, params) return call def controller_wrapper3(caller): def call(config, controller, remainder, params): wrapper_has_been_visited.append(True) return caller(config, controller, remainder, params) return call conf = AppConfig(minimal=True, root_controller=RootController()) conf.register_hook('controller_wrapper', controller_wrapper2) conf.register_hook('controller_wrapper', controller_wrapper3) conf.register_hook('controller_wrapper', controller_wrapper) conf.package = PackageWithModel() app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') assert len(wrapper_has_been_visited) == 3 def test_dedicated_controller_wrapper(self): milestones._reset_all() class RootController(TGController): @expose() def test(self): return 'HI!' wrapper_has_been_visited = [] def controller_wrapper(caller): def call(*args, **kw): wrapper_has_been_visited.append(True) return caller(*args, **kw) return call conf = AppConfig(minimal=True, root_controller=RootController()) conf.register_controller_wrapper(controller_wrapper, controller=RootController.test) conf.package = PackageWithModel() app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') assert wrapper_has_been_visited[0] is True def test_dedicated_controller_wrapper_old(self): milestones._reset_all() class RootController(TGController): @expose() def test(self): return 'HI!' wrapper_has_been_visited = [] def controller_wrapper(caller): def call(*args, **kw): wrapper_has_been_visited.append(True) return caller(*args, **kw) return call conf = AppConfig(minimal=True, root_controller=RootController()) tg.hooks.wrap_controller(controller_wrapper, controller=RootController.test) conf.package = PackageWithModel() app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') assert wrapper_has_been_visited[0] is True def test_mixed_controller_wrapper(self): milestones._reset_all() class RootController(TGController): @expose() def test(self): return 'HI!' app_wrapper_has_been_visited = [] def app_controller_wrapper(caller): def call(*args, **kw): app_wrapper_has_been_visited.append(True) return caller(*args, **kw) return call wrapper_has_been_visited = [] def controller_wrapper(caller): def call(*args, **kw): wrapper_has_been_visited.append(True) return caller(*args, **kw) return call conf = AppConfig(minimal=True, root_controller=RootController()) tg.hooks.wrap_controller(app_controller_wrapper) tg.hooks.wrap_controller(controller_wrapper, controller=RootController.test) conf.package = PackageWithModel() app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') assert wrapper_has_been_visited[0] is True assert app_wrapper_has_been_visited[0] is True def test_controler_wrapper_after_environment_setup(self): milestones._reset_all() class RootController(TGController): @expose() def test(self): return 'HI!' wrapper_has_been_visited = [] def controller_wrapper(caller): def call(*args, **kw): wrapper_has_been_visited.append(True) return caller(*args, **kw) return call conf = AppConfig(minimal=True, root_controller=RootController()) conf.register_controller_wrapper(controller_wrapper) conf.package = PackageWithModel() app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') assert wrapper_has_been_visited[0] is True assert len(wrapper_has_been_visited) == 1 conf.register_controller_wrapper(controller_wrapper) app2 = conf.make_wsgi_app() app2 = TestApp(app2) wrapper_has_been_visited[:] = [] assert 'HI!' in app2.get('/test') assert wrapper_has_been_visited[0] is True assert len(wrapper_has_been_visited) == 2 def test_application_wrapper_setup(self): class RootController(TGController): @expose() def test(self): return 'HI!' wrapper_has_been_visited = [] class AppWrapper(object): def __init__(self, dispatcher): self.dispatcher = dispatcher def __call__(self, *args, **kw): wrapper_has_been_visited.append(True) return self.dispatcher(*args, **kw) conf = AppConfig(minimal=True, root_controller=RootController()) conf.register_wrapper(AppWrapper) conf.package = PackageWithModel() app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') assert wrapper_has_been_visited[0] == True def test_application_wrapper_ordering_after(self): class AppWrapper1: pass class AppWrapper2: pass class AppWrapper3: pass class AppWrapper4: pass class AppWrapper5: pass conf = AppConfig(minimal=True) conf.register_wrapper(AppWrapper2) conf.register_wrapper(AppWrapper4, after=AppWrapper3) conf.register_wrapper(AppWrapper3) conf.register_wrapper(AppWrapper1, after=False) conf.register_wrapper(AppWrapper5, after=AppWrapper3) milestones.environment_loaded.reach() assert conf.application_wrappers[0] == AppWrapper1 assert conf.application_wrappers[1] == AppWrapper2 assert conf.application_wrappers[2] == AppWrapper3 assert conf.application_wrappers[3] == AppWrapper4 assert conf.application_wrappers[4] == AppWrapper5 def test_wrap_app(self): class RootController(TGController): @expose() def test(self): return 'HI!' middleware_has_been_visited = [] class AppWrapper(object): def __init__(self, app): self.app = app def __call__(self, environ, start_response): middleware_has_been_visited.append(True) return self.app(environ, start_response) conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = PackageWithModel() app = conf.make_wsgi_app(wrap_app=AppWrapper) app = TestApp(app) assert 'HI!' in app.get('/test') assert middleware_has_been_visited[0] == True def test_unsupported_renderer(self): renderers = self.config.renderers self.config.renderers = ['unknwon'] try: self.config._setup_renderers() except TGConfigError: self.config.renderers = renderers else: assert False @raises(TGConfigError) def test_cookie_secret_required(self): self.config.sa_auth = {} self.config.setup_auth() self.config.add_auth_middleware(None, False) def test_sqla_auth_middleware(self): if PY3: raise SkipTest() self.config.auth_backend = 'sqlalchemy' self.config['sa_auth'] = {'authmetadata': ApplicationAuthMetadata(), 'dbsession': None, 'user_class':None, 'cookie_secret':'12345', 'authenticators':UncopiableList([('default', None)])} self.config.setup_auth() self.config.add_auth_middleware(None, True) authenticators = [x[0] for x in self.config['sa_auth']['authenticators']] assert 'cookie' in authenticators assert 'sqlauth' in authenticators self.config['sa_auth'] = {} self.config.auth_backend = None def test_sqla_auth_middleware_using_translations(self): if PY3: raise SkipTest() self.config.auth_backend = 'sqlalchemy' self.config['sa_auth'] = {'authmetadata': ApplicationAuthMetadata(), 'dbsession': None, 'user_class':None, 'translations': {'user_name':'SomethingElse'}, 'cookie_secret':'12345', 'authenticators':UncopiableList([('default', None)])} self.config.setup_auth() self.config.add_auth_middleware(None, True) authenticators = [x[0] for x in self.config['sa_auth']['authenticators']] assert 'cookie' in authenticators assert 'sqlauth' in authenticators auth = None for authname, authobj in self.config['sa_auth']['authenticators']: if authname == 'sqlauth': auth = authobj break assert auth is not None, self.config['sa_auth']['authenticators'] assert auth.translations['user_name'] == 'SomethingElse', auth.translations self.config['sa_auth'] = {} self.config.auth_backend = None def test_sqla_auth_middleware_default_after(self): if PY3: raise SkipTest() self.config.auth_backend = 'sqlalchemy' self.config['sa_auth'] = {'authmetadata': ApplicationAuthMetadata(), 'cookie_secret':'12345', 'dbsession': None, 'user_class': None, 'authenticators':UncopiableList([('superfirst', None), ('default', None)])} self.config.setup_auth() self.config.add_auth_middleware(None, True) authenticators = [x[0] for x in self.config['sa_auth']['authenticators']] assert authenticators[1] == 'superfirst' assert 'cookie' in authenticators assert 'sqlauth' in authenticators self.config['sa_auth'] = {} self.config.auth_backend = None def test_sqla_auth_middleware_no_authenticators(self): if PY3: raise SkipTest() self.config.auth_backend = 'sqlalchemy' self.config['sa_auth'] = {'authmetadata': ApplicationAuthMetadata(), 'dbsession': None, 'user_class': None, 'cookie_secret':'12345'} #In this case we can just test it doesn't crash #as the sa_auth dict doesn't have an authenticators key to check for self.config.setup_auth() self.config.add_auth_middleware(None, True) self.config['sa_auth'] = {} self.config.auth_backend = None def test_sqla_auth_middleware_only_mine(self): past_config_sa_auth = config.sa_auth config.sa_auth = {} class RootController(TGController): @expose() def test(self): return str(request.environ) @expose() def forbidden(self): response.status = "401" package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = package conf.model = package.model conf.auth_backend = 'sqlalchemy' conf.use_sqlalchemy = True conf['sqlalchemy.url'] = 'sqlite://' alwaysadmin = _AuthenticationForgerPlugin(fake_user_key='FAKE_USER') conf['sa_auth'] = {'authmetadata': ApplicationAuthMetadata(), 'cookie_secret':'12345', 'form_plugin':alwaysadmin, 'authenticators':UncopiableList([('alwaysadmin', alwaysadmin)]), 'identifiers':[('alwaysadmin', alwaysadmin)], 'challengers':[]} app = conf.make_wsgi_app() authenticators = [x[0] for x in conf['sa_auth']['authenticators']] assert authenticators[0] == 'alwaysadmin' assert 'sqlauth' not in authenticators challengers = [x[1] for x in conf['sa_auth']['challengers']] assert alwaysadmin in challengers app = TestApp(app) assert 'repoze.who.identity' in app.get('/test', extra_environ={'FAKE_USER':'admin'}) assert app.get('/forbidden', status=401) self.config['sa_auth'] = {} self.config.auth_backend = None config.sa_auth = past_config_sa_auth def test_sqla_auth_logging_stderr(self): past_config_sa_auth = config.sa_auth config.sa_auth = {} package = PackageWithModel() conf = AppConfig(minimal=True, root_controller=None) conf.package = package conf.model = package.model conf.auth_backend = 'sqlalchemy' conf.use_sqlalchemy = True conf['sqlalchemy.url'] = 'sqlite://' alwaysadmin = _AuthenticationForgerPlugin(fake_user_key='FAKE_USER') conf['sa_auth'] = {'authmetadata': ApplicationAuthMetadata(), 'cookie_secret':'12345', 'form_plugin':alwaysadmin, 'log_level':'DEBUG', 'authenticators':UncopiableList([('alwaysadmin', alwaysadmin)]), 'identifiers':[('alwaysadmin', alwaysadmin)], 'challengers':[]} conf['sa_auth']['log_file'] = 'stderr' app = conf.make_wsgi_app() conf['sa_auth']['log_file'] = 'stdout' app = conf.make_wsgi_app() import tempfile f = tempfile.NamedTemporaryFile() conf['sa_auth']['log_file'] = f.name app = conf.make_wsgi_app() self.config['sa_auth'] = {} self.config.auth_backend = None config.sa_auth = past_config_sa_auth def test_ming_auth_middleware(self): if PY3: raise SkipTest() self.config.auth_backend = 'ming' self.config['sa_auth'] = {'authmetadata': ApplicationAuthMetadata(), 'user_class':None, 'cookie_secret':'12345', 'authenticators':UncopiableList([('default', None)])} self.config.setup_auth() self.config.add_auth_middleware(None, True) authenticators = [x[0] for x in self.config['sa_auth']['authenticators']] assert 'cookie' in authenticators assert 'mingauth' in authenticators self.config['sa_auth'] = {} self.config.auth_backend = None @raises(KeyError) def test_sqla_auth_middleware_no_backend(self): #This is expected to raise error as no authenticators are specified for a custom backend past_config_sa_auth = config.sa_auth config.sa_auth = {} self.config.auth_backend = None self.config['sa_auth'] = {'authmetadata': ApplicationAuthMetadata(), 'cookie_secret':'12345'} self.config.setup_auth() self.config.add_auth_middleware(None, True) authenticators = [x[0] for x in self.config['sa_auth']['authenticators']] assert 'cookie' in authenticators assert len(authenticators) == 1 self.config['sa_auth'] = {} self.config.auth_backend = None config.sa_auth = past_config_sa_auth def test_tgauthmetadata_auth_middleware(self): self.config.auth_backend = 'sqlalchemy' self.config['sa_auth'] = {'authmetadata': ApplicationAuthMetadataWithAuthentication(), 'dbsession': None, 'user_class':None, 'cookie_secret':'12345', 'authenticators':UncopiableList([('default', None)])} self.config.setup_auth() self.config.add_auth_middleware(None, True) authenticators = [x[0] for x in self.config['sa_auth']['authenticators']] assert 'cookie' in authenticators assert 'tgappauth' in authenticators self.config['sa_auth'] = {} self.config.auth_backend = None def test_auth_middleware_doesnt_touch_authenticators(self): # Checks that the auth middleware process doesn't touch original authenticators # list, to prevent regressions on this. self.config.auth_backend = 'sqlalchemy' self.config['sa_auth'] = {'authmetadata': ApplicationAuthMetadataWithAuthentication(), 'dbsession': None, 'user_class':None, 'cookie_secret':'12345', 'authenticators':[('default', None)]} self.config.setup_auth() self.config.add_auth_middleware(None, True) authenticators = [x[0] for x in self.config['sa_auth']['authenticators']] assert len(authenticators) == 1 self.config['sa_auth'] = {} self.config.auth_backend = None def test_tgauthmetadata_loginpwd(self): who_authenticator = _AuthMetadataAuthenticator(ApplicationAuthMetadataWithAuthentication(), using_password=True) assert who_authenticator.authenticate({}, {}) == None def test_tgauthmetadata_nologinpwd(self): who_authenticator = _AuthMetadataAuthenticator(ApplicationAuthMetadataWithAuthentication(), using_password=False) assert who_authenticator.authenticate({}, {}) == 1 def test_toscawidgets_recource_variant(self): if PY3: raise SkipTest() resultingconfig = {} def fake_make_middleware(app, twconfig): resultingconfig.update(twconfig) return app import tw.api prev_tw_make_middleware = tw.api.make_middleware tw.api.make_middleware = fake_make_middleware config['toscawidgets.framework.resource_variant'] = 'min' self.config.add_tosca_middleware(None) config.pop('toscawidgets.framework.resource_variant', None) def test_error_middleware_disabled_with_optimize(self): class RootController(TGController): @expose() def test(self): return 'HI!' conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = PackageWithModel() os.environ['PYTHONOPTIMIZE'] = '2' app = conf.make_wsgi_app() os.environ.pop('PYTHONOPTIMIZE') app = TestApp(app) assert 'HI!' in app.get('/test') def test_serve_statics(self): class RootController(TGController): @expose() def test(self): return 'HI!' conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = PackageWithModel() conf.serve_static = True app = conf.make_wsgi_app() assert app.__class__.__name__.startswith('Statics') app = TestApp(app) assert 'HI!' in app.get('/test') def test_mount_point_with_minimal(self): class SubController(TGController): @expose() def test(self): return self.mount_point class RootController(TGController): sub = SubController() conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = PackageWithModel() app = conf.make_wsgi_app() app = TestApp(app) assert '/sub' in app.get('/sub/test') def test_application_test_vars(self): class RootController(TGController): pass conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = PackageWithModel() app = conf.make_wsgi_app() app = TestApp(app) assert 'DONE' in app.get('/_test_vars') assert request.path == '/_test_vars' # This should trash away the preserved registry to avoid # leaking memory. app.get('/', status=404) try: request.path except TypeError: # TypeError means the request has been properly removed pass else: assert False, 'There should have been no requests in place...' def test_application_empty_controller(self): class RootController(object): def __call__(self, environ, start_response): return None conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = PackageWithModel() app = conf.make_wsgi_app() app = TestApp(app) try: r = app.get('/something') except Exception as e: assert 'No content returned by controller' in str(e) else: assert False, 'Should have raised "No content returned by controller"' def test_application_test_mode_detection(self): class FakeRegistry(object): def register(self, *args, **kw): pass a = TGApp() testmode, __, __ = a.setup_app_env({'paste.registry':FakeRegistry()}) assert testmode is False testmode, __, __ = a.setup_app_env({'paste.registry':FakeRegistry(), 'paste.testing_variables':{}}) assert testmode is True def test_application_no_controller_hijacking(self): class RootController(TGController): @expose() def test(self): return 'HI!' class AppWrapper(object): def __init__(self, dispatcher): self.dispatcher = dispatcher def __call__(self, controller, environ, start_response): return self.dispatcher(None, environ, start_response) conf = AppConfig(minimal=True, root_controller=RootController()) conf.register_wrapper(AppWrapper) conf.package = PackageWithModel() app = conf.make_wsgi_app() app = TestApp(app) app.get('/test', status=404) def test_package_no_app_globals(self): class RootController(TGController): pass conf = AppConfig(minimal=True, root_controller=RootController()) conf.package = sys.modules[__name__] app = conf.make_wsgi_app() def test_custom_error_document(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): abort(403) conf = AppConfig(minimal=True, root_controller=RootController()) conf['errorpage.enabled'] = True conf['errorpage.handle_exceptions'] = False app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test', status=403) assert 'ERROR!!!' in resp, resp def test_custom_error_document_with_streamed_response(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): response.status_code = 403 def _output(): yield 'Hi' yield 'World' return _output() conf = AppConfig(minimal=True, root_controller=RootController()) conf['errorpage.enabled'] = True conf['errorpage.handle_exceptions'] = False app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test', status=403) assert 'ERROR!!!' in resp, resp def test_custom_old_error_document(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): abort(403) conf = AppConfig(minimal=True, root_controller=RootController()) conf['errorpage.enabled'] = True conf.status_code_redirect = True app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test', status=403) assert 'ERROR!!!' in resp, resp def test_custom_old_error_document_with_streamed_response(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): response.status_code = 403 def _output(): yield 'Hi' yield 'World' return _output() conf = AppConfig(minimal=True, root_controller=RootController()) conf['errorpage.enabled'] = True conf.status_code_redirect = True app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test', status=403) assert 'ERROR!!!' in resp, resp def test_custom_500_document(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): abort(500) conf = AppConfig(minimal=True, root_controller=RootController()) conf['errorpage.enabled'] = True conf['debug'] = False conf['errorpage.handle_exceptions'] = False conf['errorpage.status_codes'] += [500] app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test', status=500) assert 'ERROR!!!' in resp, resp def test_custom_500_document_on_crash(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): raise Exception('Crash!') conf = AppConfig(minimal=True, root_controller=RootController()) conf['errorpage.enabled'] = True conf['debug'] = False conf['errorpage.handle_exceptions'] = True app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test', status=500) assert 'ERROR!!!' in resp, resp def test_errorpage_reraises_exceptions(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): raise Exception('Crash!') conf = AppConfig(minimal=True, root_controller=RootController()) conf['errorpage.enabled'] = True conf['debug'] = False conf['errorpage.handle_exceptions'] = False app = conf.make_wsgi_app(full_stack=False) app = TestApp(app) try: resp = app.get('/test', status=500) except Exception as e: assert 'Crash!' in str(e) else: assert False, 'Should have raised Crash! exception' def test_old_custom_500_document(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): abort(500) conf = AppConfig(minimal=True, root_controller=RootController()) conf['debug'] = False conf.status_code_redirect = True conf['errorpage.enabled'] = True conf['errorpage.status_codes'] += [500] app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test', status=500) assert 'ERROR!!!' in resp, resp def test_skips_custom_500_document_when_debug(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): abort(500) conf = AppConfig(minimal=True, root_controller=RootController()) conf['errorpage.enabled'] = True conf['debug'] = True conf['errorpage.handle_exceptions'] = False app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test', status=500) assert 'ERROR!!!' not in resp, resp def test_skips_old_custom_500_document_when_debug(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): abort(500) conf = AppConfig(minimal=True, root_controller=RootController()) conf['debug'] = True conf.status_code_redirect = True conf['errorpage.enabled'] = True app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test', status=500) assert 'ERROR!!!' not in resp, resp def test_skips_custom_error_document_when_disabled(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): abort(403) conf = AppConfig(minimal=True, root_controller=RootController()) conf['errorpage.enabled'] = False conf['errorpage.status_codes'] = (403, 404) conf['errorpage.handle_exceptions'] = False app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test', status=403) assert 'ERROR!!!' not in resp, resp def test_skips_custom_error_document_when_disabled_and_manually_registered(self): class ErrorController(TGController): @expose() def document(self, *args, **kw): return 'ERROR!!!' class RootController(TGController): error = ErrorController() @expose() def test(self): abort(403) conf = AppConfig(minimal=True, root_controller=RootController()) conf.register_wrapper(ErrorPageApplicationWrapper) conf['errorpage.enabled'] = False conf['errorpage.status_codes'] = (403, 404) conf['errorpage.handle_exceptions'] = False app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test', status=403) assert 'ERROR!!!' not in resp, resp def test_errorware_configuration(self): class RootController(TGController): @expose() def test(self, *args, **kwargs): return 'HI' conf = AppConfig(minimal=True, root_controller=RootController()) app = conf.make_wsgi_app(global_conf={'trace_errors.error_email': 'test@domain.com'}, full_stack=True) app = TestApp(app) resp = app.get('/test') assert 'HI' in resp, resp assert config['tg.errorware']['error_email'] == 'test@domain.com' assert config['tg.errorware']['error_subject_prefix'] == 'WebApp Error: ' assert config['tg.errorware']['error_message'] == 'An internal server error occurred' def test_tw2_unsupported_renderer(self): import tw2.core class RootController(TGController): @expose() def test(self, *args, **kwargs): rl = tw2.core.core.request_local() tw2conf = rl['middleware'].config return ','.join(tw2conf.preferred_rendering_engines) conf = AppConfig(minimal=True, root_controller=RootController()) conf.prefer_toscawidgets2 = True conf.renderers = ['json', 'genshi'] conf.default_renderer = 'json' app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test') assert 'genshi' in resp, resp def test_tw2_renderers_preference(self): import tw2.core class RootController(TGController): @expose() def test(self, *args, **kwargs): rl = tw2.core.core.request_local() tw2conf = rl['middleware'].config return ','.join(tw2conf.preferred_rendering_engines) conf = AppConfig(minimal=True, root_controller=RootController()) conf.prefer_toscawidgets2 = True conf.renderers = ['genshi'] conf.default_renderer = 'genshi' app = conf.make_wsgi_app(full_stack=True) app = TestApp(app) resp = app.get('/test') assert 'genshi' in resp, resp def test_tw2_unsupported(self): import tw2.core class RootController(TGController): @expose() def test(self, *args, **kwargs): rl = tw2.core.core.request_local() tw2conf = rl['middleware'].config return ','.join(tw2conf.preferred_rendering_engines) conf = AppConfig(minimal=True, root_controller=RootController()) conf.prefer_toscawidgets2 = True conf.renderers = ['json'] conf.default_renderer = 'json' try: app = conf.make_wsgi_app(full_stack=True) assert False except TGConfigError as e: assert 'None of the configured rendering engines is supported' in str(e) def test_backward_compatible_engine_failed_setup(self): class RootController(TGController): @expose() def test(self, *args, **kwargs): return 'HELLO' def setup_broken_renderer(): return False conf = AppConfig(minimal=True, root_controller=RootController()) conf.setup_broken_renderer = setup_broken_renderer conf.renderers = ['json', 'broken'] app = conf.make_wsgi_app(full_stack=True) assert conf.renderers == ['json'] def test_backward_compatible_engine_success_setup(self): class RootController(TGController): @expose() def test(self, *args, **kwargs): return 'HELLO' conf = AppConfig(minimal=True, root_controller=RootController()) def setup_broken_renderer(): conf.render_functions.broken = 'BROKEN' return True conf.setup_broken_renderer = setup_broken_renderer conf.renderers = ['json', 'broken'] app = conf.make_wsgi_app(full_stack=True) assert conf.renderers == ['json', 'broken'] assert conf.render_functions.broken == 'BROKEN' def test_render_factory_success(self): class RootController(TGController): @expose() def test(self, *args, **kwargs): return 'HELLO' class FailedFactory(RendererFactory): engines = {'broken': {'content_type': 'text/plain'}} @classmethod def create(cls, config, app_globals): return {'broken': 'BROKEN'} conf = AppConfig(minimal=True, root_controller=RootController()) conf.register_rendering_engine(FailedFactory) conf.renderers = ['json', 'broken'] app = conf.make_wsgi_app(full_stack=True) assert conf.renderers == ['json', 'broken'] assert conf.render_functions.broken == 'BROKEN' def test_render_factory_failure(self): class RootController(TGController): @expose() def test(self, *args, **kwargs): return 'HELLO' class FailedFactory(RendererFactory): engines = {'broken': {'content_type': 'text/plain'}} @classmethod def create(cls, config, app_globals): return None conf = AppConfig(minimal=True, root_controller=RootController()) conf.register_rendering_engine(FailedFactory) conf.renderers = ['json', 'broken'] app = conf.make_wsgi_app(full_stack=True) assert conf.renderers == ['json'] def test_make_body_seekable(self): class RootController(TGController): @expose() def test(self, *args, **kwargs): request.body_file.seek(0) return 'HELLO' conf = AppConfig(minimal=True, root_controller=RootController()) conf['make_body_seekable'] = True app = conf.make_wsgi_app(full_stack=False) assert app.application.__class__.__name__ == 'SeekableRequestBodyMiddleware', \ app.application.__class__ app = TestApp(app) assert 'HELLO' in app.get('/test') def test_make_body_seekable_disabled(self): class RootController(TGController): @expose() def test(self, *args, **kwargs): request.body_file.seek(0) return 'HELLO' conf = AppConfig(minimal=True, root_controller=RootController()) conf['make_body_seekable'] = False app = conf.make_wsgi_app(full_stack=False) app = TestApp(app) assert 'HELLO' in app.get('/test') def test_debug_middleware(self): class RootController(TGController): @expose() def test(self): raise Exception('Crash!') conf = AppConfig(minimal=True, root_controller=RootController()) conf['errorpage.enabled'] = True app = conf.make_wsgi_app(global_conf={'debug': True}, full_stack=True) app = TestApp(app) resp = app.get('/test', status=500) assert 'Exception: Crash! // Backlash' in resp, resp def test_make_app_with_custom_appglobals(self): class RootController(TGController): @expose('') def test(self, *args, **kwargs): return tg.app_globals.TEXT class FakeGlobals(Bunch): def __init__(self): super(FakeGlobals, self).__init__() self['TEXT'] = 'HI!' conf = AppConfig(minimal=True, root_controller=RootController()) conf.app_globals = FakeGlobals app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test') def test_make_app_with_custom_helpers(self): class RootController(TGController): @expose('') def test(self, *args, **kwargs): return config['helpers'].get_text() class FakeHelpers(Bunch): @classmethod def get_text(cls): return 'HI!' conf = AppConfig(minimal=True, root_controller=RootController()) conf.helpers = FakeHelpers() app = conf.make_wsgi_app() app = TestApp(app) assert 'HI!' in app.get('/test')TurboGears2-2.3.7/tests/test_configuration_dictionary.py0000644000076500000240000000550512536240617023617 0ustar amolstaff00000000000000from nose.tools import raises #from tg.configuration.utils import ConfigurationBunch class TestConfigurationDictionary(object): def setup(self): self.d = ConfigurationBunch() """ def test_plain_to_nested(self): d = self.d d['1st.2nd.3rd'] = 'HELLO' assert d['1st']['2nd']['3rd'] == 'HELLO' def test_nested_to_plain(self): d = self.d d['1st'] = {} d['1st']['2nd'] = {} d['1st']['2nd']['3rd'] = 'HELLO' assert d['1st.2nd.3rd'] == 'HELLO' def test_plain_to_plain(self): d = self.d d['1st.2nd.3rd'] = 'HELLO' assert d['1st.2nd.3rd'] == 'HELLO' def test_nested_to_attrs(self): d = self.d d['st1'] = {} d['st1']['nd2'] = {} d['st1']['nd2']['rd3'] = 'HELLO' assert d.st1.nd2.rd3 == 'HELLO' def test_plain_to_attrs(self): d = self.d d['st1.nd2.rd3'] = 'HELLO' assert d.st1.nd2.rd3 == 'HELLO' def test_iterate(self): d = self.d d['simple.sub'] = {'sub1': [3, 4], 'sub2': 'hi', 'sub3': {'subsub1': 7, 'subsub2': 8}} d['simple.sub.x'] = 'hi' flatkeys = list(iter(d)) assert flatkeys == ['simple.sub.x', 'simple.sub.sub2', 'simple.sub.sub3.subsub2', 'simple.sub.sub3.subsub1', 'simple.sub.sub1'], flatkeys @raises(KeyError) def test_delete_plain(self): d = self.d d['st1'] = {} d['st1']['nd2'] = {} d['st1']['nd2']['rd3'] = 'HELLO' d.pop('st1.nd2.rd3', None) d['st1']['nd2']['rd3'] @raises(AttributeError) def test_plain_to_attrs_not_found(self): d = self.d d['st1.nd2.rd3'] = 'HELLO' d.st1.nd2.rd4 def test_set_plain(self): self.d['hi'] = 5 self.d['simple.sub.sub1'] = [3, 4] self.d['simple.sub.sub2'] = [3, 4] assert sorted(list(self.d.keys())) == sorted(['hi', 'simple']), self.d assert 'sub' in self.d['simple'], self.d assert len(self.d['simple.sub'].keys()) == 2 def test_set_subdict(self): d = self.d d['simple.sub'] = {'sub1': [3, 4], 'sub2': 'hi', 'sub3': {'subsub1': 7, 'subsub2': 8}} d['simple.sub.x'] = 'hi' assert len(d) == 1, d assert d['simple'] == {'sub': {'x': 'hi', 'sub1': [3, 4], 'sub2': 'hi', 'sub3': {'subsub1': 7, 'subsub2': 8}}} def test_get_subdict(self): self.test_set_subdict() assert self.d['simple.sub.sub3'] == {'subsub1': 7, 'subsub2': 8} @raises(TypeError) def test_odd_parents_and_children1(self): self.d['parent'] = 5 self.d['parent.child'] = 3 @raises(TypeError) def test_odd_parents_and_children2(self): self.d['parent.child'] = 3 self.d['parent'] = 3 # parent is now an int so it should fail self.d['parent.child'] """TurboGears2-2.3.7/tests/test_controllers.py0000644000076500000240000001130412555020522021053 0ustar amolstaff00000000000000# -*- coding: utf-8 -*- import tg from tg.controllers import * from tg.exceptions import HTTPFound from nose.tools import eq_ from tests.base import setup_session_dir, teardown_session_dir from tg.util import no_warn from tg.util.webtest import test_context from tg._compat import u_, string_type def setup(): setup_session_dir() def teardown(): teardown_session_dir() def test_create_request(): with test_context(None, '/', { 'SCRIPT_NAME' : '/xxx' }): eq_('http://localhost/xxx/hello', tg.request.relative_url('hello')) eq_('http://localhost/xxx', tg.request.application_url) def test_approots(): with test_context(None, '/subthing/',{ 'SCRIPT_NAME' : '/subthing' }): eq_("foo", url("foo")) eq_("/subthing/foo", url("/foo")) def test_lowerapproots(): with test_context(None, '/subthing/subsubthing/',{ 'SCRIPT_NAME' : '/subthing/subsubthing' }): eq_("/subthing/subsubthing/foo", url("/foo")) @no_warn def test_multi_values(): with test_context(None, '/'): r = url("/foo", params=dict(bar=("asdf", "qwer"))) assert r in \ ["/foo?bar=qwer&bar=asdf", "/foo?bar=asdf&bar=qwer"], r r = url("/foo", params=dict(bar=[1,2])) assert r in \ ["/foo?bar=1&bar=2", "/foo?bar=2&bar=1"], r @no_warn def test_unicode(): """url() can handle unicode parameters""" with test_context(None, '/'): unicodestring = u_('àèìòù') eq_(url('/', params=dict(x=unicodestring)), '/?x=%C3%A0%C3%A8%C3%AC%C3%B2%C3%B9' ) @no_warn def test_list(): """url() can handle list parameters, with unicode too""" with test_context(None, '/'): value = url('/', params=dict(foo=['bar', u_('à')])), assert '/?foo=bar&foo=%C3%A0' in value, value @no_warn def test_url_positional_params(): with test_context(None, '/'): params = {'spamm': 'eggs'} result = url('/foo', params) assert 'spamm=eggs' in result def test_url_with_params_key(): with test_context(None, '/'): params = {'spamm': 'eggs'} result = url('/foo', params=params) assert 'spamm=eggs' in result @no_warn def test_url_strip_None(): with test_context(None, '/'): params = {'spamm':'eggs', 'hamm':None } result = url('/foo', params=params) assert 'hamm' not in result, result def test_lurl(): with test_context(None, '/'): params = {'spamm':'eggs', 'hamm':None } assert url('/foo', params=params) == str(lurl('/foo', params=params)) @no_warn def test_url_qualified(): """url() can handle list parameters, with unicode too""" with test_context(None, '/'): value = url('/', qualified=True) assert value.startswith('http') @no_warn def test_lurl(): """url() can handle list parameters, with unicode too""" with test_context(None, '/'): value = lurl('/lurl') assert not isinstance(value, string_type) assert value.startswith('/lurl') assert str(value) == repr(value) == value.id == value.encode('utf-8').decode('utf-8') == value.__html__() def test_lurl_as_HTTPFound_location(): with test_context(None, '/'): exc = HTTPFound(location=lurl('/lurl')) def _fake_start_response(*args, **kw): pass resp = exc({'PATH_INFO':'/', 'wsgi.url_scheme': 'HTTP', 'REQUEST_METHOD': 'GET', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80'}, _fake_start_response) assert b'resource was found at http://localhost:80/lurl' in resp[0] def test_HTTPFound_without_location(): exc = HTTPFound(add_slash=True) def _fake_start_response(*args, **kw): pass resp = exc({'PATH_INFO':'/here', 'wsgi.url_scheme': 'HTTP', 'REQUEST_METHOD': 'GET', 'SERVER_NAME': 'localhost', 'SERVER_PORT': '80'}, _fake_start_response) assert b'resource was found at http://localhost:80/here/' in resp[0] @no_warn def test_lurl_format(): """url() can handle list parameters, with unicode too""" with test_context(None, '/'): value = lurl('/lurl/{0}') value = value.format('suburl') assert value == '/lurl/suburl', value @no_warn def test_lurl_add(): """url() can handle list parameters, with unicode too""" with test_context(None, '/'): value = lurl('/lurl') value = value + '/suburl' assert value == '/lurl/suburl', value @no_warn def test_lurl_radd(): """url() can handle list parameters, with unicode too""" with test_context(None, '/'): value = lurl('/lurl') value = '/suburl' + value assert value == '/suburl/lurl', value TurboGears2-2.3.7/tests/test_converters.py0000644000076500000240000000353312413576166020721 0ustar amolstaff00000000000000from nose.tools import raises from tg.support.converters import asbool, asint, aslist, astemplate class TestAsBool(object): def test_asbool_truthy(self): assert asbool('true') assert asbool('yes') assert asbool('on') assert asbool('y') assert asbool('t') assert asbool('1') def test_asbool_falsy(self): assert not asbool('false') assert not asbool('no') assert not asbool('off') assert not asbool('n') assert not asbool('f') assert not asbool('0') @raises(ValueError) def test_asbool_broken(self): asbool('Test') @raises(ValueError) def test_nonstring(self): asint([True]) class TestAsInt(object): def test_fine(self): assert asint('55') == 55 @raises(ValueError) def test_nan(self): asint('hello') @raises(ValueError) def test_nonstring(self): asint(['55']) class TestAsList(object): def test_fine(self): assert aslist('first, second, third', ',') == ['first', 'second', 'third'] assert aslist('first second third') == ['first', 'second', 'third'] assert aslist('first, second, third', ',', False) == ['first', ' second', ' third'] def test_nonstring(self): assert aslist(55) == [55] def test_already_list(self): assert aslist([55]) == [55] def test_None(self): assert aslist(None) == [] class TestAsTemplate(object): def test_fine(self): assert hasattr(astemplate('You are ${name}'), 'substitute') assert astemplate('You are ${name}').substitute(name='John') == 'You are John' @raises(ValueError) def test_nonstring(self): astemplate(55) def test_aslready_template(self): assert astemplate(astemplate('You are ${name}')).substitute(name='John') == 'You are John'TurboGears2-2.3.7/tests/test_errorware.py0000644000076500000240000000465112413576166020541 0ustar amolstaff00000000000000from tg.error import ErrorReporter from tg.error import SlowReqsReporter def simple_app(environ, start_response): status = '200 OK' headers = [('Content-type', 'text/plain')] start_response(status, headers) return ['HELLO'] class TestErrorReporterConfig(object): middleware_name = 'TraceErrorsMiddleware' def test_enable_none(self): app = ErrorReporter(simple_app, {}) assert app.__class__.__name__ == self.middleware_name assert not app.reporters def test_enable_email(self): app = ErrorReporter(simple_app, {}, error_email='user@somedomain.com') assert app.__class__.__name__ == self.middleware_name assert any(r.__class__.__name__ == 'EmailReporter' for r in app.reporters) def test_enable_sentry(self): app = ErrorReporter(simple_app, {}, sentry_dsn='http://public:secret@example.com/1') assert app.__class__.__name__ == self.middleware_name assert any(r.__class__.__name__ == 'SentryReporter' for r in app.reporters) def test_debug_mode(self): app = ErrorReporter(simple_app, dict(debug='on'), enable=True, error_email='user@somedomain.com') assert app is simple_app class TestSlowReqsReporterConfig(object): middleware_name = 'TraceSlowRequestsMiddleware' def test_disable_all(self): app = SlowReqsReporter(simple_app, {}) assert app is simple_app def test_enable_without_reporter(self): app = SlowReqsReporter(simple_app, {}, enable=True) assert app.__class__.__name__ == self.middleware_name assert not app.reporters def test_enable_email(self): app = SlowReqsReporter(simple_app, {}, enable=True, error_email='user@somedomain.com') assert app.__class__.__name__ == self.middleware_name assert any(r.__class__.__name__ == 'EmailReporter' for r in app.reporters) def test_enable_sentry(self): app = SlowReqsReporter(simple_app, {}, enable=True, sentry_dsn='http://public:secret@example.com/1') assert app.__class__.__name__ == self.middleware_name assert any(r.__class__.__name__ == 'SentryReporter' for r in app.reporters) def test_debug_mode(self): app = SlowReqsReporter(simple_app, dict(debug='on'), enable=True, error_email='user@somedomain.com') assert app is simple_app TurboGears2-2.3.7/tests/test_fastform.py0000644000076500000240000001006012413576166020341 0ustar amolstaff00000000000000from webob.exc import HTTPFound, HTTPUnauthorized from tg.configuration.auth.fastform import FastFormPlugin class FakeCookieAuth(object): def remember(self, *args, **kw): return 'REMEMBER' def forget(self, *args, **kw): return 'FORGET' def build_env(path_info, qs='', SCRIPT_NAME=''): environ = { 'PATH_INFO': path_info, 'SCRIPT_NAME': SCRIPT_NAME, 'QUERY_STRING': qs, 'SERVER_NAME': 'example.org', 'SERVER_PORT': '80', 'wsgi.input': '', 'wsgi.url_scheme': 'http', 'CONTENT_TYPE': "application/x-www-form-urlencoded", } environ['repoze.who.plugins'] = {'cookie': FakeCookieAuth()} return environ class TestFastFormPlugin(object): def setup(self): self.fform = FastFormPlugin('/login', '/login_handler', '/post_login', '/logout_handler', '/post_logout', 'cookie') def test_login(self): env = build_env('/login_handler', 'login=user&password=pwd&came_from=/goback') cred = self.fform.identify(env) assert isinstance(env['repoze.who.application'], HTTPFound) assert cred['login'] == 'user' assert cred['password'] == 'pwd' assert env['repoze.who.application'].location == '/post_login?came_from=%2Fgoback' def test_login_nocred(self): env = build_env('/login_handler', 'login=user&came_from=/goback') cred = self.fform.identify(env) assert cred is None def test_login_counter(self): env = build_env('/login_handler', 'login=user&password=pwd&__logins=1') cred = self.fform.identify(env) assert isinstance(env['repoze.who.application'], HTTPFound) assert cred['login'] == 'user' assert cred['password'] == 'pwd' assert env['repoze.who.application'].location == '/post_login?__logins=1' def test_login_counter_keep(self): env = build_env('/login', '__logins=1') self.fform.identify(env) assert 'logins' not in env['QUERY_STRING'] assert env['repoze.who.logins'] == 1 def test_logout_handler(self): env = build_env('/logout_handler', 'came_from=%2Fgoback') self.fform.identify(env) assert isinstance(env['repoze.who.application'], HTTPUnauthorized) assert env['came_from'] == '/goback' def test_logout_handler_no_came_from(self): env = build_env('/logout_handler') self.fform.identify(env) assert isinstance(env['repoze.who.application'], HTTPUnauthorized) assert env['came_from'] == '/' def test_logout_handler_challenge(self): env = build_env('/logout_handler', 'came_from=%2Fgoback') self.fform.identify(env) ans = self.fform.challenge(env, '401 Unauthorized', [('app', '1')], [('forget', '1')]) assert isinstance(ans, HTTPFound) assert ans.location == '/post_logout?came_from=%2Fgoback' def test_challenge_redirect_to_form(self): env = build_env('/private', SCRIPT_NAME='/SOMEWHERE') ans = self.fform.challenge(env, '401 Unauthorized', [('app', '1')], [('forget', '1')]) assert isinstance(ans, HTTPFound) assert ans.location == '/SOMEWHERE/login?came_from=%2FSOMEWHERE%2Fprivate' def test_challenge_redirect_to_form_with_args(self): env = build_env('/private', qs='A=1&B=2', SCRIPT_NAME='/SOMEWHERE') ans = self.fform.challenge(env, '401 Unauthorized', [('app', '1')], [('forget', '1')]) assert isinstance(ans, HTTPFound) # Cope with different dictionary ordering on Py2 and Py3 assert ans.location in ('/SOMEWHERE/login?came_from=%2FSOMEWHERE%2Fprivate%3FA%3D1%26B%3D2', '/SOMEWHERE/login?came_from=%2FSOMEWHERE%2Fprivate%3FB%3D2%26A%3D1'), ans.location def test_remember_forget(self): env = build_env('/private', SCRIPT_NAME='/SOMEWHERE') assert self.fform.remember(env, {}) == 'REMEMBER' assert self.fform.forget(env, {}) == 'FORGET' def test_repr(self): assert repr(self.fform).startswith(' 3: raise StopIteration() return str(self.step) def close(self): self.closed = True def __repr__(self): return '%s - %s' % (self.step, self.closed) class TestDBSessionRemoverMiddleware(object): def setup(self): self.app_with_close = FakeAppWithClose() self.session = FakeDBSession() self.app = TestApp(DBSessionRemoverMiddleware(self.session, self.app_with_close)) def test_close_is_called(self): r = self.app.get('/nonerror') assert self.app_with_close.closed == True, self.app_with_close def test_session_is_removed(self): r = self.app.get('/nonerror') assert self.session.removed == True, self.app_with_close def test_session_is_removed_on_crash(self): try: r = self.app.get('/crash') except: pass assert self.session.removed == True, self.app_with_close class TestMingSessionRemoverMiddlewaree(object): def setup(self): self.app_with_close = FakeAppWithClose() self.session = FakeDBSession() self.app = TestApp(MingSessionRemoverMiddleware(self.session, self.app_with_close)) def test_close_is_called(self): r = self.app.get('/nonerror') assert self.app_with_close.closed == True, self.app_with_close def test_session_is_removed(self): r = self.app.get('/nonerror') assert self.session.removed == True, self.app_with_close def test_session_is_removed_on_crash(self): try: r = self.app.get('/crash') except: pass assert self.session.removed == True, self.app_with_close TurboGears2-2.3.7/tests/test_predicates.py0000644000076500000240000004161712413576166020657 0ustar amolstaff00000000000000# -*- coding: utf-8 -*- """Tests for Predicates, mostly took from repoze.what test suite""" ############################################################################## # # Copyright (c) 2007, Agendaless Consulting and Contributors. # Copyright (c) 2008, Florent Aide . # Copyright (c) 2008-2009, Gustavo Narea . # All Rights Reserved. # # This software is subject to the provisions of the BSD-like license at # http://www.repoze.org/LICENSE.txt. A copy of the license should accompany # this distribution. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL # EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, # THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND # FITNESS FOR A PARTICULAR PURPOSE. # ############################################################################## from nose.tools import raises from webtest import TestApp from tg._compat import u_, unicode_text from tg import predicates, TGController, expose, config from tg.configuration import AppConfig class BasePredicateTester(object): """Base test case for predicates.""" def assertEqual(self, val1, val2): assert val1 == val2, (val1, val2) def eval_met_predicate(self, p, environ): """Evaluate a predicate that should be met""" self.assertEqual(p.check_authorization(environ), None) self.assertEqual(p.is_met(environ), True) def eval_unmet_predicate(self, p, environ, expected_error): """Evaluate a predicate that should not be met""" credentials = environ.get('repoze.what.credentials') # Testing check_authorization try: p.evaluate(environ, credentials) self.fail('Predicate must not be met; expected error: %s' % expected_error) except predicates.NotAuthorizedError as error: self.assertEqual(unicode_text(error), expected_error) # Testing is_met: self.assertEqual(p.is_met(environ), False) #{ The test suite itself class TestPredicate(BasePredicateTester): @raises(NotImplementedError) def test_evaluate_isnt_implemented(self): p = MockPredicate() p.evaluate(None, None) def test_message_is_changeable(self): previous_msg = EqualsTwo.message new_msg = 'It does not equal two!' p = EqualsTwo(msg=new_msg) self.assertEqual(new_msg, p.message) def test_message_isnt_changed_unless_required(self): previous_msg = EqualsTwo.message p = EqualsTwo() self.assertEqual(previous_msg, p.message) def test_unicode_messages(self): unicode_msg = u_('请登陆') p = EqualsTwo(msg=unicode_msg) environ = {'test_number': 3} self.eval_unmet_predicate(p, environ, unicode_msg) def test_authorized(self): environ = {'test_number': 4} p = EqualsFour() p.check_authorization(environ) def test_unauthorized(self): environ = {'test_number': 3} p = EqualsFour(msg="Go away!") try: p.check_authorization(environ) self.fail('Authorization must have been rejected') except predicates.NotAuthorizedError as e: self.assertEqual(str(e), "Go away!") def test_unauthorized_with_unicode_message(self): # This test is broken on Python 2.4 and 2.5 because the unicode() # function doesn't work when converting an exception into an unicode # string (this is, to extract its message). unicode_msg = u_('请登陆') environ = {'test_number': 3} p = EqualsFour(msg=unicode_msg) try: p.check_authorization(environ) self.fail('Authorization must have been rejected') except predicates.NotAuthorizedError as e: self.assertEqual(unicode_text(e), unicode_msg) def test_custom_failure_message(self): message = u_('This is a custom message whose id is: %(id_number)s') id_number = 23 p = EqualsFour(msg=message) try: p.unmet(message, id_number=id_number) self.fail('An exception must have been raised') except predicates.NotAuthorizedError as e: self.assertEqual(unicode_text(e), message % dict(id_number=id_number)) def test_credentials_dict_when_anonymous(self): """The credentials must be a dict even if the user is anonymous""" class CredentialsPredicate(predicates.Predicate): message = "Some text" def evaluate(self, environ, credentials): if 'something' in credentials: self.unmet() # --- Setting the environ up environ = {} # --- Testing it: p = CredentialsPredicate() self.eval_met_predicate(p, environ) self.assertEqual(True, p.is_met(environ)) class TestContextRelatedBoolPredicate(BasePredicateTester): def setup(self): class RootController(TGController): @expose() def test(self): return str(bool(EqualsTwo())) conf = AppConfig(minimal=True, root_controller=RootController()) app = conf.make_wsgi_app() self.app = TestApp(app) def teardown(self): config.pop('tg.root_controller', None) def test_success(self): ans = self.app.get('/test', extra_environ={'test_number':'2'}) assert 'True' in ans, ans def test_faillure(self): ans = self.app.get('/test', extra_environ={'test_number':'4'}) assert 'False' in ans, ans class TestCompoundPredicate(BasePredicateTester): def test_one_predicate_works(self): p = EqualsTwo() cp = predicates.CompoundPredicate(p) self.assertEqual(cp.predicates, (p,)) def test_two_predicates_work(self): p1 = EqualsTwo() p2 = MockPredicate() cp = predicates.CompoundPredicate(p1, p2) self.assertEqual(cp.predicates, (p1, p2)) class TestNotPredicate(BasePredicateTester): def test_failure(self): environ = {'test_number': 4} # It must NOT equal 4 p = predicates.Not(EqualsFour()) # It equals 4! self.eval_unmet_predicate(p, environ, 'The condition must not be met') def test_failure_with_custom_message(self): environ = {'test_number': 4} # It must not equal 4 p = predicates.Not(EqualsFour(), msg='It must not equal four') # It equals 4! self.eval_unmet_predicate(p, environ, 'It must not equal four') def test_success(self): environ = {'test_number': 5} # It must not equal 4 p = predicates.Not(EqualsFour()) # It doesn't equal 4! self.eval_met_predicate(p, environ) class TestAllPredicate(BasePredicateTester): def test_one_true(self): environ = {'test_number': 2} p = predicates.All(EqualsTwo()) self.eval_met_predicate(p, environ) def test_one_false(self): environ = {'test_number': 3} p = predicates.All(EqualsTwo()) self.eval_unmet_predicate(p, environ, "Number 3 doesn't equal 2") def test_two_true(self): environ = {'test_number': 4} p = predicates.All(EqualsFour(), GreaterThan(3)) self.eval_met_predicate(p, environ) def test_two_false(self): environ = {'test_number': 1} p = predicates.All(EqualsFour(), GreaterThan(3)) self.eval_unmet_predicate(p, environ, "Number 1 doesn't equal 4") def test_two_mixed(self): environ = {'test_number': 5} p = predicates.All(EqualsFour(), GreaterThan(3)) self.eval_unmet_predicate(p, environ, "Number 5 doesn't equal 4") class TestAnyPredicate(BasePredicateTester): def test_one_true(self): environ = {'test_number': 2} p = predicates.Any(EqualsTwo()) self.eval_met_predicate(p, environ) def test_one_false(self): environ = {'test_number': 3} p = predicates.Any(EqualsTwo()) self.eval_unmet_predicate(p, environ, "At least one of the following predicates must be " "met: Number 3 doesn't equal 2") def test_two_true(self): environ = {'test_number': 4} p = predicates.Any(EqualsFour(), GreaterThan(3)) self.eval_met_predicate(p, environ) def test_two_false(self): environ = {'test_number': 1} p = predicates.Any(EqualsFour(), GreaterThan(3)) self.eval_unmet_predicate(p, environ, "At least one of the following predicates must be " "met: Number 1 doesn't equal 4, 1 is not greater " "than 3") def test_two_mixed(self): environ = {'test_number': 5} p = predicates.Any(EqualsFour(), GreaterThan(3)) self.eval_met_predicate(p, environ) class TestIsUserPredicate(BasePredicateTester): def test_user_without_credentials(self): environ = {} p = predicates.is_user('gustavo') self.eval_unmet_predicate(p, environ, 'The current user must be "gustavo"') def test_user_without_userid(self): environ = {'repoze.what.credentials': {}} p = predicates.is_user('gustavo') self.eval_unmet_predicate(p, environ, 'The current user must be "gustavo"') def test_right_user(self): environ = make_environ('gustavo') p = predicates.is_user('gustavo') self.eval_met_predicate(p, environ) def test_wrong_user(self): environ = make_environ('andreina') p = predicates.is_user('gustavo') self.eval_unmet_predicate(p, environ, 'The current user must be "gustavo"') class TestInGroupPredicate(BasePredicateTester): def test_user_belongs_to_group(self): environ = make_environ('gustavo', ['developers']) p = predicates.in_group('developers') self.eval_met_predicate(p, environ) def test_user_doesnt_belong_to_group(self): environ = make_environ('gustavo', ['developers', 'admins']) p = predicates.in_group('designers') self.eval_unmet_predicate(p, environ, 'The current user must belong to the group "designers"') class TestInAllGroupsPredicate(BasePredicateTester): def test_user_belongs_to_groups(self): environ = make_environ('gustavo', ['developers', 'admins']) p = predicates.in_all_groups('developers', 'admins') self.eval_met_predicate(p, environ) def test_user_doesnt_belong_to_groups(self): environ = make_environ('gustavo', ['users', 'admins']) p = predicates.in_all_groups('developers', 'designers') self.eval_unmet_predicate(p, environ, 'The current user must belong to the group "developers"') def test_user_doesnt_belong_to_one_group(self): environ = make_environ('gustavo', ['developers']) p = predicates.in_all_groups('developers', 'designers') self.eval_unmet_predicate(p, environ, 'The current user must belong to the group "designers"') class TestInAnyGroupsPredicate(BasePredicateTester): def test_user_belongs_to_groups(self): environ = make_environ('gustavo', ['developers',' admins']) p = predicates.in_any_group('developers', 'admins') self.eval_met_predicate(p, environ) def test_user_doesnt_belong_to_groups(self): environ = make_environ('gustavo', ['users', 'admins']) p = predicates.in_any_group('developers', 'designers') self.eval_unmet_predicate(p, environ, 'The member must belong to at least one of the ' 'following groups: developers, designers') def test_user_doesnt_belong_to_one_group(self): environ = make_environ('gustavo', ['designers']) p = predicates.in_any_group('developers', 'designers') self.eval_met_predicate(p, environ) class TestIsAnonymousPredicate(BasePredicateTester): def test_authenticated_user(self): environ = make_environ('gustavo') p = predicates.is_anonymous() self.eval_unmet_predicate(p, environ, 'The current user must be anonymous') def test_anonymous_user(self): environ = {} p = predicates.is_anonymous() self.eval_met_predicate(p, environ) class TestNotAnonymousPredicate(BasePredicateTester): def test_authenticated_user(self): environ = make_environ('gustavo') p = predicates.not_anonymous() self.eval_met_predicate(p, environ) def test_anonymous_user(self): environ = {} p = predicates.not_anonymous() self.eval_unmet_predicate(p, environ, 'The current user must have been authenticated') class TestHasPermissionPredicate(BasePredicateTester): def test_user_has_permission(self): environ = make_environ('gustavo', permissions=['watch-tv']) p = predicates.has_permission('watch-tv') self.eval_met_predicate(p, environ) def test_user_doesnt_have_permission(self): environ = make_environ('gustavo', permissions=['watch-tv']) p = predicates.has_permission('eat') self.eval_unmet_predicate(p, environ, 'The user must have the "eat" permission') class TestHasAllPermissionsPredicate(BasePredicateTester): def test_user_has_all_permissions(self): environ = make_environ('gustavo', permissions=['watch-tv', 'party', 'eat']) p = predicates.has_all_permissions('watch-tv', 'eat') self.eval_met_predicate(p, environ) def test_user_doesnt_have_permissions(self): environ = make_environ('gustavo', permissions=['watch-tv', 'party', 'eat']) p = predicates.has_all_permissions('jump', 'scream') self.eval_unmet_predicate(p, environ, 'The user must have the "jump" permission') def test_user_has_one_permission(self): environ = make_environ('gustavo', permissions=['watch-tv', 'party', 'eat']) p = predicates.has_all_permissions('party', 'scream') self.eval_unmet_predicate(p, environ, 'The user must have the "scream" permission') class TestUserHasAnyPermissionsPredicate(BasePredicateTester): def test_user_has_all_permissions(self): environ = make_environ('gustavo', permissions=['watch-tv', 'party', 'eat']) p = predicates.has_any_permission('watch-tv', 'eat') self.eval_met_predicate(p, environ) def test_user_doesnt_have_all_permissions(self): environ = make_environ('gustavo', permissions=['watch-tv', 'party', 'eat']) p = predicates.has_any_permission('jump', 'scream') self.eval_unmet_predicate(p, environ, 'The user must have at least one of the following ' 'permissions: jump, scream') def test_user_has_one_permission(self): environ = make_environ('gustavo', permissions=['watch-tv', 'party', 'eat']) p = predicates.has_any_permission('party', 'scream') self.eval_met_predicate(p, environ) #{ Test utilities def make_environ(user, groups=None, permissions=None): """Make a WSGI enviroment with the credentials dict""" credentials = {'repoze.what.userid': user} credentials['groups'] = groups or [] credentials['permissions'] = permissions or [] environ = {'repoze.what.credentials': credentials} return environ #{ Mock definitions class MockPredicate(predicates.Predicate): message = "I'm a fake predicate" class EqualsTwo(predicates.Predicate): message = "Number %(number)s doesn't equal 2" def evaluate(self, environ, credentials): number = environ.get('test_number') if not number or int(number) != 2: self.unmet(number=number) class EqualsFour(predicates.Predicate): message = "Number %(number)s doesn't equal 4" def evaluate(self, environ, credentials): number = environ.get('test_number') if number == 4: return self.unmet(number=number) class GreaterThan(predicates.Predicate): message = "%(number)s is not greater than %(compared_number)s" def __init__(self, compared_number, **kwargs): super(GreaterThan, self).__init__(**kwargs) self.compared_number = compared_number def evaluate(self, environ, credentials): number = environ.get('test_number') if not number > self.compared_number: self.unmet(number=number, compared_number=self.compared_number) class LessThan(predicates.Predicate): message = "%(number)s must be less than %(compared_number)s" def __init__(self, compared_number, **kwargs): super(LessThan, self).__init__(**kwargs) self.compared_number = compared_number def evaluate(self, environ, credentials): number = environ.get('test_number') if not number < self.compared_number: self.unmet(number=number, compared_number=self.compared_number) TurboGears2-2.3.7/tests/test_render.py0000644000076500000240000001241212555020522017765 0ustar amolstaff00000000000000""" Testing for TG2 Configuration """ from nose.tools import raises import tg from tg.render import MissingRendererError, _get_tg_vars from tests.base import setup_session_dir, teardown_session_dir from tg.configuration import AppConfig from mako.exceptions import TemplateLookupException from tg.util.webtest import test_context def setup(): setup_session_dir() def teardown(): teardown_session_dir() class FakePackage: __name__ = 'tests' __file__ = __file__ class lib: class app_globals: class Globals: pass @raises(MissingRendererError) def test_render_missing_renderer(): conf = AppConfig(minimal=True) app = conf.make_wsgi_app() tg.render_template({}, 'gensh') def test_jinja_lookup_nonexisting_template(): conf = AppConfig(minimal=True) conf.use_dotted_templatenames = True conf.renderers.append('jinja') conf.package = FakePackage() app = conf.make_wsgi_app() from jinja2 import TemplateNotFound try: render_jinja = conf.render_functions['jinja'] render_jinja('tg.this_template_does_not_exists', {'app_globals':tg.config['tg.app_globals']}) assert False except TemplateNotFound: pass class TestMakoLookup(object): def setup(self): conf = AppConfig(minimal=True) conf.use_dotted_templatenames = True conf.renderers.append('mako') conf.package = FakePackage() self.conf = conf self.app = conf.make_wsgi_app() def test_adjust_uri(self): render_mako = self.conf.render_functions['mako'] mlookup = render_mako.loader assert mlookup.adjust_uri('this_template_should_pass_unaltered', None) == 'this_template_should_pass_unaltered' dotted_test = mlookup.adjust_uri('tests.test_stack.rendering.templates.mako_inherits_local', None) assert dotted_test.endswith('tests/test_stack/rendering/templates/mako_inherits_local.mak') dotted_test = mlookup.adjust_uri('local:test_stack.rendering.templates.mako_inherits_local', None) assert dotted_test.endswith('tests/test_stack/rendering/templates/mako_inherits_local.mak') def test_local_lookup(self): render_mako = self.conf.render_functions['mako'] res = render_mako('tests.test_stack.rendering.templates.mako_inherits_local', {'app_globals':tg.config['tg.app_globals']}) assert 'inherited mako page' in res def test_passthrough_text_literal__check(self): from mako.template import Template t = Template('Hi') render_mako = self.conf.render_functions['mako'] mlookup = render_mako.loader mlookup.template_cache['hi_template'] = t assert mlookup.get_template('hi_template') is t @raises(TemplateLookupException) def test__check_not_existing_anymore(self): from mako.template import Template t = Template('Hi', filename='deleted_template.mak') render_mako = self.conf.render_functions['mako'] mlookup = render_mako.loader mlookup.template_cache['deleted_template'] = t mlookup.get_template('deleted_template') @raises(IOError) def test_never_existed(self): render_mako = self.conf.render_functions['mako'] mlookup = render_mako.loader mlookup.get_template('deleted_template') def test__check_should_reload_on_cache_expire(self): render_mako = self.conf.render_functions['mako'] mlookup = render_mako.loader template_path = mlookup.adjust_uri('tests.test_stack.rendering.templates.mako_inherits_local', None) t = mlookup.get_template(template_path) #cache the template t.output_encoding = 'FAKE_ENCODING' t = mlookup.get_template(template_path) assert t.output_encoding == 'FAKE_ENCODING' import os, stat def fake_os_stat(o): return {stat.ST_MTIME:t.module._modified_time+1} old_stat = os.stat os.stat = fake_os_stat try: t = mlookup.get_template(template_path) #if the template got reloaded should not have our fake encoding anymore assert t.output_encoding != 'FAKE_ENCODING' finally: os.stat = old_stat def test__check_should_not_reload_when_disabled(self): render_mako = self.conf.render_functions['mako'] mlookup = render_mako.loader mlookup.auto_reload = False template_path = mlookup.adjust_uri('tests.test_stack.rendering.templates.mako_inherits_local', None) t = mlookup.get_template(template_path) #cache the template t.output_encoding = 'FAKE_ENCODING' t = mlookup.get_template(template_path) assert t.output_encoding == 'FAKE_ENCODING' import os, stat def fake_os_stat(o): return {stat.ST_MTIME:t.module._modified_time+1} old_stat = os.stat os.stat = fake_os_stat try: t = mlookup.get_template(template_path) assert t.output_encoding == 'FAKE_ENCODING' finally: os.stat = old_stat def test_fallback_validation_context_in_templates(self): with test_context(None, '/'): vars = _get_tg_vars() assert vars.tg.errors == {}, vars.tg assert vars.tg.inputs == {}, vars.tgTurboGears2-2.3.7/tests/test_rest_controller_dispatch.py0000644000076500000240000005137612413576166023636 0ustar amolstaff00000000000000# -*- coding: utf-8 -*- from webob import Response, Request from tg.controllers import TGController, RestController from tg.decorators import expose from tg.util import no_warn from tests.base import ( TestWSGIController, make_app, setup_session_dir, teardown_session_dir) def setup(): setup_session_dir() def teardown(): teardown_session_dir() def wsgi_app(environ, start_response): req = Request(environ) if req.method == 'POST': resp = Response(req.POST['data']) else: resp = Response("Hello from %s/%s"%(req.script_name, req.path_info)) return resp(environ, start_response) class LookupHelper: def __init__(self, var): self.var = var @expose() def index(self): return self.var class LookupController(TGController): @expose() def _lookup(self, a, *args): return LookupHelper(a), args class DeprecatedLookupController(TGController): @expose() def _lookup(self, a, *args): return LookupHelper(a), args class LookupAlwaysHelper: """for testing _dispatch""" def __init__(self, var): self.var = var def _setup_wsgiorg_routing_args(self, url_path, remainder, params): pass @expose() def always(self, *args, **kwargs): return 'always go here' def _dispatch(self, state, remainder): state.add_method(self.always, remainder) return state class LookupAlwaysController(TGController): @expose() def _lookup(self, a, *args): return LookupAlwaysHelper(a), args class CustomDispatchingSubController(TGController): @expose() def always(self, *args, **kwargs): return 'always go here' def _dispatch(self, state, remainder): state.add_method(self.always, remainder) return state class OptionalArgumentRestController(RestController): @expose() def get_one(self, optional=None): return "SUBREST GET ONE" @expose() def put(self, optional=None): return "subrest put" @expose() def post(self, optional=None): return "subrest post" @expose() def edit(self, optional=None): return "subrest edit" @expose() def new(self, optional=None): return "subrest new" @expose() def get_delete(self, optional=None): return "subrest get delete" @expose() def post_delete(self, optional=None): return "subrest post delete" class RequiredArgumentRestController(RestController): @expose() def get_one(self, something): return "subrest get one" @expose() def put(self, something): return "subrest put" @expose() def post(self, something): return "subrest post" @expose() def edit(self, something): return "subrest edit" @expose() def new(self): return "subrest new" @expose() def get_delete(self, something): return "subrest get delete" @expose() def post_delete(self, something): return "subrest post delete" class VariableSubRestController(RestController): @expose() def get_one(self, *args): return "subrest get one" @expose() def put(self, *args): return "subrest put" @expose() def edit(self, *args): return "subrest edit" @expose() def new(self, *args): return "subrest new" @expose() def get_delete(self, *args): return "subrest get delete" @expose() def post_delete(self, *args): return "subrest post delete" class SubRestController(RestController): @expose() def get_all(self): return "subrest get all" @expose() def get_one(self, nr): return "subrest get one %s" % nr @expose() def new(self): return "subrest new" @expose() def edit(self, nr): return "subrest edit %s" % nr @expose() def post(self): return "subrest post" @expose() def put(self, nr): return "subrest put %s" % nr @expose() def fxn(self): return "subrest fxn" @expose() def get_delete(self, nr): return "subrest get delete %s" % nr @expose() def post_delete(self, nr): return "subrest post delete %s" % nr class VariableRestController(RestController): subrest = SubRestController() vsubrest = VariableSubRestController() @expose() def get_all(self): return "rest get all" @expose() def get_one(self, *args): return "rest get onE" @expose() def get_delete(self, *args): return "rest get delete" @expose() def post_delete(self, *args): return "rest post delete" class ExtraRestController(RestController): @expose() def get_all(self): return "rest get all" @expose() def get_one(self, nr): return "rest get one %s" % nr @expose() def get_delete(self, nr): return "rest get delete %s" % nr @expose() def post_delete(self, nr): return "rest post delete %s" % nr class SubClass(TGController): @expose() def index(self): return "rest sub index" sub = SubClass() subrest = SubRestController() optsubrest = OptionalArgumentRestController() reqsubrest = RequiredArgumentRestController() @expose() def post_archive(self): return 'got to post archive' @expose() def get_archive(self): return 'got to get archive' class BasicRestController(RestController): @expose() def get(self): return "rest get" @expose() def post(self): return "rest post" @expose() def put(self): return "rest put" @expose() def delete(self): return "rest delete" @expose() def new(self): return "rest new" @expose() def edit(self, *args, **kw): return "rest edit" @expose() def other(self): return "rest other" @expose() def archive(self): return 'got to archive' class EmptyRestController(RestController): pass class SubController(TGController): rest = BasicRestController() @expose() def sub_method(self, arg): return 'sub %s'%arg class BasicTGController(TGController): sub = SubController() custom_dispatch = CustomDispatchingSubController() lookup = LookupController() deprecated_lookup = LookupController() lookup_dispatch = LookupAlwaysController() rest = BasicRestController() rest2 = ExtraRestController() rest3 = VariableRestController() empty = EmptyRestController() @expose() def index(self, **kwargs): return 'hello world' @expose() def _default(self, *remainder): return "Main default page called for url /%s" % [str(r) for r in remainder] @expose() def hello(self, name, silly=None): return "Hello %s" % name class BasicTGControllerNoDefault(TGController): @expose() def index(self, **kwargs): return 'hello world' class TestTGControllerRoot(TestWSGIController): def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.app = make_app(BasicTGControllerNoDefault) def test_root_default_dispatch(self): self.app.get('/i/am/not/a/sub/controller', status=404) class TestTGController(TestWSGIController): def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.app = make_app(BasicTGController) def test_lookup(self): r = self.app.get('/lookup/eye') msg = 'eye' assert msg in r, r def test_deprecated_lookup(self): r = self.app.get('/deprecated_lookup/eye') msg = 'eye' assert msg in r, r def test_lookup_with_dispatch(self): r = self.app.get('/lookup_dispatch/eye') msg = 'always' assert msg in r, r def test_root_method_dispatch(self): resp = self.app.get('/hello/Bob') assert "Hello Bob" in resp, resp def test_root_index_dispatch(self): resp = self.app.get('/') assert "hello world" in resp, resp def test_no_sub_index_dispatch(self): resp = self.app.get('/sub/') assert "['sub']" in resp, resp def test_root_default_dispatch(self): resp = self.app.get('/i/am/not/a/sub/controller') assert "['i', 'am', 'not', 'a', 'sub', 'controller']" in resp, resp def test_default_dispatch_not_found_in_sub_controller(self): resp = self.app.get('/sub/no/default/found') assert "['sub', 'no', 'default', 'found']" in resp, resp def test_root_method_dispatch_with_trailing_slash(self): resp = self.app.get('/hello/Bob/') assert "Hello Bob" in resp, resp def test_sub_method_dispatch(self): resp = self.app.get('/sub/sub_method/army of darkness') assert "sub army" in resp, resp def test_custom_dispatch(self): resp = self.app.get('/custom_dispatch/army of darkness') assert "always" in resp, resp class TestRestController(TestWSGIController): def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.app = make_app(BasicTGController) def test_post(self): r = self.app.post('/rest/') assert 'rest post' in r, r def _test_non_resty(self): r = self.app.post('/rest/non_resty_thing') assert 'non_resty' in r, r def test_custom_action_simple_get(self): r = self.app.get('/rest/archive') assert 'got to archive' in r, r def test_custom_action_simple_post(self): r = self.app.post('/rest/archive') assert 'got to archive' in r, r def test_custom_action_simple_post_args(self): r = self.app.post('/rest?_method=archive') assert 'got to archive' in r, r def test_custom_action_get(self): r = self.app.get('/rest2/archive') assert 'got to get archive' in r, r def test_custom_action_post(self): r = self.app.post('/rest2?_method=archive') assert 'got to post archive' in r, r def test_get(self): r = self.app.get('/rest/') assert 'rest get' in r, r def test_put(self): r = self.app.put('/rest/') assert 'rest put' in r, r def test_put_post(self): r = self.app.post('/rest?_method=PUT') assert 'rest put' in r, r def test_put_post_params(self): r = self.app.post('/rest', params={'_method':'PUT'}) assert 'rest put' in r, r def test_put_get(self): self.app.get('/rest?_method=PUT', status=405) def test_get_delete_bad(self): self.app.get('/rest?_method=DELETE', status=405) def test_delete(self): r = self.app.delete('/rest/') assert 'rest delete' in r, r def test_post_delete(self): r = self.app.post('/rest/', params={'_method':'DELETE'}) assert 'rest delete' in r, r def test_get_all(self): r = self.app.get('/rest2/') assert 'rest get all' in r, r def test_get_one(self): r = self.app.get('/rest2/1') assert 'rest get one 1' in r, r def test_get_delete(self): r = self.app.get('/rest2/1/delete') assert 'rest get delete' in r, r def test_post_delete_params(self): r = self.app.post('/rest2/1', params={'_method':'DELETE'}) assert 'rest post delete' in r, r def test_post_delete_var(self): r = self.app.post('/rest3/a/b/c', params={'_method':'DELETE'}) assert 'rest post delete' in r, r def test_get_delete_var(self): r = self.app.get('/rest3/a/b/c/delete') assert 'rest get delete' in r, r def test_get_method(self): r = self.app.get('/rest/other') assert 'rest other' in r, r @no_warn def test_get_sub_controller(self): r = self.app.get('/rest2/sub') assert 'rest sub index' in r, r @no_warn def test_put_sub_controller(self): r = self.app.put('/rest2/sub') assert 'rest sub index' in r, r def test_post_sub_controller(self): r = self.app.post('/rest2/sub') assert 'rest sub index' in r, r def test_post_miss(self): r = self.app.post('/rest2/something') assert "/['rest2', 'something']" in r, r def test_get_empty(self): r = self.app.get('/empty/') assert "/['empty']" in r, r def test_post_empty(self): r = self.app.post('/empty/') assert "/['empty']" in r, r def test_put_empty(self): r = self.app.put('/empty/') assert "/['empty']" in r, r @no_warn def test_delete_empty(self): r = self.app.delete('/empty/') assert "/['empty']" in r, r def test_put_miss(self): r = self.app.put('/rest/something') assert "/['rest', 'something']" in r, r def test_delete_miss(self): r = self.app.delete('/rest/something') assert "/['rest', 'something']" in r, r def test_get_miss(self): r = self.app.get('/rest2/something/else') assert "/['rest2', 'something', 'else']" in r, r def test_post_method(self): r = self.app.post('/rest/other') assert 'rest other' in r, r def test_new_method(self): r = self.app.post('/rest/new') assert 'rest new' in r, r def test_edit_method(self): r = self.app.get('/rest/1/edit') assert 'rest edit' in r, r def test_delete_method(self): self.app.delete('/rest/other', status=405) def test_sub_with_rest_delete(self): r = self.app.delete('/sub/rest/') assert 'rest delete' in r, r def test_put_method(self): r = self.app.put('/rest/other') assert 'rest other' in r, r def test_sub_get_all_method(self): r = self.app.get('/rest2/1/subrest') assert 'subrest get all' in r, r def test_var_sub_get_all_method(self): r = self.app.get('/rest3/1/3/3/subrest') assert 'subrest get all' in r, r r = self.app.get('/rest3/1/3/subrest') assert 'subrest get all' in r, r r = self.app.get('/rest3/subrest') assert 'subrest get all' in r, r def test_var_sub_get_one_method(self): r = self.app.get('/rest3/1/3/3/subrest/1') assert 'subrest get one' in r, r r = self.app.get('/rest3/1/3/subrest/1') assert 'subrest get one' in r, r r = self.app.get('/rest3/subrest/1') assert 'subrest get one' in r, r def test_var_sub_edit_method(self): r = self.app.get('/rest3/1/3/3/subrest/1/edit') assert 'subrest edit' in r, r r = self.app.get('/rest3/1/3/subrest/1/edit') assert 'subrest edit' in r, r r = self.app.get('/rest3/subrest/1/edit') assert 'subrest edit' in r, r def test_var_sub_edit_var_method(self): r = self.app.get('/rest3/1/3/3/vsubrest/1/edit') assert 'subrest edit' in r, r r = self.app.get('/rest3/1/3/vsubrest/1/a/edit') assert 'subrest edit' in r, r r = self.app.get('/rest3/vsubrest/edit') assert 'subrest edit' in r, r def test_var_sub_delete_method(self): r = self.app.get('/rest3/1/3/3/subrest/1/delete') assert 'subrest get delete' in r, r r = self.app.get('/rest3/1/3/subrest/1/delete') assert 'subrest get delete' in r, r r = self.app.get('/rest3/subrest/1/delete') assert 'subrest get delete' in r, r def test_var_sub_new_method(self): r = self.app.get('/rest3/1/3/3/subrest/new') assert 'subrest new' in r, r r = self.app.get('/rest3/1/3/subrest/new') assert 'subrest new' in r, r r = self.app.get('/rest3/subrest/new') assert 'subrest new' in r, r def test_var_sub_var_get_one_method(self): r = self.app.get('/rest3/1/3/3/vsubrest/1') assert 'subrest get one' in r, r r = self.app.get('/rest3/1/3/vsubrest/1/a') assert 'subrest get one' in r, r r = self.app.get('/rest3/vsubrest/') assert 'subrest get one' in r, r def test_var_sub_var_put_method(self): r = self.app.put('/rest3/1/3/3/vsubrest/1') assert 'subrest put' in r, r r = self.app.put('/rest3/1/3/vsubrest/1/asdf') assert 'subrest put' in r, r r = self.app.put('/rest3/vsubrest/') assert 'subrest put' in r, r def test_var_sub_post_method(self): r = self.app.post('/rest3/1/3/3/subrest/') assert 'subrest post' in r, r r = self.app.post('/rest3/1/3/subrest/') assert 'subrest post' in r, r r = self.app.post('/rest3/subrest/') assert 'subrest post' in r, r def test_var_sub_post_delete_method(self): r = self.app.delete('/rest3/1/3/3/subrest/1') assert 'subrest post delete' in r, r r = self.app.delete('/rest3/1/3/subrest/1') assert 'subrest post delete' in r, r def test_var_sub_put_method(self): r = self.app.put('/rest3/1/3/3/subrest/1') assert 'subrest put' in r, r r = self.app.put('/rest3/1/3/subrest/1') assert 'subrest put' in r, r r = self.app.put('/rest3/subrest/1') assert 'subrest put' in r, r def test_var_sub_put_hack_method(self): r = self.app.post('/rest3/1/3/3/subrest/1?_method=PUT') assert 'subrest put' in r, r r = self.app.post('/rest3/1/3/subrest/1?_method=put') assert 'subrest put' in r, r r = self.app.post('/rest3/subrest/1?_method=put') assert 'subrest put' in r, r def test_var_sub_var_delete_method(self): r = self.app.delete('/rest3/1/3/3/vsubrest/1') assert 'subrest post delete' in r, r r = self.app.delete('/rest3/1/3/vsubrest/1') assert 'subrest post delete' in r, r r = self.app.delete('/rest3/vsubrest/') assert 'subrest post delete' in r, r def test_var_sub_delete_var_hack_method(self): r = self.app.post('/rest3/1/3/3/vsubrest/1?_method=DELETE') assert 'subrest post delete' in r, r r = self.app.post('/rest3/1/3/vsubrest/1?_method=delete') assert 'subrest post delete' in r, r r = self.app.post('/rest3/vsubrest?_method=delete') assert 'subrest post delete' in r, r def test_var_sub_var_put_hack_method(self): r = self.app.post('/rest3/1/3/3/vsubrest/1?_method=PUT') assert 'subrest put' in r, r r = self.app.post('/rest3/1/3/vsubrest/1/a?_method=put') assert 'subrest put' in r, r r = self.app.post('/rest3/vsubrest/?_method=put') assert 'subrest put' in r, r def test_var_sub_delete_hack_method(self): r = self.app.post('/rest3/1/3/3/subrest/1?_method=DELETE') assert 'subrest post delete' in r, r r = self.app.post('/rest3/1/3/subrest/1?_method=delete') assert 'subrest post delete' in r, r r = self.app.post('/rest3/subrest/1?_method=delete') assert 'subrest post delete' in r, r def test_sub_new(self): r = self.app.get('/rest2/1/subrest/new') assert 'subrest new' in r, r def test_sub_edit(self): r = self.app.get('/rest2/1/subrest/1/edit') assert 'subrest edit' in r, r def test_sub_post(self): r = self.app.post('/rest2/1/subrest/') assert 'subrest post' in r, r def test_sub_put(self): r = self.app.put('/rest2/1/subrest/2') assert 'subrest put' in r, r def test_sub_post_opt(self): r = self.app.post('/rest2/1/optsubrest/1') assert 'subrest post' in r, r def test_sub_put_opt(self): r = self.app.put('/rest2/1/optsubrest/1') assert 'subrest put' in r, r def test_sub_put_opt_hack(self): r = self.app.post('/rest2/1/optsubrest/1?_method=PUT') assert 'subrest put' in r, r def test_sub_delete_opt_hack(self): r = self.app.post('/rest2/1/optsubrest/1?_method=DELETE') assert 'subrest ' in r, r def test_put_post_req(self): r = self.app.post('/rest2/reqsubrest', params={'something':'required'}) assert 'subrest post' in r, r def test_sub_put_req(self): r = self.app.post('/rest2/reqsubrest', params={'_method':'PUT', 'something':'required'}) assert 'subrest put' in r, r def test_sub_post_req_bad(self): r = self.app.post('/rest2/reqsubrest',) assert "['rest2', 'reqsubrest']" in r, r def test_sub_delete_hack(self): r = self.app.post('/rest2/1/subrest/2?_method=DELETE') assert 'subrest post delete' in r, r def test_sub_get_delete(self): r = self.app.get('/rest2/1/subrest/2/delete') assert 'subrest get delete' in r, r def test_sub_post_delete(self): r = self.app.delete('/rest2/1/subrest/2') assert 'subrest post delete' in r, r def test_sub_get_fxn(self): r = self.app.get('/rest2/1/subrest/fxn') assert 'subrest fxn' in r, r def test_sub_post_fxn(self): r = self.app.post('/rest2/1/subrest/fxn') assert 'subrest fxn' in r, r TurboGears2-2.3.7/tests/test_stack/0000755000076500000240000000000012607177763017263 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/__init__.py0000644000076500000240000000443112607177564021375 0ustar amolstaff00000000000000import os from webtest import TestApp import tg import tests from tg.util import DottedFileNameFinder from tg.configuration import AppConfig from tg.configuration import milestones from tg._compat import PY3 class TestConfig(AppConfig): __test__ = False def __init__(self, folder, values=None): if values is None: values = {} AppConfig.__init__(self) # First we setup some base values that we know will work self.renderers = ['genshi', 'mako', 'jinja','json', 'jsonp', 'kajiki'] self.render_functions = tg.util.Bunch() self.package = tests.test_stack self.default_renderer = 'genshi' self.globals = self self.auth_backend = None self.auto_reload_templates = False self.use_legacy_renderer = False self.use_dotted_templatenames = False self.serve_static = False self['errorpage.enabled'] = False root = os.path.dirname(os.path.dirname(tests.__file__)) test_base_path = os.path.join(root,'tests', 'test_stack',) test_config_path = os.path.join(test_base_path, folder) self.paths = tg.util.Bunch( root=test_base_path, controllers=os.path.join(test_config_path, 'controllers'), static_files=os.path.join(test_config_path, 'public'), templates=[os.path.join(test_config_path, 'templates')], i18n=os.path.join(test_config_path, 'i18n') ) # then we override those values with what was passed in for key, value in values.items(): setattr(self, key, value) def add_debugger_middleware(self, global_conf, app): return app def app_from_config(base_config, deployment_config=None, reset_milestones=True): if not deployment_config: deployment_config = {'debug': 'false', 'error_email_from': 'paste@localhost', 'smtp_server': 'localhost'} # Reset milestones so that they can be reached again # on next configuration initialization if reset_milestones: milestones._reset_all() env_loader = base_config.make_load_environment() app_maker = base_config.setup_tg_wsgi_app(env_loader) app = TestApp(app_maker(deployment_config, full_stack=False)) return app TurboGears2-2.3.7/tests/test_stack/baseutils.py0000644000076500000240000000262112517763457021632 0ustar amolstaff00000000000000import tg class FakePackage(object): pass default_config = { 'debug': False, 'package': FakePackage, 'package_name' : 'FakePackage', 'paths': {'root': None, 'controllers': None, 'templates': [], 'static_files': None}, 'db_engines': {}, 'tg.strict_tmpl_context':False, 'use_dotted_templatenames':True, 'buffet.template_engines': [], 'buffet.template_options': {}, 'default_renderer':'json', 'renderers': ['json'], 'render_functions': {'json': tg.renderers.json.JSONRenderer.render_json}, 'rendering_engines_options': {'json': {'content_type': 'application/json'}}, 'rendering_engines_without_vars': set(('json',)), 'use_legacy_renderers': False, 'use_sqlalchemy': False, 'i18n.lang': None } class FakeRoutes(object): def __init__(self, app): self.app = app def __call__(self, environ, start_response): environ['wsgiorg.routing_args'] = [None, {'controller':'root'}] environ['routes.url'] = None return self.app(environ, start_response) class ControllerWrap(object): def __init__(self, controller): self.controller = controller def __call__(self, environ, start_response): app = self.controller() return app(environ, start_response) TurboGears2-2.3.7/tests/test_stack/config/0000755000076500000240000000000012607177763020530 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/config/__init__.py0000644000076500000240000000000012413576166022622 0ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/config/controllers/0000755000076500000240000000000012607177763023076 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/config/controllers/__init__.py0000644000076500000240000000000012413576166025170 0ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/config/controllers/root.py0000644000076500000240000000145112413576166024427 0ustar amolstaff00000000000000"""Main Controller""" from tg import expose, redirect, config from tg.controllers import TGController class RootController(TGController): @expose() def index(self): return "my foo" @expose() def config_test(self): return str(config) @expose() def config_attr_lookup(self): return str(config.render_functions) @expose() def config_dotted_values(self): return str(config.paths) @expose() def config_attr_set(self, foo): config.test_value = foo return str(config.test_value) @expose() def config_set_method(self): return str(config.get('pylons')) @expose() def config_dict_set(self, foo): config['test_value'] = foo return str(config.test_value) TurboGears2-2.3.7/tests/test_stack/config/test_config.py0000644000076500000240000000234212413576166023402 0ustar amolstaff00000000000000from tests.test_stack import TestConfig, app_from_config def setup_noDB(): base_config = TestConfig(folder = 'config', values = {'use_sqlalchemy': False, 'use_toscawidgets': False, 'use_toscawidgets2':False} ) return app_from_config(base_config) def test_basic_stack(): app = setup_noDB() resp = app.get('/') assert resp.body.decode('ascii') == "my foo" def test_config_reading(): """Ensure that the config object can be read via dict and attr access""" app = setup_noDB() resp = app.get('/config_test') resp_body = resp.body.decode('ascii') assert "default_renderer" in resp_body resp = app.get('/config_attr_lookup') assert "genshi" in resp_body resp = app.get('/config_dotted_values') assert "root" in resp_body def test_config_writing(): """Ensure that new values can be added to the config object""" app = setup_noDB() value = "gooberblue" resp = app.get('/config_attr_set/'+value) resp_body = resp.body.decode('ascii') assert value in resp_body resp = app.get('/config_dict_set/'+value) assert value in resp_body TurboGears2-2.3.7/tests/test_stack/dispatch/0000755000076500000240000000000012607177763021062 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/dispatch/__init__.py0000644000076500000240000000000012413576166023154 0ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/dispatch/controllers/0000755000076500000240000000000012607177763023430 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/dispatch/controllers/__init__.py0000644000076500000240000000000012413576166025522 0ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/dispatch/controllers/root.py0000644000076500000240000001401212607177564024762 0ustar amolstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals import tg from tg.controllers import TGController from tg.decorators import expose, validate, https, variable_decode, with_trailing_slash, \ without_trailing_slash, with_engine from tg import expose, redirect, config from tg.controllers import TGController from tg import dispatched_controller from nose.tools import eq_ from tests.test_validation import validators from tg._compat import unicode_text from paste.deploy.converters import asbool class NestedSubController(TGController): @expose() def index(self): return '-'.join((self.mount_point, dispatched_controller().mount_point)) @expose() def hitme(self): return '*'.join((self.mount_point, dispatched_controller().mount_point)) @expose() def _lookup(self, *args): lookup = LookupController() return lookup, args class SubController(TGController): nested = NestedSubController() @expose() def foo(self,): return 'sub_foo' @expose() def index(self): return 'sub index' @expose() def _default(self, *args): return ("recieved the following args (from the url): %s" %list(args)) @expose() def redirect_me(self, target, **kw): tg.redirect(target, **kw) @expose() def redirect_sub(self): tg.redirect('index') @expose() def redirect_list(self): tg.redirect(["/sub2", "list"]) @expose() def hello(self, name): return "Why HELLO! " + name @expose() def hitme(self): return '@'.join((self.mount_point, dispatched_controller().mount_point)) class LookupController(TGController): nested = NestedSubController() @expose() def findme(self, *args, **kw): return 'got to lookup' @expose() def hiddenhitme(self, *args, **kw): return ' '.join((self.mount_point, dispatched_controller().mount_point)) class SubController2(object): @expose() def index(self): tg.redirect('list') @expose() def list(self, **kw): return "hello list" @expose() def _lookup(self, *args): lookup = LookupController() return lookup, args class RootController(TGController): @expose() def index(self, **kwargs): return 'hello world' @expose() def _default(self, remainder): return "Main Default Page called for url /%s"%remainder @expose() def feed(self, feed=None): return feed sub = SubController() sub2 = SubController2() @expose() def redirect_me(self, target, **kw): tg.redirect(target, kw) @expose() def hello(self, name, silly=None): return "Hello " + name @expose() def redirect_cookie(self, name): tg.response.set_cookie('name', name) tg.redirect('/hello_cookie') @expose() def hello_cookie(self): return "Hello " + tg.request.cookies['name'] @expose() def flash_redirect(self): tg.flash("Wow,
flash!") tg.redirect("/flash_after_redirect") @expose() def flash_render(self, using_js=False, with_message=True): if asbool(with_message): tg.flash('JS
Flash') return tg.flash.render('flash', asbool(using_js)) @expose() def bigflash_redirect(self): tg.flash('x' * 5000) tg.redirect('/flash_after_redirect') @expose() def flash_unicode(self): tg.flash("Привет, мир!") tg.redirect("/flash_after_redirect") @expose() def flash_after_redirect(self): return tg.get_flash() @expose() def flash_status(self): return tg.get_status() @expose() def flash_no_redirect(self): tg.flash("Wow, flash!") return tg.get_flash() @expose('json') @validate(validators={"some_int": validators.Int()}) def validated_int(self, some_int): assert isinstance(some_int, int) return dict(response=some_int) @expose('json') @validate(validators={"a":validators.Int()}) def validated_and_unvalidated(self, a, b): assert isinstance(a, int) assert isinstance(b, unicode_text) return dict(int=a,str=b) @expose() @expose('json') def stacked_expose(self, tg_format=None): return dict(got_json=True) @expose('json') def json_return_list(self): return [1,2,3] @expose(content_type='image/png') def custom_content_type(self): return b'PNG' @expose() def custom_content_type2(self): tg.response.content_type = 'image/png' return b'PNG2' @expose(content_type='text/plain') def custom_content_text_plain_type(self): return 'a
bx' @expose() def check_params(self, *args, **kwargs): if not args and not kwargs: return "None recieved" else: return "Controler recieved: %s, %s" %(args, kwargs) @expose() def test_url_sop(self): from tg import url eq_('/foo', url('/foo')) u = url("/foo", params=dict(bar=1, baz=2)) assert u in \ ["/foo?bar=1&baz=2", "/foo?baz=2&bar=1"], u @https @expose() def test_https(self, **kw): return '' @expose('json') @variable_decode def test_vardec(self, **kw): return kw @expose('mako:echo.mak') def echo(self): return dict() @expose() @with_trailing_slash def with_tslash(self): return 'HI' @expose() @without_trailing_slash def without_tslash(self): return 'HI' @expose() @with_engine('mainslave') def onmaster_without_params(self, **kw): return '%s-%s' % (tg.request._tg_force_sqla_engine, kw) @expose() @with_engine('mainslave', master_params=['first']) def onmaster_withlist(self, **kw): return '%s-%s' % (tg.request._tg_force_sqla_engine, kw) @expose() @with_engine('mainslave', master_params={'first':True, 'second':False}) def onmaster(self, **kw): return '%s-%s' % (tg.request._tg_force_sqla_engine, kw)TurboGears2-2.3.7/tests/test_stack/dispatch/test_config.py0000644000076500000240000000300612413576166023732 0ustar amolstaff00000000000000import os from tests.test_stack import TestConfig from webtest import TestApp def setup_noDB(): global_config = {'debug': 'true', 'error_email_from': 'paste@localhost', 'smtp_server': 'localhost'} base_config = TestConfig(folder = 'config', values = {'use_sqlalchemy': False, 'use_toscawidgets':False, 'use_toscawidgets2':False} ) env_loader = base_config.make_load_environment() app_maker = base_config.setup_tg_wsgi_app(env_loader) app = TestApp(app_maker(global_config, full_stack=True)) return app def test_basic_stack(): app = setup_noDB() resp = app.get('/') assert resp.body.decode('ascii') == "my foo" def test_config_reading(): """Ensure that the config object can be read via dict and attr access""" app = setup_noDB() resp = app.get('/config_test') assert "default_renderer" in str(resp.body) resp = app.get('/config_attr_lookup') assert "genshi" in str(resp.body) resp = app.get('/config_dotted_values') assert "root" in str(resp.body) def test_config_writing(): """Ensure that new values can be added to the config object""" app = setup_noDB() value = "gooberblue" resp = app.get('/config_attr_set/'+value) assert value in str(resp.body) resp = app.get('/config_dict_set/'+value) assert value in str(resp.body) TurboGears2-2.3.7/tests/test_stack/dispatch/test_decorated_controller.py0000644000076500000240000001551512607177564026676 0ustar amolstaff00000000000000# -*- coding: utf-8 -*- from nose.tools import raises import os, tg from tests.test_stack import TestConfig, app_from_config from tg.configuration.hooks import _TGGlobalHooksNamespace from tg.decorators import Decoration from tg.configuration import milestones from tg.util import Bunch class TestHooks(object): def setUp(self): milestones._reset_all() tg.hooks = _TGGlobalHooksNamespace() def tearDown(self): milestones._reset_all() tg.hooks = _TGGlobalHooksNamespace() def test_hooks_syswide(self): base_config = TestConfig(folder = 'dispatch', values = {'use_sqlalchemy': False, 'use_toscawidgets': False, 'use_toscawidgets2': False, 'ignore_parameters': ["ignore", "ignore_me"] }) def hook(*args, **kw): tg.tmpl_context.echo = 'WORKED' base_config.register_hook('before_call', hook) app = app_from_config(base_config, reset_milestones=False) ans = app.get('/echo') assert 'WORKED' in ans def test_decoration_run_hooks_backward_compatibility(self): # TODO: Remove test when Decoration.run_hooks gets removed def func(*args, **kw): pass def hook(*args, **kw): hook.did_run = True hook.did_run = False milestones.renderers_ready.reach() tg.hooks.register('before_call', hook, controller=func) deco = Decoration.get_decoration(func) deco.run_hooks(Bunch(config=None), 'before_call') assert hook.did_run is True class TestExpose(object): def setUp(self): milestones.renderers_ready._reset() def tearDown(self): milestones.renderers_ready._reset() def test_unregisterd_renderers_detection(self): #If no renderers are available we should just issue a warning #and avoid crashing. Simply bypass rendering availability check. base_config = TestConfig(folder = 'dispatch', values = {'use_sqlalchemy': False, 'use_toscawidgets': False, 'use_toscawidgets2': False, 'ignore_parameters': ["ignore", "ignore_me"] }) app = app_from_config(base_config) old_renderers = tg.config['renderers'] tg.config['renderers'] = [] @tg.expose('mako:nonexisting') def func(*args, **kw): pass tg.config['renderers'] = old_renderers def test_use_default_renderer(self): base_config = TestConfig(folder = 'dispatch', values = {'use_sqlalchemy': False, 'use_toscawidgets': False, 'use_toscawidgets2': False, 'ignore_parameters': ["ignore", "ignore_me"] }) app = app_from_config(base_config) exposition = tg.expose('nonexisting') exposition._resolve_options() assert exposition.engine == tg.config['default_renderer'] assert exposition.template == 'nonexisting' def test_expose_without_function_does_nothing(self): base_config = TestConfig(folder = 'dispatch', values = {'use_sqlalchemy': False, 'use_toscawidgets': False, 'use_toscawidgets2': False, 'ignore_parameters': ["ignore", "ignore_me"] }) app = app_from_config(base_config) exposition = tg.expose('nonexisting') exposition._apply() assert exposition._func is None assert exposition.engine is None def test_expose_idempotent(self): base_config = TestConfig(folder = 'dispatch', values = {'use_sqlalchemy': False, 'use_toscawidgets': False, 'use_toscawidgets2': False, 'ignore_parameters': ["ignore", "ignore_me"] }) app = app_from_config(base_config) exposition = tg.expose('nonexisting') @exposition @exposition def func(*args, **kw): pass milestones.renderers_ready.reach() deco = Decoration.get_decoration(func) assert len(deco.engines) == 1, deco.engines class TestDecorators(object): def setup(self): base_config = TestConfig(folder = 'dispatch', values = {'use_sqlalchemy': False, 'use_toscawidgets': False, 'use_toscawidgets2': False, 'ignore_parameters': ["ignore", "ignore_me"] }) self.app = app_from_config(base_config) def test_variabledecode_fail(self): resp = self.app.get('/test_vardec', params={'test-1': '1', 'test-2': 2, 'test--repetitions': 'hi'}) assert resp.json['test-1'] == '1', resp.json assert resp.json['test--repetitions'] == 'hi', resp.json assert 'test' not in resp.json, resp.json def test_variabledecode_partial_fail(self): resp = self.app.get('/test_vardec', params={'test-1': '1', 'test-2': 2, 'test-': 4}) assert resp.json['test-1'] == '1' assert resp.json['test-'] == '4' assert len(resp.json['test']) == 2 def test_variable_decode(self): from formencode.variabledecode import variable_encode obj = dict(a=['1','2','3'], b=dict(c=[dict(d='1')])) params = variable_encode(dict(obj=obj), add_repetitions=False) resp = self.app.get('/test_vardec', params=params) assert resp.json['obj'] == obj, (resp.json['obj'], obj) def test_without_trailing_slash(self): resp = self.app.get('/without_tslash/', status=301) assert resp.headers['Location'].endswith('/without_tslash') def test_with_trailing_slash(self): resp = self.app.get('/with_tslash', status=301) assert resp.headers['Location'].endswith('/with_tslash/') def test_with_engine(self): resp = self.app.get('/onmaster') assert 'mainslave' in resp def test_with_engine_without_params(self): resp = self.app.get('/onmaster_without_params?first=1&second=1') assert 'mainslave' in resp def test_with_engine_nopop(self): resp = self.app.get('/onmaster?second=1') assert 'master' in resp assert 'second' in resp def test_with_engine_pop(self): resp = self.app.get('/onmaster?first=1') assert 'master' in resp assert 'first' not in resp def test_with_engine_using_list(self): resp = self.app.get('/onmaster_withlist?first=1') assert 'master' in resp assert 'first' not in resp TurboGears2-2.3.7/tests/test_stack/dispatch/test_url_dispatch.py0000644000076500000240000001542712555020522025143 0ustar amolstaff00000000000000# -*- coding: utf-8 -*- from tests.test_stack import TestConfig, app_from_config from tg.util import no_warn from tg._compat import u_ def setup_noDB(html_flash=False): config = {'use_sqlalchemy': False, 'use_toscawidgets': False, 'use_toscawidgets2': False, 'ignore_parameters': ["ignore", "ignore_me"]} if html_flash: config['flash.allow_html'] = True base_config = TestConfig(folder='dispatch', values=config) return app_from_config(base_config) app = None def setup(): global app app = setup_noDB() @no_warn #should be _default now def test_tg_style_default(): resp = app.get('/sdfaswdfsdfa') #random string should be caught by the default route assert 'Default' in resp.body.decode('utf-8') def test_url_encoded_param_passing(): resp = app.get('/feed?feed=http%3A%2F%2Fdeanlandolt.com%2Ffeed%2Fatom%2F') assert "http://deanlandolt.com/feed/atom/" in resp.body.decode('utf-8') def test_tg_style_index(): resp = app.get('/index/') assert 'hello' in resp.body.decode('utf-8'), resp def test_tg_style_subcontroller_index(): resp = app.get('/sub/index') assert "sub index" in resp.body.decode('utf-8') def test_tg_style_subcontroller_default(): resp=app.get('/sub/bob/tim/joe') assert 'bob' in resp.body.decode('utf-8'), resp assert 'tim' in resp.body.decode('utf-8'), resp assert 'joe' in resp.body.decode('utf-8'), resp def test_redirect_absolute(): resp = app.get('/redirect_me?target=/') assert resp.status == "302 Found", resp.status assert 'http://localhost/' in resp.headers['location'] resp = resp.follow() assert 'hello world' in resp, resp @no_warn def test_redirect_relative(): resp = app.get('/redirect_me?target=hello&name=abc') resp = resp.follow() assert 'Hello abc' in resp, resp resp = app.get('/sub/redirect_me?target=hello&name=def') resp = resp.follow() assert 'Why HELLO! def' in resp, resp resp = app.get('/sub/redirect_me?target=../hello&name=ghi') resp = resp.follow() assert 'Hello ghi' in resp, resp def test_redirect_external(): resp = app.get('/redirect_me?target=http://example.com') assert resp.status == "302 Found" and resp.headers['location'] == 'http://example.com', resp def test_redirect_param(): resp = app.get('/redirect_me?target=/hello&name=paj') resp = resp.follow() assert 'Hello paj' in resp, resp resp = app.get('/redirect_me?target=/hello&name=pbj') resp = resp.follow() assert 'Hello pbj' in resp, resp resp = app.get('/redirect_me?target=/hello&silly=billy&name=pcj') resp = resp.follow() assert 'Hello pcj' in resp, resp def test_redirect_cookie(): resp = app.get('/redirect_cookie?name=stefanha').follow() assert 'Hello stefanha' in resp def test_subcontroller_redirect_subindex(): resp=app.get('/sub/redirect_sub').follow() assert 'sub index' in resp def test_subcontroller_redirect_sub2index(): resp=app.get('/sub2/').follow() assert 'hello list' in resp #this test does not run because of some bug in nose def _test_subcontroller_lookup(): resp=app.get('/sub2/findme').follow() assert 'lookup' in resp, resp def test_subcontroller_redirect_no_slash_sub2index(): resp=app.get('/sub2/').follow() assert 'hello list' in resp, resp def test_redirect_to_list_of_strings(): resp = app.get('/sub/redirect_list').follow() assert 'hello list' in resp, resp def test_flash_redirect(): resp = app.get('/flash_redirect').follow() assert 'Wow,
flash!' in resp, resp def test_bigflash_redirect(): try: resp = app.get('/bigflash_redirect') assert False except Exception as e: assert 'Flash value is too long (cookie would be >4k)' in str(e) def test_flash_no_redirect(): resp = app.get('/flash_no_redirect') assert 'Wow, flash!' in resp, resp def test_flash_unicode(): resp = app.get('/flash_unicode').follow() content = resp.body.decode('utf8') assert u_('Привет, мир!') in content, content def test_flash_status(): resp = app.get('/flash_status') assert 'ok' in resp, resp def test_flash_javascript(): resp = app.get('/flash_render?using_js=True') expected = 'webflash({"id": "flash", "name": "webflash"})' epxected_reverse = 'webflash({"name": "webflash", "id": "flash"})' assert expected in resp or epxected_reverse in resp, resp assert 'webflash.render()' in resp, resp def test_flash_render_plain(): resp = app.get('/flash_render') assert 'JS <br/>Flash' in resp, resp def test_flash_render_plain_with_html(): app = setup_noDB(html_flash=True) resp = app.get('/flash_render') assert 'JS
Flash' in resp, resp def test_flash_render_no_message(): resp = app.get('/flash_render?with_message=False') assert 'flash' not in resp def test_custom_content_type(): resp = app.get('/custom_content_type') assert 'image/png' == dict(resp.headers)['Content-Type'], resp assert resp.body.decode('utf-8') == 'PNG', resp def test_custom_text_plain_content_type(): resp = app.get('/custom_content_text_plain_type') assert 'text/plain; charset=utf-8' == dict(resp.headers)['Content-Type'], resp assert resp.body.decode('utf-8') == """a
bx""", resp @no_warn def test_custom_content_type2(): resp = app.get('/custom_content_type2') assert 'image/png' == dict(resp.headers)['Content-Type'], resp assert resp.body.decode('utf-8') == 'PNG2', resp @no_warn def test_basicurls(): resp = app.get("/test_url_sop") def test_ignore_parameters(): resp = app.get("/check_params?ignore='bar'&ignore_me='foo'") assert "None Received" def test_json_return_list(): try: resp = app.get("/json_return_list") assert False except Exception as e: assert 'You may not expose with JSON a list' in str(e) def test_https_redirect(): resp = app.get("/test_https?foo=bar&baz=bat") assert 'https://' in resp, resp assert resp.location.endswith("/test_https?foo=bar&baz=bat") resp = app.post("/test_https?foo=bar&baz=bat", status=405) class TestVisits(object): def test_visit_path_sub1(self): resp = app.get("/sub/hitme") assert str(resp).endswith('/sub@/sub') def test_visit_path_nested(self): resp = app.get("/sub/nested/hitme") assert str(resp).endswith('/sub/nested*/sub/nested') def test_visit_path_nested_index(self): resp = app.get("/sub/nested") assert str(resp).endswith('/sub/nested-/sub/nested') def test_runtime_visit_path_subcontroller(self): resp = app.get("/sub/nested/nested/hitme") assert str(resp).endswith('*/sub/nested') def test_runtime_visit_path(self): resp = app.get("/sub/nested/hiddenhitme") assert str(resp).endswith(' /sub/nested') TurboGears2-2.3.7/tests/test_stack/fixture/0000755000076500000240000000000012607177763020751 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/fixture/__init__.py0000644000076500000240000000000012413576166023043 0ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/lib/0000755000076500000240000000000012607177763020031 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/lib/__init__.py0000644000076500000240000000037212413576166022137 0ustar amolstaff00000000000000"""Pylons requires that packages have a lib.base and lib.helpers So we've added on here so we can run tests in the context of the tg package itself, pylons will likely remove this restriction before 1.0 and this package can then be removed. """TurboGears2-2.3.7/tests/test_stack/lib/base.py0000644000076500000240000000037212413576166021312 0ustar amolstaff00000000000000"""Pylons requires that packages have a lib.base and lib.helpers So we've added on here so we can run tests in the context of the tg package itself, pylons will likely remove this restriction before 1.0 and this module can then be removed. """TurboGears2-2.3.7/tests/test_stack/lib/helpers.py0000644000076500000240000000037212413576166022042 0ustar amolstaff00000000000000"""Pylons requires that packages have a lib.base and lib.helpers So we've added on here so we can run tests in the context of the tg package itself, pylons will likely remove this restriction before 1.0 and this module can then be removed. """TurboGears2-2.3.7/tests/test_stack/lib/templatetools/0000755000076500000240000000000012607177763022725 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/lib/templatetools/__init__.py0000644000076500000240000000003312413576166025025 0ustar amolstaff00000000000000__author__ = 'clsdaniel' TurboGears2-2.3.7/tests/test_stack/lib/templatetools/jinja_filters.py0000644000076500000240000000050712413576166026117 0ustar amolstaff00000000000000try: from hashlib import sha1 except ImportError: from sha1 import sha1 # avoid polluting module namespace __all__ = ['codify'] def codify(value): string_hash = sha1(value.encode('ascii')) return string_hash.hexdigest() def polluting_function(value): return "Template filter namespace has been POLLUTED" TurboGears2-2.3.7/tests/test_stack/rendering/0000755000076500000240000000000012607177763021240 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/rendering/__init__.py0000644000076500000240000000000012413576166023332 0ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/rendering/controllers/0000755000076500000240000000000012607177763023606 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/rendering/controllers/__init__.py0000644000076500000240000000000012413576166025700 0ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/rendering/controllers/root.py0000644000076500000240000003440012607177564025143 0ustar amolstaff00000000000000"""Main Controller""" import tg from tg import expose, redirect, config, validate, override_template, response, render_template, tmpl_context from tg import cache, i18n, request from tg.decorators import paginate, use_custom_format, with_trailing_slash, Decoration, before_render, decode_params from tg.controllers import TGController from tg.validation import TGValidationError from tg._compat import PY3 from tg.render import _get_tg_vars, cached_template import datetime if not PY3: from tw.forms import TableForm, TextField, CalendarDatePicker, SingleSelectField, TextArea from tw.api import WidgetsList class MovieForm(TableForm): # This WidgetsList is just a container class fields(WidgetsList): title = TextField() year = TextField(size=4, default=1984) description = TextArea() #then, we create an instance of this form base_movie_form = MovieForm("movie_form", action='create') else: base_movie_form = None import tw2.forms as tw2f import tw2.core as tw2c class TW2MovieForm(tw2f.TableForm): title = tw2f.TextField(validator=tw2c.Required) year = tw2f.TextField(size=4, validator=tw2c.IntValidator) tw2_movie_form = TW2MovieForm() class IntValidator(object): def to_python(self, value): try: return int(value) except: raise TGValidationError('Not a number') class GoodJsonObject(object): def __json__(self): return {'Json':'Rocks'} class BadJsonObject(object): pass class JsonController(TGController): @expose('json') def json(self): return dict(a='hello world', b=True) @expose('json', exclude_names=["b"]) def excluded_b(self): return dict(a="visible", b="invisible") @expose('json') @expose('genshi:test', content_type='application/xml') def xml_or_json(self): return dict(name="John Carter", title='officer', status='missing') @expose('json') def json_with_object(self): return dict(obj=GoodJsonObject()) @expose('json') def json_with_bad_object(self): return dict(obj=BadJsonObject()) class SubClassableController(TGController): @expose('genshi:index.html') def index(self): return {} @expose('genshi:index.html') def index_override(self): return {} def before_render_data(remainder, params, output): output['parent_value'] = 'PARENT' @expose('json') @before_render(before_render_data) def data(self): return {'v':5} class SubClassingController(SubClassableController): @expose(inherit=True) def index(self, *args, **kw): return super(SubClassingController, self).index(*args, **kw) @expose('genshi:genshi_doctype.html', inherit=True) def index_override(self, *args, **kw): return super(SubClassingController, self).index_override(*args, **kw) def before_render_data(remainder, params, output): output['child_value'] = 'CHILD' @expose(inherit=True) @before_render(before_render_data) def data(self, *args, **kw): return super(SubClassingController, self).data(*args, **kw) class RootController(TGController): j = JsonController() sub1 = SubClassableController() sub2 = SubClassingController() @expose('genshi:index.html') def index(self): return {} @expose('genshi:genshi_doctype.html') def auto_doctype(self): return {} @expose('genshi:genshi_doctype.html', content_type='text/html') def auto_doctype_html(self): return {} @expose('genshi:genshi_doctype.html', content_type='application/xhtml+xml') def auto_doctype_xhtml(self): return {} @expose('genshi:genshi_doctype.html', render_params=dict(doctype=None)) def explicit_no_doctype(self): return {} @expose('genshi:genshi_doctype.html', render_params=dict(doctype='html')) def explicit_doctype_html(self): return {} @expose('genshi:genshi_doctype.html', render_params=dict(doctype='xhtml')) def explicit_doctype_xhtml(self): return {} @expose('genshi:genshi_form.html') def form(self): return dict(form=base_movie_form) @expose('genshi:genshi_form.html') def tw2form(self): return dict(form=tw2_movie_form) @expose('genshi:genshi_foreign.html') def foreign(self): return {} @expose('json') @validate(form=base_movie_form) def process_form_errors(self, **kwargs): #add error messages to the kwargs dictionary and return it kwargs['errors'] = request.validation['errors'] return dict(kwargs) @expose() @paginate('testdata') def paginated_text(self): return '''Some Text''' @expose('kajiki:kajiki_paginated.xhtml') @expose('json') @paginate('testdata', max_items_per_page=20) def paginated(self, n): return dict(testdata=range(int(n))) @expose('kajiki:kajiki_paginated.xhtml') @paginate('testdata') def paginate_with_params(self, n): url_params = dict(param1='hi', param2='man') return dict(testdata=range(int(n)), url_params=url_params) @expose('kajiki:kajiki_paginated.xhtml') @paginate('testdata') @validate(dict(n=IntValidator())) def paginated_validated(self, n): return dict(testdata=range(n)) @expose('kajiki:kajiki_paginated.xhtml') @validate(dict(n=IntValidator())) @paginate('testdata') def validated_paginated(self, n): return dict(testdata=range(n)) @expose('kajiki:kajiki_paginated.xhtml') @paginate('testdata', use_prefix=True) @paginate('testdata2', use_prefix=True) def multiple_paginators(self, n): n = int(n) return dict(testdata=range(n), testdata2=range(n+100, n+100+n)) @expose('genshi:genshi_inherits.html') def genshi_inherits(self): return {} @expose('genshi:genshi_inherits_sub.html') def genshi_inherits_sub(self): return {} @expose('genshi:sub/frombottom.html') def genshi_inherits_sub_from_bottom(self): return {} @expose('jinja:jinja_noop.jinja') def jinja_index(self): return {} @expose('jinja:jinja_autoload.jinja') def jinja_autoload(self): return {} @expose('jinja:jinja_inherits.jinja') def jinja_inherits(self): return {} @expose('jinja:tests.test_stack.rendering.templates.jinja_noop') def jinja_dotted(self): return {} @expose('jinja:tests.test_stack.rendering.templates.jinja_inherits_dotted') def jinja_inherits_dotted(self): return {} @expose('jinja:tests.test_stack.rendering.templates.jinja_inherits') def jinja_inherits_mixed(self): return {} @expose('jinja:jinja_extensions.jinja') def jinja_extensions(self): test_autoescape_on = "Test Autoescape On" test_autoescape_off = "Autoescape Off" return dict(test_autoescape_off=test_autoescape_off, test_autoescape_on=test_autoescape_on) @expose('jinja:jinja_filters.jinja') def jinja_filters(self): return {} @expose('jinja:jinja_buildins.jinja') def jinja_buildins(self): return {} @expose('jinja:jinja_i18n.jinja') def jinja_i18n(self): return {} @expose('jinja:jinja_i18n.jinja') def jinja_i18n_en(self): i18n.set_temporary_lang("en") return {} @expose('jinja:jinja_i18n.jinja') def jinja_i18n_de(self): i18n.set_temporary_lang("de") return {} @expose('chameleon_genshi:index.html') def chameleon_genshi_index(self): return {} @expose('chameleon_genshi:genshi_inherits.html') def chameleon_genshi_inherits(self): return {} @expose('mako:mako_noop.mak') def mako_index(self): return {} @expose('mako:mako_inherits.mak') def mako_inherits(self): return {} @expose('chameleon_genshi:tests.test_stack.rendering.templates.index') def chameleon_index_dotted(self): return {} @expose('kajiki:tests.test_stack.rendering.templates.index') def kajiki_index_dotted(self): return {} @expose('kajiki:tests.test_stack.rendering.templates.missing') def kajiki_missing_template(self): return {} @expose('kajiki:tests.test_stack.rendering.templates.kajiki_i18n') def kajiki_i18n(self): return {} @expose('kajiki:tests.test_stack.rendering.templates.kajiki_i18n') def kajiki_i18n_de(self): i18n.set_temporary_lang("de") return {} @expose('genshi:tests.test_stack.rendering.templates.index') def index_dotted(self): return {} @expose('genshi:tests.test_stack.rendering.templates.genshi_inherits') def genshi_inherits_dotted(self): return {} @expose('genshi:tests.test_stack.rendering.templates.genshi_inherits_sub_dotted') def genshi_inherits_sub_dotted(self): return {} @expose('genshi:tests.test_stack.rendering.templates.sub.frombottom_dotted') def genshi_inherits_sub_dotted_from_bottom(self): return {} @expose('mako:tests.test_stack.rendering.templates.mako_noop') def mako_index_dotted(self): return {} @expose('mako:tests.test_stack.rendering.templates.mako_inherits_dotted') def mako_inherits_dotted(self): return {} @expose('json') @expose('genshi:index.html') def html_and_json(self): return {} @expose('json', custom_format='json') @expose('mako:mako_custom_format.mak', content_type='text/xml', custom_format='xml') @expose('genshi:genshi_custom_format.html', content_type='text/html', custom_format='html') def custom_format(self, format='default'): if format != 'default': use_custom_format(self.custom_format, format) return dict(format=format, status="ok") else: return 'OK' @expose("genshi:tests.non_overridden") def template_override(self, override=False): if override: override_template(self.template_override, "genshi:tests.overridden") return dict() @with_trailing_slash @expose("genshi:tests.non_overridden") def template_override_wts(self, override=False): if override: override_template(self.template_override_wts, "genshi:tests.overridden") return dict() @expose(content_type='text/javascript') def template_override_content_type(self, override=False): if override: override_template(self.template_override_content_type, "mako:tests.overridden_js") return dict() else: return "alert('Not overridden')" @expose('mako:mako_custom_format.mak', content_type='text/xml') @expose('genshi:genshi_custom_format.html', content_type='text/html') def template_override_multiple_content_type(self, override=False): if override: override_template(self.template_override_multiple_content_type, "mako:mako_noop.mak") return dict(format='something', status="ok") @expose() def jinja2_manual_rendering(self, frompylons=False): try: import pylons except ImportError: frompylons = False if frompylons: from pylons.templating import render_jinja2 return render_jinja2('jinja_inherits.jinja') else: return render_template({}, 'jinja', 'jinja_inherits.jinja') @expose() def no_template_generator(self): def output(): num = 0 while num < 5: num += 1 yield str(num).encode('ascii') return output() @expose() def genshi_manual_rendering_with_doctype(self, doctype=None): response.content_type = 'text/html' response.charset = 'utf-8' return render_template({}, 'genshi', 'genshi_doctype.html', doctype=doctype) @expose('mako:mako_custom_format.mak') @expose('genshi:genshi_custom_format.html') def multiple_engines(self): deco = Decoration.get_decoration(self.multiple_engines) used_engine = deco.engines.get('text/html')[0] return dict(format=used_engine, status='ok') @expose('json') def get_tg_vars(self): return dict(tg_vars=list(_get_tg_vars().keys())) @expose('genshi:index.html') def template_caching(self): from datetime import datetime tmpl_context.now = datetime.utcnow return dict(tg_cache={'key':'TEMPLATE_CACHE_TEST', 'type':'memory', 'expire':'never'}) @expose('genshi:index.html') def template_caching_default_type(self): from datetime import datetime tmpl_context.now = datetime.utcnow return dict(tg_cache={'key':'TEMPLATE_CACHE_TEST2', 'expire':'never'}) @expose('json') def template_caching_options(self, **kwargs): _cache_options = {} class FakeCache(object): def get_cache(self, *args, **kwargs): _cache_options['args'] = args _cache_options['kwargs'] = kwargs try: c = cache.get_cache(*args, **kwargs) _cache_options['cls'] = c.namespace.__class__.__name__ except TypeError: _cache_options['cls'] = 'NoImplementation' c = cache.get_cache(*args, type='memory', **kwargs) return c tg.cache.kwargs['type'] = 'NoImplementation' old_cache = tg.cache tg.cache = FakeCache() try: def render_func(*args, **kw): return 'OK' cached_template('index.html', render_func, **kwargs) return _cache_options finally: tg.cache = old_cache @expose('jsonp', render_params={'callback_param': 'call'}) def get_jsonp(self, **kwargs): return {'value': 5} @expose('json') def get_json_isodates_default(self, **kwargs): return {'date': datetime.datetime.utcnow()} @expose('json', render_params={'isodates': True}) def get_json_isodates_on(self, **kwargs): return {'date': datetime.datetime.utcnow()} @expose('json', render_params={'isodates': False}) def get_json_isodates_off(self, **kwargs): return {'date': datetime.datetime.utcnow()} @expose('json') @decode_params('json') def echo_json(self, **kwargs): return kwargs TurboGears2-2.3.7/tests/test_stack/rendering/templates/0000755000076500000240000000000012607177763023236 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/rendering/templates/__init__.py0000644000076500000240000000000012413576166025330 0ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/rendering/templates/sub/0000755000076500000240000000000012607177763024027 5ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/rendering/templates/sub/__init__.py0000644000076500000240000000000012413576166026121 0ustar amolstaff00000000000000TurboGears2-2.3.7/tests/test_stack/rendering/test_decorators.py0000644000076500000240000001531512517763457025024 0ustar amolstaff00000000000000from nose.tools import raises from tests.test_stack import TestConfig, app_from_config from tg.util import no_warn from tg.configuration import config from tg.configuration import milestones from tg.decorators import Decoration, decode_params import tg import json def make_app(): base_config = TestConfig(folder = 'rendering', values = {'use_sqlalchemy': False, 'use_legacy_renderer': False, # this is specific to mako # to make sure inheritance works 'use_dotted_templatenames': False, 'use_toscawidgets': False, 'use_toscawidgets2': False } ) return app_from_config(base_config) class TestTGController(object): def setup(self): self.app = make_app() def test_simple_jsonification(self): resp = self.app.get('/j/json') expected = {"a": "hello world", "b": True} assert expected == resp.json_body def test_multi_dispatch_json(self): resp = self.app.get('/j/xml_or_json', headers={'accept':'application/json'}) assert '''"status": "missing"''' in resp assert '''"name": "John Carter"''' in resp assert '''"title": "officer"''' in resp def test_json_with_object(self): resp = self.app.get('/j/json_with_object') assert '''"Json": "Rocks"''' in str(resp.body) @no_warn def test_json_with_bad_object(self): try: resp = self.app.get('/j/json_with_bad_object') assert False except Exception as e: assert "is not JSON serializable" in str(e), str(e) def test_multiple_engines(self): default_renderer = config['default_renderer'] resp = self.app.get('/multiple_engines') assert default_renderer in resp, resp def test_decode_params_json(self): params = {'name': 'Name', 'surname': 'Surname'} resp = self.app.post_json('/echo_json', params) assert resp.json_body == params @raises(ValueError) def test_decode_params_notjson(self): @decode_params('xml') def _fakefunc(): pass class TestExposeInheritance(object): def setup(self): self.app = make_app() def test_inherited_expose_template(self): resp1 = self.app.get('/sub1/index') resp2 = self.app.get('/sub2/index') assert resp1.body == resp2.body def test_inherited_expose_override(self): resp1 = self.app.get('/sub1/index_override') resp2 = self.app.get('/sub2/index_override') assert resp1.body != resp2.body def test_inherited_expose_hooks(self): resp1 = self.app.get('/sub1/data') assert ('"v"' in resp1 and '"parent_value"' in resp1) resp2 = self.app.get('/sub2/data') assert ('"v"' in resp2 and '"parent_value"' in resp2 and '"child_value"' in resp2) class TestExposeLazyInheritance(object): def test_lazy_inheritance(self): milestones.renderers_ready._reset() class BaseController(tg.TGController): @tg.expose('template.html') def func(self): pass class SubController(BaseController): @tg.expose(inherit=True) def func(self): pass milestones.renderers_ready.reach() deco = Decoration.get_decoration(SubController.func) assert len(deco.engines) == 1, deco.engines assert deco.engines['text/html'][1] == 'template.html', deco.engines def test_lazy_inheritance_with_template(self): milestones.renderers_ready._reset() class BaseController(tg.TGController): @tg.expose('template.html') def func(self): pass class SubController(BaseController): @tg.expose('new_template.html', inherit=True) def func(self): pass milestones.renderers_ready.reach() deco = Decoration.get_decoration(SubController.func) assert len(deco.engines) == 1, deco.engines assert deco.engines['text/html'][1] == 'new_template.html', deco.engines def test_lazy_inheritance_with_nested_template(self): milestones.renderers_ready._reset() class BaseController(tg.TGController): @tg.expose('template.html') @tg.expose('template.html', content_type='text/plain') def func(self): pass class SubController(BaseController): @tg.expose('new_template.html', inherit=True) @tg.expose('new_template.html', content_type='text/plain') def func(self): pass class SubSubController(SubController): @tg.expose('new2_template.html', inherit=True) def func(self): pass milestones.renderers_ready.reach() deco = Decoration.get_decoration(SubSubController.func) assert len(deco.engines) == 2, deco.engines assert deco.engines['text/html'][1] == 'new2_template.html', deco.engines assert deco.engines['text/plain'][1] == 'new_template.html', deco.engines def test_lazy_inheritance_with_3nested_template(self): milestones.renderers_ready._reset() class BaseController(tg.TGController): @tg.expose('template.html') @tg.expose('template.html', content_type='text/plain') @tg.expose('template.html', content_type='text/javascript') def func(self): pass class SubController(BaseController): @tg.expose('new_template.html', inherit=True) @tg.expose('new_template.html', content_type='text/plain') @tg.expose('new_template.html', content_type='text/javascript') def func(self): pass class SubSubController(SubController): @tg.expose('new2_template.html', inherit=True) @tg.expose('new2_template.html', content_type='text/javascript') def func(self): pass class SubSubSubController(SubSubController): @tg.expose('new3_template.html', inherit=True) def func(self): pass milestones.renderers_ready.reach() deco = Decoration.get_decoration(SubSubSubController.func) assert len(deco.engines) == 3, deco.engines assert deco.engines['text/html'][1] == 'new3_template.html', deco.engines assert deco.engines['text/plain'][1] == 'new_template.html', deco.engines assert deco.engines['text/javascript'][1] == 'new2_template.html', deco.engines TurboGears2-2.3.7/tests/test_stack/rendering/test_dotted_rendering.py0000644000076500000240000001135212607177564026172 0ustar amolstaff00000000000000# -*- coding: utf-8 -*- import sys from nose import SkipTest from tests.test_stack import TestConfig, app_from_config from tg.util import Bunch, no_warn from webtest import TestApp from tg._compat import PY3, u_, im_func from tg.configuration import milestones from tg import expose from tg.decorators import Decoration try: from tgext.chameleon_genshi import ChameleonGenshiRenderer except ImportError: ChameleonGenshiRenderer = None def setup_noDB(extra_init=None): base_config = TestConfig(folder = 'rendering', values = {'use_sqlalchemy': False, # we want to test the new renderer functions 'use_legacy_renderer': False, # in this test we want dotted names support 'use_dotted_templatenames': True, 'use_toscawidgets': False, 'use_toscawidgets2': False } ) if extra_init is not None: extra_init(base_config) return app_from_config(base_config) def test_default_chameleon_genshi_renderer(): if ChameleonGenshiRenderer is None: raise SkipTest() def add_chameleon_renderer(app_config): app_config.register_rendering_engine(ChameleonGenshiRenderer) app_config.renderers.append('chameleon_genshi') app = setup_noDB(add_chameleon_renderer) # Manually add the exposition again as it was already discarded # due to chameleon_genshi not being in the available renderes. milestones.renderers_ready._reset() from .controllers.root import RootController controller = im_func(RootController.chameleon_index_dotted) expose('chameleon_genshi:tests.test_stack.rendering.templates.index')(controller) milestones.renderers_ready.reach() resp = app.get('/chameleon_index_dotted') assert "Welcome" in resp, resp assert "TurboGears" in resp, resp def test_default_kajiki_renderer(): app = setup_noDB() resp = app.get('/kajiki_index_dotted') assert "Welcome" in resp, resp assert "TurboGears" in resp, resp def test_kajiki_i18n(): app = setup_noDB() resp = app.get('/kajiki_i18n') assert u_("Your application is now running") in resp def test_kajiki_i18n_de(): app = setup_noDB() resp = app.get('/kajiki_i18n_de') assert u_("Ihre Anwendung läuft jetzt einwandfrei") in resp def test_kajiki_missing_template(): app = setup_noDB() try: resp = app.get('/kajiki_missing_template') except IOError as e: assert 'missing.xhtml not found' in str(e) else: assert False, 'Should have raised IOError' def test_jinja_dotted(): app = setup_noDB() resp = app.get('/jinja_dotted') assert "move along, nothing to see here" in resp, resp def test_jinja_inherits_dotted(): app = setup_noDB() resp = app.get('/jinja_inherits_dotted') assert "Welcome on my awsome homepage" in resp, resp def test_jinja_inherits_mixed(): # Mixed notation, dotted and regular app = setup_noDB() resp = app.get('/jinja_inherits_mixed') assert "Welcome on my awsome homepage" in resp, resp def test_jinja_i18n(): app = setup_noDB() resp = app.get('/jinja_i18n', status=200) def test_jinja_i18n_en(): app = setup_noDB() resp = app.get('/jinja_i18n_en') assert "Your application is now running" in resp def test_jinja_i18n_de(): app = setup_noDB() resp = app.get('/jinja_i18n_de') assert u_("Ihre Anwendung läuft jetzt einwandfrei") in resp def test_default_genshi_renderer(): app = setup_noDB() resp = app.get('/index_dotted') assert "Welcome" in resp, resp assert "TurboGears" in resp, resp def test_genshi_inheritance(): app = setup_noDB() resp = app.get('/genshi_inherits_dotted') assert "Inheritance template" in resp, resp assert "Master template" in resp, resp def test_genshi_sub_inheritance(): app = setup_noDB() resp = app.get('/genshi_inherits_sub_dotted') assert "Inheritance template" in resp, resp assert "Master template" in resp, resp assert "from sub-template: sub.tobeincluded" in resp, resp def test_genshi_sub_inheritance_frombottom(): app = setup_noDB() resp = app.get('/genshi_inherits_sub_dotted_from_bottom') assert "Master template" in resp, resp assert "from sub-template: sub.frombottom_dotted" in resp, resp def test_mako_renderer(): app = setup_noDB() resp = app.get('/mako_index_dotted') assert "

This is the mako index page

" in resp, resp def test_mako_inheritance(): app = setup_noDB() resp = app.get('/mako_inherits_dotted') assert "inherited mako page" in resp, resp assert "Inside parent template" in resp, resp TurboGears2-2.3.7/tests/test_stack/rendering/test_pagination.py0000644000076500000240000002543712555020522024773 0ustar amolstaff00000000000000import json from nose import SkipTest from tests.test_stack import TestConfig, app_from_config from tg.support.paginate import Page from tg.controllers.util import _urlencode from tg import json_encode from tg.util.webtest import test_context def setup_noDB(): base_config = TestConfig(folder='rendering', values={ 'use_sqlalchemy': False, 'use_toscawidgets': False, 'use_toscawidgets2': False }) return app_from_config(base_config) _pager = ('
1' ' 2' ' 3' ' ..' ' 5
') _data = '
    %s
' % ''.join( '
  • %d
  • ' % i for i in range(10)) class TestPagination: def setup(self): self.app = setup_noDB() def test_basic_pagination(self): url = '/paginated/42' page = self.app.get(url) assert _pager % locals() in page, page assert _data in page, page url = '/paginated/42?page=2' page = self.app.get(url) assert '
  • 0
  • ' not in page assert '
  • 10
  • ' in page def test_pagination_negative(self): url = '/paginated/42?page=-1' page = self.app.get(url) assert '
  • 0
  • ' in page def test_pagination_items_per_page(self): url = '/paginated/42?items_per_page=20' page = self.app.get(url) assert '
  • 0
  • ' in page assert '
  • 19
  • ' in page def test_pagination_items_per_page_negative(self): url = '/paginated/42?items_per_page=-1' page = self.app.get(url) assert '
  • 0
  • ' in page assert '
  • 10
  • ' not in page def test_pagination_non_paginable(self): url = '/paginated_text' page = self.app.get(url) assert 'Some Text' in page def test_pagination_with_validation(self): url = '/paginated_validated/42' page = self.app.get(url) assert _pager % locals() in page, page assert _data in page, page url = '/paginated_validated/42?page=2' page = self.app.get(url) assert '
  • 0
  • ' not in page assert '
  • 10
  • ' in page def test_validation_with_pagination(self): url = '/validated_paginated/42' page = self.app.get(url) assert _pager % locals() in page, page assert _data in page, page url = '/validated_paginated/42?page=2' page = self.app.get(url) assert '
  • 0
  • ' not in page assert '
  • 10
  • ' in page def test_pagination_with_link_args(self): url = '/paginate_with_params/42' page = self.app.get(url) assert 'param1=hi' in page assert 'param2=man' in page assert 'partial' not in page assert '/fake_url' in page url = '/paginate_with_params/42?page=2' page = self.app.get(url) assert '
  • 0
  • ' not in page assert '
  • 10
  • ' in page def test_multiple_paginators(self): url = '/multiple_paginators/42' try: from collections import OrderedDict params = (('testdata_page', 2), ('testdata2_page', 2)) reverse_params = OrderedDict(reversed(params)) params = OrderedDict(params) except ImportError: reverse_params = params = {'testdata2_page': 2, 'testdata_page': 2} goto_page2_link = url + '?' + _urlencode(params) goto_page2_reverse_link = url + '?' + _urlencode(reverse_params) page = self.app.get(url) assert '/multiple_paginators/42?testdata2_page=2' in page, str(page) assert '/multiple_paginators/42?testdata_page=2' in page, str(page) url = '/multiple_paginators/42?testdata_page=2' page = self.app.get(url) assert ( goto_page2_link in page or goto_page2_reverse_link in page ), str(page) assert '/multiple_paginators/42?testdata_page=4' in page, str(page) assert '
  • 0
  • ' not in page assert '
  • 10
  • ' in page assert '
  • 142
  • ' in page assert '
  • 151
  • ' in page url = '/multiple_paginators/42?testdata2_page=2' page = self.app.get(url) assert ( goto_page2_link in page or goto_page2_reverse_link in page ), str(page) assert '/multiple_paginators/42?testdata2_page=4' in page, str(page) assert '
  • 0
  • ' in page assert '
  • 9
  • ' in page assert '
  • 151
  • ' not in page assert '
  • 161
  • ' in page def test_json_pagination(self): url = '/paginated/42.json' page = self.app.get(url) assert '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]' in page url = '/paginated/42.json?page=2' page = self.app.get(url) assert '[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]' in page class TestPage(object): def test_not_a_number_page(self): p = Page(range(100), items_per_page=10, page='A') sec = list(p) assert sec[-1] == 9, sec def test_empty_list(self): p = Page([], items_per_page=10, page=1) assert list(p) == [] def test_page_out_of_bound(self): p = Page(range(100), items_per_page=10, page=10000) sec = list(p) assert sec[-1] == 99, sec def test_page_out_of_lower_bound(self): p = Page(range(100), items_per_page=10, page=-5) sec = list(p) assert sec[-1] == 9, sec def test_navigator_one_page(self): with test_context(None, '/'): p = Page(range(10), items_per_page=10, page=10) assert p.pager() == '' def test_navigator_middle_page(self): with test_context(None, '/'): p = Page(range(100), items_per_page=10, page=5) pager = p.pager() assert '?page=1' in pager assert '?page=4' in pager assert '?page=6' in pager assert '?page=10' in pager def test_navigator_ajax(self): with test_context(None, '/'): p = Page(range(100), items_per_page=10, page=5) pager = p.pager(onclick='goto($page)') assert 'goto(1)' in pager assert 'goto(4)' in pager assert 'goto(6)' in pager assert 'goto(10)' in pager try: import sqlite3 except: import pysqlite2 from sqlalchemy import (MetaData, Table, Column, ForeignKey, Integer, String) from sqlalchemy.orm import create_session, mapper, relation metadata = MetaData('sqlite:///:memory:') test1 = Table('test1', metadata, Column('id', Integer, primary_key=True), Column('val', String(8))) test2 = Table('test2', metadata, Column('id', Integer, primary_key=True), Column('test1id', Integer, ForeignKey('test1.id')), Column('val', String(8))) test3 = Table('test3', metadata, Column('id', Integer, primary_key=True), Column('val', String(8))) test4 = Table('test4', metadata, Column('id', Integer, primary_key=True), Column('val', String(8))) metadata.create_all() class Test2(object): pass mapper(Test2, test2) class Test1(object): pass mapper(Test1, test1, properties={'test2s': relation(Test2)}) class Test3(object): pass mapper(Test3, test3) class Test4(object): pass mapper(Test4, test4) test1.insert().execute({'id': 1, 'val': 'bob'}) test2.insert().execute({'id': 1, 'test1id': 1, 'val': 'fred'}) test2.insert().execute({'id': 2, 'test1id': 1, 'val': 'alice'}) test3.insert().execute({'id': 1, 'val': 'bob'}) test4.insert().execute({'id': 1, 'val': 'alberto'}) class TestPageSQLA(object): def setup(self): self.s = create_session() def test_relationship(self): t = self.s.query(Test1).get(1) p = Page(t.test2s, items_per_page=1, page=1) assert len(list(p)) == 1 assert list(p)[0].val == 'fred', list(p) def test_query(self): q = self.s.query(Test2) p = Page(q, items_per_page=1, page=1) assert len(list(p)) == 1 assert list(p)[0].val == 'fred', list(p) def test_json_query(self): q = self.s.query(Test2) p = Page(q, items_per_page=1, page=1) res = json.loads(json_encode(p)) assert len(res['entries']) == 1 assert res['total'] == 2 assert res['entries'][0]['val'] == 'fred' try: import ming from ming import create_datastore, Session, schema, ASCENDING from ming.odm import ODMSession, FieldProperty, ForeignIdProperty, RelationProperty, Mapper from ming.odm.declarative import MappedClass except ImportError: ming = None class TestPageMing(object): @classmethod def setupClass(cls): if ming is None: raise SkipTest('Ming not available...') cls.basic_session = Session(create_datastore('mim:///')) cls.s = ODMSession(cls.basic_session) class Author(MappedClass): class __mongometa__: session = cls.s name = 'wiki_author' _id = FieldProperty(schema.ObjectId) name = FieldProperty(str) pages = RelationProperty('WikiPage') class WikiPage(MappedClass): class __mongometa__: session = cls.s name = 'wiki_page' _id = FieldProperty(schema.ObjectId) title = FieldProperty(str) text = FieldProperty(str) order = FieldProperty(int) author_id = ForeignIdProperty(Author) author = RelationProperty(Author) cls.Author = Author cls.WikiPage = WikiPage Mapper.compile_all() cls.author = Author(name='author1') author2 = Author(name='author2') WikiPage(title='Hello', text='Text', order=1, author=cls.author) WikiPage(title='Another', text='Text', order=2, author=cls.author) WikiPage(title='ThirdOne', text='Text', order=3, author=author2) cls.s.flush() cls.s.clear() def teardown(self): self.s.clear() def test_query(self): q = self.WikiPage.query.find().sort([('order', ASCENDING)]) p = Page(q, items_per_page=1, page=1) assert len(list(p)) == 1 assert list(p)[0].title == 'Hello', list(p) def test_json_query(self): q = self.WikiPage.query.find().sort([('order', ASCENDING)]) p = Page(q, items_per_page=1, page=1) res = json.loads(json_encode(p)) assert len(res['entries']) == 1 assert res['total'] == 3 assert res['entries'][0]['title'] == 'Hello', res['entries'] assert res['entries'][0]['author_id'] == str(self.author._id), res['entries'] def test_relation(self): a = self.Author.query.find({'name': 'author1'}).first() p = Page(a.pages, items_per_page=1, page=1) assert len(list(p)) == 1 assert list(p)[0].title in ('Hello', 'Another'), list(p) TurboGears2-2.3.7/tests/test_stack/rendering/test_rendering.py0000644000076500000240000007073512607177564024641 0ustar amolstaff00000000000000# -*- coding: utf-8 -*- from nose import SkipTest import shutil, os import json import tg from tg.configuration import milestones #tg.configuration.reqlocal_config.push_process_config({}) from tests.test_stack import TestConfig, app_from_config from tg.configuration.hooks import _TGGlobalHooksNamespace from tg.util import Bunch from tg._compat import PY3, im_func from tg.renderers.genshi import GenshiRenderer from tg import expose from tg import TGController, AppConfig from webtest import TestApp from datetime import datetime try: from tgext.chameleon_genshi import ChameleonGenshiRenderer except ImportError: ChameleonGenshiRenderer = None def setup_noDB(genshi_doctype=None, genshi_method=None, genshi_encoding=None, extra=None, extra_init=None): base_config = TestConfig(folder='rendering', values={ 'use_sqlalchemy': False, 'use_legacy_renderer': False, # this is specific to mako to make sure inheritance works 'use_dotted_templatenames': False, 'use_toscawidgets': False, 'use_toscawidgets2': False }) deployment_config = {} # remove previous option value to avoid using the old one tg.config.pop('templating.genshi.doctype', None) if genshi_doctype: deployment_config['templating.genshi.doctype'] = genshi_doctype tg.config.pop('templating.genshi.method', None) if genshi_method: deployment_config['templating.genshi.method'] = genshi_method tg.config.pop('templating.genshi.encoding', None) if genshi_encoding: deployment_config['templating.genshi.encoding'] = genshi_encoding deployment_config.update(extra or {}) if extra_init is not None: extra_init(base_config) return app_from_config(base_config, deployment_config) def test_default_genshi_renderer(): app = setup_noDB() resp = app.get('/') assert ('') in resp assert "Welcome" in resp assert "TurboGears" in resp def test_genshi_nameconstant(): from genshi.template.astutil import ASTCodeGenerator, parse from tg.renderers.genshi import GenshiRenderer # This checks genshi gets monkeypatched to fix it on Py34 if option is provided GenshiRenderer.create(Bunch({ 'templating.genshi.name_constant_patch': True, 'use_dotted_templatenames': False, 'auto_reload_templates': False, 'paths': Bunch({'templates': '/tmp'}) }), None) assert hasattr(ASTCodeGenerator, 'visit_NameConstant') astgen = ASTCodeGenerator(parse('range(10)', mode='eval')) for n in (False, True, None): astgen._new_line() astgen.visit_NameConstant(Bunch(value=n)) line = str(astgen.line) assert line == str(n), line astgen._new_line() try: astgen.visit_NameConstant(Bunch(value='HELLO_WORLD')) except Exception as e: assert 'Unknown NameConstant' in str(e) else: assert False def test_genshi_doctype_html5(): app = setup_noDB(genshi_doctype='html5') resp = app.get('/') assert '' in resp assert "Welcome" in resp assert "TurboGears" in resp def test_genshi_auto_doctype(): app = setup_noDB() resp = app.get('/auto_doctype') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_method_html(): app = setup_noDB(genshi_method='html') resp = app.get('/auto_doctype') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_method_xhtml(): app = setup_noDB(genshi_method='xhtml') resp = app.get('/auto_doctype') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_doctype_html(): app = setup_noDB(genshi_doctype='html') resp = app.get('/auto_doctype') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_doctype_html5(): app = setup_noDB(genshi_doctype='html5') resp = app.get('/auto_doctype') assert '' in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_doctype_xhtml_strict(): app = setup_noDB(genshi_doctype='xhtml-strict') resp = app.get('/auto_doctype') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_doctype_html_maps_to_xhtml(): app = setup_noDB(genshi_doctype={'text/html': ('xhtml', 'html')}) resp = app.get('/auto_doctype_html') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_method_html_maps_to_xhtml(): app = setup_noDB(genshi_method={'text/html': ('xhtml', 'html')}) resp = app.get('/auto_doctype_html') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_method_xml_overridden_by_content_type_html(): app = setup_noDB(genshi_method='xml') resp = app.get('/auto_doctype_html') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_method_xhtml_is_ok_with_content_type_html(): app = setup_noDB(genshi_method='xhtml') resp = app.get('/auto_doctype_html') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_doctype_xhtml_maps_to_html(): app = setup_noDB( genshi_doctype={'application/xhtml+xml': ('html', 'xhtml')}) resp = app.get('/auto_doctype_xhtml') assert ('') in resp assert 'content="application/xhtml+xml; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_method_xhtml_maps_to_html(): app = setup_noDB( genshi_doctype={'application/xhtml+xml': ('html', 'xhtml')}, genshi_method={'application/xhtml+xml': ('html', 'xhtml')}) resp = app.get('/auto_doctype_xhtml') assert ('') in resp assert 'content="application/xhtml+xml; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_method_xml_overridden_by_content_type_xhtml(): app = setup_noDB(genshi_method='xml') resp = app.get('/auto_doctype_xhtml') assert ('') in resp assert 'content="application/xhtml+xml; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_method_html_overridden_by_content_type_xhtml(): app = setup_noDB(genshi_method='html') resp = app.get('/auto_doctype_xhtml') assert ('') in resp assert 'content="application/xhtml+xml; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_explicit_no_doctype(): app = setup_noDB() resp = app.get('/explicit_no_doctype') assert 'DOCTYPE' not in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_explicit_doctype_html(): app = setup_noDB(genshi_doctype='xhtml') resp = app.get('/explicit_doctype_html') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_explicit_doctype_xhtml(): app = setup_noDB(genshi_doctype='html') resp = app.get('/explicit_doctype_xhtml') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "doctype generation" in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_html_priority_for_ie(): app = setup_noDB() resp = app.get('/html_and_json', headers={'Accept': 'application/x-ms-application, image/jpeg, application/xaml+xml,' ' image/gif, image/pjpeg, application/x-ms-xbap, */*'}) assert 'text/html' in str(resp), resp def test_genshi_foreign_characters(): app = setup_noDB() resp = app.get('/foreign') assert "Foreign Cuisine" in resp assert "Crème brûlée with Käsebrötchen" in resp def test_genshi_inheritance(): app = setup_noDB() resp = app.get('/genshi_inherits') assert "Inheritance template" in resp assert "Master template" in resp def test_genshi_sub_inheritance(): app = setup_noDB() resp = app.get('/genshi_inherits_sub') assert "Inheritance template" in resp assert "Master template" in resp assert "from sub-template: sub.tobeincluded" in resp def test_genshi_sub_inheritance_from_bottom(): app = setup_noDB() resp = app.get('/genshi_inherits_sub_from_bottom') assert "from sub-template: sub.frombottom" in resp assert "Master template" in resp def test_chameleon_genshi_base(): if ChameleonGenshiRenderer is None: raise SkipTest() def add_chameleon_renderer(app_config): app_config.register_rendering_engine(ChameleonGenshiRenderer) app_config.renderers.append('chameleon_genshi') app = setup_noDB(extra_init=add_chameleon_renderer) # Manually add the exposition again as it was already discarded # due to chameleon_genshi not being in the available renderes. milestones.renderers_ready._reset() from .controllers.root import RootController controller = im_func(RootController.chameleon_genshi_index) expose('chameleon_genshi:index.html')(controller) milestones.renderers_ready.reach() resp = app.get('/chameleon_genshi_index') assert ("

    TurboGears 2 is rapid web application development toolkit" " designed to make your life easier.

    ") in resp def test_chameleon_genshi_inheritance(): if ChameleonGenshiRenderer is None: raise SkipTest() def add_chameleon_renderer(app_config): app_config.register_rendering_engine(ChameleonGenshiRenderer) app_config.renderers.append('chameleon_genshi') try: import lxml except ImportError: # match templates need lxml, but since they don're really work anyway # (at least not fully compatible with Genshi), we just skip this test return app = setup_noDB(extra_init=add_chameleon_renderer) milestones.renderers_ready._reset() from .controllers.root import RootController controller = im_func(RootController.chameleon_genshi_inherits) expose('chameleon_genshi:genshi_inherits.html')(controller) milestones.renderers_ready.reach() try: resp = app.get('/chameleon_genshi_inherits') except NameError as e: # known issue with chameleon.genshi 1.0 if 'match_templates' not in str(e): raise except AttributeError as e: # known issue with chameleon.genshi 1.3 if 'XPathResult' not in str(e): raise else: assert "Inheritance template" in resp assert "Master template" in resp def test_jinja_autoload(): app = setup_noDB() try: resp = app.get('/jinja_autoload') assert False except Exception as e: assert "no filter named 'polluting_function'" in str(e) def _test_jinja_inherits(): app = setup_noDB() resp = app.get('/jinja_inherits') assert "Welcome on my awsome homepage" in resp, resp def test_jinja_extensions(): base_config = TestConfig(folder = 'rendering', values = {'use_sqlalchemy': False, 'use_legacy_renderer': False, # this is specific to mako # to make sure inheritance works 'use_dotted_templatenames': False, 'renderers':['jinja'], 'jinja_extensions': ['jinja2.ext.do', 'jinja2.ext.i18n', 'jinja2.ext.with_', 'jinja2.ext.autoescape'], 'use_toscawidgets': False, 'use_toscawidgets2': False } ) app = app_from_config(base_config) resp = app.get('/jinja_extensions') assert "Autoescape Off" in resp, resp assert "<b>Test Autoescape On</b>" in resp, resp def test_jinja_buildin_filters(): app = setup_noDB() resp = app.get('/jinja_buildins') assert 'HELLO JINJA!' in resp, resp def test_jinja_custom_filters(): # Simple test filter to get a md5 hash of a string def codify(value): try: from hashlib import md5 except ImportError: from md5 import md5 string_hash = md5(value.encode('ascii')) return string_hash.hexdigest() base_config = TestConfig(folder = 'rendering', values = {'use_sqlalchemy': False, 'use_legacy_renderer': False, # this is specific to mako # to make sure inheritance works 'use_dotted_templatenames': False, 'renderers':['jinja'], 'jinja_filters': {'codify': codify}, 'use_toscawidgets': False, 'use_toscawidgets2': False } ) app = app_from_config(base_config) try: resp = app.get('/jinja_filters') finally: # Remove filters so we don't mess with other test units tg.config.pop('jinja_filters') assert '8bb23e0b574ecb147536efacc864891b' in resp, resp def test_jinja_autoload_filters(): app = setup_noDB() resp = app.get('/jinja_filters') assert '29464d5ffe8f8dba1782fffcd6ed9fca6ceb4742' in resp, resp def test_mako_renderer(): app = setup_noDB() resp = app.get('/mako_index') assert "

    This is the mako index page

    " in resp, resp def test_mako_renderer_compiled(): app = setup_noDB(extra={ 'templating.mako.compiled_templates_dir': '_tg_tests_mako_compiled/dest' }) resp = app.get('/mako_index') assert "

    This is the mako index page

    " in resp, resp assert os.path.exists('_tg_tests_mako_compiled') shutil.rmtree('_tg_tests_mako_compiled', True) def test_mako_renderer_compiled_existing(): os.makedirs('_tg_tests_mako_compiled/dest') test_mako_renderer_compiled() def test_mako_renderer_compiled_no_access(): os.makedirs('_tg_tests_mako_compiled') os.makedirs('_tg_tests_mako_compiled/dest', mode=0o400) test_mako_renderer_compiled() def test_mako_renderer_compiled_no_access_parent(): os.makedirs('_tg_tests_mako_compiled', mode=0o400) test_mako_renderer_compiled() def test_mako_inheritance(): app = setup_noDB() resp = app.get('/mako_inherits') assert "inherited mako page" in resp, resp assert "Inside parent template" in resp, resp def test_template_override(): # app = setup_noDB() base_config = TestConfig(folder = 'rendering', values = {'use_sqlalchemy': False, 'use_legacy_renderer': False, # this is specific to mako # to make sure inheritance works 'use_dotted_templatenames': True, 'renderers':['genshi'], 'use_toscawidgets': False, 'use_toscawidgets2': False } ) app = app_from_config(base_config) r =app.get('/template_override') assert "Not overridden" in r, r r = app.get('/template_override', params=dict(override=True)) assert "This is overridden." in r, r # now invoke the controller again without override, # it should yield the old result r = app.get('/template_override') assert "Not overridden" in r, r def test_template_override_wts(): # app = setup_noDB() base_config = TestConfig(folder = 'rendering', values = {'use_sqlalchemy': False, 'use_legacy_renderer': False, # this is specific to mako # to make sure inheritance works 'use_dotted_templatenames': True, 'renderers':['genshi'], 'use_toscawidgets': False, 'use_toscawidgets2': False } ) app = app_from_config(base_config) r = app.get('/template_override_wts', status=301) # ensure with_trailing_slash r =app.get('/template_override_wts/') assert "Not overridden" in r, r r = app.get('/template_override_wts/', params=dict(override=True)) assert "This is overridden." in r, r # now invoke the controller again without override, # it should yield the old result r = app.get('/template_override_wts/') assert "Not overridden" in r, r def test_template_override_content_type(): base_config = TestConfig(folder = 'rendering', values = {'use_sqlalchemy': False, 'use_legacy_renderer': False, # this is specific to mako # to make sure inheritance works 'use_dotted_templatenames': True, 'renderers':['mako', 'genshi'], 'use_toscawidgets': False, 'use_toscawidgets2': False } ) app = app_from_config(base_config) r =app.get('/template_override_content_type') assert r.content_type == 'text/javascript' assert "Not overridden" in r, r r = app.get('/template_override_content_type', params=dict(override=True)) assert r.content_type == 'text/javascript' assert "This is overridden." in r, r # now invoke the controller again without override, # it should yield the old result r = app.get('/template_override_content_type') assert "Not overridden" in r, r def test_template_custom_format_default(): app = setup_noDB() resp = app.get('/custom_format') assert 'OK' in resp assert resp.content_type == 'text/html' def test_template_custom_format_xml(): app = setup_noDB() resp = app.get('/custom_format?format=xml') assert 'xml' in resp assert resp.content_type == 'text/xml' def test_template_custom_format_json(): app = setup_noDB() resp = app.get('/custom_format?format=json') assert 'json' in resp assert resp.content_type == 'application/json' def test_template_custom_format_html(): app = setup_noDB() resp = app.get('/custom_format?format=html') assert 'html' in resp assert resp.content_type == 'text/html' def test_template_custom_format_nonexisting(): app = setup_noDB() try: resp = app.get('/custom_format?format=csv') assert False except Exception as e: assert 'not a valid custom_format' in str(e) def test_template_override_multiple_content_type(): app = setup_noDB() resp = app.get('/template_override_multiple_content_type') assert 'something' in resp resp = app.get( '/template_override_multiple_content_type', params=dict(override=True)) assert 'This is the mako index page' in resp def test_override_template_on_noncontroller(): tg.override_template(None, 'this.is.not.a.template') def test_jinja2_manual_rendering(): app = setup_noDB() tgresp = app.get('/jinja2_manual_rendering') pyresp = app.get('/jinja2_manual_rendering?frompylons=1') assert str(tgresp) == str(pyresp), str(tgresp) + '\n------\n' + str(pyresp) def test_no_template(): app = setup_noDB() resp = app.get('/no_template_generator') assert '1234' in resp, resp def test_genshi_manual_render_no_doctype(): app = setup_noDB() resp = app.get('/genshi_manual_rendering_with_doctype') assert 'DOCTYPE' not in resp, resp assert "
    " in resp assert 'content="text/html; charset=utf-8"' in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_manual_render_auto_doctype(): app = setup_noDB() resp = app.get('/genshi_manual_rendering_with_doctype?doctype=auto') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_manual_render_html_doctype(): app = setup_noDB() resp = app.get('/genshi_manual_rendering_with_doctype?doctype=html') assert ('') in resp assert 'content="text/html; charset=utf-8"' in resp assert "
    " in resp assert "

    Rendered with Genshi.

    " in resp def test_genshi_manual_render_svg_doctype(): app = setup_noDB() resp = app.get('/genshi_manual_rendering_with_doctype?doctype=svg') assert '" @expose() def multi_value_kws(sekf, *args, **kw): assert kw['foo'] == ['1', '2'], kw @expose() def with_routing_args(self, **kw): return str(tg.request._controller_state.routing_args) @expose('json') @expose('genshi') @expose() def get_response_type(self): return dict(ctype=tg.request.response_type) @expose() def hello_ext(self, *args): return str(tg.request.response_ext) class TestNotFoundController(TestWSGIController): def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.app = make_app(NotFoundController) def test_not_found(self): r = self.app.get('/something', status=404) assert '404 Not Found' in r, r def test_not_found_blank(self): r = self.app.get('/', status=404) assert '404 Not Found' in r, r def test_not_found_unicode(self): r = self.app.get('/%D0%BF%D1%80%D0%B0%D0%B2%D0%B0', status=404) assert '404 Not Found' in r, r class TestNotFoundWithIndexController(TestWSGIController): def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) self.app = make_app(NotFoundWithIndexController) def test_not_found(self): r = self.app.get('/something', status=404) assert '404 Not Found' in r, r class TestWSGIAppController(TestWSGIController): def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) class TestedWSGIAppController(WSGIAppController): def __init__(self): def test_app(environ, start_response): if environ.get('CONTENT_LENGTH', None) in (-1, '-1'): del environ['CONTENT_LENGTH'] return validator(demo_app)(environ, start_response) super(TestedWSGIAppController, self).__init__(test_app) self.app = make_app(TestedWSGIAppController, config_options={ 'make_body_seekable': True }) def test_valid_wsgi(self): try: r = self.app.get('/some_url') except Exception as e: raise AssertionError(str(e)) assert 'some_url' in r class TestWSGIAppControllerNotHTML(TestWSGIController): def __init__(self, *args, **kargs): TestWSGIController.__init__(self, *args, **kargs) class TestedWSGIAppController(WSGIAppController): def __init__(self): def test_app(environ, start_response): start_response('200 OK', [('Content-type','text/plain'), ('Content-Length', '5')]) return [b'HELLO'] super(TestedWSGIAppController, self).__init__(test_app) self.app = make_app(TestedWSGIAppController, config_options={ 'make_body_seekable': True }) def test_right_wsgi_headers(self): r = self.app.get('/some_url') assert 'HELLO' in r assert r.content_length == 5 assert r.content_type == 'text/plain' class TestTGController(TestWSGIController): def setUp(self, *args, **kargs): TestWSGIController.setUp(self, *args, **kargs) self.app = make_app(BasicTGController, config_options={ 'make_body_seekable': True }) def test_enable_routing_args(self): self.app = make_app(BasicTGController, config_options={ 'enable_routing_args': True }) r = self.app.get('/with_routing_args?a=1&b=2&c=3') assert 'a' in str(r) assert 'b' in str(r) assert 'c' in str(r) def test_response_without_charset(self): r = self.app.get('/index_unicode') assert 'Hello World' in r, r assert 'charset=utf-8' in str(r), r def test_lookup(self): r = self.app.get('/lookup/EYE') msg = 'EYE' assert msg in r, r def test_lookup_with_sub(self): r = self.app.get('/lookup_with_sub/EYE') msg = 'EYE' assert msg in r, r def test_lookup_with_args(self): r = self.app.get('/lookup_with_args/get_here/got_here') msg = 'got_here' assert r.body.decode('utf-8')==msg, r def test_post_with_mixed_args(self): r = self.app.post('/lookup_with_args/post_with_mixed_args/test', params={'arg2': 'time'}) msg = 'testtime' assert r.body.decode('utf-8')==msg, r def test_validated_int(self): r = self.app.get('/validated_int/1') assert '{"response": 1}' in r, r def test_validated_with_error_handler(self): r = self.app.get('/validated_with_error_handler?a=asdf&b=123') msg = 'validation error handler' assert msg in r, r def test_validated_with_remote_error_handler(self): r = self.app.get('/validated_with_remote_error_handler?a=asdf&b=123') msg = 'remote error handler' assert msg in r, r def test_unknown_template(self): r = self.app.get('/sub/unknown_template/') msg = 'sub unknown template' assert msg in r, r def test_mounted_wsgi_app_at_root(self): r = self.app.get('/mounted_app/') assert 'Hello from /mounted_app' in r, r def test_mounted_wsgi_app_at_subcontroller(self): r = self.app.get('/sub/mounted_app/') assert 'Hello from /sub/mounted_app/' in r, r def test_request_for_wsgi_app_with_extension(self): r = self.app.get('/sub/mounted_app/some_document.pdf') assert 'Hello from /sub/mounted_app//some_document.pdf' in r, r def test_posting_to_mounted_app(self): r = self.app.post('/mounted_app/', params={'data':'Foooo'}) assert 'Foooo' in r, r def test_use_wsgi_app(self): r = self.app.get('/use_wsgi_app') assert '/use_wsgi_app' in r, r def test_custom_content_type_replace_header(self): s = ''' textvalue ''' r = self.app.post('/xml_rpc/', s, [('Content-Type', 'text/xml')]) assert len(r.headers.getall('Content-Type')) == 1, r.headers.getall('Content-Type') assert r.headers['Content-Type'] == 'text/xml' def test_response_type(self): r = self.app.post('/stacked_expose.json') assert 'got_json' in r.body.decode('utf-8'), r def test_multi_value_kw(self): r = self.app.get('/multi_value_kws?foo=1&foo=2') def test_before_controller(self): r = self.app.get('/sub/before') assert '__my_before__' in r, r def test_new_before_controller(self): r = self.app.get('/sub/newbefore') assert '__my_before__' in r, r def test_visit_entry_point(self): r = self.app.get('/sub/newbefore/visited') assert 'visited' in r, r def test_before_with_args(self): r = self.app.get('/sub/newbefore/with_args/1/2?x=5') assert '__my_before__5' in r, r def test_before_controller_mounted_in_subpath(self): r = self.app.get('/subpath/sub/before', extra_environ={'SCRIPT_NAME':'/subpath'}) assert '__my_before__' in r, r def test_empty_path_after_script_name_removal(self): r = self.app.get('/') check_again_response = r.text r = self.app.get('/subpath', extra_environ={'SCRIPT_NAME':'/subpath'}) assert r.text == check_again_response, r def test_before_controller_without_script_name(self): req = self.app.RequestClass.blank('/sub/before', {}) req.environ.pop('SCRIPT_NAME') r = self.app.do_request(req, status=None, expect_errors=False) assert '__my_before__' in r, r @no_warn def test_unicode_default_dispatch(self): r =self.app.get('/sub/%C3%A4%C3%B6') assert u_("äö") in r.body.decode('utf-8'), r def test_default_with_empty_second_arg(self): r =self.app.get('/sub4/default_with_args/a') assert "default with args a None" in r.body.decode('utf-8'), r assert "deprecated" not in r.body.decode('utf-8') import warnings warnings.filterwarnings('ignore', category=DeprecationWarning) r = self.app.get('/sub4/deprecated_default_with_args/a') warnings.resetwarnings() assert "deprecated default with args a None" in r.body.decode('utf-8'), r def test_default_with_args_a_b(self): r =self.app.get('/sub4/default_with_args/a/b') assert "default with args a b" in r.body.decode('utf-8'), r assert "deprecated" not in r.body.decode('utf-8') import warnings warnings.filterwarnings('ignore', category=DeprecationWarning) r = self.app.get('/sub4/deprecated_default_with_args/a/b') warnings.resetwarnings() assert "deprecated default with args a b" in r.body.decode('utf-8'), r def test_default_with_query_arg(self): r =self.app.get('/sub4/default_with_args?a=a') assert "default with args a None" in r.body.decode('utf-8'), r assert "deprecated" not in r.body.decode('utf-8') import warnings warnings.filterwarnings('ignore', category=DeprecationWarning) r = self.app.get('/sub4/deprecated_default_with_args?a=a') warnings.resetwarnings() assert "deprecated default with args a None" in r.body.decode('utf-8'), r def test_default_with_validator_fail(self): r =self.app.get('/sub5/default_with_args?a=True') assert "failure" in r.body.decode('utf-8'), r def test_default_with_validator_pass(self): r =self.app.get('/sub5/default_with_args?a=66') assert "default with args and validators 66 None" in r.body.decode('utf-8'), r def test_default_with_validator_pass2(self): r =self.app.get('/sub5/default_with_args/66') assert "default with args and validators 66 None" in r.body.decode('utf-8'), r def test_default_with_validator_fail2(self): r =self.app.get('/sub5/default_with_args/True/more') assert "failure" in r.body.decode('utf-8'), r def test_custom_content_type_in_controller(self): resp = self.app.get('/custom_content_type_in_controller') assert 'PNG' in resp, resp assert resp.headers['Content-Type'] == 'image/png', resp def test_custom_content_type_in_controller_charset(self): resp = self.app.get('/custom_content_type_in_controller_charset') assert 'TXT' in resp, resp assert resp.headers['Content-Type'] == 'application/json; charset=utf-8', resp def test_custom_content_type_in_decorator(self): resp = self.app.get('/custom_content_type_in_decorator') assert 'PNG' in resp, resp assert resp.headers['Content-Type'] == 'image/png', resp def test_removed_spurious_content_type(self): r = self.app.get('/test_204') assert r.headers.get('Content-Type', 'MISSING') == 'MISSING' def test_optional_and_req_args(self): resp = self.app.get('/optional_and_req_args/test/one') assert "name=test, one=one, two=2, three=3" in resp.body.decode('utf-8'), resp def test_optional_and_req_args_at_root(self): resp = self.app.get('/test_args/test/one') assert "name=test, one=one, two=2, three=3" in resp.body.decode('utf-8'), resp def test_no_args(self): resp = self.app.get('/test_args/test/') assert "name=test, one=None, two=2, three=3" in resp.body.decode('utf-8'), resp def test_one_extra_arg(self): resp = self.app.get('/test_args/test/1') assert "name=test, one=1, two=2, three=3" in resp.body.decode('utf-8'), resp def test_two_extra_args(self): resp = self.app.get('/test_args/test/1/2') assert "name=test, one=1, two=2, three=3" in resp.body.decode('utf-8'), resp def test_three_extra_args(self): resp = self.app.get('/test_args/test/1/2/3') assert "name=test, one=1, two=2, three=3" in resp.body.decode('utf-8'), resp def test_extra_args_forces_default_lookup(self): resp = self.app.get('/test_args/test/1/2/3/4') assert resp.body.decode('utf-8') == """Main default page called for url /['test_args', 'test', '1', '2', '3', '4']""", resp def test_not_enough_args(self): resp = self.app.get('/test_args/test/1') assert "name=test, one=1, two=2, three=3" in resp.body.decode('utf-8'), resp def test_ticket_2412_with_ordered_arg(self): resp = self.app.get('/ticket2412/Abip%C3%B3n') assert u_("""Abipón""") in resp.body.decode('utf-8'), resp def test_ticket_2412_with_named_arg(self): resp = self.app.get('/ticket2412?arg1=Abip%C3%B3n') assert u_("""Abipón""") in resp.body.decode('utf-8'), resp def test_ticket_2351_bad_content_type(self): resp = self.app.get('/ticket2351', headers={'Accept':'text/html'}) assert 'test' in resp.body.decode('utf-8'), resp def test_embedded_lookup_with_index_first(self): resp = self.app.get('/embedded_lookup_with_index/') assert 'first controller with index' in resp.body.decode('utf-8'), resp def test_embedded_lookup_with_index_second(self): resp = self.app.get('/embedded_lookup_with_index/a') assert 'second controller with index' in resp.body.decode('utf-8'), resp def test_embedded_lookup_with_index_helper(self): resp = self.app.get('/embedded_lookup_with_index/a/b') assert 'helper index' in resp.body.decode('utf-8'), resp def test_embedded_lookup_with_index_method(self): resp = self.app.get('/embedded_lookup_with_index/a/b/method') assert 'helper method' in resp.body.decode('utf-8'), resp def test_self_calling_lookup_simple_index(self): resp = self.app.get('/self_calling') assert '((), {})' in resp.body.decode('utf-8'), resp def test_self_calling_lookup_method(self): resp = self.app.get('/self_calling/a/method/a/b') assert "('a', 'b', {})" in resp.body.decode('utf-8'), resp def test_self_calling_lookup_multiple_calls_method(self): resp = self.app.get('/self_calling/a/b/c/method/a/b') assert "('a', 'b', {})" in resp.body.decode('utf-8'), resp def test_controller_state(self): resp = self.app.get('/sub/get_controller_state') assert '/sub' in resp def test_response_type_json(self): resp = self.app.get('/get_response_type.json') assert 'json' in resp def test_response_type_html(self): resp = self.app.get('/get_response_type.html') assert 'html' in resp def test_extensions_single(self): resp = self.app.get('/hello_ext.html') assert resp.body.decode('ascii') == '.html', resp.body def test_extensions_missing(self): resp = self.app.get('/hello_ext') assert resp.body.decode('ascii') == 'None', resp.body def test_extensions_two(self): resp = self.app.get('/hello_ext.json.html') assert 'Main default page' in resp, resp assert 'hello_ext.json' in resp, resp def test_extensions_three(self): resp = self.app.get('/hello_ext.jpg.json.html') assert 'Main default page' in resp, resp assert 'hello_ext.jpg.json' in resp, resp def test_controller_url(self): resp = self.app.get('/sub3/controller_url/false/a/b/c') assert resp.text == 'sub3/controller_url', resp.text def test_controller_url_backward_compatibility(self): resp = self.app.get('/sub3/controller_url/true/a/b/c') assert resp.text == 'sub3/controller_url', resp.text class TestNestedWSGIAppWithoutSeekable(TestWSGIController): def setUp(self, *args, **kargs): TestWSGIController.setUp(self, *args, **kargs) self.app = make_app(BasicTGController, config_options={ 'make_body_seekable': False }) @raises(RuntimeError) def test_missing_body_seekable_trapped(self): self.app.get('/mounted_app') TurboGears2-2.3.7/tests/test_util.py0000644000076500000240000002211412607177564017504 0ustar amolstaff00000000000000# -*- coding: utf-8 -*- from datetime import datetime, timedelta import tg from tg.util import * from tg.configuration.utils import get_partial_dict from nose.tools import eq_, raises import os from tg.controllers.util import * from tg.util.dates import get_fixed_timezone, utctz, parse_datetime from tg.util.files import safe_filename from tg.util.html import script_json_encode from tg.util.webtest import test_context from tg.wsgiapp import TemplateContext, AttribSafeTemplateContext import tg._compat from tg._compat import u_ path = None def setup(): global path path = os.curdir os.chdir(os.path.abspath(os.path.dirname(os.path.dirname(tg.__file__)))) def teardown(): global path os.chdir(path) def test_get_partial_dict(): eq_(get_partial_dict('prefix', {'prefix.xyz':1, 'prefix.zyx':2, 'xy':3}), {'xyz':1,'zyx':2}) def test_compat_im_class(): class FakeClass(object): def method(self): pass def func(): pass o = FakeClass() assert tg._compat.im_class(o.method) == FakeClass assert tg._compat.im_class(func) == None class TestUrlMethod(object): def test_url_unicode(self): with test_context(None, '/'): res = url('.', {'p1':u_('v1')}) assert res == '.?p1=v1' def test_url_unicode_nonascii(self): with test_context(None, '/'): res = url('.', {'p1':u_('àèìòù')}) assert res == '.?p1=%C3%A0%C3%A8%C3%AC%C3%B2%C3%B9' def test_url_nonstring(self): with test_context(None, '/'): res = url('.', {'p1':1}) assert res == '.?p1=1' def test_url_object(self): class Object(object): def __str__(self): return 'aeiou' with test_context(None, '/'): res = url('.', {'p1': Object()}) assert res == '.?p1=aeiou' def test_url_object_unicodeerror(self): class Object(object): def __str__(self): return u_('àèìòù') with test_context(None, '/'): res = url('.', {'p1': Object()}) assert res == '.?p1=%C3%A0%C3%A8%C3%AC%C3%B2%C3%B9' def test_url_object_exception(self): class SubException(Exception): def __str__(self): return u_('àèìòù') with test_context(None, '/'): res = url('.', {'p1': SubException('a', 'b', 'c')}) assert res == '.?p1=a+b+c', res class TestBunch(object): def test_add_entry(self): d = Bunch() d['test.value'] = 5 assert d.test.value == 5 def test_del_entry(self): d = Bunch() d['test_value'] = 5 del d.test_value assert not list(d.keys()) @raises(AttributeError) def test_del_entry_fail(self): d = Bunch() del d.not_existing class TestDottedNameFinder(object): @raises(DottedFileLocatorError) def test_non_python_package(self): DottedFileNameFinder().get_dotted_filename('this.is.not.a.python.package') def test_local_file(self): abspath = os.path.abspath('this_should_be_my_template') assert DottedFileNameFinder().get_dotted_filename('this_should_be_my_template') == abspath def test_local_file_utility_method(self): abspath = os.path.abspath('this_should_be_my_template') assert DottedFileNameFinder.lookup('this_should_be_my_template') == abspath def test_local_file_returns_absolute_path(self): assert os.path.isabs(DottedFileNameFinder.lookup('this_should_be_my_template')) class TestLazyString(object): def test_lazy_string_to_str(self): l = LazyString(lambda: 'HI') assert str(l) == 'HI' def test_lazy_string_to_mod(self): l = LazyString(lambda: '%s') assert (l % 'HI') == 'HI' def test_lazy_string_format(self): l = LazyString(lambda: '{0}') lf = l.format('HI') assert lf == 'HI', lf class TestAttribSafeContextObj(object): def setup(self): self.c = AttribSafeTemplateContext() def test_attribute_default_value(self): assert self.c.something == '' self.c.something = 'HELLO' assert self.c.something == 'HELLO' assert self.c.more == '' def test_tmpl_context_long_entry(): c = TemplateContext() c.something = '3'*300 assert len(str(c)) < 300 class TestDatesUtils(object): def test_get_fixed_timezone_seconds(self): delta = get_fixed_timezone(0.5).utcoffset(None) assert delta.seconds == 0 def test_get_fixed_timezone_minutes(self): delta = get_fixed_timezone(1).utcoffset(None) assert delta.seconds == 60 def test_get_fixed_timezone_hours(self): delta = get_fixed_timezone(60).utcoffset(None) assert delta.seconds == 3600 def test_get_fixed_timezone_seconds_td(self): delta = get_fixed_timezone(timedelta(seconds=30)).utcoffset(None) assert delta.seconds == 0 def test_get_fixed_timezone_minutes_td(self): delta = get_fixed_timezone(timedelta(minutes=1)).utcoffset(None) assert delta.seconds == 60 def test_get_fixed_timezone_hours_td(self): delta = get_fixed_timezone(timedelta(hours=1)).utcoffset(None) assert delta.seconds == 3600 def test_get_fixed_timezone_usage(self): utcnow = datetime.utcnow() uktz = get_fixed_timezone(60) uknow = (utcnow + timedelta(hours=1)).replace(tzinfo=uktz) naiveuk = uknow.astimezone(utctz).replace(tzinfo=None) assert utcnow == naiveuk, (utcnow, naiveuk) def test_get_fixed_timezone_name(self): uktz = get_fixed_timezone(60) uktz_name = uktz.tzname(None) assert uktz_name == '+0100', uktz_name assert repr(uktz) == '<+0100>', repr(uktz) assert utctz.tzname(None) == 'UTC', utctz.tzname(None) assert repr(utctz) == '', repr(utctz) def test_get_fixed_timezone_unknowndst(self): uktz = get_fixed_timezone(60) assert uktz.dst(None).seconds == 0 def test_parse_datetime_tz(self): dt = parse_datetime('1997-07-16T19:20:30.45+01:00') assert dt.tzname() == '+0100', dt expected_dt = datetime(1997, 7, 16, 19, 20, 30, 450000) naive_dt = dt.replace(tzinfo=None) assert naive_dt == expected_dt, naive_dt def test_parse_datetime_utc(self): dt = parse_datetime('1997-07-16T19:20:30.45Z') assert dt.tzname() == 'UTC', dt expected_dt = datetime(1997, 7, 16, 19, 20, 30, 450000).replace(tzinfo=utctz) assert dt == expected_dt, dt def test_parse_datetime_negativetz(self): dt = parse_datetime('1997-07-16T19:20:30.45-01:00') assert dt.tzname() == '-0100', dt expected_dt = datetime(1997, 7, 16, 19, 20, 30, 450000) naive_dt = dt.replace(tzinfo=None) assert naive_dt == expected_dt, naive_dt @raises(ValueError) def test_parse_datetime_invalid_format(self): parse_datetime('1997@07@16T19:20:30.45+01:00') class TestHtmlUtils(object): def test_script_json_encode(self): rv = script_json_encode('') assert rv == u_('"\\u003c/script\\u003e"') rv = script_json_encode("<\0/script>") assert rv == '"\\u003c\\u0000/script\\u003e"' rv = script_json_encode("