예제 #1
0
  def _try_transform_rest_request(self, path_parameters, query_parameters,
                                  body_json, expected, method_params=None):
    """Takes body, query and path values from a rest request for testing.

    Args:
      path_parameters: A dict containing the parameters parsed from the path.
        For example if the request came through /a/b for the template /a/{x}
        then we'd have {'x': 'b'}.
      query_parameters: A dict containing the parameters parsed from the query
        string.
      body_json: A dict with the JSON object from the request body.
      expected: A dict with the expected JSON body after being transformed.
      method_params: Optional dictionary specifying the parameter configuration
        associated with the method.
    """
    method_params = method_params or {}

    test_request = test_utils.build_request('/_ah/api/test')
    test_request.body_json = body_json
    test_request.body = json.dumps(body_json)
    test_request.parameters = query_parameters

    transformed_request = self.server.transform_rest_request(test_request,
                                                             path_parameters,
                                                             method_params)

    self.assertEqual(expected, transformed_request.body_json)
    self.assertEqual(transformed_request.body_json,
                     json.loads(transformed_request.body))
예제 #2
0
    def test_handle_spi_response_batch_json_rpc(self):
        """Verify that batch requests have an appropriate batch response."""
        orig_request = test_utils.build_request(
            '/_ah/api/rpc', '[{"method": "foo.bar", "apiVersion": "X"}]')
        self.assertTrue(orig_request.is_batch())
        self.assertTrue(orig_request.is_rpc())
        orig_request.request_id = 'Z'
        spi_request = orig_request.copy()
        spi_response = dispatcher.ResponseTuple('200 OK', [('a', 'b')],
                                                '{"some": "response"}')

        response = self.server.handle_spi_response(orig_request, spi_request,
                                                   spi_response, {},
                                                   self.start_response)
        response = ''.join(
            response)  # Merge response iterator into single body.

        self.assertEqual(self.response_status, '200 OK')
        self.assertIn(('a', 'b'), self.response_headers)
        self.assertEqual([{
            'id': 'Z',
            'result': {
                'some': 'response'
            }
        }], json.loads(response))
예제 #3
0
  def test_static_non_existing_file(self):
    relative_url = '/_ah/api/static/blah.html'

    # Set up mocks for the call to DiscoveryApiProxy.get_static_file.
    discovery_api = self.mox.CreateMock(
        discovery_api_proxy.DiscoveryApiProxy)
    self.mox.StubOutWithMock(discovery_api_proxy, 'DiscoveryApiProxy')
    discovery_api_proxy.DiscoveryApiProxy().AndReturn(discovery_api)
    static_response = self.mox.CreateMock(httplib.HTTPResponse)
    static_response.status = 404
    static_response.reason = 'Not Found'
    static_response.getheaders().AndReturn([('Content-Type', 'test/type')])
    test_body = 'No Body'
    discovery_api.get_static_file(relative_url).AndReturn(
        (static_response, test_body))

    # Make sure the dispatch works as expected.
    request = test_utils.build_request(relative_url)
    self.mox.ReplayAll()
    response = self.server.dispatch(request, self.start_response)
    self.mox.VerifyAll()

    response = ''.join(response)
    self.assert_http_match(response, '404 Not Found',
                           [('Content-Length', '%d' % len(test_body)),
                            ('Content-Type', 'test/type')],
                           test_body)
예제 #4
0
 def test_transform_rest_request_with_query_params(self):
   """Verify body is updated with query parameters."""
   orig_request = test_utils.build_request('/_ah/api/test?foo=bar',
                                           '{"sample": "body"}')
   new_request = self.server.transform_rest_request(orig_request, {})
   self.assertEqual({'sample': 'body', 'foo': ['bar']},
                    json.loads(new_request.body))
예제 #5
0
 def test_transform_rest_request(self):
   """Verify body is updated with path params."""
   orig_request = test_utils.build_request('/_ah/api/test',
                                           '{"sample": "body"}')
   new_request = self.server.transform_rest_request(orig_request, {'gid': 'X'})
   self.assertEqual({'sample': 'body', 'gid': 'X'},
                    json.loads(new_request.body))
 def test_transform_rest_request_with_query_params(self):
   """Verify body is updated with query parameters."""
   orig_request = test_utils.build_request('/_ah/api/test?foo=bar',
                                           '{"sample": "body"}')
   new_request = self.server.transform_rest_request(orig_request, {})
   self.assertEqual({'sample': 'body', 'foo': ['bar']},
                    json.loads(new_request.body))
 def test_transform_rest_request(self):
   """Verify body is updated with path params."""
   orig_request = test_utils.build_request('/_ah/api/test',
                                           '{"sample": "body"}')
   new_request = self.server.transform_rest_request(orig_request, {'gid': 'X'})
   self.assertEqual({'sample': 'body', 'gid': 'X'},
                    json.loads(new_request.body))
