Skip to content

Commit

Permalink
Merge branch '1208-dictize-changes-2'
Browse files Browse the repository at this point in the history
  • Loading branch information
joetsoi committed Dec 12, 2013
2 parents 19496ce + 5890793 commit 9dfef5f
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 46 deletions.
7 changes: 7 additions & 0 deletions ckan/controllers/group.py
Expand Up @@ -181,6 +181,9 @@ def read(self, id, limit=20):
q = c.q = request.params.get('q', '')

try:
# Do not query for the group datasets when dictizing, as they will
# be ignored and get requested on the controller anyway
context['include_datasets'] = False
c.group_dict = self._action('group_show')(context, data_dict)
c.group = context['group']
except NotFound:
Expand Down Expand Up @@ -330,6 +333,7 @@ def pager_url(q=None, page=None):
items_per_page=limit
)

c.group_dict['package_count'] = query['count']
c.facets = query['facets']
maintain.deprecate_context_item('facets',
'Use `c.search_facets` instead.')
Expand Down Expand Up @@ -372,6 +376,9 @@ def bulk_process(self, id):
data_dict = {'id': id}

try:
# Do not query for the group datasets when dictizing, as they will
# be ignored and get requested on the controller anyway
context['include_datasets'] = False
c.group_dict = self._action('group_show')(context, data_dict)
c.group = context['group']
except NotFound:
Expand Down
31 changes: 23 additions & 8 deletions ckan/lib/dictization/model_dictize.py
Expand Up @@ -348,7 +348,6 @@ def _get_members(context, group, member_type):


def group_dictize(group, context):
model = context['model']
result_dict = d.table_dictize(group, context)

result_dict['display_name'] = group.display_name
Expand All @@ -358,16 +357,32 @@ def group_dictize(group, context):

context['with_capacity'] = True

result_dict['packages'] = d.obj_list_dictize(
_get_members(context, group, 'packages'),
context)
include_datasets = context.get('include_datasets', True)

q = {
'facet': 'false',
'rows': 0,
}

query = search.PackageSearchQuery()
if group.is_organization:
q = {'q': 'owner_org:"%s" +capacity:public' % group.id, 'rows': 1}
q['fq'] = 'owner_org:"{0}"'.format(group.id)
else:
q = {'q': 'groups:"%s" +capacity:public' % group.name, 'rows': 1}
result_dict['package_count'] = query.run(q)['count']
q['fq'] = 'groups:"{0}"'.format(group.name)

is_group_member = (context.get('user') and
new_authz.has_user_permission_for_group_or_org(group.id, context.get('user'), 'read'))
if is_group_member:
context['ignore_capacity_check'] = True

if include_datasets:
q['rows'] = 1000 # Only the first 1000 datasets are returned

search_results = logic.get_action('package_search')(context, q)

if include_datasets:
result_dict['packages'] = search_results['results']

result_dict['package_count'] = search_results['count']

