import os import sys from lxml import etree from paste.fixture import TestApp from paste.urlparser import StaticURLParser from paste.response import header_value from paste.wsgilib import intercept_output from deliverance.wsgimiddleware import DeliveranceMiddleware from formencode.doctest_xml_compare import xml_compare from deliverance.htmlserialize import tostring from deliverance.cache_fixture import CacheFixtureResponseInfo, CacheFixtureApp from deliverance import cache_utils from time import time as now from rfc822 import formatdate static_data = os.path.join(os.path.dirname(__file__), 'test-data', 'static') tasktracker_data = os.path.join(os.path.dirname(__file__), 'test-data', 'tasktracker') nycsr_data = os.path.join(os.path.dirname(__file__), 'test-data', 'nycsr') necoro_data = os.path.join(os.path.dirname(__file__), 'test-data', 'necoro') guidesearch_data = os.path.join(os.path.dirname(__file__), 'test-data', 'guidesearch') ajax_data = os.path.join(os.path.dirname(__file__), 'test-data', 'ajax') url_data = os.path.join(os.path.dirname(__file__), 'test-data', 'wsgiurl') aggregate_data = os.path.join(os.path.dirname(__file__), 'test-data', 'aggregate') aggregate2_data = os.path.join(os.path.dirname(__file__), 'test-data', 'aggregate2') ignore_data = os.path.join(os.path.dirname(__file__), 'test-data', 'ignore') urienv_data = os.path.join(os.path.dirname(__file__), 'test-data', 'urienv') static_app = StaticURLParser(static_data) tasktracker_app = StaticURLParser(tasktracker_data) nycsr_app = StaticURLParser(nycsr_data) necoro_app = StaticURLParser(necoro_data) guidesearch_app = StaticURLParser(guidesearch_data) ajax_app = StaticURLParser(ajax_data) url_app = StaticURLParser(url_data) aggregate_app = StaticURLParser(aggregate_data) aggregate2_app = StaticURLParser(aggregate2_data) ignore_app = StaticURLParser(ignore_data) urienv_app = StaticURLParser(urienv_data) def html_string_compare(astr, bstr): """ compare to strings containing html based on html equivalence. Raises ValueError if the strings are not equivalent. """ def reporter(x): print x a = None b = None try: a = etree.HTML(astr) except: print a raise try: b = etree.HTML(bstr) except: print b raise reporter = [] result = xml_compare(a, b, reporter.append) if not result: raise ValueError( "Comparison failed between actual:\n==================\n%s\n\nexpected:\n==================\n%s\n\nReport:\n%s" % (astr, bstr, '\n'.join(reporter))) def do_basic(renderer_type, name): wsgi_app = DeliveranceMiddleware(static_app, 'theme.html', 'rules.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/example.html') res2 = app.get('/example_expected.html?notheme') html_string_compare(res.body, res2.body) def do_text(renderer_type, name): wsgi_app = DeliveranceMiddleware(static_app, 'theme.html', 'text-rules.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/example.html') res2 = app.get('/texttest_expected.html?notheme') html_string_compare(res.body, res2.body) def do_tasktracker(renderer_type, name): wsgi_app = DeliveranceMiddleware(tasktracker_app, 'http://codespeak.net/svn/z3/deliverance/trunk/deliverance/test-data/nycsr/nycsr_theme.html', 'tasktracker.xml',renderer_type) app = TestApp(wsgi_app) res = app.get('/content.html') res2 = app.get('/expected.html?notheme') html_string_compare(res.body, res2.body) def do_xinclude(renderer_type, name): wsgi_app = DeliveranceMiddleware(static_app, 'xinclude_theme.html', 'xinclude_rules.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/example.html') res2 = app.get('/xinclude_expected.html?notheme') html_string_compare(res.body, res2.body) def do_with_spaces(renderer_type, name): wsgi_app = DeliveranceMiddleware(static_app, 'xinclude_theme.html', 'xinclude_rules.xml', renderer_type) app = TestApp(wsgi_app) expected = app.get('/xinclude_expected.html?notheme').body res = app.get('/example%20with%20spaces.html') html_string_compare(res.body, expected) wsgi_app = DeliveranceMiddleware(static_app, 'xinclude_theme.html', 'xinclude_rules%20with%20spaces.xml', renderer_type) app = TestApp(wsgi_app) res2 = app.get('/example.html') html_string_compare(res2.body, expected) def do_nycsr(renderer_type, name): wsgi_app = DeliveranceMiddleware(nycsr_app, 'http://codespeak.net/svn/z3/deliverance/trunk/deliverance/test-data/nycsr/nycsr_theme.html','nycsr.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/openplans.html') res2 = app.get('/nycsr_expected.html?notheme') html_string_compare(res.body, res2.body) def do_necoro(renderer_type, name): wsgi_app = DeliveranceMiddleware(necoro_app, 'theme.html','necoro.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/zope.html') res2 = app.get('/expected.html?notheme') html_string_compare(res.body, res2.body) def do_guidesearch(renderer_type, name): wsgi_app = DeliveranceMiddleware(guidesearch_app, 'theme.html','guidesearch.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/zope.html') res2 = app.get('/expected.html?notheme') html_string_compare(res.body, res2.body) def do_ajax(renderer_type, name): wsgi_app = DeliveranceMiddleware(ajax_app, 'theme.html','rules.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/content.html') res2 = app.get('/content.html?notheme') html_string_compare(res.body, res2.body) def do_url(renderer_type, name): wsgi_app = DeliveranceMiddleware(url_app, '/foo/bar/test_url_theme.html','/foo/bar/test_url.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/foo/bar/test_url_content.html') res2 = app.get('/foo/bar/test_url_expected.html?notheme') html_string_compare(res.body,res2.body) def do_aggregate(renderer_type, name): wsgi_app = DeliveranceMiddleware(aggregate_app, 'theme.html', 'rules.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/example.html') res2 = app.get('/expected.html?notheme') html_string_compare(res.body, res2.body) def do_aggregate2(renderer_type, name): wsgi_app = DeliveranceMiddleware(aggregate2_app, 'theme.html', 'rules.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/index.html') res2 = app.get('/expected.html?notheme') html_string_compare(res.body, res2.body) def do_ignore(renderer_type, name): ## FIXME: there are no files in test-data/ignore/, where this comes from. return wsgi_app = DeliveranceMiddleware(ignore_app, 'theme.html', 'rules.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/index.html') res2 = app.get('/expected.html?notheme') html_string_compare(res.body, res2.body) res = app.get('/index2.html') res2 = app.get('/expected2.html?notheme') html_string_compare(res.body, res2.body) def do_ignore_header(renderer_type, name): ## FIXME: there are no files in test-data/ignore/, where this comes from. return class NoThemeHeaderApp: def __init__(self, app): self.app = app def __call__(self, environ, start_response): status, headers, body = intercept_output(environ, self.app) headers.append(('x-deliverance-no-theme','1')) start_response(status, headers) return [body] wsgi_app = DeliveranceMiddleware(NoThemeHeaderApp(ignore_app), 'theme.html', 'rules.xml', renderer_type) app = TestApp(wsgi_app) res = app.get('/index2.html') res2 = app.get('/expected3.html?notheme') html_string_compare(res.body, res2.body) def do_cache(renderer_type, name): # XXX this should be busted up into multiple tests I spose theme_data = """ theme
""" rule_data = """ """ content_data = """
foo
""" expected_data = """ theme
foo
""" theme_info = CacheFixtureResponseInfo(theme_data) rule_info = CacheFixtureResponseInfo(rule_data) content_info = CacheFixtureResponseInfo(content_data) expected_info = CacheFixtureResponseInfo(expected_data) capp = CacheFixtureApp() capp.map_url('/theme.html',theme_info) capp.map_url('/rules.xml',rule_info) capp.map_url('/content.html',content_info) capp.map_url('/expected.html',expected_info) wsgi_app = DeliveranceMiddleware(capp, '/theme.html', '/rules.xml', renderer_type) # check that everything works straight up app = TestApp(wsgi_app) res = app.get('/content.html') res2 = app.get('/expected.html?notheme') html_string_compare(res.body, res2.body) # set some etags on the fixture theme_info.etag = "theme_etag" rule_info.etag = "rule_etag" content_info.etag = "content_etag" # grab the page and make sure an etag comes back res = app.get('/content.html') composite_etag = header_value(res.headers, 'etag') assert(composite_etag is not None and len(composite_etag) > 0) # check that deliverance gives 304 when the composite etag is given res = app.get('/content.html', headers={'If-None-Match': composite_etag}) status = res.status assert(status == 304) theme_info.etag = 'something_else' # check that deliverance rebuilds when one of the etags changes res = app.get('/content.html', headers={'If-None-Match': composite_etag}) status = res.status # make sure the response etag changed assert(header_value(res.headers, 'etag') != composite_etag) assert(status == 200) # clear etags theme_info.etag = None rule_info.etag = None content_info.etag = None # make sure there is no more etag res = app.get('/content.html') composite_etag = header_value(res.headers, 'etag') assert(composite_etag is None or len(composite_etag) == 0) # test modification dates then = now() theme_info.mod_time = then - 10 rule_info.mod_time = then - 20 content_info.mod_time = then - 30 res = app.get('/content.html') status = res.status assert(status == 200) res = app.get('/content.html', headers={'If-Modified-Since': formatdate(then)}) status = res.status assert(status == 304) res = app.get('/content.html', headers={'If-Modified-Since': formatdate(then-60)}) status = res.status assert(status == 200) res = app.get('/content.html', headers={'If-Modified-Since': formatdate(then-15)}) status = res.status assert(status == 200) def do_rule_uri_environ(renderer_type, name): from deliverance.utils import set_rule_uri wsgi_app = DeliveranceMiddleware(urienv_app, 'theme.html', 'rules.xml', renderer_type) environ = {} set_rule_uri(environ, 'rules2.xml') app = TestApp(wsgi_app, extra_environ=environ) res = app.get('/example.html') res2 = app.get('/example_expected_rule_uri_environ.html?notheme') html_string_compare(res.body, res2.body) def do_theme_uri_environ(renderer_type, name): from deliverance.utils import set_theme_uri wsgi_app = DeliveranceMiddleware(urienv_app, 'theme.html', 'rules.xml', renderer_type) environ = {} set_theme_uri(environ, 'theme2.html') app = TestApp(wsgi_app, extra_environ=environ) res = app.get('/example.html') res2 = app.get('/example_expected_theme_uri_environ.html?notheme') html_string_compare(res.body, res2.body) def do_serializer_environ(renderer_type, name): from deliverance.utils import set_serializer wsgi_app = DeliveranceMiddleware(urienv_app, 'theme.html', 'rules.xml', renderer_type) environ = {} set_serializer(environ, 'deliverance.test_wsgi:_uppercaseTextNodes') app = TestApp(wsgi_app, extra_environ=environ) res = app.get('/example.html') res2 = app.get('/example_expected_uppercase.html?notheme') html_string_compare(res.body, res2.body) def _uppercaseTextNodes(content): from htmlserialize import tostring return tostring(content, doctype_pair=("-//W3C//DTD HTML 4.01 Transitional//EN", "http://www.w3.org/TR/html4/loose.dtd") ).upper() RENDERER_TYPES = ['py', 'xslt'] TEST_FUNCS = [ do_url, do_basic, do_text, do_tasktracker, do_xinclude, do_with_spaces, do_nycsr, do_necoro, do_guidesearch, do_ajax, do_aggregate, do_aggregate2, do_cache, do_ignore, do_ignore_header, do_rule_uri_environ, do_theme_uri_environ, do_serializer_environ ] def test_all(): for renderer_type in RENDERER_TYPES: for test_func in TEST_FUNCS: yield test_func, renderer_type, test_func.func_name if __name__ == '__main__': pass