TurboGears2-2.3.7/ 0000755 0000765 0000024 00000000000 12607177763 013755 5 ustar amol staff 0000000 0000000 TurboGears2-2.3.7/PKG-INFO 0000644 0000765 0000024 00000003230 12607177763 015050 0 ustar amol staff 0000000 0000000 Metadata-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.rst 0000644 0000765 0000024 00000002205 12413576166 015436 0 ustar amol staff 0000000 0000000 TurboGears
==============
.. 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.cfg 0000644 0000765 0000024 00000000402 12607177763 015572 0 ustar amol staff 0000000 0000000 [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.py 0000644 0000765 0000024 00000005460 12607177564 015473 0 ustar amol staff 0000000 0000000 import 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/ 0000755 0000765 0000024 00000000000 12607177763 015117 5 ustar amol staff 0000000 0000000 TurboGears2-2.3.7/tests/__init__.py 0000644 0000765 0000024 00000000000 12413576166 017211 0 ustar amol staff 0000000 0000000 TurboGears2-2.3.7/tests/base.py 0000644 0000765 0000024 00000006637 12555020522 016375 0 ustar amol staff 0000000 0000000 # -*- 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/ 0000755 0000765 0000024 00000000000 12607177763 016770 5 ustar amol staff 0000000 0000000 TurboGears2-2.3.7/tests/fixtures/__init__.py 0000644 0000765 0000024 00000000116 12413576166 021072 0 ustar amol staff 0000000 0000000 """TG developers may use this package to store fixtures for the test suite"""
TurboGears2-2.3.7/tests/fixtures/model.py 0000644 0000765 0000024 00000003100 12413576166 020427 0 ustar amol staff 0000000 0000000 """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.py 0000644 0000765 0000024 00000005703 12413576166 022024 0 ustar amol staff 0000000 0000000 from 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.py 0000644 0000765 0000024 00000043125 12607177564 020130 0 ustar amol staff 0000000 0000000 # -*- 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.py 0000644 0000765 0000024 00000006173 12413576166 022241 0 ustar amol staff 0000000 0000000 from 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) == 2 TurboGears2-2.3.7/tests/test_configuration.py 0000644 0000765 0000024 00000224256 12607177564 021411 0 ustar amol staff 0000000 0000000 """
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.py 0000644 0000765 0000024 00000005505 12536240617 023617 0 ustar amol staff 0000000 0000000 from 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.py 0000644 0000765 0000024 00000011304 12555020522 021053 0 ustar amol staff 0000000 0000000 # -*- 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.py 0000644 0000765 0000024 00000003533 12413576166 020721 0 ustar amol staff 0000000 0000000 from 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.py 0000644 0000765 0000024 00000004651 12413576166 020541 0 ustar amol staff 0000000 0000000 from 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.py 0000644 0000765 0000024 00000010060 12413576166 020341 0 ustar amol staff 0000000 0000000 from 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('