Пример #1
0
 def setUp(self):
     self.ep = CrunchbaseEndpoint(CrunchbaseQuery.ENDPOINTS['companies'])
Пример #2
0
class EndpointTest(TestCase, CBSampleDataMixin):
    # The actual CrunchBase API does not seem to allow setting a page size, so we're gonna have to work around that
    # by implementing a sub-pagination in our model, with some related stuff
    def setUp(self):
        self.ep = CrunchbaseEndpoint(CrunchbaseQuery.ENDPOINTS['companies'])

    def test_list_returns_data(self):
        data = self.ep.list()
        self.assertIsInstance(data, dict)

    def test_crunchquery_list_can_be_limited(self):
        json = self.ep.list(per_page=10)['data']
        self.assertEqual(len(json['items']), 10)

    def test_crunchquery_list_can_be_paginated(self):
        # Since the default page size is 10, we're getting the results for two pages here
        full_list = self.ep.list(per_page=20)
        self.assertEqual(full_list['data']['paging']['per_page'], 20)
        self.assertEqual(full_list['data']['paging']['page'], 0)
        second_page = self.ep.list(page=1)  # page is 0-based, so this is the second page
        self.assertSequenceEqual(second_page['data']['items'], full_list['data']['items'][10:])
        self.assertEqual(second_page['data']['paging']['per_page'], 10)
        self.assertEqual(second_page['data']['paging']['page'], 1)

    def test_crunchquery_list_retrieves_new_pages_when_required(self):
        # If the page number * per_page is more than what a CB page returns, we should try to get the proper one
        far_page = self.ep.list(page=101)  # Second page of CB
        self.assertEqual(len(far_page['data']['items']), 10)  # For now I'll settle for checking the metadata, rather than the val
        self.assertEqual(far_page['data']['paging']['per_page'], 10)
        self.assertEqual(far_page['data']['paging']['page'], 101)
        # If we try to fetch a non-existing page, we should raise a 404
        self.assertRaises(Http404, lambda: self.ep.list(page=100000, per_page=100000))

    @skip("To avoid clearing the cache during the tests")
    def test_list_items_are_cached(self):
        actual_return = self.ep.list(raw=True)
        with mock.patch('crunchbase.views.requests', autospec=True) as req:
            cache.clear()
            req.get.return_value = actual_return
            self.ep.list()
            self.assertEqual(req.get.call_count, 1)
            # If we call it a second time, we expect requests not to be called again
            self.ep.list()
            self.assertEqual(req.get.call_count, 1)

    def test_detail_returns_data(self):
        # The value should be cached, hopefully - Ideally we would mock this up but...
        path = self.sample_list_data['items'][0]['path']
        detail_response = self.ep.detail(path, raw=True)
        self.assertEqual(detail_response.status_code, 200)
        detail_data = self.ep.detail(path)['data']
        # At the moment, the only data we're interested in is the description
        self.assertIn('short_description', detail_data['properties'])

    @skip("To avoid removing the cached values")
    def test_detail_data_is_cached(self):
        # It should be "are cached", yes.
        path = self.sample_list_data['data']['items'][0]['path']
        actual_return = self.ep.detail(path, raw=True)
        with mock.patch('crunchbase.views.requests', autospec=True) as req:
            cache.delete(path)
            req.get.return_value = actual_return
            self.ep.detail(path)
            self.assertEqual(req.get.call_count, 1)
            self.ep.detail(path)
            self.assertEqual(req.get.call_count, 1)

    def test_list_items_can_include_extra_information(self):
        # We should be able to leverage the previously set cache; in any case, we're going to load only the first 2 items here
        data = self.sample_list_data
        # A better solution would be to use something like a queryset, so that we could do list().values('something','etc')
        # but, given the time constraints we'll go with a dict of extra values
        data = self.ep.list(per_page=2, fetch_values=('properties__short_description',))['data']
        item = data['items'][0]
        self.assertIn('properties__short_description', item)
        # Of course, we expect the actual description to match that in the details page of the item, so:
        detail = self.ep.detail(item['path'])
        self.assertEqual(detail['data']['properties']['short_description'], item['properties__short_description'])

    def test_fetch_values_returns_correct_image_data(self):
        # Testing images with the live Crunchbase API proved basically useless, so I've decided to go with fixtures for this
        fetched_values = self.ep.fetch_item_values(self.sample_list_data['items'][0]['path'], ('primary_image', ))
        self.assertEqual(
            self.sample_detail_data['metadata']['image_path_prefix'] +
            self.sample_detail_data['data']['relationships']['primary_image']['items'][0]['path'],
            fetched_values['primary_image'])

    def test_list_data_can_be_sliced(self):
        self.assertTrue(hasattr(self.ep, 'datastore'))
        # The idea is that the datastore will allow to retrieve all the metadata and that it will work basically as a queryset
        # for Django purposes;
        # This means that it must have some sort of meta attribute to store all the metadata from the queries (single and list)
        # and that it must support slicing, length and item retrieval.
        self.assertIsInstance(self.ep.datastore, CrunchbaseQueryset)