예제 #1
0
class TestLaunchpadBrowserRequest_getNearest(TestCase):

    def setUp(self):
        super(TestLaunchpadBrowserRequest_getNearest, self).setUp()
        self.request = LaunchpadBrowserRequest('', {})
        self.thing_set = ThingSet()
        self.thing = Thing()

    def test_return_value(self):
        # .getNearest() returns a two-tuple with the object and the interface
        # that matched. The second item in the tuple is useful when multiple
        # interfaces are passed to getNearest().
        request = self.request
        request.traversed_objects.extend([self.thing_set, self.thing])
        self.assertEquals(request.getNearest(IThing), (self.thing, IThing))
        self.assertEquals(
            request.getNearest(IThingSet), (self.thing_set, IThingSet))

    def test_multiple_traversed_objects_with_common_interface(self):
        # If more than one object of a particular interface type has been
        # traversed, the most recently traversed one is returned.
        thing2 = Thing()
        self.request.traversed_objects.extend(
            [self.thing_set, self.thing, thing2])
        self.assertEquals(self.request.getNearest(IThing), (thing2, IThing))

    def test_interface_not_traversed(self):
        # If a particular interface has not been traversed, the tuple
        # (None, None) is returned.
        self.request.traversed_objects.extend([self.thing_set])
        self.assertEquals(self.request.getNearest(IThing), (None, None))
예제 #2
0
class TestLaunchpadBrowserRequest_getNearest(TestCase):
    def setUp(self):
        super(TestLaunchpadBrowserRequest_getNearest, self).setUp()
        self.request = LaunchpadBrowserRequest('', {})
        self.thing_set = ThingSet()
        self.thing = Thing()

    def test_return_value(self):
        # .getNearest() returns a two-tuple with the object and the interface
        # that matched. The second item in the tuple is useful when multiple
        # interfaces are passed to getNearest().
        request = self.request
        request.traversed_objects.extend([self.thing_set, self.thing])
        self.assertEquals(request.getNearest(IThing), (self.thing, IThing))
        self.assertEquals(request.getNearest(IThingSet),
                          (self.thing_set, IThingSet))

    def test_multiple_traversed_objects_with_common_interface(self):
        # If more than one object of a particular interface type has been
        # traversed, the most recently traversed one is returned.
        thing2 = Thing()
        self.request.traversed_objects.extend(
            [self.thing_set, self.thing, thing2])
        self.assertEquals(self.request.getNearest(IThing), (thing2, IThing))

    def test_interface_not_traversed(self):
        # If a particular interface has not been traversed, the tuple
        # (None, None) is returned.
        self.request.traversed_objects.extend([self.thing_set])
        self.assertEquals(self.request.getNearest(IThing), (None, None))
예제 #3
0
 def test_baserequest_response_should_vary_after_retry(self):
     """Test that our base response has a proper vary header."""
     request = LaunchpadBrowserRequest(StringIO.StringIO(''), {})
     retried_request = request.retry()
     self.assertEquals(
         retried_request.response.getHeader('Vary'),
         'Cookie, Authorization')
예제 #4
0
    def prepareRequest(self, form):
        """Return a `LaunchpadBrowserRequest` with the given form.

        Also set the accepted charset to 'utf-8'.
        """
        request = LaunchpadBrowserRequest('', form)
        request.charsets = ['utf-8']
        return request
예제 #5
0
 def test_set(self):
     # Test that setInWSGIEnvironment() can set keys in the WSGI
     # environment.
     data = StringIO.StringIO('foo')
     env = {}
     request = LaunchpadBrowserRequest(data, env)
     request.setInWSGIEnvironment('key', 'value')
     self.assertEqual(request._orig_env['key'], 'value')
예제 #6
0
    def prepareRequest(self, form):
        """Return a `LaunchpadBrowserRequest` with the given form.

        Also set the accepted charset to 'utf-8'.
        """
        request = LaunchpadBrowserRequest('', form)
        request.charsets = ['utf-8']
        return request
예제 #7
0
 def test_set(self):
     # Test that setInWSGIEnvironment() can set keys in the WSGI
     # environment.
     data = StringIO.StringIO('foo')
     env = {}
     request = LaunchpadBrowserRequest(data, env)
     request.setInWSGIEnvironment('key', 'value')
     self.assertEqual(request._orig_env['key'], 'value')
예제 #8
0
 def test_baserequest_recovers_from_bad_path_info_encoding(self):
     # The request object recodes PATH_INFO to ensure sane_environment
     # does not raise a UnicodeDecodeError when LaunchpadBrowserRequest
     # is instantiated.
     bad_path = 'fnord/trunk\xE4'
     env = {'PATH_INFO': bad_path}
     request = LaunchpadBrowserRequest(StringIO.StringIO(''), env)
     self.assertEquals(u'fnord/trunk\ufffd', request.getHeader('PATH_INFO'))
