Skip to content
This repository has been archived by the owner on Jan 18, 2020. It is now read-only.

Commit

Permalink
Merge pull request #140 from cbmi/issue-132
Browse files Browse the repository at this point in the history
Change default concept sort order to be relative to category
  • Loading branch information
bruth committed Jan 28, 2014
2 parents 53955ef + e3d648f commit 693bf7f
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 29 deletions.
11 changes: 9 additions & 2 deletions serrano/resources/concept.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ def is_not_found(self, request, response, *args, **kwargs):
def get(self, request, pk=None):
params = self.get_params(request)

order = ['-category__order' if params['order'] == 'desc'
else 'category__order']

queryset = self.get_queryset(request)

# For privileged users, check if any filters are applied, otherwise
Expand All @@ -234,8 +237,12 @@ def get(self, request, pk=None):
objects = (x.object for x in results)
else:
if params['sort'] == 'name':
order = '-name' if params['order'] == 'desc' else 'name'
queryset = queryset.order_by(order)
order.append('-name' if params['order'] == 'desc'
else 'name')

# We need to order before a possible slice is taken because
# querysets cannot be ordered post-slice.
queryset = queryset.order_by(*order)

if params['limit']:
queryset = queryset[:params['limit']]
Expand Down
150 changes: 123 additions & 27 deletions tests/cases/resources/tests/concept.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
from django.test.utils import override_settings
from avocado.models import DataConcept, DataConceptField, DataField
from avocado.models import DataConcept, DataConceptField, DataField, \
DataCategory
from avocado.events.models import Log
from .base import BaseTestCase

Expand All @@ -9,12 +10,12 @@ class ConceptResourceTestCase(BaseTestCase):
def setUp(self):
super(ConceptResourceTestCase, self).setUp()

self.name_field = DataField.objects.get_by_natural_key('tests',
'title', 'name')
self.salary_field = DataField.objects.get_by_natural_key('tests',
'title', 'salary')
self.boss_field = DataField.objects.get_by_natural_key('tests',
'title', 'boss')
self.name_field = DataField.objects.get_by_natural_key(
'tests', 'title', 'name')
self.salary_field = DataField.objects.get_by_natural_key(
'tests', 'title', 'salary')
self.boss_field = DataField.objects.get_by_natural_key(
'tests', 'title', 'boss')

c1 = DataConcept(name='Title', published=True)
c1.save()
Expand All @@ -33,10 +34,105 @@ def setUp(self):

def test_get_all(self):
response = self.client.get('/api/concepts/',
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 2)

def test_get_all_category_sort(self):
# Create some temporary concepts and categories
cat1 = DataCategory(name='Category1', order=1.0, published=True)
cat1.save()

c1 = DataConcept(name='B', published=True, category=cat1)
c1.save()
field1 = DataConceptField(concept=c1, field=self.name_field, order=1)
field1.save()

c2 = DataConcept(name='C', published=True, category=cat1)
c2.save()
field2 = DataConceptField(concept=c2, field=self.name_field, order=1)
field2.save()

c3 = DataConcept(name='A', published=True, category=cat1)
c3.save()
field3 = DataConceptField(concept=c3, field=self.name_field, order=1)
field3.save()

# Check that category ordering is happening by default
response = self.client.get('/api/concepts/',
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 5)
names = [concept.get('name', '') for concept in
json.loads(response.content)]
self.assertEqual(names, ['Title', 'Name', 'B', 'C', 'A'])

# Reverse the ordering of the categories
response = self.client.get('/api/concepts/',
{'order': 'desc'},
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 5)
names = [concept.get('name', '') for concept in
json.loads(response.content)]
self.assertEqual(names, ['B', 'C', 'A', 'Title', 'Name'])

# Order by concept name in addition to category
response = self.client.get('/api/concepts/',
{'sort': 'name'},
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 5)
names = [concept.get('name', '') for concept in
json.loads(response.content)]
self.assertEqual(names, ['Name', 'Title', 'A', 'B', 'C'])

# Reverse the name and category sorting
response = self.client.get('/api/concepts/',
{'sort': 'name', 'order': 'desc'},
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 5)
names = [concept.get('name', '') for concept in
json.loads(response.content)]
self.assertEqual(names, ['C', 'B', 'A', 'Title', 'Name'])

