Skip to content

Commit

Permalink
Test validation activity logging
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-saeon committed Jul 4, 2018
1 parent 44542e8 commit 0ef729f
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 145 deletions.
3 changes: 2 additions & 1 deletion ckanext/metadata/logic/action/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ def metadata_model_create(context, data_dict):
invalidate_context.update({
'defer_commit': True,
'trigger_action': 'metadata_model_create',
'trigger_object': metadata_model,
'trigger_object_id': metadata_model.id,
'trigger_revision_id': rev.id,
})
for metadata_record_id in dependent_record_list:
tk.get_action('metadata_record_invalidate')(invalidate_context, {'id': metadata_record_id})
Expand Down
11 changes: 6 additions & 5 deletions ckanext/metadata/logic/action/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,21 @@ def metadata_model_delete(context, data_dict):

tk.check_access('metadata_model_delete', context, data_dict)

rev = model.repo.new_revision()
rev.author = user
rev.message = _(u'REST API: Delete metadata model %s') % metadata_model_id

dependent_record_list = tk.get_action('metadata_model_dependent_record_list')(context, {'id': metadata_model_id})
invalidate_context = context.copy()
invalidate_context.update({
'defer_commit': True,
'trigger_action': 'metadata_model_delete',
'trigger_object': metadata_model,
'trigger_object_id': metadata_model_id,
'trigger_revision_id': rev.id,
})
for metadata_record_id in dependent_record_list:
tk.get_action('metadata_record_invalidate')(invalidate_context, {'id': metadata_record_id})

rev = model.repo.new_revision()
rev.author = user
rev.message = _(u'REST API: Delete metadata model %s') % metadata_model_id

