Beispiel #1
0
 def test_keyword_arguments(self):
     response = self._post_json('/test_view_two_default_arguments', {'args': [], 'kwargs': {}})
     self._assert_api_status_code(response, 200, 
         '/test_view_two_default_arguments with no arguments should result in HTTP 200.')
     self.assertEqual(jinx_json.loads(response.content), ["default1", "default2"])
     
     response = self._post_json('/test_view_two_default_arguments', {'args': ['test1'], 'kwargs': {}})
     self._assert_api_status_code(response, 200, 
         '/test_view_two_default_arguments with no arguments should result in HTTP 200.')
     self.assertEqual(jinx_json.loads(response.content), ["test1", "default2"])
     
     response = self._post_json('/test_view_two_default_arguments', {'args': [], 'kwargs': {'arg2': 'test2'}})
     self._assert_api_status_code(response, 200, 
         '/test_view_two_default_arguments with no arguments should result in HTTP 200.')
     self.assertEqual(jinx_json.loads(response.content), ["default1", "test2"])
Beispiel #2
0
 def test_normal_call(self):
     response = self._post_json("/test_view_normal", [])
     
     self.assertEqual(jinx_json.loads(response.content), "Hello, world!", 
         'test_view_normal should return "Hello, world!"')
     self._assert_api_status_code(response, 200,
         'test_view_normal should return status code 200.')
Beispiel #3
0
    def do_api_call(self, *args, **kwargs):
        """Performs the API call for this test case and returns the results.
        
        JSON encoding and decoding is handled behind the scenes.  The decoded
        response data is stored in response.data (as opposed to 
        response.content, which will hold the raw JSON blob).
        """

        response = self.client.post(
            self.api_call_path, jinx_json.dumps(dict(args=args, kwargs=kwargs)), "application/json"
        )

        if response.status_code == 200:
            self.assertEqual(
                response["Content-Type"],
                "application/json",
                "API call %s(%s) returned type %s instead of application/json"
                % (self.api_call_path, str(args), response["Content-Type"]),
            )

            response.data = jinx_json.loads(response.content)
        else:
            response.data = response.content

        return response
Beispiel #4
0
 def test_datetime(self):
     now = datetime.datetime.now()
     response = self._post_json('/test_view_echo', [now])
     self._assert_api_status_code(response, 200, '/test_view_echo should return HTTP 200.')
     self.assertEqual(jinx_json.loads(response.content), [now],
         "should be able to send and receive datetime.datetime objects")
         
     delta = datetime.timedelta(seconds=1394875, days=21)
     response = self._post_json('/test_view_echo', [delta])
     self._assert_api_status_code(response, 200, '/test_view_echo should return HTTP 200.')
     self.assertEqual(jinx_json.loads(response.content), [delta],
         "should be able to send and receive datetime.timedelta objects")
     
     response = self._post_json('/test_view_echo', [[[[[[{'1': now}]]], {'2': delta}]]])
     self._assert_api_status_code(response, 200, '/test_view_echo should return HTTP 200.')
     self.assertEqual(jinx_json.loads(response.content), [[[[[[{'1': now}]]], {'2': delta}]]],
         "should be able to send and receive datetime.datetime and datetime.timedelta inside complex data structures")
Beispiel #5
0
 def test_arguments(self):
     response = self._post_json('/test_view_reverse_three_arguments', [1,2,"3"])
     self._assert_api_status_code(response, 200, "/test_view_reverse_three_arguments should return HTTP 200.")
     self.assertEqual(jinx_json.loads(response.content), ["3", 2, 1], 
         "/test_view_reverse_three_arguments should return the three arguments in reverse order.")
     
     response = self._post_json('/test_view_echo', [1])
     self._assert_api_status_code(response, 200, '/test_view_echo should return HTTP 200.')
     self.assertEqual(jinx_json.loads(response.content), [1], "/test_view_echo([1]) should return [1]")
     
     response = self._post_json('/test_view_echo', [1,2,3])
     self._assert_api_status_code(response, 200, '/test_view_echo should return HTTP 200.')
     self.assertEqual(jinx_json.loads(response.content), [1,2,3], 
         "/test_view_echo([1]) should return [1,2,3] (variable number of arguments should work)")
     
     response = self._post_json('/test_view_reverse_three_arguments', [1, 2])
     self._assert_call_status_code(response, 400, 
         '/test_view_reverse_three_arguments with 2 arguments should result in HTTP 400.')
         
     response = self._post_json('/test_view_reverse_three_arguments', [1, 2, 3, 4])
     self._assert_call_status_code(response, 400, 
         '/test_view_reverse_three_arguments with 4 arguments should result in HTTP 400.')
     
     response = self._post_json('/test_view_one_default_argument', ["testarg"])
     self._assert_api_status_code(response, 200, 
         '/test_view_one_default_argument with 1 argument should result in HTTP 200.')
     self.assertEqual(jinx_json.loads(response.content), "testarg")
     
     response = self._post_json('/test_view_one_default_argument', [])
     self._assert_api_status_code(response, 200, 
         '/test_view_one_default_argument with no arguments should result in HTTP 200.')
     self.assertEqual(jinx_json.loads(response.content), "default",
         '/test_view_one_default_argument should return "default" if no argument is passed.')
     
     response = self._post_json('/test_view_one_default_argument', [1, 2])
     self._assert_call_status_code(response, 400, 
         '/test_view_one_default_argument with 2 arguments should result in HTTP 400.')
