[ckan-changes] commit/ckan: 9 new changesets

Bitbucket commits-noreply at bitbucket.org
Thu Nov 10 14:35:28 UTC 2011


9 new commits in ckan:


https://bitbucket.org/okfn/ckan/changeset/5865f02832fd/
changeset:   5865f02832fd
branch:      feature-1453-flexible-tag-names
user:        Ian Murray
date:        2011-11-09 11:30:49
summary:     [test_package] Fixed broken test class.

A 'super' call to setup_class was missing.  This caused a problem
when running TestForms on its own, as it meant that the pylons.c and
pylons.request objects weren't setup.  In practice however, this isn't likely
to cause problems when running the whole test suite, as the PylonsTestCase
class is likely to be setup by some other test class before this one.
affected #:  2 files

diff -r ae5cd77638ac5e3cd6d6ccc0fe3db3cb74604cf6 -r 5865f02832fd70781b868f6978af2f461790cd9e ckan/tests/forms/test_package.py
--- a/ckan/tests/forms/test_package.py
+++ b/ckan/tests/forms/test_package.py
@@ -9,13 +9,16 @@
     return ckan.forms.get_package_dict(pkg=pkg, blank=True, user_editable_groups=[])
 
 class TestForms(PylonsTestCase, HtmlCheckMethods):
+
     @classmethod
-    def setup_class(self):
+    def setup_class(cls):
+        super(TestForms, cls).setup_class()
         model.Session.remove()
         ckan.tests.CreateTestData.create()
 
     @classmethod
-    def teardown_class(self):
+    def teardown_class(cls):
+        super(TestForms, cls).teardown_class()
         model.Session.remove()
         model.repo.rebuild_db()
 


diff -r ae5cd77638ac5e3cd6d6ccc0fe3db3cb74604cf6 -r 5865f02832fd70781b868f6978af2f461790cd9e ckan/tests/pylons_controller.py
--- a/ckan/tests/pylons_controller.py
+++ b/ckan/tests/pylons_controller.py
@@ -48,3 +48,13 @@
         mapper = make_map()
         cls.registry.register(pylons.url, URLGenerator(mapper, {}))
         cls.registry.register(pylons.session, TestSession())
+
+    @classmethod
+    def teardown_class(cls):
+        """
+        Although there is nothing to teardown in this class, `PylonsTestCase`
+        is used as the superclass for a bunch of test cases.  So this empty
+        declaration exists to that subclasses can safely call `teardown_class`
+        on their superclasses.
+        """
+        pass



https://bitbucket.org/okfn/ckan/changeset/21139e058f10/
changeset:   21139e058f10
branch:      feature-1453-flexible-tag-names
user:        Ian Murray
date:        2011-11-09 15:43:25
summary:     [tag-name validation] Weakened tag-name validation schema by allowing more characters.

 - allow spaces
 - allow capital letters
 - allow all punctuation except commas
affected #:  3 files

diff -r 5865f02832fd70781b868f6978af2f461790cd9e -r 21139e058f10e7c063cf0f7998f25a7b4fc20607 ckan/logic/schema.py
--- a/ckan/logic/schema.py
+++ b/ckan/logic/schema.py
@@ -73,7 +73,7 @@
                  unicode,
                  tag_length_validator,
                  tag_name_validator,
-                 tag_not_uppercase],
+                ],
         'revision_timestamp': [ignore],
         'state': [ignore],
     }


diff -r 5865f02832fd70781b868f6978af2f461790cd9e -r 21139e058f10e7c063cf0f7998f25a7b4fc20607 ckan/logic/validators.py
--- a/ckan/logic/validators.py
+++ b/ckan/logic/validators.py
@@ -153,10 +153,9 @@
 
 def tag_name_validator(value, context):
 
-    tagname_match = re.compile('[\w\-_.]*$', re.UNICODE)
+    tagname_match = re.compile('[^,]*$', re.UNICODE)
     if not tagname_match.match(value):
-        raise Invalid(_('Tag "%s" must be alphanumeric '
-                        'characters or symbols: -_.') % (value))
+        raise Invalid(_('Tag "%s" must not contain commas' % value))
     return value
 
 def tag_not_uppercase(value, context):


diff -r 5865f02832fd70781b868f6978af2f461790cd9e -r 21139e058f10e7c063cf0f7998f25a7b4fc20607 ckan/tests/lib/test_dictization_schema.py
--- a/ckan/tests/lib/test_dictization_schema.py
+++ b/ckan/tests/lib/test_dictization_schema.py
@@ -13,7 +13,8 @@
 
 from ckan.lib.dictization.model_save import package_dict_save
 