예제 #9
0
 def test_baserequest_recovers_from_bad_path_info_encoding(self):
     # The request object recodes PATH_INFO to ensure sane_environment
     # does not raise a UnicodeDecodeError when LaunchpadBrowserRequest
     # is instantiated.
     bad_path = 'fnord/trunk\xE4'
     env = {'PATH_INFO': bad_path}
     request = LaunchpadBrowserRequest(StringIO.StringIO(''), env)
     self.assertEquals(u'fnord/trunk\ufffd', request.getHeader('PATH_INFO'))
예제 #10
0
 def test_set_twice(self):
     # Test that setInWSGIEnvironment() can change the value of
     # keys in the WSGI environment that it had previously set.
     data = StringIO.StringIO('foo')
     env = {}
     request = LaunchpadBrowserRequest(data, env)
     request.setInWSGIEnvironment('key', 'first value')
     request.setInWSGIEnvironment('key', 'second value')
     self.assertEqual(request._orig_env['key'], 'second value')
예제 #11
0
 def test_set_after_retry(self):
     # Test that setInWSGIEnvironment() a key in the environment
     # can be set twice over a request retry.
     data = StringIO.StringIO('foo')
     env = {}
     request = LaunchpadBrowserRequest(data, env)
     request.setInWSGIEnvironment('key', 'first value')
     new_request = request.retry()
     new_request.setInWSGIEnvironment('key', 'second value')
     self.assertEqual(new_request._orig_env['key'], 'second value')
예제 #12
0
 def test_set_after_retry(self):
     # Test that setInWSGIEnvironment() a key in the environment
     # can be set twice over a request retry.
     data = StringIO.StringIO('foo')
     env = {}
     request = LaunchpadBrowserRequest(data, env)
     request.setInWSGIEnvironment('key', 'first value')
     new_request = request.retry()
     new_request.setInWSGIEnvironment('key', 'second value')
     self.assertEqual(new_request._orig_env['key'], 'second value')
예제 #13
0
 def test_baserequest_security_headers(self):
     response = LaunchpadBrowserRequest(StringIO.StringIO(''), {}).response
     self.assertEquals(
         response.getHeader('X-Frame-Options'), 'SAMEORIGIN')
     self.assertEquals(
         response.getHeader('X-Content-Type-Options'), 'nosniff')
     self.assertEquals(
         response.getHeader('X-XSS-Protection'), '1; mode=block')
     self.assertEquals(
         response.getHeader(
             'Strict-Transport-Security'), 'max-age=2592000')
예제 #14
0
 def test_request_with_invalid_query_string_recovers(self):
     # When the query string has invalid utf-8, it is decoded with
     # replacement.
     env = {'QUERY_STRING': 'field.title=subproc\xe9s '}
     request = LaunchpadBrowserRequest(StringIO.StringIO(''), env)
     self.assertEqual([u'subproc\ufffds '],
                      request.query_string_params['field.title'])
예제 #15
0
 def test_request_with_invalid_query_string_recovers(self):
     # When the query string has invalid utf-8, it is decoded with
     # replacement.
     env = {'QUERY_STRING': 'field.title=subproc\xe9s '}
     request = LaunchpadBrowserRequest(StringIO.StringIO(''), env)
     # XXX: Python 2.6 and 2.7 handle unicode replacement differently.
     self.assertIn(request.query_string_params['field.title'],
                   ([u'subproc\ufffd'], [u'subproc\ufffds ']))
예제 #16
0
 def test_set_fails_for_existing_key(self):
     # Test that setInWSGIEnvironment() fails if the user tries to
     # set a key that existed in the WSGI environment.
     data = StringIO.StringIO('foo')
     env = {'key': 'old value'}
     request = LaunchpadBrowserRequest(data, env)
     self.assertRaises(KeyError, request.setInWSGIEnvironment, 'key',
                       'new value')
     self.assertEqual(request._orig_env['key'], 'old value')
예제 #17
0
 def test_set_twice(self):
     # Test that setInWSGIEnvironment() can change the value of
     # keys in the WSGI environment that it had previously set.
     data = StringIO.StringIO('foo')
     env = {}
     request = LaunchpadBrowserRequest(data, env)
     request.setInWSGIEnvironment('key', 'first value')
     request.setInWSGIEnvironment('key', 'second value')
     self.assertEqual(request._orig_env['key'], 'second value')
예제 #18
0
 def test_baserequest_security_headers(self):
     response = LaunchpadBrowserRequest(StringIO.StringIO(''), {}).response
     self.assertEquals(response.getHeader('X-Frame-Options'), 'SAMEORIGIN')
     self.assertEquals(response.getHeader('X-Content-Type-Options'),
                       'nosniff')
     self.assertEquals(response.getHeader('X-XSS-Protection'),
                       '1; mode=block')
     self.assertEquals(response.getHeader('Strict-Transport-Security'),
                       'max-age=2592000')