Beispiel #6
0
 def _test_serialize(self, data):
     self.assertEquals(jinx_json.loads(jinx_json.dumps(data)), data)
Beispiel #7
0
 def process_view(self, request, view, view_args, view_kwargs):
     """Handle a JSON-based API call.
     
     This function is called when Django is about to call a view.  It will
     decode a POST body in JSON format, call the view, and encode the
     response in JSON format.
     
     The request should be a POST with a Content-Type of "application/json".
     The body of the request should be a JSON-encoded list of arguments to
     pass to the API call.  The arguments will be unpacked and passed in as
     positional and keyword arguments to the view function as described 
     below.  If the view function returns data, it will be JSON-encoded and
     sent back as a response with Content-Type "application/json".  If the 
     view function returns an HttpResponse object, this will be sent back 
     to the client as is.
     
     The request body can specify API calls in one of two ways, the old 
     style or the new style.  In the old style, only positional arguments
     may be passed, and the request body is simply a list of positional
     arguments.  In the new style, both positional and keyword arguments may
     be passed, and the request body is a dict with 'args' and 'kwargs' 
     entries.  
     
     Old style: ['arg1', 'arg2']
     New style: {
                 'args': ['arg1', 'arg2'],
                 'kwargs': {'arg3': 'value3, 'arg4': 'value4'}
                }
     
     Arguments:
         request -- The HttpRequest object from Django.
         view -- The view function that Django is about to call.
         view_args -- The position arguments Django would pass to the view.
         view_kwargs -- The keyword arguments Django would pass to the view.
         
     Status Codes Returned:
         200 -- The request was completed successfully.
         405 -- A method other than POST was used.
         415 -- A request body type other than application/json was sent.
         500 -- The view function raised an unhandled exception, or returned
             unserializable data (see exception value for details).
         ?   -- View functions may return whatever HTTP status codes they
             deem appropriate.  See the documentation for each view function.
         
     """
 
     content_type = request.META['CONTENT_TYPE']
     method = request.META['REQUEST_METHOD']
     
     if method != 'POST':
         return HttpResponseNotAllowed('The Jinx API requires a POST')
         
     if content_type != "application/json":
         return HttpResponseUnsupportedMediaType('The Jinx API requires a request with Content-Type: application/json')
         
     json_data = request.raw_post_data
     
     try:
         json_args = jinx_json.loads(json_data)
     except ValueError, e:
         return HttpResponseUnsupportedMediaType('Request body could not be parsed as a JSON object: %s' % str(e))
    def __getattr__(self, api_call):
        """Attribute look up method, which makes an HTTP call to Jinx API
        
        Keyword arguments:
        api_call -- string containing the api call

        """
        

        def _get_help(api_call_name):
            """ Generates the url and post body to get the API docstring from 
            the Jinx API.
            
            Keyword arguments:
            api_call_name -- the name of the API call to retrieve documentation for
            
            """

            if not isinstance(api_call_name, basestring):
                raise JinxInvalidRequestError("Argument is not a string: '%s'" % api_call_name)
            if self.interactive:
                self.auth()
            url = "https://%s/jinx/%s/%s?doc" %(self.jinx_host, self.api_version, api_call_name)
            json = jinx_json.dumps(list())
            resp_code, resp_hdrs, resp = _post_data(url, json)
            # If the headers expire, re-auth.
            if resp_code == 401:
                self.auth_hdr = None
                resp_code, resp_hdrs, resp = _post_data(url, json)
            elif resp_code == 404:
                raise NameError("API call '%s' does not exist" % api_call_name)

            _check_resp_code(resp_code, resp_hdrs, resp)

            print resp
            return


        def _call_jinx(*args, **kwargs):
            """Generates the url and post body to send.

            Keyword arguments:
            *args -- python tuple of arguments required for the API call
            **kwargs -- dict of keyword arguments required for the API call

            """

            url = "https://%s/jinx/%s/%s" %(self.jinx_host, self.api_version, api_call)            
            try:
                json = jinx_json.dumps({'args': list(args), 'kwargs': kwargs})
            except TypeError, e:
                _be_verbose(e)
                raise JinxInvalidRequestError("Request arguments are in a non-serializable format: %s" % args)
            if self.interactive:
                self.auth()
            resp_code, resp_hdrs, resp = _post_data(url, json)
            # If the headers expire, re-auth.
            if resp_code == 401:
                self.auth_hdr = None
                resp_code, resp_hdrs, resp = _post_data(url, json)

            _check_resp_code(resp_code, resp_hdrs, resp)

            try:
                resp = jinx_json.loads(resp)
            except simplejson.decoder.JSONDecodeError, e:
                _be_verbose(e)
                raise JinxInvalidResponseError("Response is not formatted with JSON")