diff --git a/products/tests.py b/products/tests.py index 2fdb597..46f57c7 100644 --- a/products/tests.py +++ b/products/tests.py @@ -488,10 +488,41 @@ class ProductSearchTest(TestCase): # check ids for i in range(len(payload['products'])): self.assertTrue(payload['products'][i]['id'] == expected_instances[i].id) + # check results ordered by rank + current = 1 + for i in range(len(payload['products'])): + self.assertTrue(payload['products'][i]['rank'] <= current ) + current = payload['products'][i]['rank'] # check for filters self.assertNotEquals([], payload['filters']['singles']) self.assertTrue(len(payload['filters']) >= 2 ) + def test_anon_user_can_paginate_search(self): + expected_instances = [ + self.factory(tags="lunares/rojos", category='zapatos', description="zapatos verdes"), + self.factory(tags="colores/rojos, tono/brillante"), + self.factory(tags="lunares/azules", description="zapatos rojos"), + self.factory(tags="lunares/rojos", description="zapatos"), + self.factory(attributes='"zapatos de campo", tono/oscuro'), + ] + unexpected_instances = [ + self.factory(description="chanclas"), + self.factory(tags="azules"), + ] + + query_string = quote("zapatos rojos") + limit = 2 + + url = f"{self.endpoint}?query_string={query_string}&limit=2" + # send in request + response = self.client.get(url) + + # check response + self.assertEqual(response.status_code, 200) + # load response data + payload = response.json() + # check for object creation + self.assertEquals(len(payload['products']), limit) class MyProductsViewTest(APITestCase): """my_products tests diff --git a/products/views.py b/products/views.py index 39466da..a54ea68 100644 --- a/products/views.py +++ b/products/views.py @@ -145,8 +145,14 @@ def load_coop_products(request): def product_search(request): """ Takes a string of data, return relevant products + + Params: + - query_string: used for search [MANDATORY] + - limit: max number of returned instances [OPTIONAL] + - offset: where to start counting results [OPTIONAL] """ query_string = request.GET.get('query_string', None) + if query_string is None: return Response({"errors": {"details": "No query string to parse"}}) try: @@ -166,8 +172,19 @@ def product_search(request): # order results and respond result_list = list(result_set) ranked_products = sorted(result_list, key= lambda rank:rank.rank, reverse=True) - # TODO: slice ranked_products as per pagination serializer = SearchResultSerializer(ranked_products, many=True) - return Response(data={"filters": filters, "products": [dict(i) for i in serializer.data]}) + product_results = [dict(i) for i in serializer.data] + # check for pagination + limit = request.GET.get('limit', None) + offset = request.GET.get('offset', None) + if limit is not None and offset is not None: + limit = int(limit) + offset = int(offset) + product_results = product_results[offset:(limit+offset)] + elif limit is not None: + limit = int(limit) + product_results = product_results[:limit] + + return Response(data={"filters": filters, "products": product_results}) except Exception as e: return Response({"errors": {"details": str(e)}}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)