예제 #8
0
  def test_static_non_existing_file(self):
    relative_url = '/_ah/api/static/blah.html'

    # Set up mocks for the call to DiscoveryApiProxy.get_static_file.
    discovery_api = self.mox.CreateMock(
        discovery_api_proxy.DiscoveryApiProxy)
    self.mox.StubOutWithMock(discovery_api_proxy, 'DiscoveryApiProxy')
    discovery_api_proxy.DiscoveryApiProxy().AndReturn(discovery_api)
    static_response = self.mox.CreateMock(six.moves.http_client.HTTPResponse)
    static_response.status = 404
    static_response.reason = 'Not Found'
    static_response.getheaders().AndReturn([('Content-Type', 'test/type')])
    test_body = 'No Body'
    discovery_api.get_static_file(relative_url).AndReturn(
        (static_response, test_body))

    # Make sure the dispatch works as expected.
    request = test_utils.build_request(relative_url)
    self.mox.ReplayAll()
    response = self.server.dispatch(request, self.start_response)
    self.mox.VerifyAll()

    response = ''.join(response)
    self.assert_http_match(response, '404 Not Found',
                           [('Content-Length', '%d' % len(test_body)),
                            ('Content-Type', 'test/type')],
                           test_body)
예제 #9
0
  def _try_transform_rest_request(self, path_parameters, query_parameters,
                                  body_json, expected, method_params=None):
    """Takes body, query and path values from a rest request for testing.

    Args:
      path_parameters: A dict containing the parameters parsed from the path.
        For example if the request came through /a/b for the template /a/{x}
        then we'd have {'x': 'b'}.
      query_parameters: A dict containing the parameters parsed from the query
        string.
      body_json: A dict with the JSON object from the request body.
      expected: A dict with the expected JSON body after being transformed.
      method_params: Optional dictionary specifying the parameter configuration
        associated with the method.
    """
    method_params = method_params or {}

    test_request = test_utils.build_request('/_ah/api/test')
    test_request.body_json = body_json
    test_request.body = json.dumps(body_json)
    test_request.parameters = query_parameters

    transformed_request = self.server.transform_rest_request(test_request,
                                                             path_parameters,
                                                             method_params)

    self.assertEqual(expected, transformed_request.body_json)
    self.assertEqual(transformed_request.body_json,
                     json.loads(transformed_request.body))
 def test_batch_too_large(self):
   """Verify that additional items are dropped if the batch size is > 1."""
   request = test_utils.build_request('/_ah/api/rpc',
                                      '[{"method": "foo", "apiVersion": "v1"},'
                                      '{"method": "bar", "apiversion": "v1"}]')
   self.assertTrue(request.is_batch())
   self.assertEqual(json.loads('{"method": "foo", "apiVersion": "v1"}'),
                    request.body_json)
예제 #11
0
 def test_batch_too_large(self):
     """Verify that additional items are dropped if the batch size is > 1."""
     request = test_utils.build_request(
         '/_ah/api/rpc', '[{"method": "foo", "apiVersion": "v1"},'
         '{"method": "bar", "apiversion": "v1"}]')
     self.assertTrue(request.is_batch())
     self.assertEqual(json.loads('{"method": "foo", "apiVersion": "v1"}'),
                      request.body_json)
예제 #12
0
 def test_check_empty_response(self):
   """Test that check_empty_response returns 204 for an empty response."""
   orig_request = test_utils.build_request('/_ah/api/test', '{}')
   method_config = {'response': {'body': 'empty'}}
   empty_response = self.server.check_empty_response(orig_request,
                                                     method_config,
                                                     self.start_response)
   self.assert_http_match(empty_response, 204, [('Content-Length', '0')], '')
예제 #13
0
    def test_transform_json_rpc_request(self):
        """Verify request_id is extracted and body is scoped to body.params."""
        orig_request = test_utils.build_request(
            '/_ah/api/rpc', '{"params": {"sample": "body"}, "id": "42"}')

        new_request = self.server.transform_jsonrpc_request(orig_request)
        self.assertEqual({'sample': 'body'}, json.loads(new_request.body))
        self.assertEqual('42', new_request.request_id)
예제 #14
0
 def test_check_empty_response(self):
   """Test that check_empty_response returns 204 for an empty response."""
   orig_request = test_utils.build_request('/_ah/api/test', '{}')
   method_config = {'response': {'body': 'empty'}}
   empty_response = self.server.check_empty_response(orig_request,
                                                     method_config,
                                                     self.start_response)
   self.assert_http_match(empty_response, 204, [('Content-Length', '0')], '')
예제 #15
0
 def test_explorer_redirect(self):
   request = test_utils.build_request('/_ah/api/explorer')
   response = self.server.dispatch(request, self.start_response)
   self.assert_http_match(response, 302,
                          [('Content-Length', '0'),
                           ('Location', ('https://developers.google.com/'
                                         'apis-explorer/?base='
                                         'http://localhost:42/_ah/api'))],
                          '')
예제 #16
0
 def test_generate_discovery_doc_rest_unknown_api(self):
   request = test_utils.build_request('/_ah/api/foo',
                                      '{"api": "blah", "version": "v1"}')
   discovery_api = discovery_service.DiscoveryService(
       self.api_config_manager)
   discovery_api.handle_discovery_request(
       discovery_service.DiscoveryService._GET_REST_API, request,
       self.start_response)
   self.assertEquals(self.response_status, '404')
예제 #17
0
  def test_transform_json_rpc_request(self):
    """Verify request_id is extracted and body is scoped to body.params."""
    orig_request = test_utils.build_request(
        '/_ah/api/rpc', '{"params": {"sample": "body"}, "id": "42"}')

    new_request = self.server.transform_jsonrpc_request(orig_request)
    self.assertEqual({'sample': 'body'},
                     json.loads(new_request.body))
    self.assertEqual('42', new_request.request_id)