result_dict['tags'] = tag_list_dictize(
_get_members(context, group, 'tags'),
Expand Down
14 changes: 14 additions & 0 deletions ckan/logic/action/get.py
Expand Up @@ -960,6 +960,11 @@ def _group_or_org_show(context, data_dict, is_org=False):
group = model.Group.get(id)
context['group'] = group

include_datasets = data_dict.get('include_datasets', True)
if isinstance(include_datasets, basestring):
include_datasets = (include_datasets.lower() in ('true', '1'))
context['include_datasets'] = include_datasets

if group is None:
raise NotFound
if is_org and not group.is_organization:
Expand Down Expand Up @@ -1006,9 +1011,14 @@ def group_show(context, data_dict):
:param id: the id or name of the group
:type id: string
:param include_datasets: include a list of the group's datasets
(optional, default: ``True``)
:type id: boolean
:rtype: dictionary
.. note:: Only its first 1000 datasets are returned
'''
return _group_or_org_show(context, data_dict)

Expand All @@ -1017,9 +1027,13 @@ def organization_show(context, data_dict):
:param id: the id or name of the organization
:type id: string
:param include_datasets: include a list of the organization's datasets
(optional, default: ``True``)
:type id: boolean
:rtype: dictionary
.. note:: Only its first 1000 datasets are returned
'''
return _group_or_org_show(context, data_dict, is_org=True)

Expand Down
1 change: 1 addition & 0 deletions ckan/logic/schema.py
Expand Up @@ -277,6 +277,7 @@ def default_group_schema():
'approval_status': [ignore_missing, unicode],
'extras': default_extras_schema(),
'__extras': [ignore],
'__junk': [ignore],
'packages': {
"id": [not_empty, unicode, package_id_or_name_exists],
"title":[ignore_missing, unicode],
Expand Down
79 changes: 79 additions & 0 deletions ckan/new_tests/factories.py
Expand Up @@ -99,6 +99,85 @@ def _create(cls, target_class, *args, **kwargs):
return user_dict


class Group(factory.Factory):
'''A factory class for creating CKAN groups.'''

# This is the class that GroupFactory will create and return instances
# of.
FACTORY_FOR = ckan.model.Group

# These are the default params that will be used to create new groups.
type = 'group'
is_organization = False

title = 'Test Group'
description = 'Just another test group.'
image_url = 'http://placekitten.com/g/200/200'

# Generate a different group name param for each user that gets created.
name = factory.Sequence(lambda n: 'test_group_{n}'.format(n=n))

@classmethod
def _build(cls, target_class, *args, **kwargs):
raise NotImplementedError(".build() isn't supported in CKAN")

@classmethod
def _create(cls, target_class, *args, **kwargs):
if args:
assert False, "Positional args aren't supported, use keyword args."

#TODO: we will need to be able to define this when creating the
# instance perhaps passing a 'user' param?
context = {
'user': helpers.call_action('get_site_user')['name']
}

group_dict = helpers.call_action('group_create',
context=context,
**kwargs)
return group_dict


class Organization(factory.Factory):
'''A factory class for creating CKAN organizations.'''

# This is the class that OrganizationFactory will create and return
# instances of.
FACTORY_FOR = ckan.model.Group

# These are the default params that will be used to create new
# organizations.
type = 'organization'
is_organization = True

title = 'Test Organization'
description = 'Just another test organization.'
image_url = 'http://placekitten.com/g/200/100'

# Generate a different group name param for each user that gets created.
name = factory.Sequence(lambda n: 'test_org_{n}'.format(n=n))

@classmethod
def _build(cls, target_class, *args, **kwargs):
raise NotImplementedError(".build() isn't supported in CKAN")

@classmethod
def _create(cls, target_class, *args, **kwargs):
if args:
assert False, "Positional args aren't supported, use keyword args."

#TODO: we will need to be able to define this when creating the
# instance perhaps passing a 'user' param?
context = {
'user': helpers.call_action('get_site_user')['name']
}

group_dict = helpers.call_action('organization_create',
context=context,
**kwargs)
return group_dict


class MockUser(factory.Factory):
'''A factory class for creating mock CKAN users using the mock library.'''

Expand Down
145 changes: 144 additions & 1 deletion ckan/new_tests/logic/action/test_get.py
@@ -1,10 +1,153 @@
import nose.tools
import nose.case

import ckan.logic as logic
import ckan.lib.search as search
import ckan.new_tests.helpers as helpers
import ckan.new_tests.factories as factories


class TestGet(object):

@classmethod
def setup_class(cls):
helpers.reset_db()

def setup(self):
import ckan.model as model

# Reset the db before each test method.
model.repo.rebuild_db()

# Clear the search index
search.clear()

def test_group_list(self):

group1 = factories.Group()
group2 = factories.Group()

group_list = helpers.call_action('group_list')

assert (sorted(group_list) ==
sorted([g['name'] for g in [group1, group2]]))

def test_group_show(self):

group = factories.Group()

group_dict = helpers.call_action('group_show', id=group['id'])

# FIXME: Should this be returned by group_create?
group_dict.pop('num_followers', None)
assert group_dict == group

def test_group_show_packages_returned(self):

user_name = helpers.call_action('get_site_user')['name']

group = factories.Group()

datasets = [
{'name': 'dataset_1', 'groups': [{'name': group['name']}]},
{'name': 'dataset_2', 'groups': [{'name': group['name']}]},
]

for dataset in datasets:
helpers.call_action('package_create',
context={'user': user_name},
**dataset)

group_dict = helpers.call_action('group_show', id=group['id'])

assert len(group_dict['packages']) == 2
assert group_dict['package_count'] == 2

def test_group_show_no_packages_returned(self):

user_name = helpers.call_action('get_site_user')['name']

group = factories.Group()

datasets = [
{'name': 'dataset_1', 'groups': [{'name': group['name']}]},
{'name': 'dataset_2', 'groups': [{'name': group['name']}]},
]

for dataset in datasets:
helpers.call_action('package_create',
context={'user': user_name},
**dataset)

group_dict = helpers.call_action('group_show', id=group['id'],
include_datasets=False)

assert not 'packages' in group_dict
assert group_dict['package_count'] == 2

def test_organization_list(self):

org1 = factories.Organization()
org2 = factories.Organization()

org_list = helpers.call_action('organization_list')

assert (sorted(org_list) ==
sorted([g['name'] for g in [org1, org2]]))

def test_organization_show(self):

org = factories.Organization()

org_dict = helpers.call_action('organization_show', id=org['id'])

# FIXME: Should this be returned by organization_create?
org_dict.pop('num_followers', None)
assert org_dict == org

def test_organization_show_packages_returned(self):

user_name = helpers.call_action('get_site_user')['name']

org = factories.Organization()

datasets = [
{'name': 'dataset_1', 'owner_org': org['name']},
{'name': 'dataset_2', 'owner_org': org['name']},
]

for dataset in datasets:
helpers.call_action('package_create',
context={'user': user_name},
**dataset)

org_dict = helpers.call_action('organization_show', id=org['id'])

assert len(org_dict['packages']) == 2
assert org_dict['package_count'] == 2

def test_organization_show_private_packages_not_returned(self):

user_name = helpers.call_action('get_site_user')['name']

org = factories.Organization()

datasets = [
{'name': 'dataset_1', 'owner_org': org['name']},
{'name': 'dataset_2', 'owner_org': org['name'], 'private': True},
]

for dataset in datasets:
helpers.call_action('package_create',
context={'user': user_name},
**dataset)

org_dict = helpers.call_action('organization_show', id=org['id'])

assert len(org_dict['packages']) == 1
assert org_dict['packages'][0]['name'] == 'dataset_1'
assert org_dict['package_count'] == 1


class TestBadLimitQueryParameters(object):
'''test class for #1258 non-int query parameters cause 500 errors
Expand Down

0 comments on commit 9dfef5f

Please sign in to comment.