diff --git a/ckan/controllers/api.py b/ckan/controllers/api.py index a587f3d824d..31795f9a0b2 100644 --- a/ckan/controllers/api.py +++ b/ckan/controllers/api.py @@ -591,7 +591,7 @@ def group_autocomplete(self): limit = 20 limit = min(50, limit) - query = model.Group.search_by_name(q, t) + query = model.Group.search_by_name_or_title(q, t) def convert_to_dict(user): out = {} for k in ['id', 'name', 'title']: diff --git a/ckan/model/group.py b/ckan/model/group.py index de2e4cd1a53..79eacf5768c 100644 --- a/ckan/model/group.py +++ b/ckan/model/group.py @@ -9,6 +9,7 @@ import vdm.sqlalchemy from ckan.model import extension, User from sqlalchemy.ext.associationproxy import association_proxy +import sqlalchemy as sa __all__ = ['group_table', 'Group', 'package_revision_table', 'Member', 'GroupRevision', 'MemberRevision', @@ -181,12 +182,13 @@ def active_packages(self, load_eager=True, with_private=False): return query @classmethod - def search_by_name(cls, text_query, group_type=None): + def search_by_name_or_title(cls, text_query, group_type=None): text_query = text_query.strip().lower() - if not group_type: - q = Session.query(cls).filter(cls.name.contains(text_query)) - else: - q = Session.query(cls).filter(cls.name.contains(text_query)).filter(cls.type==group_type) + q = Session.query(cls) \ + .filter(sa.or_(cls.name.contains(text_query), + cls.title.ilike('%' + text_query + '%'))) + if group_type: + q = q.filter(cls.type==group_type) return q.order_by(cls.title) def as_dict(self, ref_package_by='name'): diff --git a/ckan/tests/functional/api/test_util.py b/ckan/tests/functional/api/test_util.py index f652022142b..fc24ef5258f 100644 --- a/ckan/tests/functional/api/test_util.py +++ b/ckan/tests/functional/api/test_util.py @@ -100,6 +100,22 @@ def test_tag_autocomplete(self): assert_equal(response.body, '{"ResultSet": {"Result": [{"Name": "russian"}]}}') assert_equal(response.header('Content-Type'), 'application/json;charset=utf-8') + def test_group_autocomplete(self): + url = url_for(controller='api', action='group_autocomplete', ver=2) + assert_equal(url, '/api/2/util/group/autocomplete') + response = self.app.get( + url=url, + params={ + 'q': u'dave', + }, + status=200, + ) + results = json.loads(response.body) + assert_equal(len(results), 1) + assert_equal(results[0]['name'], 'david') + assert_equal(results[0]['title'], 'Dave\'s books') + assert_equal(response.header('Content-Type'), 'application/json;charset=utf-8') + def test_markdown(self): markdown = '''##Title''' response = self.app.get( diff --git a/ckan/tests/models/test_group.py b/ckan/tests/models/test_group.py index 92ccc5b4a48..703b63778f8 100644 --- a/ckan/tests/models/test_group.py +++ b/ckan/tests/models/test_group.py @@ -1,3 +1,5 @@ +from nose.tools import assert_equal + import ckan.model as model from ckan.tests import * @@ -51,6 +53,20 @@ def test_2_add_packages(self): assert set(grp.active_packages().all()) == set((anna, war)), grp.active_packages().all() assert grp in anna.get_groups() + def test_3_search(self): + def search_results(query): + results = model.Group.search_by_name_or_title(query) + return set([group.name for group in results]) + assert_equal(search_results('random'), set([])) + assert_equal(search_results('david'), set(['david'])) + assert_equal(search_results('roger'), set(['roger'])) + assert_equal(search_results('roger '), set(['roger'])) + assert_equal(search_results('David'), set(['david'])) + assert_equal(search_results('Dave'), set(['david'])) + assert_equal(search_results('Dave\'s'), set(['david'])) + assert_equal(search_results('Dave\'s books'), set(['david'])) + assert_equal(search_results('Books'), set(['david', 'roger'])) + class TestGroupRevisions: @classmethod