예제 #18
0
  def test_lookup_rpc_method(self):
    self.mox.StubOutWithMock(self.server.config_manager, 'lookup_rpc_method')
    self.server.config_manager.lookup_rpc_method('foo', 'v1').AndReturn('bar')

    self.mox.ReplayAll()
    orig_request = test_utils.build_request(
        '/_ah/api/rpc', '{"method": "foo", "apiVersion": "v1"}')
    self.assertEqual('bar', self.server.lookup_rpc_method(orig_request))
    self.mox.VerifyAll()
예제 #19
0
  def test_lookup_rpc_method(self):
    self.mox.StubOutWithMock(self.server.config_manager, 'lookup_rpc_method')
    self.server.config_manager.lookup_rpc_method('foo', 'v1').AndReturn('bar')

    self.mox.ReplayAll()
    orig_request = test_utils.build_request(
        '/_ah/api/rpc', '{"method": "foo", "apiVersion": "v1"}')
    self.assertEqual('bar', self.server.lookup_rpc_method(orig_request))
    self.mox.VerifyAll()
예제 #20
0
 def test_generate_discovery_doc_rest_unknown_api(self):
     request = test_utils.build_request('/_ah/api/foo',
                                        '{"api": "blah", "version": "v1"}')
     discovery_api = discovery_service.DiscoveryService(
         self.api_config_manager)
     discovery_api.handle_discovery_request(
         discovery_service.DiscoveryService._GET_REST_API, request,
         self.start_response)
     self.assertEquals(self.response_status, '404')
예제 #21
0
 def test_explorer_redirect(self):
   request = test_utils.build_request('/_ah/api/explorer')
   response = self.server.dispatch(request, self.start_response)
   self.assert_http_match(response, 302,
                          [('Content-Length', '0'),
                           ('Location', ('http://apis-explorer.appspot.com/'
                                         'apis-explorer/?base='
                                         'http://localhost:42/_ah/api'))],
                          '')
예제 #22
0
 def test_transform_json_rpc_response_batch(self):
   """Verify request_id inserted into the body, and body into body.result."""
   orig_request = test_utils.build_request(
       '/_ah/api/rpc', '[{"params": {"sample": "body"}, "id": "42"}]')
   request = orig_request.copy()
   request.request_id = '42'
   orig_response = '{"sample": "body"}'
   response = self.server.transform_jsonrpc_response(request, orig_response)
   self.assertEqual([{'result': {'sample': 'body'}, 'id': '42'}],
                    json.loads(response))
예제 #23
0
 def test_check_non_empty_response(self):
     """Test that check_empty_response returns None for a non-empty response."""
     orig_request = test_utils.build_request('/_ah/api/test', '{}')
     method_config = {'response': {'body': 'autoTemplate(backendResponse)'}}
     empty_response = self.server.check_empty_response(
         orig_request, method_config, self.start_response)
     self.assertIsNone(empty_response)
     self.assertIsNone(self.response_status)
     self.assertIsNone(self.response_headers)
     self.assertIsNone(self.response_exc_info)
예제 #24
0
 def test_parse_empty_values(self):
     request = test_utils.build_request('/_ah/api/foo?bar')
     self.assertEqual('foo', request.path)
     self.assertEqual('bar', request.query)
     self.assertEqual({'bar': ['']}, request.parameters)
     self.assertEqual('', request.body)
     self.assertEqual({}, request.body_json)
     self.assertEqual([('CONTENT-TYPE', 'application/json')],
                      list(request.headers.items()))
     self.assertEqual(None, request.request_id)
 def test_parse_empty_values(self):
   request = test_utils.build_request('/_ah/api/foo?bar')
   self.assertEqual('foo', request.path)
   self.assertEqual('bar', request.query)
   self.assertEqual({'bar': ['']}, request.parameters)
   self.assertEqual('', request.body)
   self.assertEqual({}, request.body_json)
   self.assertEqual([('CONTENT-TYPE', 'application/json')],
                    list(request.headers.items()))
   self.assertEqual(None, request.request_id)
예제 #26
0
 def test_transform_json_rpc_response_batch(self):
   """Verify request_id inserted into the body, and body into body.result."""
   orig_request = test_utils.build_request(
       '/_ah/api/rpc', '[{"params": {"sample": "body"}, "id": "42"}]')
   request = orig_request.copy()
   request.request_id = '42'
   orig_response = '{"sample": "body"}'
   response = self.server.transform_jsonrpc_response(request, orig_response)
   self.assertEqual([{'result': {'sample': 'body'}, 'id': '42'}],
                    json.loads(response))
예제 #27
0
 def _common_setup(self):
     api_config_file = os.path.join(os.path.dirname(__file__),
                                    'testdata/tictactoe-v1.api')
     with open(api_config_file, 'r') as api_file:
         api_config = api_file.read()
     api_config_dict = {'items': [api_config]}
     self.api_config_manager = api_config_manager.ApiConfigManager()
     self.api_config_manager.parse_api_config_response(
         json.dumps(api_config_dict))
     self.api_request = test_utils.build_request(
         '/_ah/api/foo', '{"api": "tictactoe", "version": "v1"}')