-from ckan.logic.schema import default_package_schema, default_group_schema
+from ckan.logic.schema import default_package_schema, default_group_schema, \
+    default_tags_schema
 
 from ckan.lib.navl.dictization_functions import validate
 
@@ -158,3 +159,68 @@
         converted_data, errors = validate(data, default_group_schema(), context)
         assert errors ==  {'packages': [{'id': [u'Dataset was not found.']}, {'id': [u'Missing value']}]} , pformat(errors)
 
+    def test_3_tag_schema_allows_spaces(self):
+        """Asserts that a tag name with space is valid"""
+        context = {'model': model,
+                   'session': model.Session}
+
+        ignored = ""
+        data = {
+            'name': u'with space',
+            'revision_timestamp': ignored, 
+            'state': ignored
+            }
+
+        _, errors = validate(data, default_tags_schema(), context)
+        assert not errors, str(errors)
+
+    def test_4_tag_schema_allows_punctuation(self):
+        """Asserts that a tag name with punctuation (except commas) is valid"""
+        context = {'model': model,
+                   'session': model.Session}
+
+        ignored = ""
+        data = {
+            'name': u'.?!<>\\/"%^&*()-_+=~#\'@`',
+            'revision_timestamp': ignored,
+            'state': ignored
+            }
+
+        _, errors = validate(data, default_tags_schema(), context)
+        assert not errors, str(errors)
+
+    def test_5_tag_schema_allows_capital_letters(self):
+        """Asserts that tag names can have capital letters"""
+        context = {'model': model,
+                   'session': model.Session}
+
+        ignored = ""
+        data = {
+            'name': u'CAPITALS',
+            'revision_timestamp': ignored,
+            'state': ignored
+            }
+
+        _, errors = validate(data, default_tags_schema(), context)
+        assert not errors, str(errors)
+
+    def test_6_tag_schema_does_not_allow_commas(self):
+        """Asserts that a tag name cannot contain commas"""
+        context = {'model': model,
+                   'session': model.Session}
+
+        ignored = ""
+        data = {
+            'name': u'eats, shoots, and leaves',
+            'revision_timestamp': ignored,
+            'state': ignored
+            }
+
+        _, errors = validate(data, default_tags_schema(), context)
+        assert errors, pprint(errors)
+        assert 'name' in errors
+        error_message = errors['name'][0]
+        assert data['name'] in error_message
+        assert "must not contain commas" in error_message
+
+



https://bitbucket.org/okfn/ckan/changeset/148ebdda27ba/
changeset:   148ebdda27ba
branch:      feature-1453-flexible-tag-names
user:        Ian Murray
date:        2011-11-09 15:48:48
summary:     [tag-name validation] Small clean-up of the testing code.
affected #:  1 file

diff -r 21139e058f10e7c063cf0f7998f25a7b4fc20607 -r 148ebdda27ba9de2b37406bd4f08df5b6d98275d ckan/tests/lib/test_dictization_schema.py
--- a/ckan/tests/lib/test_dictization_schema.py
+++ b/ckan/tests/lib/test_dictization_schema.py
@@ -19,6 +19,11 @@
 from ckan.lib.navl.dictization_functions import validate
 
 class TestBasicDictize:
+
+    def setup(self):
+        self.context = {'model': model,
+                        'session': model.Session}
+
     @classmethod
     def setup_class(cls):
         CreateTestData.create()
@@ -48,14 +53,11 @@
 
     def test_1_package_schema(self):
 
-        context = {'model': model,
-                   'session': model.Session}
-
         pkg = model.Session.query(model.Package).filter_by(name='annakarenina').first()
 
         package_id = pkg.id
 
-        result = package_dictize(pkg, context)
+        result = package_dictize(pkg, self.context)
 
         self.remove_changable_columns(result)
 
@@ -63,7 +65,7 @@
 
         result['name'] = 'anna2'
 
-        converted_data, errors = validate(result, default_package_schema(), context)
+        converted_data, errors = validate(result, default_package_schema(), self.context)
 
 
         pprint(errors)
@@ -100,7 +102,7 @@
         data["resources"][0]["url"] = 'fsdfafasfsaf'
         data["resources"][1].pop("url") 
 