예제 #19
0
def canonical_url(
    obj, request=None, rootsite=None, path_only_if_possible=False,
    view_name=None, force_local_path=False):
    """Return the canonical URL string for the object.

    If the canonical url configuration for the given object binds it to a
    particular root site, then we use that root URL.

    (There is an assumption here that traversal works the same way on
     different sites.  When that isn't so, we need to specify the url
     in full in the canonical url configuration.  We may want to
     register canonical url configuration *for* particular sites in the
     future, to allow more flexibility for traversal.
     I foresee a refactoring where we'll combine the concepts of
     sites, layers, URLs and so on.)

    Otherwise, we attempt to take the protocol, host and port from
    the request.  If a request is not provided, but a web-request is in
    progress, the protocol, host and port are taken from the current request.

    :param request: The web request; if not provided, canonical_url attempts
        to guess at the current request, using the protocol, host, and port
        taken from the root_url given in launchpad.conf.
    :param path_only_if_possible: If the protocol and hostname can be omitted
        for the current request, return a url containing only the path.
    :param view_name: Provide the canonical url for the specified view,
        rather than the default view.
    :param force_local_path: Strip off the site no matter what.
    :raises: NoCanonicalUrl if a canonical url is not available.
    """
    urlparts = [urldata.path
                for urldata in canonical_urldata_iterator(obj)
                if urldata.path]

    if rootsite is None:
        obj_urldata = ICanonicalUrlData(obj, None)
        if obj_urldata is None:
            raise NoCanonicalUrl(obj, obj)
        rootsite = obj_urldata.rootsite

    # The request is needed when there's no rootsite specified.
    if request is None:
        # Look for a request from the interaction.
        current_request = get_current_browser_request()
        if current_request is not None:
            if WebServiceLayer.providedBy(current_request):
                from lp.services.webapp.publication import (
                    LaunchpadBrowserPublication)
                from lp.services.webapp.servers import (
                    LaunchpadBrowserRequest)
                current_request = LaunchpadBrowserRequest(
                    current_request.bodyStream.getCacheStream(),
                    dict(current_request.environment))
                current_request.setPublication(
                    LaunchpadBrowserPublication(None))
                current_request.setVirtualHostRoot(names=[])
                main_root_url = current_request.getRootURL(
                    'mainsite')
                current_request._app_server = main_root_url.rstrip('/')

            request = current_request

    if view_name is not None:
        # Make sure that the view is registered for the site requested.
        fake_request = FakeRequest()
        directlyProvides(fake_request, layer_for_rootsite(rootsite))
        # Look first for a view.
        if queryMultiAdapter((obj, fake_request), name=view_name) is None:
            # Look if this is a special name defined by Navigation.
            navigation = queryMultiAdapter(
                (obj, fake_request), IBrowserPublisher)
            if isinstance(navigation, Navigation):
                all_names = navigation.all_traversal_and_redirection_names
            else:
                all_names = []
            if view_name not in all_names:
                raise AssertionError(
                    'Name "%s" is not registered as a view or navigation '
                    'step for "%s" on "%s".' % (
                        view_name, obj.__class__.__name__, rootsite))
        urlparts.insert(0, view_name)

    if request is None:
        # Yes this really does need to be here, as rootsite can be None, and
        # we don't want to make the getRootURL from the request break.
        if rootsite is None:
            rootsite = 'mainsite'
        root_url = allvhosts.configs[rootsite].rooturl
    else:
        root_url = request.getRootURL(rootsite)

    path = u'/'.join(reversed(urlparts))
    if ((path_only_if_possible and
         request is not None and
         root_url.startswith(request.getApplicationURL()))
        or force_local_path):
        return unicode('/' + path)
    return unicode(root_url + path)
예제 #20
0
 def setUp(self):
     super(TestLaunchpadBrowserRequest_getNearest, self).setUp()
     self.request = LaunchpadBrowserRequest('', {})
     self.thing_set = ThingSet()
     self.thing = Thing()
예제 #21
0
 def test_baserequest_revision_header(self):
     response = LaunchpadBrowserRequest(StringIO.StringIO(''), {}).response
     self.assertEqual(versioninfo.revision,
                      response.getHeader('X-Launchpad-Revision'))
예제 #22
0
 def setUp(self):
     super(TestLaunchpadBrowserRequest_getNearest, self).setUp()
     self.request = LaunchpadBrowserRequest('', {})
     self.thing_set = ThingSet()
     self.thing = Thing()
 def makeRequest(self):
     """Construct an arbitrary `LaunchpadBrowserRequest` object."""
     data = StringIO.StringIO()
     env = {}
     return LaunchpadBrowserRequest(data, env)
예제 #24
0
 def test_baserequest_response_should_vary_after_retry(self):
     """Test that our base response has a proper vary header."""
     request = LaunchpadBrowserRequest(StringIO.StringIO(''), {})
     retried_request = request.retry()
     self.assertEquals(retried_request.response.getHeader('Vary'),
                       'Cookie, Authorization')