diff --git a/ckan/logic/converters.py b/ckan/logic/converters.py index 17e355dac10..d8abe86bfc4 100644 --- a/ckan/logic/converters.py +++ b/ckan/logic/converters.py @@ -7,11 +7,18 @@ from ckan.common import _ + def convert_to_extras(key, data, errors, context): - extras = data.get(('extras',), []) - if not extras: - data[('extras',)] = extras - extras.append({'key': key[-1], 'value': data[key]}) + + # Get the current extras index + current_indexes = [k[1] for k in data.keys() + if len(k) > 1 and k[0] == 'extras'] + + new_index = max(current_indexes) + 1 if current_indexes else 0 + + data[('extras', new_index, 'key')] = key[-1] + data[('extras', new_index, 'value')] = data[key] + def convert_from_extras(key, data, errors, context): diff --git a/ckan/new_tests/lib/navl/test_converters.py b/ckan/new_tests/lib/navl/test_converters.py new file mode 100644 index 00000000000..3a137252374 --- /dev/null +++ b/ckan/new_tests/lib/navl/test_converters.py @@ -0,0 +1,98 @@ +import nose + +from ckan import model +import ckan.plugins as p +import ckan.lib.plugins as lib_plugins +from ckan.lib.navl.dictization_functions import validate + + +eq_ = nose.tools.eq_ + + +class TestConvertToExtras(object): + + @classmethod + def setup_class(cls): + p.load('example_idatasetform') + + @classmethod + def teardown_class(cls): + p.unload('example_idatasetform') + + def test_convert_to_extras_field_gets_stored_as_extra(self): + + data_dict = { + 'name': 'test-dataset', + 'custom_text': 'Hi', + } + + context = { + 'model': model, + 'session': model.Session, + } + + package_plugin = lib_plugins.lookup_package_plugin('dataset') + schema = package_plugin.create_package_schema() + + data, errors = validate(data_dict, schema, context) + + assert 'extras' in data + eq_(len(data['extras']), 1) + eq_(data['extras'][0]['key'], 'custom_text') + eq_(data['extras'][0]['value'], 'Hi') + + def test_convert_to_extras_field_can_be_combined_with_a_proper_extra(self): + + data_dict = { + 'name': 'test-dataset', + 'custom_text': 'Hi', + 'extras': [ + {'key': 'proper_extra', 'value': 'Bye'}, + + ] + } + + context = { + 'model': model, + 'session': model.Session, + } + + package_plugin = lib_plugins.lookup_package_plugin('dataset') + schema = package_plugin.create_package_schema() + + data, errors = validate(data_dict, schema, context) + + assert 'extras' in data + eq_(len(data['extras']), 2) + eq_(sorted([e['key'] for e in data['extras']]), + ['custom_text', 'proper_extra']) + eq_(sorted([e['value'] for e in data['extras']]), + ['Bye', 'Hi']) + + def test_convert_to_extras_field_can_be_combined_with_more_extras(self): + + data_dict = { + 'name': 'test-dataset', + 'custom_text': 'Hi', + 'extras': [ + {'key': 'proper_extra', 'value': 'Bye'}, + {'key': 'proper_extra2', 'value': 'Bye2'}, + ] + } + + context = { + 'model': model, + 'session': model.Session, + } + + package_plugin = lib_plugins.lookup_package_plugin('dataset') + schema = package_plugin.create_package_schema() + + data, errors = validate(data_dict, schema, context) + + assert 'extras' in data + eq_(len(data['extras']), 3) + eq_(sorted([e['key'] for e in data['extras']]), + ['custom_text', 'proper_extra', 'proper_extra2']) + eq_(sorted([e['value'] for e in data['extras']]), + ['Bye', 'Bye2', 'Hi'])