예제 #28
0
 def test_check_non_empty_response(self):
   """Test that check_empty_response returns None for a non-empty response."""
   orig_request = test_utils.build_request('/_ah/api/test', '{}')
   method_config = {'response': {'body': 'autoTemplate(backendResponse)'}}
   empty_response = self.server.check_empty_response(orig_request,
                                                     method_config,
                                                     self.start_response)
   self.assertIsNone(empty_response)
   self.assertIsNone(self.response_status)
   self.assertIsNone(self.response_headers)
   self.assertIsNone(self.response_exc_info)
예제 #29
0
  def test_transform_request(self):
    """Verify path is method name after a request is transformed."""
    request = test_utils.build_request('/_ah/api/test/{gid}',
                                       '{"sample": "body"}')
    method_config = {'rosyMethod': 'GuestbookApi.greetings_get'}

    new_request = self.server.transform_request(request, {'gid': 'X'},
                                                method_config)
    self.assertEqual({'sample': 'body', 'gid': 'X'},
                     json.loads(new_request.body))
    self.assertEqual('GuestbookApi.greetings_get', new_request.path)
예제 #30
0
 def test_parse_multiple_values(self):
   request = test_utils.build_request('/_ah/api/foo?bar=baz&foo=bar&bar=foo')
   self.assertEqual('foo', request.path)
   self.assertEqual('bar=baz&foo=bar&bar=foo', request.query)
   self.assertEqual({'bar': ['baz', 'foo'], 'foo': ['bar']},
                    request.parameters)
   self.assertEqual('', request.body)
   self.assertEqual({}, request.body_json)
   self.assertEqual([('CONTENT-TYPE', 'application/json')],
                    request.headers.items())
   self.assertEqual(None, request.request_id)
예제 #31
0
  def test_transform_request(self):
    """Verify path is method name after a request is transformed."""
    request = test_utils.build_request('/_ah/api/test/{gid}',
                                       '{"sample": "body"}')
    method_config = {'rosyMethod': 'GuestbookApi.greetings_get'}

    new_request = self.server.transform_request(request, {'gid': 'X'},
                                                method_config)
    self.assertEqual({'sample': 'body', 'gid': 'X'},
                     json.loads(new_request.body))
    self.assertEqual('GuestbookApi.greetings_get', new_request.path)
예제 #32
0
 def test_handle_spi_response_rest(self):
     orig_request = test_utils.build_request('/_ah/api/test', '{}')
     spi_request = orig_request.copy()
     body = json.dumps({'some': 'response'}, indent=1)
     spi_response = dispatcher.ResponseTuple('200 OK', [('a', 'b')], body)
     response = self.server.handle_spi_response(orig_request, spi_request,
                                                spi_response, {},
                                                self.start_response)
     self.assert_http_match(response, '200 OK',
                            [('a', 'b'),
                             ('Content-Length', '%d' % len(body))], body)
예제 #33
0
 def test_parse_with_body(self):
     request = test_utils.build_request('/_ah/api/foo?bar=baz',
                                        '{"test": "body"}')
     self.assertEqual('foo', request.path)
     self.assertEqual('bar=baz', request.query)
     self.assertEqual({'bar': ['baz']}, request.parameters)
     self.assertEqual('{"test": "body"}', request.body)
     self.assertEqual({'test': 'body'}, request.body_json)
     self.assertEqual([('CONTENT-TYPE', 'application/json')],
                      list(request.headers.items()))
     self.assertEqual(None, request.request_id)
 def test_parse_with_body(self):
   request = test_utils.build_request('/_ah/api/foo?bar=baz',
                                      '{"test": "body"}')
   self.assertEqual('foo', request.path)
   self.assertEqual('bar=baz', request.query)
   self.assertEqual({'bar': ['baz']}, request.parameters)
   self.assertEqual('{"test": "body"}', request.body)
   self.assertEqual({'test': 'body'}, request.body_json)
   self.assertEqual([('CONTENT-TYPE', 'application/json')],
                    list(request.headers.items()))
   self.assertEqual(None, request.request_id)
예제 #35
0
 def _common_setup(self):
   api_config_file = os.path.join(os.path.dirname(__file__),
                                  'testdata/tictactoe-v1.api')
   with open(api_config_file, 'r') as api_file:
     api_config = api_file.read()
   api_config_dict = {'items': [api_config]}
   self.api_config_manager = api_config_manager.ApiConfigManager()
   self.api_config_manager.parse_api_config_response(
       json.dumps(api_config_dict))
   self.api_request = test_utils.build_request(
       '/_ah/api/foo', '{"api": "tictactoe", "version": "v1"}')