metadata_model.delete()
if not defer_commit:
model.repo.commit()
Expand Down
3 changes: 1 addition & 2 deletions ckanext/metadata/logic/action/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,7 @@ def metadata_record_validation_activity_show(context, data_dict):
:param id: the id or name of the metadata record
:type id: string
:rtype: dictionary including activity detail list under 'details',
or None if the record has never been validated
:rtype: dictionary, or None if the record has never been validated
"""
log.debug("Retrieving metadata record validation activity: %r", data_dict)

Expand Down
39 changes: 20 additions & 19 deletions ckanext/metadata/logic/action/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,22 +170,23 @@ def metadata_model_update(context, data_dict):
else:
affected_record_ids = set(old_dependent_record_list) ^ set(new_dependent_record_list)

rev = model.repo.new_revision()
rev.author = user
if 'message' in context:
rev.message = context['message']
else:
rev.message = _(u'REST API: Update metadata model %s') % metadata_model_id

invalidate_context = context.copy()
invalidate_context.update({
'defer_commit': True,
'trigger_action': 'metadata_model_update',
'trigger_object': metadata_model,
'trigger_object_id': metadata_model_id,
'trigger_revision_id': rev.id,
})
for metadata_record_id in affected_record_ids:
tk.get_action('metadata_record_invalidate')(invalidate_context, {'id': metadata_record_id})

rev = model.repo.new_revision()
rev.author = user
if 'message' in context:
rev.message = context['message']
else:
rev.message = _(u'REST API: Update metadata model %s') % metadata_model_id

if not defer_commit:
model.repo.commit()

Expand Down Expand Up @@ -394,7 +395,8 @@ def metadata_record_update(context, data_dict):
invalidate_context.update({
'defer_commit': True,
'trigger_action': 'metadata_record_update',
'trigger_object': metadata_record,
'trigger_object_id': metadata_record_id,
'trigger_revision_id': model.Package.get(metadata_record_id).revision_id,
})
tk.get_action('metadata_record_invalidate')(invalidate_context, {'id': metadata_record_id})

Expand All @@ -415,9 +417,10 @@ def metadata_record_invalidate(context, data_dict):
Note: this function is typically called from within another action function
whose effect triggers invalidation of the given metadata record. In such a
case, the calling function should pass 'trigger_action' (its own name, e.g.
'metadata_model_update') and 'trigger_object' (the object being modified,
e.g. a MetadataModel instance) in the context.
case, the calling function should pass the following items in the context:
'trigger_action': the calling function name, e.g. 'metadata_model_update'
'trigger_object_id': the id of the object (e.g. a MetadataModel) being modified
'trigger_revision_id': the id of the revision for this modification
:param id: the id or name of the metadata record to invalidate
:type id: string
Expand Down Expand Up @@ -445,15 +448,14 @@ def metadata_record_invalidate(context, data_dict):
metadata_record.extras['errors'] = '{}'

trigger_action = context.get('trigger_action')
trigger_object = context.get('trigger_object')
trigger_object_id = trigger_object.id if trigger_object else None
trigger_revision_id = trigger_object.revision_id if trigger_object else None
trigger_object_id = context.get('trigger_object_id')
trigger_revision_id = context.get('trigger_revision_id')

activity_context = context.copy()
activity_context.update({
'defer_commit': True,
'schema': {
'user_id': [],
'user_id': [unicode, tk.get_validator('convert_user_name_or_id_to_id')],
'object_id': [],
'revision_id': [],
'activity_type': [],
Expand Down Expand Up @@ -538,7 +540,7 @@ def metadata_record_validate(context, data_dict):
activity_context.update({
'defer_commit': True,
'schema': {
'user_id': [],
'user_id': [unicode, tk.get_validator('convert_user_name_or_id_to_id')],
'object_id': [],
'revision_id': [],
'activity_type': [],
Expand All @@ -551,8 +553,7 @@ def metadata_record_validate(context, data_dict):
'activity_type': METADATA_VALIDATION_ACTIVITY_TYPE,
'data': {
'action': 'metadata_record_validate',
'errors': accumulated_errors,
'details': validation_results,
'results': validation_results,
}
}
tk.get_action('activity_create')(activity_context, activity_dict)
Expand Down
66 changes: 65 additions & 1 deletion ckanext/metadata/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import re
import json
from paste.deploy.converters import asbool
import pkg_resources

from ckan.tests import factories as ckan_factories
from ckan.tests.helpers import FunctionalTestBase, call_action
Expand All @@ -26,6 +27,10 @@
}


def load_example(filename):
return pkg_resources.resource_string(__name__, '../../../examples/' + filename)


def make_uuid():
return unicode(uuid.uuid4())

Expand Down Expand Up @@ -136,7 +141,17 @@ def setup(self):

def _test_action(self, action_name, should_error=False, exception_class=tk.ValidationError,
sysadmin=False, check_auth=False, **kwargs):

"""
Test an API action.
:param action_name: action function name, e.g. 'metadata_record_create'
:param should_error: True if this test should raise an exception, False otherwise
:param exception_class: the type of exception to be expected if should_error is True
:param sysadmin: True to execute the action as a sysadmin, False to run it as a normal user
:param check_auth: True to check whether the user is authorized to perform the action,
False to ignore the auth check
:param kwargs: additional args to pass to the action function
:return: tuple(result dict, result obj)
"""
model, method = action_name.rsplit('_', 1)
user = self.sysadmin_user if sysadmin else self.normal_user
context = {
Expand Down Expand Up @@ -176,3 +191,52 @@ def _test_action(self, action_name, should_error=False, exception_class=tk.Valid
obj = model_class.get(kwargs['id'])

return result, obj

def _assert_validate_activity_logged(self, metadata_record_id, *validation_models, **validation_errors):
"""
:param validation_models: iterable of metadata model dictionaries
:param validation_errors: dictionary mapping metadata model keys to expected error patterns (regex's)
"""
activity_dict = call_action('metadata_record_validation_activity_show', id=metadata_record_id)
assert activity_dict['user_id'] == self.normal_user['id']
assert activity_dict['object_id'] == metadata_record_id
assert activity_dict['activity_type'] == 'metadata validation'
assert activity_dict['data']['action'] == 'metadata_record_validate'
logged_results = activity_dict['data']['results']
assert len(logged_results) == len(validation_models)
logged_errors = {}
for validation_model in validation_models:
logged_result = next((result for result in logged_results
if result['metadata_model_id'] == validation_model['id']), None)
assert logged_result
assert logged_result['metadata_model_revision_id'] == validation_model['revision_id']
logged_errors.update(logged_result['errors'])
assert len(logged_errors) == len(validation_errors)
for error_key, error_pattern in validation_errors.items():
assert_error(logged_errors, error_key, error_pattern)

def _assert_invalidate_activity_logged(self, metadata_record_id, trigger_action, trigger_object):
activity_dict = call_action('metadata_record_validation_activity_show', id=metadata_record_id)
assert activity_dict['user_id'] == self.normal_user['id']
assert activity_dict['object_id'] == metadata_record_id
assert activity_dict['activity_type'] == 'metadata validation'
assert activity_dict['data'] == {
'action': 'metadata_record_invalidate',
'trigger_action': trigger_action,
'trigger_object_id': trigger_object.id if trigger_object else None,
'trigger_revision_id': trigger_object.revision_id if trigger_object else None,
}

def _assert_metadata_record_has_validation_models(self, metadata_record_id, *metadata_model_names):
"""
Check that the given record has the expected set of validation models.
"""
validation_model_list = call_action('metadata_record_validation_model_list', id=metadata_record_id)
assert set(validation_model_list) == set(metadata_model_names)

def _assert_metadata_model_has_dependent_records(self, metadata_model_id, *metadata_record_ids):
"""
Check that the given model has the expected set of dependent records.
"""
dependent_record_list = call_action('metadata_model_dependent_record_list', id=metadata_model_id)
assert set(dependent_record_list) == set(metadata_record_ids)
Loading

0 comments on commit 0ef729f

Please sign in to comment.