c1.delete()
c2.delete()
c3.delete()
field1.delete()
field2.delete()
field3.delete()
cat1.delete()

def test_get_all_name_sort(self):
response = self.client.get('/api/concepts/',
{'sort': 'name'},
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 2)
names = [concept.get('name', '') for concept in
json.loads(response.content)]
self.assertEqual(names, ['Name', 'Title'])

response = self.client.get('/api/concepts/',
{'sort': 'name', 'order': 'desc'},
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 2)
names = [concept.get('name', '') for concept in
json.loads(response.content)]
self.assertEqual(names, ['Title', 'Name'])

def test_get_all_limit(self):
# Name and title are both published but with the limit param set below
# we should only get one back.
response = self.client.get('/api/concepts/',
{'limit': 1},
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 1)

@override_settings(SERRANO_CHECK_ORPHANED_FIELDS=True)
def test_get_all_orphan(self):
# Orphan one of the fields we are about to embed in the concepts we
Expand All @@ -45,14 +141,14 @@ def test_get_all_orphan(self):
.update(field_name='XXX')

response = self.client.get('/api/concepts/', {'embed': True},
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 1)

# If we aren't embedding the fields, then none of the concepts
# should be filtered out.
response = self.client.get('/api/concepts/',
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 2)

Expand All @@ -64,24 +160,24 @@ def test_get_all_orphan_check_off(self):
.update(field_name='XXX')

response = self.client.get('/api/concepts/', {'embed': True},
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 2)

# If we aren't embedding the fields, then none of the concepts
# should be filtered out.
response = self.client.get('/api/concepts/',
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 2)

def test_get_one(self):
response = self.client.get('/api/concepts/999/',
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 404)

response = self.client.get('/api/concepts/3/',
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertTrue(json.loads(response.content))
self.assertTrue(Log.objects.filter(event='read', object_id=3).exists())
Expand All @@ -93,12 +189,12 @@ def test_get_one_orphan(self):
.update(field_name='XXX')

response = self.client.get('/api/concepts/1/', {'embed': True},
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 500)

# If we aren't embedding the fields, there should not be a server error
response = self.client.get('/api/concepts/1/',
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)

@override_settings(SERRANO_CHECK_ORPHANED_FIELDS=False)
Expand All @@ -108,25 +204,25 @@ def test_get_one_orphan_check_off(self):
.update(field_name='XXX')

response = self.client.get('/api/concepts/1/', {'embed': True},
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)

# If we aren't embedding the fields, there should not be a server error
response = self.client.get('/api/concepts/1/',
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)


class ConceptFieldResourceTestCase(BaseTestCase):
def setUp(self):
super(ConceptFieldResourceTestCase, self).setUp()

self.name_field = DataField.objects.get_by_natural_key('tests',
'title', 'name')
self.salary_field = DataField.objects.get_by_natural_key('tests',
'title', 'salary')
self.boss_field = DataField.objects.get_by_natural_key('tests',
'title', 'boss')
self.name_field = DataField.objects.get_by_natural_key(
'tests', 'title', 'name')
self.salary_field = DataField.objects.get_by_natural_key(
'tests', 'title', 'salary')
self.boss_field = DataField.objects.get_by_natural_key(
'tests', 'title', 'boss')

c1 = DataConcept(name='Title', published=True)
c1.save()
Expand All @@ -136,7 +232,7 @@ def setUp(self):

def test_get(self):
response = self.client.get('/api/concepts/1/fields/',
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(json.loads(response.content)), 3)

Expand All @@ -147,7 +243,7 @@ def test_get_orphan(self):
.update(field_name="XXX")

response = self.client.get('/api/concepts/1/fields/',
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 500)

@override_settings(SERRANO_CHECK_ORPHANED_FIELDS=False)
Expand All @@ -158,5 +254,5 @@ def test_get_orphan_check_off(self):
.update(field_name="XXX")

response = self.client.get('/api/concepts/1/fields/',
HTTP_ACCEPT='application/json')
HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)

0 comments on commit 693bf7f

Please sign in to comment.