예제 #36
0
 def test_handle_spi_response_rest(self):
   orig_request = test_utils.build_request('/_ah/api/test', '{}')
   spi_request = orig_request.copy()
   body = json.dumps({'some': 'response'}, indent=1)
   spi_response = dispatcher.ResponseTuple('200 OK', [('a', 'b')], body)
   response = self.server.handle_spi_response(orig_request, spi_request,
                                              spi_response, {},
                                              self.start_response)
   self.assert_http_match(response, '200 OK',
                          [('a', 'b'),
                           ('Content-Length', '%d' % len(body))],
                          body)
 def test_parse_multiple_values(self):
     request = test_utils.build_request(
         '/_ah/api/foo?bar=baz&foo=bar&bar=foo')
     self.assertEqual('foo', request.path)
     self.assertEqual('bar=baz&foo=bar&bar=foo', request.query)
     self.assertEqual({
         'bar': ['baz', 'foo'],
         'foo': ['bar']
     }, request.parameters)
     self.assertEqual('', request.body)
     self.assertEqual({}, request.body_json)
     self.assertEqual([('CONTENT-TYPE', 'application/json')],
                      request.headers.items())
     self.assertEqual(None, request.request_id)
예제 #38
0
 def test_parse_gzipped_body(self):
   uncompressed = '{"test": "body"}'
   compressed = zlib.compress(uncompressed)
   request = test_utils.build_request('/_ah/api/foo?bar=baz', compressed,
                                      [('Content-encoding', 'gzip')])
   self.assertEqual('foo', request.path)
   self.assertEqual('bar=baz', request.query)
   self.assertEqual({'bar': ['baz']}, request.parameters)
   self.assertEqual(uncompressed, request.body)
   self.assertEqual({'test': 'body'}, request.body_json)
   self.assertItemsEqual([('CONTENT-TYPE', 'application/json'),
                          ('CONTENT-ENCODING', 'gzip')],
                         request.headers.items())
   self.assertEqual(None, request.request_id)
예제 #39
0
 def test_parse_gzipped_body(self):
     uncompressed = '{"test": "body"}'
     compressed = zlib.compress(uncompressed)
     request = test_utils.build_request('/_ah/api/foo?bar=baz', compressed,
                                        [('Content-encoding', 'gzip')])
     self.assertEqual('foo', request.path)
     self.assertEqual('bar=baz', request.query)
     self.assertEqual({'bar': ['baz']}, request.parameters)
     self.assertEqual(uncompressed, request.body)
     self.assertEqual({'test': 'body'}, request.body_json)
     self.assertItemsEqual([('CONTENT-TYPE', 'application/json'),
                            ('CONTENT-ENCODING', 'gzip')],
                           request.headers.items())
     self.assertEqual(None, request.request_id)
예제 #40
0
 def test_dispatch_json_rpc(self):
     config = json.dumps({
         'name': 'guestbook_api',
         'version': 'X',
         'methods': {
             'foo.bar': {
                 'httpMethod': 'GET',
                 'path': 'greetings/{gid}',
                 'rosyMethod': 'baz.bim'
             }
         }
     })
     request = test_utils.build_request(
         '/_ah/api/rpc', '{"method": "foo.bar", "apiVersion": "X"}')
     self.assert_dispatch_to_spi(request, config, '/_ah/spi/baz.bim')
예제 #41
0
 def test_dispatch_rest(self):
     config = json.dumps({
         'name': 'myapi',
         'version': 'v1',
         'methods': {
             'bar': {
                 'httpMethod': 'GET',
                 'path': 'foo/{id}',
                 'rosyMethod': 'baz.bim'
             }
         }
     })
     request = test_utils.build_request('/_ah/api/myapi/v1/foo/testId')
     self.assert_dispatch_to_spi(request, config, '/_ah/spi/baz.bim',
                                 {'id': 'testId'})
예제 #42
0
 def test_dispatch_rest(self):
   config = json.dumps({
       'name': 'myapi',
       'version': 'v1',
       'methods': {
           'bar': {
               'httpMethod': 'GET',
               'path': 'foo/{id}',
               'rosyMethod': 'baz.bim'
           }
       }
   })
   request = test_utils.build_request('/_ah/api/myapi/v1/foo/testId')
   self.assert_dispatch_to_spi(request, config,
                               '/_ah/spi/baz.bim',
                               {'id': 'testId'})
예제 #43
0
 def test_handle_non_json_spi_response(self):
   orig_request = test_utils.build_request('/_ah/api/fake/path')
   spi_request = orig_request.copy()
   spi_response = dispatcher.ResponseTuple(
       200, [('Content-type', 'text/plain')],
       'This is an invalid response.')
   response = self.server.handle_spi_response(orig_request, spi_request,
                                              spi_response, {},
                                              self.start_response)
   error_json = {'error': {'message':
                           'Non-JSON reply: This is an invalid response.'}}
   body = json.dumps(error_json)
   self.assert_http_match(response, '500',
                          [('Content-Type', 'application/json'),
                           ('Content-Length', '%d' % len(body))],
                          body)
예제 #44
0
 def test_handle_non_json_spi_response(self):
   orig_request = test_utils.build_request('/_ah/api/fake/path')
   spi_request = orig_request.copy()
   spi_response = dispatcher.ResponseTuple(
       200, [('Content-type', 'text/plain')],
       'This is an invalid response.')
   response = self.server.handle_spi_response(orig_request, spi_request,
                                              spi_response, {},
                                              self.start_response)
   error_json = {'error': {'message':
                           'Non-JSON reply: This is an invalid response.'}}
   body = json.dumps(error_json)
   self.assert_http_match(response, '500',
                          [('Content-Type', 'application/json'),
                           ('Content-Length', '%d' % len(body))],
                          body)
