HEX
Server: nginx/1.28.1
System: Linux 10-41-63-61 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 20 00:40:06 UTC 2024 x86_64
User: www (1001)
PHP: 7.4.33
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
File: //lib/python3/dist-packages/twisted/web/test/test_pages.py
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

"""
Test L{twisted.web.pages}
"""

from typing import cast

from twisted.trial.unittest import SynchronousTestCase
from twisted.web.http_headers import Headers
from twisted.web.iweb import IRequest
from twisted.web.pages import errorPage, forbidden, notFound
from twisted.web.resource import IResource
from twisted.web.test.requesthelper import DummyRequest


def _render(resource: IResource) -> DummyRequest:
    """
    Render a response using the given resource.

    @param resource: The resource to use to handle the request.

    @returns: The request that the resource handled,
    """
    request = DummyRequest([b""])
    # The cast is necessary because DummyRequest isn't annotated
    # as an IRequest, and this can't be trivially done. See
    # https://github.com/twisted/twisted/issues/11719
    resource.render(cast(IRequest, request))
    return request


class ErrorPageTests(SynchronousTestCase):
    """
    Test L{twisted.web.pages._ErrorPage} and its public aliases L{errorPage},
    L{notFound} and L{forbidden}.
    """

    maxDiff = None

    def assertResponse(self, request: DummyRequest, code: int, body: bytes) -> None:
        self.assertEqual(request.responseCode, code)
        self.assertEqual(
            request.responseHeaders,
            Headers({b"content-type": [b"text/html; charset=utf-8"]}),
        )
        self.assertEqual(
            # Decode to str because unittest somehow still doesn't diff bytes
            # without truncating them in 2022.
            b"".join(request.written).decode("latin-1"),
            body.decode("latin-1"),
        )

    def test_escapesHTML(self) -> None:
        """
        The I{brief} and I{detail} parameters are HTML-escaped on render.
        """
        self.assertResponse(
            _render(errorPage(400, "A & B", "<script>alert('oops!')")),
            400,
            (
                b"<!DOCTYPE html>\n"
                b"<html><head><title>400 - A &amp; B</title></head>"
                b"<body><h1>A &amp; B</h1><p>&lt;script&gt;alert('oops!')"
                b"</p></body></html>"
            ),
        )

    def test_getChild(self) -> None:
        """
        The C{getChild} method of the resource returned by L{errorPage} returns
        the L{_ErrorPage} it is called on.
        """
        page = errorPage(404, "foo", "bar")
        self.assertIs(
            page.getChild(b"name", cast(IRequest, DummyRequest([b""]))),
            page,
        )

    def test_notFoundDefaults(self) -> None:
        """
        The default arguments to L{twisted.web.pages.notFound} produce
        a reasonable error page.
        """
        self.assertResponse(
            _render(notFound()),
            404,
            (
                b"<!DOCTYPE html>\n"
                b"<html><head><title>404 - No Such Resource</title></head>"
                b"<body><h1>No Such Resource</h1>"
                b"<p>Sorry. No luck finding that resource.</p>"
                b"</body></html>"
            ),
        )

    def test_forbiddenDefaults(self) -> None:
        """
        The default arguments to L{twisted.web.pages.forbidden} produce
        a reasonable error page.
        """
        self.assertResponse(
            _render(forbidden()),
            403,
            (
                b"<!DOCTYPE html>\n"
                b"<html><head><title>403 - Forbidden Resource</title></head>"
                b"<body><h1>Forbidden Resource</h1>"
                b"<p>Sorry, resource is forbidden.</p>"
                b"</body></html>"
            ),
        )