PageRenderTime 38ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/ckan/tests/functional/test_tag_vocab.py

https://bitbucket.org/philippkueng/ckan-liip
Python | 225 lines | 182 code | 30 blank | 13 comment | 20 complexity | 3517e8322a9d68e7cb6d61b070a250a5 MD5 | raw file
  1. import json
  2. import paste.fixture
  3. from ckan import model
  4. from ckan.lib.create_test_data import CreateTestData
  5. import ckan.lib.helpers as h
  6. from ckan.tests import WsgiAppCase
  7. # ensure that test_tag_vocab_plugin is added as a plugin in the testing .ini file
  8. from ckanext.test_tag_vocab_plugin import MockVocabTagsPlugin
  9. TEST_VOCAB_NAME = 'test-vocab'
  10. # paste.fixture.Field.Select does not handle multiple selects currently,
  11. # so replace with our own implementations of Form and Select
  12. class Form(paste.fixture.Form):
  13. def __init__(self, response, text):
  14. paste.fixture.Form.__init__(self, response, text)
  15. def submit_fields(self, name=None, index=None):
  16. """
  17. Return a list of ``[(name, value), ...]`` for the current
  18. state of the form.
  19. """
  20. submit = []
  21. if name is not None:
  22. field = self.get(name, index=index)
  23. submit.append((field.name, field.value_if_submitted()))
  24. for name, fields in self.fields.items():
  25. if name is None:
  26. continue
  27. for field in fields:
  28. value = field.value
  29. if value is None:
  30. continue
  31. if isinstance(value, list):
  32. for v in value:
  33. submit.append((name, v))
  34. else:
  35. submit.append((name, value))
  36. return submit
  37. class Select(paste.fixture.Field):
  38. def __init__(self, *args, **attrs):
  39. paste.fixture.Field.__init__(self, *args, **attrs)
  40. self.options = []
  41. self.selectedIndex = None
  42. def value__set(self, value):
  43. if not value:
  44. self.selectedIndex = None
  45. self.options = [(option, False) for (option, checked) in self.options]
  46. return
  47. for v in value:
  48. if not v in [option for (option, checked) in self.options]:
  49. raise ValueError("Option %r not found (from %s)"
  50. % (value, ', '.join(
  51. [repr(o) for o, checked in self.options]))
  52. )
  53. new_options = [(option, True) for (option, checked) in self.options if option in value]
  54. new_options += [(option, False) for (option, checked) in self.options if not option in value]
  55. self.options = new_options
  56. def value__get(self):
  57. return [option for (option, checked) in self.options if checked]
  58. value = property(value__get, value__set)
  59. class TestWUI(WsgiAppCase):
  60. @classmethod
  61. def setup_class(cls):
  62. MockVocabTagsPlugin().set_active(True)
  63. CreateTestData.create(package_type='mock_vocab_tags_plugin')
  64. cls.sysadmin_user = model.User.get('testsysadmin')
  65. cls.dset = model.Package.get('warandpeace')
  66. cls.tag1_name = 'vocab-tag-1'
  67. cls.tag2_name = 'vocab-tag-2'
  68. # use our custom select class for this test suite
  69. cls.old_select = paste.fixture.Field.classes['select']
  70. paste.fixture.Field.classes['select'] = Select
  71. # create a test vocab
  72. params = json.dumps({'name': TEST_VOCAB_NAME})
  73. extra_environ = {'Authorization' : str(cls.sysadmin_user.apikey)}
  74. response = cls.app.post('/api/action/vocabulary_create', params=params,
  75. extra_environ=extra_environ)
  76. assert json.loads(response.body)['success']
  77. vocab_id = json.loads(response.body)['result']['id']
  78. # add tags to the vocab
  79. extra_environ = {'Authorization' : str(cls.sysadmin_user.apikey)}
  80. params = json.dumps({'name': cls.tag1_name, 'vocabulary_id': vocab_id})
  81. response = cls.app.post('/api/action/tag_create', params=params,
  82. extra_environ=extra_environ)
  83. assert json.loads(response.body)['success']
  84. params = json.dumps({'name': cls.tag2_name, 'vocabulary_id': vocab_id})
  85. response = cls.app.post('/api/action/tag_create', params=params,
  86. extra_environ=extra_environ)
  87. assert json.loads(response.body)['success']
  88. @classmethod
  89. def teardown_class(cls):
  90. MockVocabTagsPlugin().set_active(False)
  91. paste.fixture.Field.classes['select'] = cls.old_select
  92. model.repo.rebuild_db()
  93. def _get_vocab_id(self, vocab_name):
  94. params = json.dumps({'id': vocab_name})
  95. response = self.app.post('/api/action/vocabulary_show', params=params)
  96. assert json.loads(response.body)['success']
  97. return json.loads(response.body)['result']['id']
  98. def _add_vocab_tag_to_dataset(self, dataset_id, vocab_id, tag_name):
  99. params = json.dumps({'id': dataset_id})
  100. response = self.app.post('/api/action/package_show', params=params)
  101. dataset = json.loads(response.body)['result']
  102. dataset['tags'] = []
  103. dataset['tags'].append({'name': tag_name, 'vocabulary_id': vocab_id})
  104. params = json.dumps(dataset)
  105. response = self.app.post('/api/action/package_update', params=params,
  106. extra_environ={'Authorization': str(self.sysadmin_user.apikey)})
  107. assert json.loads(response.body)['success']
  108. def _remove_vocab_tags(self, dataset_id, vocab_id, tag_name):
  109. params = json.dumps({'id': dataset_id})
  110. response = self.app.post('/api/action/package_show', params=params)
  111. dataset = json.loads(response.body)['result']
  112. dataset['vocab_tag_selected'] = []
  113. params = json.dumps(dataset)
  114. response = self.app.post('/api/action/package_update', params=params,
  115. extra_environ={'Authorization': str(self.sysadmin_user.apikey)})
  116. assert json.loads(response.body)['success']
  117. def test_01_dataset_view(self):
  118. vocab_id = self._get_vocab_id(TEST_VOCAB_NAME)
  119. self._add_vocab_tag_to_dataset(self.dset.id, vocab_id, self.tag1_name)
  120. response = self.app.get(h.url_for(controller='package', action='read',
  121. id=self.dset.id))
  122. assert self.tag1_name in response.body
  123. self._remove_vocab_tags(self.dset.id, vocab_id, self.tag1_name)
  124. def test_02_dataset_edit_add_vocab_tag(self):
  125. vocab_id = self._get_vocab_id(TEST_VOCAB_NAME)
  126. url = h.url_for(controller='package', action='edit', id=self.dset.id)
  127. response = self.app.get(url)
  128. fv = response.forms['dataset-edit']
  129. fv = Form(fv.response, fv.text)
  130. fv['vocab_tags'] = [self.tag2_name]
  131. response = fv.submit('save')
  132. response = response.follow()
  133. assert not self.tag1_name in response.body
  134. assert self.tag2_name in response.body
  135. self._remove_vocab_tags(self.dset.id, vocab_id, self.tag1_name)
  136. self._remove_vocab_tags(self.dset.id, vocab_id, self.tag2_name)
  137. def test_02_dataset_edit_add_free_and_vocab_tags_then_edit_again(self):
  138. vocab_id = self._get_vocab_id(TEST_VOCAB_NAME)
  139. url = h.url_for(controller='package', action='edit', id=self.dset.id)
  140. response = self.app.get(url)
  141. fv = response.forms['dataset-edit']
  142. fv = Form(fv.response, fv.text)
  143. # Add a free tag with a space in its name.
  144. fv['tag_string'] = 'water quality'
  145. # Add a vocab tag.
  146. fv['vocab_tags'] = [self.tag2_name]
  147. # Save the dataset and visit the page again
  148. response = fv.submit('save')
  149. response = response.follow()
  150. assert not self.tag1_name in response.body
  151. assert self.tag2_name in response.body
  152. url = h.url_for(controller='package', action='edit', id=self.dset.id)
  153. response = self.app.get(url)
  154. fv = response.forms['dataset-edit']
  155. fv = Form(fv.response, fv.text)
  156. assert fv['vocab_tags'].value == [self.tag2_name], fv['vocab_tags'].value
  157. self._remove_vocab_tags(self.dset.id, vocab_id, self.tag2_name)
  158. def test_03_dataset_edit_remove_vocab_tag(self):
  159. vocab_id = self._get_vocab_id(TEST_VOCAB_NAME)
  160. self._add_vocab_tag_to_dataset(self.dset.id, vocab_id, self.tag1_name)
  161. url = h.url_for(controller='package', action='edit', id=self.dset.id)
  162. response = self.app.get(url)
  163. fv = response.forms['dataset-edit']
  164. fv = Form(fv.response, fv.text)
  165. fv['vocab_tags'] = []
  166. response = fv.submit('save')
  167. response = response.follow()
  168. assert not self.tag1_name in response.body
  169. self._remove_vocab_tags(self.dset.id, vocab_id, self.tag1_name)
  170. def test_04_dataset_edit_change_vocab_tag(self):
  171. vocab_id = self._get_vocab_id(TEST_VOCAB_NAME)
  172. self._add_vocab_tag_to_dataset(self.dset.id, vocab_id, self.tag1_name)
  173. url = h.url_for(controller='package', action='edit', id=self.dset.id)
  174. response = self.app.get(url)
  175. fv = response.forms['dataset-edit']
  176. fv = Form(fv.response, fv.text)
  177. fv['vocab_tags'] = [self.tag2_name]
  178. response = fv.submit('save')
  179. response = response.follow()
  180. assert not self.tag1_name in response.body
  181. assert self.tag2_name in response.body
  182. self._remove_vocab_tags(self.dset.id, vocab_id, self.tag2_name)
  183. def test_05_dataset_edit_add_multiple_vocab_tags(self):
  184. vocab_id = self._get_vocab_id(TEST_VOCAB_NAME)
  185. url = h.url_for(controller='package', action='edit', id=self.dset.id)
  186. response = self.app.get(url)
  187. fv = response.forms['dataset-edit']
  188. fv = Form(fv.response, fv.text)
  189. fv['vocab_tags'] = [self.tag1_name, self.tag2_name]
  190. response = fv.submit('save')
  191. response = response.follow()
  192. assert self.tag1_name in response.body
  193. assert self.tag2_name in response.body
  194. self._remove_vocab_tags(self.dset.id, vocab_id, self.tag1_name)
  195. self._remove_vocab_tags(self.dset.id, vocab_id, self.tag2_name)