예제 #45
0
    def test_dispatch_rpc_error(self):
        """Test than an RPC call that returns an error is handled properly."""
        config = json.dumps({
            'name': 'guestbook_api',
            'version': 'v1',
            'methods': {
                'guestbook.get': {
                    'httpMethod': 'GET',
                    'path': 'greetings/{gid}',
                    'rosyMethod': 'MyApi.greetings_get'
                }
            }
        })
        request = test_utils.build_request(
            '/_ah/api/rpc',
            '{"method": "foo.bar", "apiVersion": "X", "id": "gapiRpc"}')
        self.prepare_dispatch(config)
        self.mox.StubOutWithMock(self.server, 'call_spi')
        # The application chose to throw a 404 error.
        response = dispatcher.ResponseTuple(
            '404 Not Found', [], ('{"state": "APPLICATION_ERROR",'
                                  ' "error_message": "Test error"}'))
        self.server.call_spi(request, mox.IgnoreArg()).AndRaise(
            errors.BackendError(response))

        self.mox.ReplayAll()
        response = self.server.dispatch(request, self.start_response)
        self.mox.VerifyAll()

        expected_response = {
            'error': {
                'code':
                404,
                'message':
                'Test error',
                'data': [{
                    'domain': 'global',
                    'reason': 'notFound',
                    'message': 'Test error',
                }]
            },
            'id': 'gapiRpc'
        }
        response = ''.join(response)
        self.assertEqual('200 OK', self.response_status)
        self.assertEqual(expected_response, json.loads(response))
예제 #46
0
  def test_dispatch_spi_error(self):
    """Check the error response if the SPI returns an error."""
    config = json.dumps({
        'name': 'guestbook_api',
        'version': 'v1',
        'methods': {
            'guestbook.get': {
                'httpMethod': 'GET',
                'path': 'greetings/{gid}',
                'rosyMethod': 'MyApi.greetings_get'
            }
        }
    })
    request = test_utils.build_request('/_ah/api/foo')
    self.prepare_dispatch(config)
    self.mox.StubOutWithMock(self.server, 'call_spi')
    # The application chose to throw a 404 error.
    response = dispatcher.ResponseTuple('404 Not Found', [],
                                        ('{"state": "APPLICATION_ERROR",'
                                         ' "error_message": "Test error"}'))
    self.server.call_spi(request, mox.IgnoreArg()).AndRaise(
        errors.BackendError(response))

    self.mox.ReplayAll()
    response = self.server.dispatch(request, self.start_response)
    self.mox.VerifyAll()

    expected_response = (
        '{\n'
        ' "error": {\n'
        '  "code": 404, \n'
        '  "errors": [\n'
        '   {\n'
        '    "domain": "global", \n'
        '    "message": "Test error", \n'
        '    "reason": "notFound"\n'
        '   }\n'
        '  ], \n'
        '  "message": "Test error"\n'
        ' }\n'
        '}')
    response = ''.join(response)
    self.assert_http_match(response, '404 Not Found',
                           [('Content-Length', '%d' % len(expected_response)),
                            ('Content-Type', 'application/json')],
                           expected_response)
예제 #47
0
 def test_dispatch_json_rpc(self):
   config = json.dumps({
       'name': 'guestbook_api',
       'version': 'X',
       'methods': {
           'foo.bar': {
               'httpMethod': 'GET',
               'path': 'greetings/{gid}',
               'rosyMethod': 'baz.bim'
           }
       }
   })
   request = test_utils.build_request(
       '/_ah/api/rpc',
       '{"method": "foo.bar", "apiVersion": "X"}')
   self.assert_dispatch_to_spi(request, config,
                               '/_ah/spi/baz.bim')
예제 #48
0
  def test_dispatch_spi_error(self):
    """Check the error response if the SPI returns an error."""
    config = json.dumps({
        'name': 'guestbook_api',
        'version': 'v1',
        'methods': {
            'guestbook.get': {
                'httpMethod': 'GET',
                'path': 'greetings/{gid}',
                'rosyMethod': 'MyApi.greetings_get'
            }
        }
    })
    request = test_utils.build_request('/_ah/api/foo')
    self.prepare_dispatch(config)
    self.mox.StubOutWithMock(self.server, 'call_spi')
    # The application chose to throw a 404 error.
    response = dispatcher.ResponseTuple('404 Not Found', [],
                                        ('{"state": "APPLICATION_ERROR",'
                                         ' "error_message": "Test error"}'))
    self.server.call_spi(request, mox.IgnoreArg()).AndRaise(
        errors.BackendError(response))

    self.mox.ReplayAll()
    response = self.server.dispatch(request, self.start_response)
    self.mox.VerifyAll()

    expected_response = (
        '{\n'
        ' "error": {\n'
        '  "code": 404, \n'
        '  "errors": [\n'
        '   {\n'
        '    "domain": "global", \n'
        '    "message": "Test error", \n'
        '    "reason": "notFound"\n'
        '   }\n'
        '  ], \n'
        '  "message": "Test error"\n'
        ' }\n'
        '}')
    response = ''.join(response)
    self.assert_http_match(response, '404 Not Found',
                           [('Content-Length', '%d' % len(expected_response)),
                            ('Content-Type', 'application/json')],
                           expected_response)
