from twisted.web import microdom
from twisted.trial.unittest import TestCase
from twisted.python.reflect import qual
from nevow.athena import LivePage
from nevow.loaders import stan
from nevow.tags import (
html, head, body, img, script, link, invisible, directive)
from nevow.context import WovenContext
from nevow.testutil import FakeRequest, AccumulatingFakeRequest as makeRequest
from nevow.flat import flatten
from nevow.inevow import IRequest
from nevow.page import renderer
from axiom.store import Store
from axiom.substore import SubStore
from axiom.dependency import installOn
from xmantissa.port import TCPPort
from xmantissa.webtheme import (
getAllThemes, getInstalledThemes, MantissaTheme, ThemedFragment,
ThemedElement, _ThemedMixin)
from xmantissa.website import WebSite
from xmantissa.offering import installOffering
from xmantissa.plugins.baseoff import baseOffering
def testHead(theme):
"""
Check that the head method of the given them doesn't explode.
@param theme: probably an L{xmantissa.webtheme.XHTMLDirectoryTheme}
"""
store = Store()
site = WebSite(store=store)
installOn(site, store)
port = TCPPort(store=store, portNumber=80, factory=site)
installOn(port, store)
flatten(theme.head(makeRequest(), site))
class WebThemeTestCase(TestCase):
def _render(self, element):
"""
Put the given L{IRenderer} provider into an L{athena.LivePage} and
render it. Return a Deferred which fires with the request object used
which is an instance of L{nevow.testutil.FakeRequest}.
"""
p = LivePage(
docFactory=stan(
html[
head(render=directive('liveglue')),
body[
invisible(render=lambda ctx, data: element)]]))
element.setFragmentParent(p)
ctx = WovenContext()
req = FakeRequest()
ctx.remember(req, IRequest)
d = p.renderHTTP(ctx)
def rendered(ign):
p.action_close(None)
return req
d.addCallback(rendered)
return d
def test_getAllThemesPrioritization(self):
"""
Test that the L{xmantissa.webtheme.getAllThemes} function returns
L{ITemplateNameResolver} providers from the installed
L{xmantissa.ixmantissa.IOffering} plugins in priority order.
"""
lastPriority = None
for theme in getAllThemes():
if lastPriority is None:
lastPriority = theme.priority
else:
self.failIf(
theme.priority > lastPriority,
"Theme out of order: %r" % (theme,))
lastPriority = theme.priority
def test_getInstalledThemes(self):
"""
Test that only themes which belong to offerings installed on a
particular store are returned by
L{xmantissa.webtheme.getInstalledThemes}.
"""
dbdir = self.mktemp()
s = Store(dbdir)
self.assertEquals(getInstalledThemes(s), [])
installOffering(s, baseOffering, {})
installedThemes = getInstalledThemes(s)
self.assertEquals(len(installedThemes), 1)
self.failUnless(isinstance(installedThemes[0], MantissaTheme))
def _defaultThemedRendering(self, cls):
class ThemedSubclass(cls):
pass
d = self._render(ThemedSubclass())
def rendered(req):
self.assertIn(
qual(ThemedSubclass),
req.v)
self.assertIn(
'specified no fragmentName attribute.',
req.v)
d.addCallback(rendered)
return d
def test_themedFragmentDefaultRendering(self):
"""
Test that a ThemedFragment which does not override fragmentName is
rendered with some debugging tips.
"""
return self._defaultThemedRendering(ThemedFragment)
def test_themedElementDefaultRendering(self):
"""
Test that a ThemedElement which does not override fragmentName is
rendered with some debugging tips.
"""
return self._defaultThemedRendering(ThemedElement)
def test_websiteDiscovery(self):
"""
Test that L{_ThemedMixin.getWebSite} finds the right object whether it
is wrapped around a user store or the store store.
"""
siteStore = Store(self.mktemp())
siteSite = WebSite(store=siteStore)
installOn(siteSite, siteStore)
subStore = SubStore.createNew(siteStore, ['user']).open()
subSite = WebSite(store=subStore)
installOn(subSite, subStore)
themed = _ThemedMixin()
themed.store = siteStore
self.assertIdentical(
themed.getWebSite(), siteSite,
"Found the wrong WebSite from the site store.")
themed = _ThemedMixin()
themed.store = subStore
self.assertEquals(
themed.getWebSite(), siteSite,
"Found the wrong WebSite from the user store.")
def test_imageSourceNotRewritten(self):
"""
Test that an image tag which includes a hostname in its source does not
have that source rewritten.
"""
store = Store()
site = WebSite(store=store, hostname=u'example.com')
installOn(site, store)
testElement = ThemedElement()
testElement.docFactory = stan(img(src='http://example.org/Foo.png'))
testElement.store = store
d = self._render(testElement)
def rendered(req):
dom = microdom.parseString(req.v)
img = dom.getElementsByTagName('img')[0]
self.assertEquals("http://example.org/Foo.png",
img.getAttribute('src'))
d.addCallback(rendered)
return d
def _mutate(self, urlString):
return "%s_mutated" % (urlString,)
def test_originalImageRendererRespected(self):
"""
Test that an image tag with a render directive has that directive
invoked after the URL has been rewritten.
"""
store = Store()
site = WebSite(store=store, hostname=u'example.com')
installOn(site, store)
class TestElement(ThemedElement):
def mutate(this, request, tag):
this.mutated = self._mutate(tag.attributes['src'])
return tag
renderer(mutate)
ele = TestElement()
ele.docFactory = stan(img(src='/Foo.png', render=directive('mutate')))
ele.store = store
d = self._render(ele)
def rendered(req):
self.assertEquals(ele.mutated, self._mutate('/Foo.png'))
d.addCallback(rendered)
return d
def test_scriptSourceNotRewritten(self):
"""
Test that a script tag which includes a hostname in its source does not
have that source rewritten.
"""
store = Store()
site = WebSite(store=store, hostname=u'example.com')
installOn(site, store)
testElement = ThemedElement()
testElement.docFactory = stan(script(src='http://example.org/Foo.js'))
testElement.store = store
d = self._render(testElement)
def rendered(req):
self.assertIn(
'',
req.v)
d.addCallback(rendered)
return d
def test_originalScriptRendererRespected(self):
"""
Test that an script tag with a render directive has that directive
invoked after the URL has been rewritten.
"""
store = Store()
site = WebSite(store=store, hostname=u'example.com')
installOn(site, store)
class TestElement(ThemedElement):
def mutate(this, request, tag):
this.mutated = self._mutate(tag.attributes['src'])
return tag
renderer(mutate)
ele = TestElement()
ele.docFactory = stan(script(src='/Foo.js', render=directive('mutate')))
ele.store = store
d = self._render(ele)
def rendered(req):
self.assertEquals(ele.mutated, self._mutate('/Foo.js'))
d.addCallback(rendered)
return d
def test_linkHypertextReferenceNotRewritten(self):
"""
Test that a link which includes a hostname in its href does not have
that href rewritten.
"""
store = Store()
site = WebSite(store=store, hostname=u'example.com')
installOn(site, store)
testElement = ThemedElement()
testElement.docFactory = stan(link(href='http://example.org/Foo.css'))
testElement.store = store
d = self._render(testElement)
def rendered(req):
self.assertIn(
'',
req.v)
d.addCallback(rendered)
return d
def test_originalLinkRendererRespected(self):
"""
Test that a link tag with a render directive has that directive invoked
after the URL has been rewritten.
"""
store = Store()
site = WebSite(store=store, hostname=u'example.com')
installOn(site, store)
class TestElement(ThemedElement):
def mutate(this, request, tag):
this.mutated = self._mutate(tag.attributes['href'])
return tag
renderer(mutate)
ele = TestElement()
ele.docFactory = stan(link(href='/Foo.css', render=directive('mutate')))
ele.store = store
d = self._render(ele)
def rendered(req):
self.assertEquals(ele.mutated, self._mutate('/Foo.css'))
d.addCallback(rendered)
return d
def test_head(self):
testHead(MantissaTheme(''))