-        converted_data, errors = validate(data, default_package_schema(), context)
+        converted_data, errors = validate(data, default_package_schema(), self.context)
 
         assert errors == {
             'name': [u'That URL is already in use.'],
@@ -110,14 +112,14 @@
 
         data["id"] = package_id
 
-        converted_data, errors = validate(data, default_package_schema(), context)
+        converted_data, errors = validate(data, default_package_schema(), self.context)
 
         assert errors == {
             #'resources': [{}, {'url': [u'Missing value']}]
         }, pformat(errors)
 
         data['name'] = '????jfaiofjioafjij'
-        converted_data, errors = validate(data, default_package_schema(), context)
+        converted_data, errors = validate(data, default_package_schema(), self.context)
         assert errors == {
             'name': [u'Url must be purely lowercase alphanumeric (ascii) characters and these symbols: -_'],
             #'resources': [{}, {'url': [u'Missing value']}]
@@ -125,14 +127,11 @@
 
     def test_2_group_schema(self):
 
-        context = {'model': model,
-                   'session': model.Session}
-
         group = model.Session.query(model.Group).first()
 
-        data = group_dictize(group, context)
+        data = group_dictize(group, self.context)
 
-        converted_data, errors = validate(data, default_group_schema(), context)
+        converted_data, errors = validate(data, default_group_schema(), self.context)
         group_pack = sorted(group.packages, key=lambda x:x.id)
 
         converted_data["packages"] = sorted(converted_data["packages"], key=lambda x:x["id"])
@@ -156,14 +155,11 @@
         data["packages"][1].pop("id")
         data["packages"][1].pop("name")
 
-        converted_data, errors = validate(data, default_group_schema(), context)
+        converted_data, errors = validate(data, default_group_schema(), self.context)
         assert errors ==  {'packages': [{'id': [u'Dataset was not found.']}, {'id': [u'Missing value']}]} , pformat(errors)
 
     def test_3_tag_schema_allows_spaces(self):
         """Asserts that a tag name with space is valid"""
-        context = {'model': model,
-                   'session': model.Session}
-
         ignored = ""
         data = {
             'name': u'with space',
@@ -171,14 +167,11 @@
             'state': ignored
             }
 
-        _, errors = validate(data, default_tags_schema(), context)
+        _, errors = validate(data, default_tags_schema(), self.context)
         assert not errors, str(errors)
 
     def test_4_tag_schema_allows_punctuation(self):
         """Asserts that a tag name with punctuation (except commas) is valid"""
-        context = {'model': model,
-                   'session': model.Session}
-
         ignored = ""
         data = {
             'name': u'.?!<>\\/"%^&*()-_+=~#\'@`',
@@ -186,14 +179,11 @@
             'state': ignored
             }
 
-        _, errors = validate(data, default_tags_schema(), context)
+        _, errors = validate(data, default_tags_schema(), self.context)
         assert not errors, str(errors)
 
     def test_5_tag_schema_allows_capital_letters(self):
         """Asserts that tag names can have capital letters"""
-        context = {'model': model,
-                   'session': model.Session}
-
         ignored = ""
         data = {
             'name': u'CAPITALS',
@@ -201,14 +191,11 @@
             'state': ignored
             }
 
-        _, errors = validate(data, default_tags_schema(), context)
+        _, errors = validate(data, default_tags_schema(), self.context)
         assert not errors, str(errors)
 
     def test_6_tag_schema_does_not_allow_commas(self):
         """Asserts that a tag name cannot contain commas"""
-        context = {'model': model,
-                   'session': model.Session}
-
         ignored = ""
         data = {
             'name': u'eats, shoots, and leaves',
@@ -216,7 +203,7 @@
             'state': ignored
             }
 
-        _, errors = validate(data, default_tags_schema(), context)
+        _, errors = validate(data, default_tags_schema(), self.context)
         assert errors, pprint(errors)
         assert 'name' in errors
         error_message = errors['name'][0]



https://bitbucket.org/okfn/ckan/changeset/c45496270595/
changeset:   c45496270595
branch:      feature-1453-flexible-tag-names
user:        Ian Murray
date:        2011-11-09 16:01:15
summary:     [model/test_package] Updated TestPackage class to use more flexible tag names

Note - haven't updated the search-related tests yet.  They will come later.
affected #:  1 file

diff -r 148ebdda27ba9de2b37406bd4f08df5b6d98275d -r c4549627059521c496a99f7cff8a8d5c0d486d6b ckan/tests/models/test_package.py
--- a/ckan/tests/models/test_package.py
+++ b/ckan/tests/models/test_package.py
@@ -123,9 +123,9 @@
     def setup_class(self):
         model.repo.init_db()
         rev1 = model.repo.new_revision()
-        self.tagname = u'testtagm2m'
+        self.tagname = u'test tag m2m!'
         self.tagname2 = u'testtagm2m2'
-        self.tagname3 = u'testtag3'
+        self.tagname3 = u'test tag3!'
         self.pkgname = u'testpkgm2m'
         pkg = model.Package(name=self.pkgname)
         self.tag = model.Tag(name=self.tagname)



https://bitbucket.org/okfn/ckan/changeset/6c16baa104f5/
changeset:   6c16baa104f5
branch:      feature-1453-flexible-tag-names
user:        Ian Murray
date:        2011-11-10 10:48:27
summary:     [apitestcase] Ensured correct path generation by the ApiTestCase class

The generated path wasn't urlencoded.

 - reserved characters (bytes) in the url path need to be percent-encoded
 - unicode needs to be encoded to utf-8, with the resulting byte array being
   percent-encoded.

The reason for this change is that flexible tags are allowed the whole range
of unicode characters, and since those names appear in the URI, we need to
ensure that the test client creates those URIs correctly.

Note - there is no problem with handling unicode in URIs in CKAN itself, this
       change is a modification of a tool used by the *tests* in creating a
       URI.
affected #:  1 file

diff -r c4549627059521c496a99f7cff8a8d5c0d486d6b -r 6c16baa104f5646ff37d9c0da9ba594baf794275 ckan/tests/functional/api/base.py
--- a/ckan/tests/functional/api/base.py
+++ b/ckan/tests/functional/api/base.py
@@ -4,6 +4,8 @@
 except ImportError:
     from StringIO import StringIO
 
+import urllib
+
 from pylons import config
 import webhelpers.util
 from nose.tools import assert_equal
@@ -63,11 +65,26 @@
 
     @classmethod
     def offset(self, path):
+        """
+        Returns the full path to the resource identified in path.
+
+        Performs necessary url-encodings, ie:
+
+         - encodes unicode to utf8
+         - urlencodes the resulting byte array
+
+        This process is described in [1], and has also been confirmed by
+        inspecting what a browser does.
+
+        [1] http://www.w3.org/International/articles/idn-and-iri/
+        """
         assert self.api_version != None, "API version is missing."
         base = '/api'
         if self.api_version:
             base += '/' + self.api_version
-        return '%s%s' % (base, path)
+        utf8_encoded = (u'%s%s' % (base, path)).encode('utf8')
+        url_encoded = urllib.quote(utf8_encoded)
+        return url_encoded
 
     def assert_msg_represents_anna(self, msg):
         assert 'annakarenina' in msg, msg



https://bitbucket.org/okfn/ckan/changeset/9170fc511017/
changeset:   9170fc511017
branch:      feature-1453-flexible-tag-names
user:        Ian Murray
date:        2011-11-10 15:07:19
summary:     [test data] Added a new flexible tag to the test data

This commit breaks a bunch of tests, which the following series of
commits will fix.
affected #:  1 file

diff -r 6c16baa104f5646ff37d9c0da9ba594baf794275 -r 9170fc5110171692ee25f302cdd73e2a1fc17771 ckan/lib/create_test_data.py
--- a/ckan/lib/create_test_data.py
+++ b/ckan/lib/create_test_data.py
@@ -363,11 +363,16 @@
         pkg2 = model.Package(name=cls.pkg_names[1])
         tag1 = model.Tag(name=u'russian')
         tag2 = model.Tag(name=u'tolstoy')
-        for obj in [pkg2, tag1, tag2]:
+
+        # Flexible tag, allows spaces, upper-case,
+        # and all punctuation except commas
+        tag3 = model.Tag(name=u'Flexible \u0489!')
+
+        for obj in [pkg2, tag1, tag2, tag3]:
             model.Session.add(obj)
-        pkg1.tags = [tag1, tag2]
-        pkg2.tags = [ tag1 ]
-        cls.tag_names = [u'russian', u'tolstoy']
+        pkg1.tags = [tag1, tag2, tag3]
+        pkg2.tags = [ tag1, tag3 ]
+        cls.tag_names = [ t.name for t in (tag1, tag2, tag3) ]
         pkg1.license_id = u'other-open'
         pkg2.license_id = u'cc-nc' # closed license
         pkg2.title = u'A Wonderful Story'



https://bitbucket.org/okfn/ckan/changeset/b89b496356e0/
changeset:   b89b496356e0
branch:      feature-1453-flexible-tag-names
user:        Ian Murray
date:        2011-11-10 15:13:30
summary:     [api/model/test_tag] Updated test_tag to test flexible tags.
affected #:  3 files

diff -r 9170fc5110171692ee25f302cdd73e2a1fc17771 -r b89b496356e03f9b426ff7305d15b520b0686966 ckan/tests/__init__.py
--- a/ckan/tests/__init__.py
+++ b/ckan/tests/__init__.py
@@ -232,6 +232,10 @@
     def tolstoy(self):
         return self.get_tag_by_name(u'tolstoy')
 
+    @property
+    def flexible_tag(self):
+        return self.get_tag_by_name(u'Flexible \u0489!')
+
 class CheckMethods(BaseCase):
 
     def assert_true(self, value):


diff -r 9170fc5110171692ee25f302cdd73e2a1fc17771 -r b89b496356e03f9b426ff7305d15b520b0686966 ckan/tests/functional/api/base.py
--- a/ckan/tests/functional/api/base.py
+++ b/ckan/tests/functional/api/base.py
@@ -112,6 +112,11 @@
         assert 'ckan_url' in msg
         assert '"ckan_url": "http://test.ckan.net/dataset/annakarenina"' in msg, msg
 
+        assert 'tags' in data, "Expected a tags list in json payload"
+        assert self.russian.name in data['tags'], data['tags']
+        assert self.tolstoy.name in data['tags'], data['tags']
+        assert self.flexible_tag.name in data['tags'], data['tags']
+
     def assert_msg_represents_roger(self, msg):
         assert 'roger' in msg, msg
         data = self.loads(msg)
@@ -134,6 +139,19 @@
         differences = expected_pkgs ^ pkgs
         assert not differences, '%r != %r' % (pkgs, expected_pkgs)
 
+    def assert_msg_represents_flexible_tag(self, msg):
+        """
+        Asserts the correct packages are associated with the flexible tag.
+
+        Namely, 'annakarenina' and 'warandpeace'.
+        """
+        data = self.loads(msg)
+        pkgs = set(data)
+        expected_pkgs = set([self.package_ref_from_name('annakarenina'),
+                             self.package_ref_from_name('warandpeace')])
+        differences = expected_pkgs ^ pkgs
+        assert not differences, '%r != %r' % (pkgs, expected_pkgs)
+
     def data_from_res(self, res):
         return self.loads(res.body)
 


diff -r 9170fc5110171692ee25f302cdd73e2a1fc17771 -r b89b496356e03f9b426ff7305d15b520b0686966 ckan/tests/functional/api/model/test_tag.py
--- a/ckan/tests/functional/api/model/test_tag.py
+++ b/ckan/tests/functional/api/model/test_tag.py
@@ -15,14 +15,27 @@
     def test_register_get_ok(self):
         offset = self.tag_offset()
         res = self.app.get(offset, status=self.STATUS_200_OK)
-        assert self.russian.name in res, res
-        assert self.tolstoy.name in res, res
+        results = self.loads(res.body)
+        assert self.russian.name in results, results
+        assert self.tolstoy.name in results, results
+        assert self.flexible_tag.name in results, results
     
     def test_entity_get_ok(self):
         offset = self.tag_offset(self.russian.name)
         res = self.app.get(offset, status=self.STATUS_200_OK)
         self.assert_msg_represents_russian(msg=res.body)
 
+    def test_entity_get_ok_flexible_tag(self):
+        """
+        Asserts that searching for a tag name with spaces and punctuation works.
+
+        The tag name is u'Flexible \u0489!', and both the 'warandpeace'
+        and 'annakarenina' packages should be returned.
+        """
+        offset = self.tag_offset(self.flexible_tag.name)
+        res = self.app.get(offset, status=self.STATUS_200_OK)
+        self.assert_msg_represents_flexible_tag(msg=res.body)
+
     def test_entity_get_not_found(self):
         offset = self.tag_offset('doesntexist')
         res = self.app.get(offset, status=404)



https://bitbucket.org/okfn/ckan/changeset/40144a62b830/
changeset:   40144a62b830
branch:      feature-1453-flexible-tag-names
user:        Ian Murray
date:        2011-11-10 15:19:31
summary:     [api/model/test_package] Updated some package tests to use flexible tags.

Nothing needed to change in order for them to pass.
affected #:  1 file

diff -r b89b496356e03f9b426ff7305d15b520b0686966 -r 40144a62b830eb9a100cfa4869d8dca91dba8e47 ckan/tests/functional/api/model/test_package.py
--- a/ckan/tests/functional/api/model/test_package.py
+++ b/ckan/tests/functional/api/model/test_package.py
@@ -346,7 +346,7 @@
         old_fixture_data = {
             'name': self.package_fixture_data['name'],
             'url': self.package_fixture_data['url'],
-            'tags': [u'tag1', u'tag2', u'tag3'],
+            'tags': [u'tag 1.1', u'tag2', u'tag3'],
             'extras': {
                 u'key1': u'val1',
                 u'key2': u'val2'
@@ -376,7 +376,7 @@
                 u'key2': None,
                 u'key7': ['a','b'],
              },
-            'tags': [u'tag1', u'tag2', u'tag4', u'tag5'],
+            'tags': [u'tag 1.1', u'tag2', u'tag 4', u'tag5!'],
         }
         self.create_package_roles_revision(old_fixture_data)
         pkg = self.get_package_by_name(old_fixture_data['name'])
@@ -522,11 +522,11 @@
         name = self.package_fixture_data['name']
         old_fixture_data = {
             'name': name,
-            'tags': ['tag1', 'tag2']
+            'tags': ['tag 1!', 'tag2']
         }
         new_fixture_data = {
             'name': name,
-            'tags': ['tag1']
+            'tags': ['tag 1!']
         }
         self.create_package_roles_revision(old_fixture_data)
         offset = self.package_offset(name)
@@ -537,7 +537,7 @@
         # Check the returned package is as expected
         pkg = self.loads(res.body)
         assert_equal(pkg['name'], new_fixture_data['name'])
-        assert_equal(pkg['tags'], ['tag1'])
+        assert_equal(pkg['tags'], ['tag 1!'])
 
         package = self.get_package_by_name(new_fixture_data['name'])
         assert len(package.tags) == 1, package.tags
@@ -547,7 +547,7 @@
         res = self.app.post(offset, params=params, status=self.STATUS_200_OK,
                             extra_environ=self.extra_environ)
         pkg = self.loads(res.body)
-        assert_equal(pkg['tags'], ['tag1', 'tag2'])
+        assert_equal(pkg['tags'], ['tag 1!', 'tag2'])
 
     def test_entity_update_conflict(self):
         package1_name = self.package_fixture_data['name']



https://bitbucket.org/okfn/ckan/changeset/5af74aad266e/
changeset:   5af74aad266e
branch:      feature-1453-flexible-tag-names
user:        Ian Murray
date:        2011-11-10 15:24:30
summary:     [action tests] Updated action tests to take into account more flexible tag names.

This includes one failing test, test_15_tag_autocomplete_search_with_capital_letters.
There's a note about it's failure in the source.
affected #:  1 file

diff -r 40144a62b830eb9a100cfa4869d8dca91dba8e47 -r 5af74aad266e45bf82e1a2fc4e95786c6f8e8da5 ckan/tests/functional/api/test_action.py
--- a/ckan/tests/functional/api/test_action.py
+++ b/ckan/tests/functional/api/test_action.py
@@ -32,7 +32,7 @@
     def teardown_class(self):
         model.repo.rebuild_db()
 
-    def _add_basic_package(self, package_name=u'test_package'):
+    def _add_basic_package(self, package_name=u'test_package', **kwargs):
         package = {
             'name': package_name,
             'title': u'A Novel By Tolstoy',
@@ -42,6 +42,7 @@
                 'url': u'http://www.annakarenina.com/download/'
             }]
         }
