Exemplo n.º 1
0
class TestVhostWebserviceFactory(WebServiceTestCase):
    class VHostTestBrowserRequest(LaunchpadBrowserRequest):
        pass

    class VHostTestPublication(LaunchpadBrowserRequest):
        pass

    def setUp(self):
        super(TestVhostWebserviceFactory, self).setUp()
        # XXX We have to use a real hostname.
        self.factory = VHostWebServiceRequestPublicationFactory(
            'bugs', self.VHostTestBrowserRequest, self.VHostTestPublication)

    def wsgi_env(self, path, method='GET'):
        """Simulate a WSGI application environment."""
        return {
            'PATH_INFO': path,
            'HTTP_HOST': 'bugs.launchpad.dev',
            'REQUEST_METHOD': method,
        }

    @property
    def api_path(self):
        """Requests to this path should be treated as webservice requests."""
        return '/' + getUtility(IWebServiceConfiguration).path_override

    @property
    def non_api_path(self):
        """Requests to this path should not be treated as webservice requests.
        """
        return '/foo'

    def test_factory_produces_webservice_objects(self):
        """The factory should produce WebService request and publication
        objects for requests to the /api root URL.
        """
        env = self.wsgi_env(self.api_path)

        # Necessary preamble and sanity check.  We need to call
        # the factory's canHandle() method with an appropriate
        # WSGI environment before it can produce a request object for us.
        self.assert_(
            self.factory.canHandle(env),
            "Sanity check: The factory should be able to handle requests.")

        wrapped_factory, publication_factory = self.factory()

        # We need to unwrap the real request factory.
        request_factory = wrapped_factory.requestfactory

        self.assertEqual(
            request_factory, WebServiceClientRequest,
            "Requests to the /api path should return a WebService "
            "request object.")
        self.assertEqual(
            publication_factory, WebServicePublication,
            "Requests to the /api path should return a WebService "
            "publication object.")

    def test_factory_produces_normal_request_objects(self):
        """The factory should return the request and publication factories
        specified in it's constructor if the request is not bound for the
        web service.
        """
        env = self.wsgi_env(self.non_api_path)
        self.assert_(
            self.factory.canHandle(env),
            "Sanity check: The factory should be able to handle requests.")

        wrapped_factory, publication_factory = self.factory()

        # We need to unwrap the real request factory.
        request_factory = wrapped_factory.requestfactory

        self.assertEqual(
            request_factory, self.VHostTestBrowserRequest,
            "Requests to normal paths should return a VHostTest "
            "request object.")
        self.assertEqual(
            publication_factory, self.VHostTestPublication,
            "Requests to normal paths should return a VHostTest "
            "publication object.")

    def test_factory_processes_webservice_http_methods(self):
        """The factory should accept the HTTP methods for requests that
        should be processed by the web service.
        """
        allowed_methods = WebServiceRequestPublicationFactory.default_methods

        for method in allowed_methods:
            env = self.wsgi_env(self.api_path, method)
            self.assert_(self.factory.canHandle(env), "Sanity check")
            # Returns a tuple of (request_factory, publication_factory).
            rfactory, pfactory = self.factory.checkRequest(env)
            self.assert_(
                rfactory is None,
                "The '%s' HTTP method should be handled by the factory." %
                method)

    def test_factory_rejects_normal_http_methods(self):
        """The factory should reject some HTTP methods for requests that
        are *not* bound for the web service.

        This includes methods like 'PUT' and 'PATCH'.
        """
        vhost_methods = VirtualHostRequestPublicationFactory.default_methods
        ws_methods = WebServiceRequestPublicationFactory.default_methods

        denied_methods = set(ws_methods) - set(vhost_methods)

        for method in denied_methods:
            env = self.wsgi_env(self.non_api_path, method)
            self.assert_(self.factory.canHandle(env), "Sanity check")
            # Returns a tuple of (request_factory, publication_factory).
            rfactory, pfactory = self.factory.checkRequest(env)
            self.assert_(
                rfactory is not None,
                "The '%s' HTTP method should be rejected by the factory." %
                method)

    def test_factory_understands_webservice_paths(self):
        """The factory should know if a path is directed at a web service
        resource path.
        """
        # This is a sanity check, so I can write '/api/foo' instead
        # of PATH_OVERRIDE + '/foo' in my tests.  The former's
        # intention is clearer.
        self.assertEqual(
            getUtility(IWebServiceConfiguration).path_override, 'api',
            "Sanity check: The web service path override should be 'api'.")

        self.assert_(self.factory.isWebServicePath('/api'),
                     "The factory should handle URLs that start with /api.")

        self.assert_(self.factory.isWebServicePath('/api/foo'),
                     "The factory should handle URLs that start with /api.")

        self.failIf(
            self.factory.isWebServicePath('/foo'),
            "The factory should not handle URLs that do not start with "
            "/api.")

        self.failIf(
            self.factory.isWebServicePath('/'),
            "The factory should not handle URLs that do not start with "
            "/api.")

        self.failIf(
            self.factory.isWebServicePath('/apifoo'),
            "The factory should not handle URLs that do not start with "
            "/api.")

        self.failIf(
            self.factory.isWebServicePath('/foo/api'),
            "The factory should not handle URLs that do not start with "
            "/api.")