예제 #49
0
  def test_copy(self):
    request = test_utils.build_request('/_ah/api/foo?bar=baz',
                                       '{"test": "body"}')
    copied = request.copy()
    self.assertEqual(list(request.headers.items()), list(copied.headers.items()))
    self.assertEqual(request.body, copied.body)
    self.assertEqual(request.body_json, copied.body_json)
    self.assertEqual(request.path, copied.path)

    copied.headers['Content-Type'] = 'text/plain'
    copied.body = 'Got a whole new body!'
    copied.body_json = {'new': 'body'}
    copied.path = 'And/a/new/path/'

    self.assertNotEqual(list(request.headers.items()), list(copied.headers.items()))
    self.assertNotEqual(request.body, copied.body)
    self.assertNotEqual(request.body_json, copied.body_json)
    self.assertNotEqual(request.path, copied.path)
  def test_handle_spi_response_json_rpc(self):
    """Verify headers transformed, JsonRpc response transformed, written."""
    orig_request = test_utils.build_request(
        '/_ah/api/rpc', '{"method": "foo.bar", "apiVersion": "X"}')
    self.assertTrue(orig_request.is_rpc())
    orig_request.request_id = 'Z'
    spi_request = orig_request.copy()
    spi_response = dispatcher.ResponseTuple('200 OK', [('a', 'b')],
                                            '{"some": "response"}')

    response = self.server.handle_spi_response(orig_request, spi_request,
                                               spi_response,
                                               self.start_response)
    response = ''.join(response)  # Merge response iterator into single body.

    self.assertEqual(self.response_status, '200 OK')
    self.assertIn(('a', 'b'), self.response_headers)
    self.assertEqual({'id': 'Z', 'result': {'some': 'response'}},
                     json.loads(response))
예제 #51
0
  def test_handle_spi_response_json_rpc(self):
    """Verify headers transformed, JsonRpc response transformed, written."""
    orig_request = test_utils.build_request(
        '/_ah/api/rpc', '{"method": "foo.bar", "apiVersion": "X"}')
    self.assertTrue(orig_request.is_rpc())
    orig_request.request_id = 'Z'
    spi_request = orig_request.copy()
    spi_response = dispatcher.ResponseTuple('200 OK', [('a', 'b')],
                                            '{"some": "response"}')

    response = self.server.handle_spi_response(orig_request, spi_request,
                                               spi_response, {},
                                               self.start_response)
    response = ''.join(response)  # Merge response iterator into single body.

    self.assertEqual(self.response_status, '200 OK')
    self.assertIn(('a', 'b'), self.response_headers)
    self.assertEqual({'id': 'Z', 'result': {'some': 'response'}},
                     json.loads(response))
예제 #52
0
  def test_dispatch_rpc_error(self):
    """Test than an RPC call that returns an error is handled properly."""
    config = json.dumps({
        'name': 'guestbook_api',
        'version': 'v1',
        'methods': {
            'guestbook.get': {
                'httpMethod': 'GET',
                'path': 'greetings/{gid}',
                'rosyMethod': 'MyApi.greetings_get'
            }
        }
    })
    request = test_utils.build_request(
        '/_ah/api/rpc',
        '{"method": "foo.bar", "apiVersion": "X", "id": "gapiRpc"}')
    self.prepare_dispatch(config)
    self.mox.StubOutWithMock(self.server, 'call_spi')
    # The application chose to throw a 404 error.
    response = dispatcher.ResponseTuple('404 Not Found', [],
                                        ('{"state": "APPLICATION_ERROR",'
                                         ' "error_message": "Test error"}'))
    self.server.call_spi(request, mox.IgnoreArg()).AndRaise(
        errors.BackendError(response))

    self.mox.ReplayAll()
    response = self.server.dispatch(request, self.start_response)
    self.mox.VerifyAll()

    expected_response = {'error': {'code': 404,
                                   'message': 'Test error',
                                   'data': [{
                                       'domain': 'global',
                                       'reason': 'notFound',
                                       'message': 'Test error',
                                       }]
                                  },
                         'id': 'gapiRpc'
                        }
    response = ''.join(response)
    self.assertEqual('200 OK', self.response_status)
    self.assertEqual(expected_response, json.loads(response))
예제 #53
0
    def test_dispatch_invalid_enum(self):
        config = json.dumps({
            'name': 'guestbook_api',
            'version': 'v1',
            'methods': {
                'guestbook.get': {
                    'httpMethod': 'GET',
                    'path': 'greetings/{gid}',
                    'rosyMethod': 'MyApi.greetings_get',
                    'request': {
                        'body': 'empty',
                        'parameters': {
                            'gid': {
                                'enum': {
                                    'X': {
                                        'backendValue': 'X'
                                    }
                                },
                                'type': 'string'
                            }
                        }
                    }
                }
            }
        })

        request = test_utils.build_request(
            '/_ah/api/guestbook_api/v1/greetings/invalid_enum')
        self.prepare_dispatch(config)
        self.mox.ReplayAll()
        response = self.server.dispatch(request, self.start_response)
        self.mox.VerifyAll()

        logging.warning('Config %s', self.server.config_manager.configs)

        self.assertEqual(self.response_status, '400 Bad Request')
        body = ''.join(response)
        body_json = json.loads(body)
        self.assertEqual(1, len(body_json['error']['errors']))
        self.assertEqual('gid', body_json['error']['errors'][0]['location'])
        self.assertEqual('invalidParameter',
                         body_json['error']['errors'][0]['reason'])