+        package.update(kwargs)
 
         postparams = '%s=1' % json.dumps(package)
         res = self.app.post('/api/action/package_create', params=postparams,
@@ -210,25 +211,38 @@
             json.loads(res.body),
             {'help': 'Returns a list of tags',
              'success': True,
-             'result': ['russian', 'tolstoy']})
+             'result': ['russian', 'tolstoy', u'Flexible \u0489!']})
         #Get all fields
         postparams = '%s=1' % json.dumps({'all_fields':True})
         res = self.app.post('/api/action/tag_list', params=postparams)
         res_obj = json.loads(res.body)
         pprint(res_obj)
         assert res_obj['success'] == True
-        if res_obj['result'][0]['name'] == 'russian':
-            russian_index = 0
-            tolstoy_index = 1
-        else:
-            russian_index = 1
-            tolstoy_index = 0
+
+        names = [ res_obj['result'][i]['name'] for i in xrange(len(res_obj['result'])) ]
+        russian_index = names.index('russian')
+        tolstoy_index = names.index('tolstoy')
+        flexible_index = names.index(u'Flexible \u0489!')
+
         assert res_obj['result'][russian_index]['name'] == 'russian'
-        assert len(res_obj['result'][russian_index]['packages']) - \
-               len(res_obj['result'][tolstoy_index]['packages']) == 1
         assert res_obj['result'][tolstoy_index]['name'] == 'tolstoy'