Exemplo n.º 2
0
 def setUp(self):
     super(TestVhostWebserviceFactory, self).setUp()
     # XXX We have to use a real hostname.
     self.factory = VHostWebServiceRequestPublicationFactory(
         'bugs', self.VHostTestBrowserRequest, self.VHostTestPublication)
Exemplo n.º 3
0
def code_request_publication_factory():
    return VHostWebServiceRequestPublicationFactory(
        'code', CodeBrowserRequest, LaunchpadBrowserPublication)
Exemplo n.º 4
0
def bugs_request_publication_factory():
    return VHostWebServiceRequestPublicationFactory(
        'bugs', BugsBrowserRequest, LaunchpadBrowserPublication)
Exemplo n.º 5
0
def translations_request_publication_factory():
    return VHostWebServiceRequestPublicationFactory(
        'translations', TranslationsBrowserRequest,
        LaunchpadBrowserPublication)
Exemplo n.º 6
0
def answers_request_publication_factory():
    return VHostWebServiceRequestPublicationFactory(
        'answers', AnswersBrowserRequest, LaunchpadBrowserPublication)
Exemplo n.º 7
0
def blueprints_request_publication_factory():
    return VHostWebServiceRequestPublicationFactory(
        'blueprints', BlueprintsBrowserRequest, LaunchpadBrowserPublication)
Exemplo n.º 8
0
 def setUp(self):
     super(TestVhostWebserviceFactory, self).setUp()
     # XXX We have to use a real hostname.
     self.factory = VHostWebServiceRequestPublicationFactory(
         'bugs', self.VHostTestBrowserRequest, self.VHostTestPublication)