예제 #54
0
  def test_parse_gzipped_body(self):
    def gzip_encode(content):
      out = cStringIO.StringIO()
      with gzip.GzipFile(fileobj=out, mode='w') as f:
        f.write(content)
      return out.getvalue()

    uncompressed = '{"test": "body"}'
    compressed = gzip_encode(uncompressed)
    request = test_utils.build_request('/_ah/api/foo?bar=baz', compressed,
                                       [('Content-encoding', 'gzip')])
    self.assertEqual('foo', request.path)
    self.assertEqual('bar=baz', request.query)
    self.assertEqual({'bar': ['baz']}, request.parameters)
    self.assertEqual(uncompressed, request.body)
    self.assertEqual({'test': 'body'}, request.body_json)
    self.assertItemsEqual([('CONTENT-TYPE', 'application/json'),
                           ('CONTENT-ENCODING', 'gzip')],
                          request.headers.items())
    self.assertEqual(None, request.request_id)
예제 #55
0
    def test_parse_gzipped_body(self):
        def gzip_encode(content):
            out = io.StringIO()
            with gzip.GzipFile(fileobj=out, mode='w') as f:
                f.write(content)
            return out.getvalue()

        uncompressed = '{"test": "body"}'
        compressed = gzip_encode(uncompressed)
        request = test_utils.build_request('/_ah/api/foo?bar=baz', compressed,
                                           [('Content-encoding', 'gzip')])
        self.assertEqual('foo', request.path)
        self.assertEqual('bar=baz', request.query)
        self.assertEqual({'bar': ['baz']}, request.parameters)
        self.assertEqual(uncompressed, request.body)
        self.assertEqual({'test': 'body'}, request.body_json)
        self.assertItemsEqual([('CONTENT-TYPE', 'application/json'),
                               ('CONTENT-ENCODING', 'gzip')],
                              list(request.headers.items()))
        self.assertEqual(None, request.request_id)
예제 #56
0
  def test_handle_spi_response_batch_json_rpc(self):
    """Verify that batch requests have an appropriate batch response."""
    orig_request = test_utils.build_request(
        '/_ah/api/rpc', '[{"method": "foo.bar", "apiVersion": "X"}]')
    self.assertTrue(orig_request.is_batch())
    self.assertTrue(orig_request.is_rpc())
    orig_request.request_id = 'Z'
    spi_request = orig_request.copy()
    spi_response = dispatcher.ResponseTuple('200 OK', [('a', 'b')],
                                            '{"some": "response"}')

    response = self.server.handle_spi_response(orig_request, spi_request,
                                               spi_response,
                                               self.start_response)
    response = ''.join(response)  # Merge response iterator into single body.

    self.assertEqual(self.response_status, '200 OK')
    self.assertIn(('a', 'b'), self.response_headers)
    self.assertEqual([{'id': 'Z', 'result': {'some': 'response'}}],
                     json.loads(response))
예제 #57
0
    def test_lily_uses_python_method_name(self):
        """Verify Lily protocol correctly uses python method name.

    This test verifies the fix to http://b/7189819
    """
        config = json.dumps({
            'name': 'guestbook_api',
            'version': 'X',
            'methods': {
                'author.greeting.info.get': {
                    'httpMethod': 'GET',
                    'path': 'authors/{aid}/greetings/{gid}/infos/{iid}',
                    'rosyMethod': 'InfoService.get'
                }
            }
        })
        request = test_utils.build_request(
            '/_ah/api/rpc',
            '{"method": "author.greeting.info.get", "apiVersion": "X"}')
        self.assert_dispatch_to_spi(request, config,
                                    '/_ah/spi/InfoService.get', {})
예제 #58
0
  def test_dispatch_invalid_path(self):
    config = json.dumps({
        'name': 'guestbook_api',
        'version': 'v1',
        'methods': {
            'guestbook.get': {
                'httpMethod': 'GET',
                'path': 'greetings/{gid}',
                'rosyMethod': 'MyApi.greetings_get'
            }
        }
    })
    request = test_utils.build_request('/_ah/api/foo')
    self.prepare_dispatch(config)
    self.mox.ReplayAll()
    response = self.server.dispatch(request, self.start_response)
    self.mox.VerifyAll()

    self.assert_http_match(response, 404,
                           [('Content-Type', 'text/plain'),
                            ('Content-Length', '9')],
                           'Not Found')
예제 #59
0
  def test_lily_uses_python_method_name(self):
    """Verify Lily protocol correctly uses python method name.

    This test verifies the fix to http://b/7189819
    """
    config = json.dumps({
        'name': 'guestbook_api',
        'version': 'X',
        'methods': {
            'author.greeting.info.get': {
                'httpMethod': 'GET',
                'path': 'authors/{aid}/greetings/{gid}/infos/{iid}',
                'rosyMethod': 'InfoService.get'
            }
        }
    })
    request = test_utils.build_request(
        '/_ah/api/rpc',
        '{"method": "author.greeting.info.get", "apiVersion": "X"}')
    self.assert_dispatch_to_spi(request, config,
                                '/_ah/spi/InfoService.get',
                                {})