+
+        number_of_russian_packages = len(res_obj['result'][russian_index]['packages'])
+        number_of_tolstoy_packages = len(res_obj['result'][tolstoy_index]['packages'])
+        number_of_flexible_packages = len(res_obj['result'][flexible_index]['packages'])
+        
+        # TODO : This "moo" package appears to have leaked in from other tests.
+        #        Is that meant to be the case? IM
+        assert number_of_russian_packages == 3, \
+               'Expected 2 packages tagged with "russian"' # warandpeace , annakarenina , moo
+        assert number_of_tolstoy_packages == 2, \
+               'Expected 2 packages tagged with "tolstoy"' # moo , annakarenina
+        assert number_of_flexible_packages == 2, \
+               u'Expected 2 packages tagged with "Flexible \u0489!"' # warandpeace , annakarenina
+
         assert 'id' in res_obj['result'][0]
         assert 'id' in res_obj['result'][1]
+        assert 'id' in res_obj['result'][2]
 
     def test_07_tag_show(self):
         postparams = '%s=1' % json.dumps({'id':'russian'})
@@ -242,6 +256,24 @@
         assert 'packages' in result and len(result['packages']) == 3
         assert [package['name'] for package in result['packages']].sort() == ['annakarenina', 'warandpeace', 'moo'].sort()
 