Exemplo n.º 9
0
class TestVhostWebserviceFactory(WebServiceTestCase):

    class VHostTestBrowserRequest(LaunchpadBrowserRequest):
        pass

    class VHostTestPublication(LaunchpadBrowserRequest):
        pass

    def setUp(self):
        super(TestVhostWebserviceFactory, self).setUp()
        # XXX We have to use a real hostname.
        self.factory = VHostWebServiceRequestPublicationFactory(
            'bugs', self.VHostTestBrowserRequest, self.VHostTestPublication)

    def wsgi_env(self, path, method='GET'):
        """Simulate a WSGI application environment."""
        return {
            'PATH_INFO': path,
            'HTTP_HOST': 'bugs.launchpad.dev',
            'REQUEST_METHOD': method,
            }

    @property
    def api_path(self):
        """Requests to this path should be treated as webservice requests."""
        return '/' + getUtility(IWebServiceConfiguration).path_override

    @property
    def non_api_path(self):
        """Requests to this path should not be treated as webservice requests.
        """
        return '/foo'

    def test_factory_produces_webservice_objects(self):
        """The factory should produce WebService request and publication
        objects for requests to the /api root URL.
        """
        env = self.wsgi_env(self.api_path)

        # Necessary preamble and sanity check.  We need to call
        # the factory's canHandle() method with an appropriate
        # WSGI environment before it can produce a request object for us.
        self.assert_(self.factory.canHandle(env),
            "Sanity check: The factory should be able to handle requests.")

        wrapped_factory, publication_factory = self.factory()

        # We need to unwrap the real request factory.
        request_factory = wrapped_factory.requestfactory

        self.assertEqual(request_factory, WebServiceClientRequest,
            "Requests to the /api path should return a WebService "
            "request object.")
        self.assertEqual(
            publication_factory, WebServicePublication,
            "Requests to the /api path should return a WebService "
            "publication object.")

    def test_factory_produces_normal_request_objects(self):
        """The factory should return the request and publication factories
        specified in it's constructor if the request is not bound for the
        web service.
        """
        env = self.wsgi_env(self.non_api_path)
        self.assert_(self.factory.canHandle(env),
            "Sanity check: The factory should be able to handle requests.")

        wrapped_factory, publication_factory = self.factory()

        # We need to unwrap the real request factory.
        request_factory = wrapped_factory.requestfactory

        self.assertEqual(request_factory, self.VHostTestBrowserRequest,
            "Requests to normal paths should return a VHostTest "
            "request object.")
        self.assertEqual(
            publication_factory, self.VHostTestPublication,
            "Requests to normal paths should return a VHostTest "
            "publication object.")

    def test_factory_processes_webservice_http_methods(self):
        """The factory should accept the HTTP methods for requests that
        should be processed by the web service.
        """
        allowed_methods = WebServiceRequestPublicationFactory.default_methods

        for method in allowed_methods:
            env = self.wsgi_env(self.api_path, method)
            self.assert_(self.factory.canHandle(env),
                "Sanity check")
            # Returns a tuple of (request_factory, publication_factory).
            rfactory, pfactory = self.factory.checkRequest(env)
            self.assert_(rfactory is None,
                "The '%s' HTTP method should be handled by the factory."
                % method)

    def test_factory_rejects_normal_http_methods(self):
        """The factory should reject some HTTP methods for requests that
        are *not* bound for the web service.

        This includes methods like 'PUT' and 'PATCH'.
        """
        vhost_methods = VirtualHostRequestPublicationFactory.default_methods
        ws_methods = WebServiceRequestPublicationFactory.default_methods

        denied_methods = set(ws_methods) - set(vhost_methods)

        for method in denied_methods:
            env = self.wsgi_env(self.non_api_path, method)
            self.assert_(self.factory.canHandle(env), "Sanity check")
            # Returns a tuple of (request_factory, publication_factory).
            rfactory, pfactory = self.factory.checkRequest(env)
            self.assert_(rfactory is not None,
                "The '%s' HTTP method should be rejected by the factory."
                % method)

    def test_factory_understands_webservice_paths(self):
        """The factory should know if a path is directed at a web service
        resource path.
        """
        # This is a sanity check, so I can write '/api/foo' instead
        # of PATH_OVERRIDE + '/foo' in my tests.  The former's
        # intention is clearer.
        self.assertEqual(
            getUtility(IWebServiceConfiguration).path_override, 'api',
            "Sanity check: The web service path override should be 'api'.")

        self.assert_(
            self.factory.isWebServicePath('/api'),
            "The factory should handle URLs that start with /api.")

        self.assert_(
            self.factory.isWebServicePath('/api/foo'),
            "The factory should handle URLs that start with /api.")

        self.failIf(
            self.factory.isWebServicePath('/foo'),
            "The factory should not handle URLs that do not start with "
            "/api.")

        self.failIf(
            self.factory.isWebServicePath('/'),
            "The factory should not handle URLs that do not start with "
            "/api.")

        self.failIf(
            self.factory.isWebServicePath('/apifoo'),
            "The factory should not handle URLs that do not start with "
            "/api.")

        self.failIf(
            self.factory.isWebServicePath('/foo/api'),
            "The factory should not handle URLs that do not start with "
            "/api.")