def setUp(self): self.transport = MockSyncTransport() self.item_resource = create_resource(self.item_payload, '') self.item = SyncTransportItemResource(self.transport, self.item_resource) self.list_resource = create_resource(self.list_payload, '') self.list = SyncTransportListResource(self.transport, self.list_resource)
def test_token_guessing(self): """Test guessing the resource's token.""" r = create_resource(self.item_payload, '') self.assertTrue('resource_token' not in r.fields) for field in self.item_payload['resource_token']: self.assertTrue(field in r.fields) r = create_resource(self.count_payload, '') self.assertTrue('count' in r.fields)
def test_resource_specific_base_class(self): """Test constructing a resource with a specific base class.""" r = create_resource(self.root_payload, '') self.assertFalse(isinstance(r, RootResource)) r = create_resource( self.root_payload, '', mime_type='application/vnd.reviewboard.org.root+json') self.assertTrue(isinstance(r, RootResource))
def test_no_token_guessing(self): """Test constructing without guessing the resource token.""" r = create_resource(self.item_payload, '', guess_token=False) self.assertTrue('resource_token' in r.fields) self.assertTrue('field1' not in r.fields) self.assertTrue('field1' in r.fields['resource_token']) r = create_resource(self.list_payload, '', guess_token=False) self.assertTrue('resource_token' in r.fields)
def test_no_token_guessing(self): """Testing constructing without guessing the resource token""" r = create_resource(self.transport, self.item_payload, '', guess_token=False) self.assertTrue('resource_token' in r) self.assertTrue('field1' not in r) self.assertTrue('field1' in r.resource_token) r = create_resource(self.transport, self.list_payload, '', guess_token=False) self.assertTrue('resource_token' in r)
def _create_resource_for_field(parent_resource, field_payload, mimetype, item_mimetype=None, url=None): """Create a resource instance based on field data. This will construct a resource instance for the payload of a field, using the given mimetype to identify it. This is intended for use with expanded resources or items in lists. Args: parent_resource (Resource): The resource containing the field payload. field_payload (dict): The field payload to use as the new resource's payload. mimetype (unicode): The mimetype of the resource. item_mimetype (unicode, optional): The mimetype of any items in the resource, if this resource represents a list. url (unicode, optional): The URL of the resource, if one is available. """ # We need to import this here to avoid circular imports. from rbtools.api.factory import create_resource return create_resource(transport=parent_resource._transport, payload=field_payload, url=url, mime_type=mimetype, item_mime_type=item_mimetype, guess_token=False)
def test_list_resource_links(self): """Testing link resource link generation.""" r = create_resource(self.transport, self.list_payload, '') self.assertTrue(hasattr(r, 'get_self')) self.assertTrue(callable(r.get_self)) request = r.get_self() self.assertTrue(isinstance(request, HttpRequest)) self.assertEqual(request.method, 'GET') self.assertEqual(request.url, self.list_payload['links']['self']['href']) self.assertTrue(hasattr(r, 'create')) self.assertTrue(callable(r.create)) request = r.create() self.assertTrue(isinstance(request, HttpRequest)) self.assertEqual(request.method, 'POST') self.assertEqual(request.url, self.list_payload['links']['create']['href']) self.assertTrue(hasattr(r, 'get_other_link')) self.assertTrue(callable(r.get_other_link)) request = r.get_other_link() self.assertTrue(isinstance(request, HttpRequest)) self.assertEqual(request.method, 'GET') self.assertEqual(request.url, self.list_payload['links']['other_link']['href']) self.assertFalse(hasattr(r, 'update')) self.assertFalse(hasattr(r, 'delete'))
def test_item_construction(self): """Testing constructing an item resource.""" r = create_resource(self.transport, self.item_payload, '') self.assertTrue(isinstance(r, ItemResource)) self.assertEqual(r.field1, self.item_payload['resource_token']['field1']) self.assertEqual(r.field2, self.item_payload['resource_token']['field2'])
def test_item_construction(self): """Test constructing an item resource.""" r = create_resource(self.item_payload, '') self.assertTrue(isinstance(r, ResourceItem)) self.assertEqual(r.fields['field1'], self.item_payload['resource_token']['field1']) self.assertEqual(r.fields['field2'], self.item_payload['resource_token']['field2'])
def test_resource_dict_field(self): """Testing access of a dictionary field.""" r = create_resource(self.transport, self.item_payload, '') field = r.nested_field self.assertTrue(isinstance(field, ResourceDictField)) self.assertEqual( field.nested1, self.item_payload['resource_token']['nested_field']['nested1'])
def test_iteritems_with_expanded_item_resource(self): """Testing ItemResource.iteritems with field as expanded item resource """ r = create_resource(transport=self.transport, payload=self.expanded_item_payload, url='') items = dict(r.iteritems()) self.assertIsInstance(items['item1'], ExpandedItemResource) self.assertIsInstance(items['item2'], ResourceDictField) self.assertIsInstance(items['other-item'], ResourceDictField)
def test_list_resource_list(self): """Testing list resource lists.""" r = create_resource(self.transport, self.list_payload, '') self.assertEqual(r.num_items, len(self.list_payload['resource_token'])) self.assertEqual(r.total_results, self.list_payload['total_results']) for index in range(r.num_items): for field in r[index].iterfields(): self.assertEqual( r[index][field], self.list_payload['resource_token'][index][field])
def test_getattr_with_expanded_item_resource(self): """Testing ItemResource.__getattr__ with field as expanded item resource """ r = create_resource(transport=self.transport, payload=self.expanded_item_payload, url='') self.assertIsInstance(r['item1'], ExpandedItemResource) self.assertIsInstance(r['item2'], ResourceDictField) self.assertIsInstance(r['other-item'], ResourceDictField)
def test_resource_dict_field_iteration(self): """Testing iterating sub-fields of a dictionary field.""" r = create_resource(self.transport, self.item_payload, '') field = r.nested_field iterated_fields = set(f for f in field.iterfields()) nested_fields = set( f for f in self.item_payload['resource_token']['nested_field']) self.assertEqual(set(), nested_fields.symmetric_difference(iterated_fields))
def test_root_resource_templates(self): """Test generation of methods for the root resource uri templates.""" r = create_resource( self.root_payload, '', mime_type='application/vnd.reviewboard.org.root+json') for template_name in self.root_payload['uri_templates']: method_name = "get_%s" % template_name self.assertTrue(hasattr(r, method_name)) self.assertTrue(callable(getattr(r, method_name)))
def test_link_field(self): """Testing access of a link field.""" r = create_resource(self.transport, self.item_payload, '') field = r.link_field self.assertTrue(isinstance(field, ResourceLinkField)) request = field.get() self.assertEqual(request.method, 'GET') self.assertEqual( request.url, self.item_payload['resource_token']['link_field']['href'])
def test_getattr_with_expanded_list_resource(self): """Testing ItemResource.__getattr__ with field as expanded list resource """ r = create_resource(transport=self.transport, payload=self.expanded_list_payload, url='') self.assertIsInstance(r['list1'], ResourceListField) self.assertIsInstance(r['list1'][0], ExpandedItemResource) self.assertIsInstance(r['list2'], ResourceListField) self.assertIsInstance(r['list2'][0], ResourceDictField) self.assertIsInstance(r['other-list'], ResourceListField) self.assertIsInstance(r['other-list'][0], ResourceDictField)
def _execute_request(self, request): """Execute an HTTPRequest and construct a resource from the payload""" logging.debug('Making HTTP %s request to %s' % (request.method, request.url)) rsp = self.server.make_request(request) info = rsp.info() mime_type = info['Content-Type'] item_content_type = info.get('Item-Content-Type', None) payload = rsp.read() payload = decode_response(payload, mime_type) return create_resource(self, payload, request.url, mime_type=mime_type, item_mime_type=item_content_type)
def test_iteritems_with_expanded_list_resource(self): """Testing ItemResource.iteritems with field as expanded list resource """ r = create_resource(transport=self.transport, payload=self.expanded_list_payload, url='') items = dict(r.iteritems()) self.assertIsInstance(items['list1'], ResourceListField) self.assertIsInstance(items['list1'][0], ExpandedItemResource) self.assertIsInstance(items['list2'], ResourceListField) self.assertIsInstance(items['list2'][0], ResourceDictField) self.assertIsInstance(items['other-list'], ResourceListField) self.assertIsInstance(items['other-list'][0], ResourceDictField)
def __getitem__(self, key): payload = self._item_list[key] # TODO: Should try and guess the url based on the parent url, # and the id number if the self link doesn't exist. try: url = payload["links"]["self"]["href"] except KeyError: url = "" # We need to import this here because of the mutual imports. from rbtools.api.factory import create_resource return create_resource(self._transport, payload, url, mime_type=self._item_mime_type, guess_token=False)
def test_absolute_url_with_url_field(self): """Testing ReviewRequestResource.absolute_url with 'url' field""" payload = { 'review_request': { 'id': 123, 'url': '/r/123/', }, 'stat': 'ok', } r = create_resource( transport=self.transport, payload=payload, url='https://example.com/', mime_type='application/vnd.reviewboard.org.review-request') self.assertTrue(isinstance(r, ReviewRequestResource)) self.assertEqual(r.absolute_url, 'https://example.com/r/123/')
def __call__(self, *args, **kwargs): """Executed when a resource's method is called.""" call_result = self._method(*args, **kwargs) if not isinstance(call_result, HttpRequest): return call_result rsp = self._transport.server.make_request(call_result) info = rsp.info() mime_type = info['Content-Type'] item_content_type = info.get('Item-Content-Type', None) payload = rsp.read() payload = decode_response(payload, mime_type) resource = create_resource(payload, call_result.url, mime_type=mime_type, item_mime_type=item_content_type) return self._transport.wrap(resource)
def get_root(self): """Return an instance of RootResource Instead of calling :py:meth:`get_root` and returning an instance of :py:class:`rbtools.api.request.HttpRequest`, an instance of :py:class:`rbtools.api.resource.RootResource` is simply returned. The type of metadata this instance contains depends on the type of :py:attr:`root_payload` passed in. Returns: rbtools.api.resource.RootResource: An instance of :py:class:`rbtools.api.request.RootResource`. """ return create_resource( transport=self, payload=self.root_payload, url='http://localhost:8080/api/', mime_type='application/vnd.reviewboard.org.root+json')
def __getitem__(self, key): payload = self._item_list[key] # TODO: Should try and guess the url based on the parent url, # and the id number if the self link doesn't exist. try: url = payload['links']['self']['href'] except KeyError: url = '' # We need to import this here because of the mutual imports. from rbtools.api.factory import create_resource return create_resource(self._transport, payload, url, mime_type=self._item_mime_type, guess_token=False)
def test_list_resource_links(self): """Test link resource link generation.""" r = create_resource(self.list_payload, '') self.assertTrue(hasattr(r, 'get_self')) self.assertTrue(callable(r.get_self)) self.assertTrue(isinstance(r.get_self(), HttpRequest)) self.assertEqual(r.get_self().method, 'GET') self.assertTrue(hasattr(r, 'create')) self.assertTrue(callable(r.create)) self.assertTrue(isinstance(r.create(), HttpRequest)) self.assertEqual(r.create().method, 'POST') self.assertTrue(hasattr(r, 'get_other_link')) self.assertTrue(callable(r.get_other_link)) self.assertTrue(isinstance(r.get_other_link(), HttpRequest)) self.assertEqual(r.get_other_link().method, 'GET') self.assertFalse(hasattr(r, 'update')) self.assertFalse(hasattr(r, 'delete'))
def _execute_request(self, request): """Execute an HTTPRequest and construct a resource from the payload""" logging.debug('Making HTTP %s request to %s', request.method, request.url) rsp = self.server.make_request(request) info = rsp.info() mime_type = info['Content-Type'] item_content_type = info.get('Item-Content-Type', None) if request.method == 'DELETE': # DELETE calls don't return any data. Everything else should. return None else: payload = rsp.read() payload = decode_response(payload, mime_type) return create_resource(self, payload, request.url, mime_type=mime_type, item_mime_type=item_content_type)
def __getitem__(self, key): if key in self._item_cache: return self._item_cache[key] payload = self._resource[key] # TODO: Should try and guess the url based on the parent url, # and the id number if the self link doesn't exist. try: url = payload['links']['self']['href'] except KeyError: url = '' resource = create_resource(payload, url, mime_type=self._resource._item_mime_type, guess_token=False) wrapped_resource = self._transport.wrap(resource) self._item_cache[key] = wrapped_resource return wrapped_resource
def __getitem__(self, key): if key in self._item_cache: return self._item_cache[key] payload = self._resource[key] # TODO: Should try and guess the url based on the parent url, # and the id number if the self link doesn't exist. try: url = payload['links']['self']['href'] except KeyError: url = '' resource = create_resource( payload, url, mime_type=self._resource._item_mime_type, guess_token=False) wrapped_resource = self._transport.wrap(resource) self._item_cache[key] = wrapped_resource return wrapped_resource
def execute_request_method(self, method, *args, **kwargs): """Return an instance of ItemResource. Instead of executing :py:meth:`execute_request_method` and carrying out an instance of :py:class:`rbtools.api.request.HttpRequest`, it returns an instance of:py:class:`rbtools.api.resource.ItemResource`. The type of metadata this instance contains depends on the type of :py:attr:`list_payload` passed in. Args: method (callable): A function that acts as a method to be executed and returns a :py:class:`rbtools.api.request.HttpRequest` instance. *args: Variable arguments used for running the passed in method. **kwargs: Keyword arguments used for running the passed in method. Returns: rbtools.api.resource.ItemResource: An instance of :py:class:`rbtools.api.resource.ItemResource` if the executed method is an instance of :py:class:`rbtools.api.request.HttpRequest`. """ request = method(*args, **kwargs) if isinstance(request, HttpRequest): return create_resource( transport=self, payload=self.list_payload, url='http://localhost:8080/api/repositories/', mime_type='application/vnd.reviewboard.org.list+json', item_mime_type='application/vnd.reviewboard.org.repository' '+json') return request
def test_list_construction(self): """Testing constructing a list resource.""" r = create_resource(self.transport, self.list_payload, '') self.assertTrue(isinstance(r, ListResource))
def test_extra_data_rewriting_update(self): """Testing rewriting of exta_data__ parameters to update""" r = create_resource(self.transport, self.item_payload, '') request = r.update(extra_data__foo='bar') self.assertTrue('extra_data.foo' in request._fields) self.assertEqual(request._fields['extra_data.foo'], 'bar')
def test_item_resource_fields(self): """Test item resource fields.""" r = create_resource(self.item_payload, '') for field in self.item_payload['resource_token']: self.assertTrue(field in r.fields)
def test_item_resource_fields(self): """Testing item resource fields.""" r = create_resource(self.transport, self.item_payload, '') for field in self.item_payload['resource_token']: self.assertTrue(field in r) self.assertTrue(hasattr(r, field))
def test_count_construction(self): """Testing constructing a count resource.""" r = create_resource(self.transport, self.count_payload, '') self.assertTrue(isinstance(r, CountResource)) self.assertEqual(r.count, self.count_payload['count'])