3 from twisted.internet import defer
4 from twisted.web import client
5 from nevow.testutil import FakeRequest
6 from nevow import inevow, context
8 class WebRenderingMixin:
9 # d=page.renderString() or s=page.renderSynchronously() will exercise
10 # docFactory, render_*/data_* . It won't exercise want_json(), or my
11 # renderHTTP() override which tests want_json(). To exercise args=, we
12 # must build a context. Pages which use a return_to= argument need a
15 # d=page.renderHTTP(ctx) will exercise my renderHTTP, want_json, and
16 # docFactory/render_*/data_*, but it requires building a context. Since
17 # we're already building a context, it is easy to exercise args= .
19 # so, use at least two d=page.renderHTTP(ctx) per page (one for json, one
20 # for html), then use lots of simple s=page.renderSynchronously() to
21 # exercise the fine details (the ones that don't require args=).
23 def make_context(self, req):
24 ctx = context.RequestContext(tag=req)
25 ctx.remember(req, inevow.IRequest)
26 ctx.remember(None, inevow.IData)
27 ctx = context.WovenContext(parent=ctx, precompile=False)
30 def render1(self, page, **kwargs):
31 # use this to exercise an overridden renderHTTP, usually for
32 # output=json or render_GET. It always returns a Deferred.
33 req = FakeRequest(**kwargs)
35 ctx = self.make_context(req)
36 d = defer.maybeDeferred(page.renderHTTP, ctx)
38 if isinstance(res, str):
44 def render2(self, page, **kwargs):
45 # use this to exercise the normal Nevow docFactory rendering. It
46 # returns a string. If one of the render_* methods returns a
47 # Deferred, this will throw an exception. (note that
48 # page.renderString is the Deferred-returning equivalent)
49 req = FakeRequest(**kwargs)
51 ctx = self.make_context(req)
52 return page.renderSynchronously(ctx)
54 def failUnlessIn(self, substring, s):
55 self.failUnless(substring in s, s)
57 def remove_tags(self, s):
58 s = re.sub(r'<[^>]*>', ' ', s)
59 s = re.sub(r'\s+', ' ', s)
63 class MyGetter(client.HTTPPageGetter):
64 handleStatus_206 = lambda self: self.handleStatus_200() # PARTIAL_CONTENT
65 handleStatus_304 = lambda self: self.handleStatus_200() # NOT_MODIFIED
67 class HTTPClientHEADFactory(client.HTTPClientFactory):
70 def noPage(self, reason):
71 # Twisted-2.5.0 and earlier had a bug, in which they would raise an
72 # exception when the response to a HEAD request had no body (when in
73 # fact they are defined to never have a body). This was fixed in
74 # Twisted-8.0 . To work around this, we catch the
75 # PartialDownloadError and make it disappear.
76 if (reason.check(client.PartialDownloadError)
77 and self.method.upper() == "HEAD"):
80 return client.HTTPClientFactory.noPage(self, reason)
82 class HTTPClientGETFactory(client.HTTPClientFactory):