+    def test_07_flexible_tag_show(self):
+        """
+        Asserts that the api can be used to retrieve the details of the flexible tag.
+
+        The flexible tag is the tag with spaces, punctuation and foreign
+        characters in its name, that's created in `ckan/lib/create_test_data.py`.
+        """
+        postparams = '%s=1' % json.dumps({'id':u'Flexible \u0489!'})
+        res = self.app.post('/api/action/tag_show', params=postparams)
+        res_obj = json.loads(res.body)
+        assert res_obj['help'] == 'Shows tag details'
+        assert res_obj['success'] == True
+        result = res_obj['result']
+        assert result['name'] == u'Flexible \u0489!'
+        assert 'id' in result
+        assert 'packages' in result and len(result['packages']) == 2
+        assert [package['name'] for package in result['packages']].sort() == ['annakarenina', 'warandpeace'].sort()
+
     def test_07_tag_show_unknown_license(self):
         # create a tagged package which has an invalid license
         CreateTestData.create_arbitrary([{
@@ -488,6 +520,150 @@
             'success': True
         }
 
+    def test_15_tag_autocomplete_tag_with_spaces(self):
+        """Asserts autocomplete finds tags that contain spaces"""
+
+        CreateTestData.create_arbitrary([{
+            'name': u'package-with-tag-that-has-a-space-1',
+            'tags': [u'with space'],
+            'license': 'never_heard_of_it',
+            }])
+
+        postparams = '%s=1' % json.dumps({'q':'w'})
+        res = self.app.post('/api/action/tag_autocomplete', params=postparams)
+        res_obj = json.loads(res.body)
+        assert res_obj['success']
+        assert 'with space' in res_obj['result'], res_obj['result']
+
+    def test_15_tag_autocomplete_tag_with_foreign_characters(self):
+        """Asserts autocomplete finds tags that contain foreign characters"""
+        
+        CreateTestData.create_arbitrary([{
+            'name': u'package-with-tag-that-has-a-foreign-character-1',
+            'tags': [u'greek beta \u03b2'],
+            'license': 'never_heard_of_it',
+            }])
+
+        postparams = '%s=1' % json.dumps({'q':'greek'})
+        res = self.app.post('/api/action/tag_autocomplete', params=postparams)
+        res_obj = json.loads(res.body)
+        assert res_obj['success']
+        assert u'greek beta \u03b2' in res_obj['result'], res_obj['result']
+
+    def test_15_tag_autocomplete_tag_with_punctuation(self):
+        """Asserts autocomplete finds tags that contain punctuation"""
+        
+        CreateTestData.create_arbitrary([{
+            'name': u'package-with-tag-that-has-a-fullstop-1',
+            'tags': [u'fullstop.'],
+            'license': 'never_heard_of_it',
+            }])
+
+        postparams = '%s=1' % json.dumps({'q':'fullstop'})
+        res = self.app.post('/api/action/tag_autocomplete', params=postparams)
+        res_obj = json.loads(res.body)
+        assert res_obj['success']
+        assert u'fullstop.' in res_obj['result'], res_obj['result']
+
+    def test_15_tag_autocomplete_tag_with_capital_letters(self):
+        """
+        Asserts autocomplete finds tags that contain capital letters
+        
+        Note : the only reason this test passes for now is that the
+               search is for a lower cases substring.  If we had searched
+               for "CAPITAL" then it would fail.  This is because currently
+               the search API lower cases all search terms.  There's a
+               sister test (`test_15_tag_autocomplete_search_with_capital_letters`)
+               that tests that functionality.
+        """
+        
+        CreateTestData.create_arbitrary([{
+            'name': u'package-with-tag-that-has-a-capital-letter-1',
+            'tags': [u'CAPITAL idea old chap'],
+            'license': 'never_heard_of_it',
+            }])
+
+        postparams = '%s=1' % json.dumps({'q':'idea'})
+        res = self.app.post('/api/action/tag_autocomplete', params=postparams)
+        res_obj = json.loads(res.body)
+        assert res_obj['success']
+        assert u'CAPITAL idea old chap' in res_obj['result'], res_obj['result']
+
+    def test_15_tag_autocomplete_search_with_space(self):
+        """
+        Asserts that a search term containing a space works correctly
+        """
+
+        CreateTestData.create_arbitrary([{
+            'name': u'package-with-tag-that-has-a-space-2',
+            'tags': [u'with space'],
+            'license': 'never_heard_of_it',
+            }])
+
+        postparams = '%s=1' % json.dumps({'q':'th sp'})
+        res = self.app.post('/api/action/tag_autocomplete', params=postparams)
+        res_obj = json.loads(res.body)
+        assert res_obj['success']
+        assert 'with space' in res_obj['result'], res_obj['result']
+
+    def test_15_tag_autocomplete_search_with_foreign_character(self):
+        """
+        Asserts that a search term containing a foreign character works correctly
+        """
+
+        CreateTestData.create_arbitrary([{
+            'name': u'package-with-tag-that-has-a-foreign-character-2',
+            'tags': [u'greek beta \u03b2'],
+            'license': 'never_heard_of_it',
+            }])
+
+        postparams = '%s=1' % json.dumps({'q':u'\u03b2'})
+        res = self.app.post('/api/action/tag_autocomplete', params=postparams)
+        res_obj = json.loads(res.body)
+        assert res_obj['success']
+        assert u'greek beta \u03b2' in res_obj['result'], res_obj['result']
+
+    def test_15_tag_autocomplete_search_with_punctuation(self):
+        """
+        Asserts that a search term containing punctuation works correctly
+        """
+
+        CreateTestData.create_arbitrary([{
+            'name': u'package-with-tag-that-has-a-fullstop-2',
+            'tags': [u'fullstop.'],
+            'license': 'never_heard_of_it',
+            }])
+
+        postparams = '%s=1' % json.dumps({'q':u'stop.'})
+        res = self.app.post('/api/action/tag_autocomplete', params=postparams)
+        res_obj = json.loads(res.body)
+        assert res_obj['success']
+        assert 'fullstop.' in res_obj['result'], res_obj['result']
+
+    def test_15_tag_autocomplete_search_with_capital_letters(self):
+        """
+        Asserts that a search term containing capital letters works correctly
+
+        NOTE - this test FAILS.  This is because I haven't implemented the
+               search side of flexible tags yet.
+
+        NOTE - when this test is fixed, remove the NOTE in
+               `test_15_tag_autocomplete_tag_with_capital_letters` that
+               references this one.
+        """
+
+        CreateTestData.create_arbitrary([{
+            'name': u'package-with-tag-that-has-a-capital-letter-2',
+            'tags': [u'CAPITAL idea old chap'],
+            'license': 'never_heard_of_it',
+            }])
+
+        postparams = '%s=1' % json.dumps({'q':u'CAPITAL'})
+        res = self.app.post('/api/action/tag_autocomplete', params=postparams)
+        res_obj = json.loads(res.body)
+        assert res_obj['success']
+        assert 'CAPITAL idea old chap' in res_obj['result'], res_obj['result']
+
     def test_16_user_autocomplete(self):
         #Empty query
         postparams = '%s=1' % json.dumps({})

Repository URL: https://bitbucket.org/okfn/ckan/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.




More information about the ckan-changes mailing list