From 5c26bdfa74edf316556561b03ae7fab0102d0f6b Mon Sep 17 00:00:00 2001 From: Sean Hammond Date: Wed, 21 Mar 2012 20:48:38 +0000 Subject: [PATCH 1/2] Make test_activity.py faster Only run create_test_data() once in tests/functional/api/test_activity.py, not before each test case. Fix the test cases to work under these conditions. --- ckan/tests/functional/api/test_activity.py | 80 ++++++++++++++-------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/ckan/tests/functional/api/test_activity.py b/ckan/tests/functional/api/test_activity.py index 96500e19250..cc6167530f1 100644 --- a/ckan/tests/functional/api/test_activity.py +++ b/ckan/tests/functional/api/test_activity.py @@ -46,11 +46,14 @@ def make_resource(): 'name': 'example resource', } -def make_package(): +def make_package(name=None): '''Return a test package in dictionary form.''' + if name is None: + name = "test_package" + # A package with no resources, tags, extras or groups. pkg = { - 'name' : 'test_package', + 'name' : name, 'title' : 'My Test Package', 'author' : 'test author', 'author_email' : 'test_author@test_author.com', @@ -88,7 +91,8 @@ def find_new_activities(before, after): class TestActivity: - def setup(self): + @classmethod + def setup_class(self): ckan.tests.CreateTestData.create() self.sysadmin_user = model.User.get('testsysadmin') self.normal_user = model.User.get('annafan') @@ -96,7 +100,8 @@ def setup(self): self.annakarenina = model.Package.get('annakarenina') self.app = paste.fixture.TestApp(pylonsapp) - def teardown(self): + @classmethod + def teardown_class(self): model.repo.rebuild_db() def user_activity_stream(self, user_id): @@ -143,7 +148,7 @@ def record_details(self, user_id, package_id=None, group_id=None): details['time'] = datetime.datetime.now() return details - def _create_package(self, user): + def _create_package(self, user, name=None): if user: user_name = user.name user_id = user.id @@ -160,7 +165,7 @@ def _create_package(self, user): 'user': user_name, 'allow_partial_update': True, } - request_data = make_package() + request_data = make_package(name) package_created = package_create(context, request_data) after = self.record_details(user_id, package_created['id']) @@ -253,7 +258,7 @@ def test_create_package_not_logged_in(self): when a new package is created by a user who is not logged in. """ - self._create_package(user=None) + self._create_package(user=None, name="not_logged_in_test_package") def _add_resource(self, package, user): if user: @@ -388,7 +393,12 @@ def _update_package(self, package, user): # Update the package. context = {'model': model, 'session': model.Session, 'user': user_name, 'allow_partial_update': True} - package_dict = {'id': package.id, 'title': 'edited'} + package_dict = {'id': package.id} + if package.title != 'edited': + package_dict['title'] = 'edited' + else: + assert package.title != 'edited again' + package_dict['title'] = 'edited again' package_update(context, package_dict) after = self.record_details(user_id, package.id) @@ -441,7 +451,7 @@ def _update_package(self, package, user): assert detail['activity_type'] == "changed", ( str(detail['activity_type'])) - def test_update_package(self): + def test_01_update_package(self): """ Test updated package activity stream. @@ -452,7 +462,7 @@ def test_update_package(self): for package in model.Session.query(model.Package).all(): self._update_package(package, user=self.normal_user) - def test_update_package_not_logged_in(self): + def test_01_update_package_not_logged_in(self): """ Test updated package activity stream when not logged in. @@ -539,7 +549,7 @@ def _update_resource(self, package, resource, user): assert detail['activity_type'] == "changed", ( str(detail['activity_type'])) - def test_update_resource(self): + def test_01_update_resource(self): """ Test that a correct activity stream item and detail item are emitted when a resource is updated. @@ -553,7 +563,7 @@ def test_update_resource(self): for resource in pkg.resources: self._update_resource(pkg, resource, user=self.normal_user) - def test_update_resource_not_logged_in(self): + def test_01_update_resource_not_logged_in(self): """ Test that a correct activity stream item and detail item are emitted when a resource is updated by a user who is not logged in. @@ -573,7 +583,7 @@ def _delete_package(self, package): item and detail are emitted. """ - before = self.record_details(self.normal_user.id, package.id) + before = self.record_details(self.sysadmin_user.id, package.id) # Query for the package object again, as the session that it belongs to # may have been closed. @@ -581,11 +591,11 @@ def _delete_package(self, package): # Delete the package. context = {'model': model, 'session': model.Session, - 'user': self.normal_user.name} + 'user': self.sysadmin_user.name} package_dict = {'id':package.id} package_delete(context, package_dict) - after = self.record_details(self.normal_user.id, package.id) + after = self.record_details(self.sysadmin_user.id, package.id) # Find the new activity in the user's activity stream. user_new_activities = (find_new_activities( @@ -611,7 +621,7 @@ def _delete_package(self, package): # Check that the new activity has the right attributes. assert activity['object_id'] == package.id, ( str(activity['object_id'])) - assert activity['user_id'] == self.normal_user.id, ( + assert activity['user_id'] == self.sysadmin_user.id, ( str(activity['user_id'])) assert activity['activity_type'] == 'deleted package', ( str(activity['activity_type'])) @@ -727,7 +737,7 @@ def _delete_resources(self, package): assert detail['activity_type'] == "deleted", ( str(detail['activity_type'])) - def test_delete_resources(self): + def test_01_delete_resources(self): """ Test deleted resource activity stream. @@ -809,7 +819,9 @@ def _update_user(self, user): 'allow_partial_update': True} user_dict = {'id': user.id} user_dict['about'] = 'edited' - if not user.email: + if user.email: + user_dict['email'] = user.email + else: user_dict['email'] = 'there has to be a value in email or validate fails' user_update(context, user_dict) @@ -926,7 +938,7 @@ def _update_group(self, group, user): assert timestamp >= before['time'] and timestamp <= after['time'], \ str(activity['timestamp']) - def test_update_group(self): + def test_01_update_group(self): """ Test updated group activity stream. @@ -1005,6 +1017,7 @@ def test_add_tag(self): 'model': model, 'session': model.Session, 'user': user.name, + 'allow_partial_update': True } pkg_dict = ckan.logic.action.get.package_show(context, {'id': pkg_name}) @@ -1068,7 +1081,7 @@ def test_add_tag(self): assert detail['activity_type'] == "added", ( str(detail['activity_type'])) - def test_remove_tag(self): + def test_01_remove_tag(self): """ Test remove tag activity. @@ -1520,7 +1533,9 @@ def test_activity_create_activity_type_not_exists(self): u"Not found: Activity type"], ( response.json['error'][u'activity_type']) - def _add_extra(self, package_dict, user): + def _add_extra(self, package_dict, user, key=None): + if key is None: + key = 'quality' if user: user_name = user.name user_id = user.id @@ -1538,10 +1553,10 @@ def _add_extra(self, package_dict, user): 'session': model.Session, 'user': user_name, 'allow_partial_update': True, - 'extras_as_string': True + 'extras_as_string': True, } extras = list(extras_before) - extras.append({'key': 'quality', 'value': '10000'}) + extras.append({'key': key, 'value': '10000'}) request_data = { 'id': package_dict['id'], 'extras': extras @@ -1642,7 +1657,7 @@ def test_add_extras_not_logged_in(self): } for package_name in package_list(context, {}): package_dict = package_show(context, {'id': package_name}) - self._add_extra(package_dict, None) + self._add_extra(package_dict, None, key='not_logged_in_extra_key') def _update_extra(self, package_dict, user): if user: @@ -1667,7 +1682,11 @@ def _update_extra(self, package_dict, user): 'extras_as_string': True } extras = list(extras_before) - extras[0]['value'] = 'edited' + if extras[0]['value'] != 'edited': + extras[0]['value'] = 'edited' + else: + assert extras[0]['value'] != 'edited again' + extras[0]['value'] = 'edited again' request_data = { 'id': package_dict['id'], 'extras': extras @@ -1734,7 +1753,7 @@ def _update_extra(self, package_dict, user): assert detail['activity_type'] == "changed", ( str(detail['activity_type'])) - def test_update_extras(self): + def test_01_update_extras(self): """ Test changed package extra activity stream. @@ -1758,7 +1777,7 @@ def test_update_extras(self): for package_dict in packages_with_extras: self._update_extra(package_dict, user=self.normal_user) - def test_update_extras_not_logged_in(self): + def test_01_update_extras_not_logged_in(self): """ Test changed package extra activity stream when no user logged in. @@ -1801,14 +1820,15 @@ def _delete_extra(self, package_dict, user): 'model': model, 'session': model.Session, 'user': user_name, - 'allow_partial_update': True, - 'extras_as_string': True + 'extras_as_string': True, } extras = list(extras_before) del extras[0] request_data = { 'id': package_dict['id'], - 'extras': extras + 'extras': extras, + 'tags': package_dict['tags'], + 'resources': package_dict['resources'] } updated_package = package_update(context, request_data) From 0b8beb73e3ea6189c39e8663c128c3ab78317dec Mon Sep 17 00:00:00 2001 From: Sean Hammond Date: Wed, 21 Mar 2012 21:02:48 +0000 Subject: [PATCH 2/2] Reorder methods in test_activity.py Put them in a more logical order --- ckan/tests/functional/api/test_activity.py | 1882 ++++++++++---------- 1 file changed, 941 insertions(+), 941 deletions(-) diff --git a/ckan/tests/functional/api/test_activity.py b/ckan/tests/functional/api/test_activity.py index cc6167530f1..64ff6a2f743 100644 --- a/ckan/tests/functional/api/test_activity.py +++ b/ckan/tests/functional/api/test_activity.py @@ -240,26 +240,6 @@ def _create_package(self, user, name=None): assert detail['object_type'] == "tag", ( str(detail['object_type'])) - def test_create_package(self): - """ - Test new package activity stream. - - Test that correct activity stream item and detail items are emitted - when a new package is created. - - """ - self._create_package(user=self.normal_user) - - def test_create_package_not_logged_in(self): - """ - Test new package activity stream when not logged in. - - Test that correct activity stream item and detail items are emitted - when a new package is created by a user who is not logged in. - - """ - self._create_package(user=None, name="not_logged_in_test_package") - def _add_resource(self, package, user): if user: user_name = user.name @@ -349,34 +329,7 @@ def _add_resource(self, package, user): assert detail['activity_type'] == "new", ( str(detail['activity_type'])) - def test_add_resources(self): - """ - Test new resource activity stream. - - Test that correct activity stream item and detail items are emitted - when a resource is added to a package. - - """ - for package in model.Session.query(model.Package).all(): - self._add_resource(package, user=self.normal_user) - - def test_add_resources_not_logged_in(self): - """ - Test new resource activity stream when no user logged in. - - Test that correct activity stream item and detail items are emitted - when a resource is added to a package by a user who is not logged in. - - """ - for package in model.Session.query(model.Package).all(): - self._add_resource(package, user=None) - - def _update_package(self, package, user): - """ - Update the given package and test that the correct activity stream - item and detail are emitted. - - """ + def _delete_extra(self, package_dict, user): if user: user_name = user.name user_id = user.id @@ -384,24 +337,33 @@ def _update_package(self, package, user): user_name = '127.0.0.1' user_id = 'not logged in' - before = self.record_details(user_id, package.id) + before = self.record_details(user_id, package_dict['id']) - # Query for the package object again, as the session that it belongs to - # may have been closed. - package = model.Session.query(model.Package).get(package.id) + extras_before = package_dict['extras'] + assert len(extras_before) > 0, ( + "Can't update an extra if the package doesn't have any") - # Update the package. - context = {'model': model, 'session': model.Session, 'user': user_name, - 'allow_partial_update': True} - package_dict = {'id': package.id} - if package.title != 'edited': - package_dict['title'] = 'edited' - else: - assert package.title != 'edited again' - package_dict['title'] = 'edited again' - package_update(context, package_dict) + # Update the package's first extra. + context = { + 'model': model, + 'session': model.Session, + 'user': user_name, + 'extras_as_string': True, + } + extras = list(extras_before) + del extras[0] + request_data = { + 'id': package_dict['id'], + 'extras': extras, + 'tags': package_dict['tags'], + 'resources': package_dict['resources'] + } + updated_package = package_update(context, request_data) - after = self.record_details(user_id, package.id) + after = self.record_details(user_id, package_dict['id']) + extras_after = updated_package['extras'] + assert len(extras_after) == len(extras_before) - 1, ( + "%s != %s" % (len(extras_after), len(extras_before) - 1)) # Find the new activity in the user's activity stream. user_new_activities = (find_new_activities( @@ -425,60 +387,40 @@ def _update_package(self, package, user): == user_new_activities # Check that the new activity has the right attributes. - assert activity['object_id'] == package.id, ( - str(activity['object_id'])) + assert activity['object_id'] == updated_package['id'], \ + str(activity['object_id']) assert activity['user_id'] == user_id, str(activity['user_id']) - assert activity['activity_type'] == 'changed package', ( - str(activity['activity_type'])) + assert activity['activity_type'] == 'changed package', \ + str(activity['activity_type']) if not activity.has_key('id'): - assert False, "activity object has no id value" + assert False, "activity object should have an id value" # TODO: Test for the _correct_ revision_id value. if not activity.has_key('revision_id'): - assert False, "activity has no revision_id value" + assert False, "activity object should have a revision_id value" timestamp = datetime_from_string(activity['timestamp']) assert (timestamp >= before['time'] and timestamp <= after['time']), str(activity['timestamp']) # Test for the presence of a correct activity detail item. details = self.activity_details(activity) - assert len(details) == 1 + assert len(details) == 1, ( + "There should be 1 activity detail but found %s" + % len(details)) detail = details[0] assert detail['activity_id'] == activity['id'], \ str(detail['activity_id']) - assert detail['object_id'] == package.id, str(detail['object_id']) - assert detail['object_type'] == "Package", ( + deleted_extras = [extra for extra in extras_before if extra not in + extras_after] + assert len(deleted_extras) == 1, "%s != 1" % len(deleted_extras) + deleted_extra = deleted_extras[0] + assert detail['object_id'] == deleted_extra['id'], ( + str(detail['object_id'])) + assert detail['object_type'] == "PackageExtra", ( str(detail['object_type'])) - assert detail['activity_type'] == "changed", ( + assert detail['activity_type'] == "deleted", ( str(detail['activity_type'])) - def test_01_update_package(self): - """ - Test updated package activity stream. - - Test that correct activity stream item and detail items are created - when packages are updated. - - """ - for package in model.Session.query(model.Package).all(): - self._update_package(package, user=self.normal_user) - - def test_01_update_package_not_logged_in(self): - """ - Test updated package activity stream when not logged in. - - Test that correct activity stream item and detail items are created - when packages are updated by a user who is not logged in. - - """ - for package in model.Session.query(model.Package).all(): - self._update_package(package, user=None) - - def _update_resource(self, package, resource, user): - """ - Update the given resource and test that the correct activity stream - item and detail are emitted. - - """ + def _update_extra(self, package_dict, user): if user: user_name = user.name user_id = user.id @@ -486,20 +428,36 @@ def _update_resource(self, package, resource, user): user_name = '127.0.0.1' user_id = 'not logged in' - before = self.record_details(user_id, package.id) + before = self.record_details(user_id, package_dict['id']) - # Query for the Package and Resource objects again, as the session that - # they belong to may have been closed. - package = model.Session.query(model.Package).get(package.id) - resource = model.Session.query(model.Resource).get(resource.id) + extras_before = package_dict['extras'] + assert len(extras_before) > 0, ( + "Can't update an extra if the package doesn't have any") - # Update the resource. - context = {'model': model, 'session': model.Session, 'user': user_name, - 'allow_partial_update': True} - resource_dict = {'id':resource.id, 'name':'edited'} - resource_update(context, resource_dict) + # Update the package's first extra. + context = { + 'model': model, + 'session': model.Session, + 'user': user_name, + 'allow_partial_update': True, + 'extras_as_string': True + } + extras = list(extras_before) + if extras[0]['value'] != 'edited': + extras[0]['value'] = 'edited' + else: + assert extras[0]['value'] != 'edited again' + extras[0]['value'] = 'edited again' + request_data = { + 'id': package_dict['id'], + 'extras': extras + } + updated_package = package_update(context, request_data) - after = self.record_details(user_id, package.id) + after = self.record_details(user_id, package_dict['id']) + extras_after = updated_package['extras'] + assert len(extras_after) == len(extras_before), ( + "%s != %s" % (len(extras_after), len(extras_before))) # Find the new activity in the user's activity stream. user_new_activities = (find_new_activities( @@ -523,79 +481,73 @@ def _update_resource(self, package, resource, user): == user_new_activities # Check that the new activity has the right attributes. - assert activity['object_id'] == package.id, ( - str(activity['object_id'])) + assert activity['object_id'] == updated_package['id'], \ + str(activity['object_id']) assert activity['user_id'] == user_id, str(activity['user_id']) - assert activity['activity_type'] == 'changed package', ( - str(activity['activity_type'])) - if not activity['id']: - assert False, "activity object has no id value" + assert activity['activity_type'] == 'changed package', \ + str(activity['activity_type']) + if not activity.has_key('id'): + assert False, "activity object should have an id value" # TODO: Test for the _correct_ revision_id value. - if not activity['revision_id']: - assert False, "activity has no revision_id value" + if not activity.has_key('revision_id'): + assert False, "activity object should have a revision_id value" timestamp = datetime_from_string(activity['timestamp']) assert (timestamp >= before['time'] and timestamp <= after['time']), str(activity['timestamp']) # Test for the presence of a correct activity detail item. details = self.activity_details(activity) - assert len(details) == 1 + assert len(details) == 1, ( + "There should be 1 activity detail but found %s" + % len(details)) detail = details[0] - assert detail['activity_id'] == activity['id'], ( - str(detail['activity_id'])) - assert detail['object_id'] == resource.id, str(detail['object_id']) - assert detail['object_type'] == "Resource", ( + assert detail['activity_id'] == activity['id'], \ + str(detail['activity_id']) + new_extras = [extra for extra in extras_after if extra not in + extras_before] + assert len(new_extras) == 1, "%s != 1" % len(new_extras) + new_extra = new_extras[0] + assert detail['object_id'] == new_extra['id'], ( + str(detail['object_id'])) + assert detail['object_type'] == "PackageExtra", ( str(detail['object_type'])) assert detail['activity_type'] == "changed", ( str(detail['activity_type'])) - def test_01_update_resource(self): - """ - Test that a correct activity stream item and detail item are emitted - when a resource is updated. - - """ - packages = model.Session.query(model.Package).all() - for package in packages: - # Query the model for the Package object again, as the session that - # it belongs to may have been closed. - pkg = model.Session.query(model.Package).get(package.id) - for resource in pkg.resources: - self._update_resource(pkg, resource, user=self.normal_user) - - def test_01_update_resource_not_logged_in(self): - """ - Test that a correct activity stream item and detail item are emitted - when a resource is updated by a user who is not logged in. + def _add_extra(self, package_dict, user, key=None): + if key is None: + key = 'quality' + if user: + user_name = user.name + user_id = user.id + else: + user_name = '127.0.0.1' + user_id = 'not logged in' - """ - packages = model.Session.query(model.Package).all() - for package in packages: - # Query the model for the Package object again, as the session that - # it belongs to may have been closed. - pkg = model.Session.query(model.Package).get(package.id) - for resource in pkg.resources: - self._update_resource(pkg, resource, user=None) + before = self.record_details(user_id, package_dict['id']) - def _delete_package(self, package): - """ - Delete the given package and test that the correct activity stream - item and detail are emitted. + extras_before = package_dict['extras'] - """ - before = self.record_details(self.sysadmin_user.id, package.id) - - # Query for the package object again, as the session that it belongs to - # may have been closed. - package = model.Session.query(model.Package).get(package.id) - - # Delete the package. - context = {'model': model, 'session': model.Session, - 'user': self.sysadmin_user.name} - package_dict = {'id':package.id} - package_delete(context, package_dict) + # Create a new extra. + context = { + 'model': model, + 'session': model.Session, + 'user': user_name, + 'allow_partial_update': True, + 'extras_as_string': True, + } + extras = list(extras_before) + extras.append({'key': key, 'value': '10000'}) + request_data = { + 'id': package_dict['id'], + 'extras': extras + } + updated_package = package_update(context, request_data) - after = self.record_details(self.sysadmin_user.id, package.id) + after = self.record_details(user_id, package_dict['id']) + extras_after = updated_package['extras'] + assert len(extras_after) == len(extras_before) + 1, ( + "%s != %s" % (len(extras_after), len(extras_before) + 1)) # Find the new activity in the user's activity stream. user_new_activities = (find_new_activities( @@ -605,7 +557,7 @@ def _delete_package(self, package): len(user_new_activities)) activity = user_new_activities[0] - # The same new activity should appear in the package's stream. + # The same new activity should appear in the package's activity stream. pkg_new_activities = (find_new_activities( before['package activity stream'], after['package activity stream'])) @@ -619,72 +571,48 @@ def _delete_package(self, package): == user_new_activities # Check that the new activity has the right attributes. - assert activity['object_id'] == package.id, ( - str(activity['object_id'])) - assert activity['user_id'] == self.sysadmin_user.id, ( - str(activity['user_id'])) - assert activity['activity_type'] == 'deleted package', ( - str(activity['activity_type'])) + assert activity['object_id'] == updated_package['id'], \ + str(activity['object_id']) + assert activity['user_id'] == user_id, str(activity['user_id']) + assert activity['activity_type'] == 'changed package', \ + str(activity['activity_type']) if not activity.has_key('id'): - assert False, "activity object has no id value" + assert False, "activity object should have an id value" # TODO: Test for the _correct_ revision_id value. if not activity.has_key('revision_id'): - assert False, "activity has no revision_id value" + assert False, "activity object should have a revision_id value" timestamp = datetime_from_string(activity['timestamp']) assert (timestamp >= before['time'] and timestamp <= after['time']), str(activity['timestamp']) # Test for the presence of a correct activity detail item. details = self.activity_details(activity) - assert len(details) == 1 - detail = details[0] + assert len(details) == 1, ( + "There should be 1 activity detail but found %s" + % len(details)) + detail = details[0] assert detail['activity_id'] == activity['id'], \ str(detail['activity_id']) - assert detail['object_id'] == package.id, str(detail['object_id']) - assert detail['object_type'] == "Package", ( + new_extras = [extra for extra in extras_after if extra not in + extras_before] + assert len(new_extras) == 1, "%s != 1" % len(new_extras) + new_extra = new_extras[0] + assert detail['object_id'] == new_extra['id'], ( + str(detail['object_id'])) + assert detail['object_type'] == "PackageExtra", ( str(detail['object_type'])) - assert detail['activity_type'] == "deleted", ( + assert detail['activity_type'] == "new", ( str(detail['activity_type'])) - def test_delete_package(self): - """ - Test deleted package activity stream. - - Test that correct activity stream item and detail items are created - when packages are deleted. - - """ - for package in model.Session.query(model.Package).all(): - self._delete_package(package) - - def _delete_resources(self, package): - """ - Remove all resources (if any) from the given package, and test that - correct activity item and detail items are emitted. - - """ - before = self.record_details(self.normal_user.id, package.id) - - # Query the model for the Package object again, as the session that it - # belongs to may have been closed. - package = model.Session.query(model.Package).get(package.id) - num_resources = len(package.resources) - assert num_resources > 0, \ - "Cannot delete resources if there aren't any." - resource_ids = [resource.id for resource in package.resources] + def _create_activity(self, user, package, params): + before = self.record_details(user.id, package.id) - # Delete the resources. - context = { - 'model': model, - 'session': model.Session, - 'user':self.normal_user.name, - } - from ckan.lib.dictization.model_dictize import package_dictize - data_dict = package_dictize(package, context) - data_dict['resources'] = [] - package_update(context, data_dict) + response = self.app.post('/api/action/activity_create', + params=json.dumps(params), + extra_environ={'Authorization': str(self.sysadmin_user.apikey)}) + assert response.json['success'] == True - after = self.record_details(self.normal_user.id, package.id) + after = self.record_details(user.id, package.id) # Find the new activity in the user's activity stream. user_new_activities = (find_new_activities( @@ -700,19 +628,12 @@ def _delete_resources(self, package): after['package activity stream'])) assert pkg_new_activities == user_new_activities - # The same new activity should appear in the recently changed datasets - # stream. - assert find_new_activities( - before['recently changed datasets stream'], - after['recently changed datasets stream']) \ - == user_new_activities - # Check that the new activity has the right attributes. - assert activity['object_id'] == package.id, ( + assert activity['object_id'] == params['object_id'], ( str(activity['object_id'])) - assert activity['user_id'] == self.normal_user.id, ( + assert activity['user_id'] == params['user_id'], ( str(activity['user_id'])) - assert activity['activity_type'] == 'changed package', ( + assert activity['activity_type'] == params['activity_type'], ( str(activity['activity_type'])) if not activity.has_key('id'): assert False, "activity object has no id value" @@ -720,88 +641,91 @@ def _delete_resources(self, package): if not activity.has_key('revision_id'): assert False, "activity has no revision_id value" timestamp = datetime_from_string(activity['timestamp']) - assert timestamp >= before['time'], str(activity['timestamp']) - assert timestamp <= after['time'], str(activity['timestamp']) + assert (timestamp >= before['time'] and + timestamp <= after['time']), str(activity['timestamp']) - # Test for the presence of correct activity detail items. - details = self.activity_details(activity) - assert len(details) == num_resources - for detail in details: - assert detail['activity_id'] == activity['id'], ( - "activity_id should be %s but is %s" - % (activity['id'], detail['activity_id'])) - assert detail['object_id'] in resource_ids, ( - str(detail['object_id'])) - assert detail['object_type'] == "Resource", ( - str(detail['object_type'])) - assert detail['activity_type'] == "deleted", ( - str(detail['activity_type'])) + def _delete_group(self, group, user): + """ + Delete the given group and test that the correct activity stream + item and detail are emitted. - def test_01_delete_resources(self): """ - Test deleted resource activity stream. + before = self.record_details(user.id, group_id=group.id) - Test that correct activity stream item and detail items are created - when resources are deleted from packages. + # Deleted the group. + context = {'model': model, 'session': model.Session, 'api_version':3, + 'user': user.name, 'allow_partial_update': True} + group_dict = {'id': group.id, 'state': 'deleted'} + group_update(context, group_dict) - """ - packages_with_resources = [] - for package in model.Session.query(model.Package).all(): - # Query for the package object again, as the session that it - # belongs to may have been closed. - package = model.Session.query(model.Package).get(package.id) - if len(package.resources) > 0: - packages_with_resources.append(package) - assert len(packages_with_resources) > 0, \ - "Need some packages with resources to test deleting resources." - for package in packages_with_resources: - self._delete_resources(package) + after = self.record_details(user.id, group_id=group.id) - def test_create_user(self): - """ - Test new user activity stream. + # Find the new activity. + new_activities = find_new_activities(before['user activity stream'], + after['user activity stream']) + assert len(new_activities) == 1, ("There should be 1 new activity in " + "the user's activity stream, but found %i" % len(new_activities)) + activity = new_activities[0] - Test that correct activity stream item and detail item are created when - a new user is created. + assert find_new_activities(before["group activity stream"], + after['group activity stream']) == new_activities, ("The same " + "activity should also appear in the group's activity stream.") + + # Check that the new activity has the right attributes. + assert activity['object_id'] == group.id, str(activity['object_id']) + assert activity['user_id'] == user.id, str(activity['user_id']) + assert activity['activity_type'] == 'deleted group', \ + str(activity['activity_type']) + if not activity.has_key('id'): + assert False, "activity object has no id value" + # TODO: Test for the _correct_ revision_id value. + if not activity.has_key('revision_id'): + assert False, "activity has no revision_id value" + timestamp = datetime_from_string(activity['timestamp']) + assert timestamp >= before['time'] and timestamp <= after['time'], \ + str(activity['timestamp']) + def _update_group(self, group, user): """ - before = datetime.datetime.now() + Update the given group and test that the correct activity stream + item and detail are emitted. - # Create a new user. - user_dict = {'name': 'testuser', - 'about': 'Just a test user', 'email': 'me@test.org', - 'password': 'testpass'} - context = {'model': model, 'session': model.Session, - 'user': self.sysadmin_user.name} - user_created = user_create(context, user_dict) + """ + before = self.record_details(user.id, group_id=group.id) - after = self.record_details(user_created['id']) + # Update the group. + context = {'model': model, 'session': model.Session, 'user': user.name, + 'allow_partial_update': True, 'api_version':3} + group_dict = {'id': group.id, 'title': 'edited'} + group_updated = group_update(context, group_dict) - user_activities = after['user activity stream'] - assert len(user_activities) == 1, ("There should be 1 activity in " - "the user's activity stream, but found %i" % len(user_activities)) - activity = user_activities[0] + after = self.record_details(user.id, group_id=group.id) + + # Find the new activity. + new_activities = find_new_activities(before['user activity stream'], + after['user activity stream']) + assert len(new_activities) == 1, ("There should be 1 new activity in " + "the user's activity stream, but found %i" % len(new_activities)) + activity = new_activities[0] + + assert find_new_activities(before["group activity stream"], + after['group activity stream']) == new_activities, ("The same " + "activity should also appear in the group's activity stream.") # Check that the new activity has the right attributes. - assert activity['object_id'] == user_created['id'], \ - str(activity['object_id']) - assert activity['user_id'] == user_created['id'], \ - str(activity['user_id']) - assert activity['activity_type'] == 'new user', \ + assert activity['object_id'] == group.id, str(activity['object_id']) + assert activity['user_id'] == user.id, str(activity['user_id']) + assert activity['activity_type'] == 'changed group', \ str(activity['activity_type']) if not activity.has_key('id'): - assert False, "activity object should have an id value" + assert False, "activity object has no id value" # TODO: Test for the _correct_ revision_id value. if not activity.has_key('revision_id'): - assert False, "activity object should have a revision_id value" + assert False, "activity has no revision_id value" timestamp = datetime_from_string(activity['timestamp']) - assert timestamp >= before and timestamp <= after['time'], \ + assert timestamp >= before['time'] and timestamp <= after['time'], \ str(activity['timestamp']) - details = self.activity_details(activity) - assert len(details) == 0, ("There shouldn't be any activity details" - " for a 'new user' activity") - def _update_user(self, user): """ Update the given user and test that the correct activity stream item @@ -848,191 +772,117 @@ def _update_user(self, user): assert timestamp >= before['time'] and timestamp <= after['time'], \ str(activity['timestamp']) - def test_update_user(self): + def _delete_resources(self, package): """ - Test updated user activity stream. - - Test that correct activity stream item is created when users are - updated. + Remove all resources (if any) from the given package, and test that + correct activity item and detail items are emitted. """ - for user in model.Session.query(model.User).all(): - self._update_user(user) - - def test_create_group(self): - - user = self.normal_user - - before = self.record_details(user.id) - - # Create a new group. - context = {'model': model, 'session': model.Session, 'user': user.name} - request_data = {'name': 'a-new-group', 'title': 'A New Group'} - group_created = group_create(context, request_data) - - after = self.record_details(user.id, group_id=group_created['id']) - - # Find the new activity. - new_activities = find_new_activities(before['user activity stream'], - after['user activity stream']) - assert len(new_activities) == 1, ("There should be 1 new activity in " - "the user's activity stream, but found %i" % len(new_activities)) - activity = new_activities[0] - - assert after['group activity stream'] == new_activities, ("The same " - "activity should also appear in the group's activity stream.") - - # Check that the new activity has the right attributes. - assert activity['object_id'] == group_created['id'], \ - str(activity['object_id']) - assert activity['user_id'] == user.id, str(activity['user_id']) - assert activity['activity_type'] == 'new group', \ - str(activity['activity_type']) - if not activity.has_key('id'): - assert False, "activity object should have an id value" - # TODO: Test for the _correct_ revision_id value. - if not activity.has_key('revision_id'): - assert False, "activity object should have a revision_id value" - timestamp = datetime_from_string(activity['timestamp']) - assert timestamp >= before['time'] and timestamp <= after['time'], \ - str(activity['timestamp']) + before = self.record_details(self.normal_user.id, package.id) - def _update_group(self, group, user): - """ - Update the given group and test that the correct activity stream - item and detail are emitted. + # Query the model for the Package object again, as the session that it + # belongs to may have been closed. + package = model.Session.query(model.Package).get(package.id) + num_resources = len(package.resources) + assert num_resources > 0, \ + "Cannot delete resources if there aren't any." + resource_ids = [resource.id for resource in package.resources] - """ - before = self.record_details(user.id, group_id=group.id) + # Delete the resources. + context = { + 'model': model, + 'session': model.Session, + 'user':self.normal_user.name, + } + from ckan.lib.dictization.model_dictize import package_dictize + data_dict = package_dictize(package, context) + data_dict['resources'] = [] + package_update(context, data_dict) - # Update the group. - context = {'model': model, 'session': model.Session, 'user': user.name, - 'allow_partial_update': True, 'api_version':3} - group_dict = {'id': group.id, 'title': 'edited'} - group_updated = group_update(context, group_dict) + after = self.record_details(self.normal_user.id, package.id) - after = self.record_details(user.id, group_id=group.id) + # Find the new activity in the user's activity stream. + user_new_activities = (find_new_activities( + before['user activity stream'], after['user activity stream'])) + assert len(user_new_activities) == 1, ("There should be 1 new " + " activity in the user's activity stream, but found %i" % + len(user_new_activities)) + activity = user_new_activities[0] - # Find the new activity. - new_activities = find_new_activities(before['user activity stream'], - after['user activity stream']) - assert len(new_activities) == 1, ("There should be 1 new activity in " - "the user's activity stream, but found %i" % len(new_activities)) - activity = new_activities[0] + # The same new activity should appear in the package's activity stream. + pkg_new_activities = (find_new_activities( + before['package activity stream'], + after['package activity stream'])) + assert pkg_new_activities == user_new_activities - assert find_new_activities(before["group activity stream"], - after['group activity stream']) == new_activities, ("The same " - "activity should also appear in the group's activity stream.") + # The same new activity should appear in the recently changed datasets + # stream. + assert find_new_activities( + before['recently changed datasets stream'], + after['recently changed datasets stream']) \ + == user_new_activities # Check that the new activity has the right attributes. - assert activity['object_id'] == group.id, str(activity['object_id']) - assert activity['user_id'] == user.id, str(activity['user_id']) - assert activity['activity_type'] == 'changed group', \ - str(activity['activity_type']) + assert activity['object_id'] == package.id, ( + str(activity['object_id'])) + assert activity['user_id'] == self.normal_user.id, ( + str(activity['user_id'])) + assert activity['activity_type'] == 'changed package', ( + str(activity['activity_type'])) if not activity.has_key('id'): assert False, "activity object has no id value" # TODO: Test for the _correct_ revision_id value. if not activity.has_key('revision_id'): assert False, "activity has no revision_id value" timestamp = datetime_from_string(activity['timestamp']) - assert timestamp >= before['time'] and timestamp <= after['time'], \ - str(activity['timestamp']) - - def test_01_update_group(self): - """ - Test updated group activity stream. - - Test that correct activity stream item and detail items are created - when groups are updated. + assert timestamp >= before['time'], str(activity['timestamp']) + assert timestamp <= after['time'], str(activity['timestamp']) - """ - for group in model.Session.query(model.Group).all(): - self._update_group(group, user=self.sysadmin_user) + # Test for the presence of correct activity detail items. + details = self.activity_details(activity) + assert len(details) == num_resources + for detail in details: + assert detail['activity_id'] == activity['id'], ( + "activity_id should be %s but is %s" + % (activity['id'], detail['activity_id'])) + assert detail['object_id'] in resource_ids, ( + str(detail['object_id'])) + assert detail['object_type'] == "Resource", ( + str(detail['object_type'])) + assert detail['activity_type'] == "deleted", ( + str(detail['activity_type'])) - def _delete_group(self, group, user): + def _update_package(self, package, user): """ - Delete the given group and test that the correct activity stream + Update the given package and test that the correct activity stream item and detail are emitted. """ - before = self.record_details(user.id, group_id=group.id) - - # Deleted the group. - context = {'model': model, 'session': model.Session, 'api_version':3, - 'user': user.name, 'allow_partial_update': True} - group_dict = {'id': group.id, 'state': 'deleted'} - group_update(context, group_dict) - - after = self.record_details(user.id, group_id=group.id) - - # Find the new activity. - new_activities = find_new_activities(before['user activity stream'], - after['user activity stream']) - assert len(new_activities) == 1, ("There should be 1 new activity in " - "the user's activity stream, but found %i" % len(new_activities)) - activity = new_activities[0] - - assert find_new_activities(before["group activity stream"], - after['group activity stream']) == new_activities, ("The same " - "activity should also appear in the group's activity stream.") - - # Check that the new activity has the right attributes. - assert activity['object_id'] == group.id, str(activity['object_id']) - assert activity['user_id'] == user.id, str(activity['user_id']) - assert activity['activity_type'] == 'deleted group', \ - str(activity['activity_type']) - if not activity.has_key('id'): - assert False, "activity object has no id value" - # TODO: Test for the _correct_ revision_id value. - if not activity.has_key('revision_id'): - assert False, "activity has no revision_id value" - timestamp = datetime_from_string(activity['timestamp']) - assert timestamp >= before['time'] and timestamp <= after['time'], \ - str(activity['timestamp']) - - def test_delete_group(self): - """ - Test deleted group activity stream. - - Test that correct activity stream item and detail items are created - when groups are deleted. - - """ - for group in model.Session.query(model.Group).all(): - self._delete_group(group, self.sysadmin_user) + if user: + user_name = user.name + user_id = user.id + else: + user_name = '127.0.0.1' + user_id = 'not logged in' - def test_add_tag(self): - """ - Test add tag activities. + before = self.record_details(user_id, package.id) - If a package is updated by adding one new tag to it, a - 'changed package' activity with a single 'added tag' activity detail - should be emitted. + # Query for the package object again, as the session that it belongs to + # may have been closed. + package = model.Session.query(model.Package).get(package.id) - """ - # Get a package. - user = self.normal_user - pkg_name = u"warandpeace" - context = { - 'model': model, - 'session': model.Session, - 'user': user.name, - 'allow_partial_update': True - } - pkg_dict = ckan.logic.action.get.package_show(context, - {'id': pkg_name}) + # Update the package. + context = {'model': model, 'session': model.Session, 'user': user_name, + 'allow_partial_update': True} + package_dict = {'id': package.id} + if package.title != 'edited': + package_dict['title'] = 'edited' + else: + assert package.title != 'edited again' + package_dict['title'] = 'edited again' + package_update(context, package_dict) - # Add one new tag to the package. - before = self.record_details(user.id, pkg_dict['id']) - new_tag_name = 'test tag' - assert new_tag_name not in [tag['name'] for tag in pkg_dict['tags']] - new_tag_list = pkg_dict['tags'] + [{'name': new_tag_name}] - data_dict = { - 'id': pkg_dict['id'], - 'tags': new_tag_list - } - package_update(context, data_dict) - after = self.record_details(user.id, pkg_dict['id']) + after = self.record_details(user_id, package.id) # Find the new activity in the user's activity stream. user_new_activities = (find_new_activities( @@ -1042,7 +892,7 @@ def test_add_tag(self): len(user_new_activities)) activity = user_new_activities[0] - # The same new activity should appear in the package's stream. + # The same new activity should appear in the package's activity stream. pkg_new_activities = (find_new_activities( before['package activity stream'], after['package activity stream'])) @@ -1056,9 +906,9 @@ def test_add_tag(self): == user_new_activities # Check that the new activity has the right attributes. - assert activity['object_id'] == pkg_dict['id'], ( + assert activity['object_id'] == package.id, ( str(activity['object_id'])) - assert activity['user_id'] == user.id, str(activity['user_id']) + assert activity['user_id'] == user_id, str(activity['user_id']) assert activity['activity_type'] == 'changed package', ( str(activity['activity_type'])) if not activity.has_key('id'): @@ -1076,41 +926,39 @@ def test_add_tag(self): detail = details[0] assert detail['activity_id'] == activity['id'], \ str(detail['activity_id']) - assert detail['object_type'] == "tag", ( + assert detail['object_id'] == package.id, str(detail['object_id']) + assert detail['object_type'] == "Package", ( str(detail['object_type'])) - assert detail['activity_type'] == "added", ( + assert detail['activity_type'] == "changed", ( str(detail['activity_type'])) - def test_01_remove_tag(self): + def _update_resource(self, package, resource, user): """ - Test remove tag activity. - - If a package is updated by removing one tag from it, a - 'changed package' activity with a single 'removed tag' activity detail - should be emitted. + Update the given resource and test that the correct activity stream + item and detail are emitted. """ - # Get a package. - user = self.normal_user - pkg_name = u"warandpeace" - context = { - 'model': model, - 'session': model.Session, - 'user': user.name, - } - pkg_dict = ckan.logic.action.get.package_show(context, - {'id': pkg_name}) + if user: + user_name = user.name + user_id = user.id + else: + user_name = '127.0.0.1' + user_id = 'not logged in' - # Remove one tag from the package. - assert len(pkg_dict['tags']) >= 1, ("The package has to have at least" - " one tag to test removing a tag.") - before = self.record_details(user.id, pkg_dict['id']) - data_dict = { - 'id': pkg_dict['id'], - 'tags': pkg_dict['tags'][0:-1], - } - package_update(context, data_dict) - after = self.record_details(user.id, pkg_dict['id']) + before = self.record_details(user_id, package.id) + + # Query for the Package and Resource objects again, as the session that + # they belong to may have been closed. + package = model.Session.query(model.Package).get(package.id) + resource = model.Session.query(model.Resource).get(resource.id) + + # Update the resource. + context = {'model': model, 'session': model.Session, 'user': user_name, + 'allow_partial_update': True} + resource_dict = {'id':resource.id, 'name':'edited'} + resource_update(context, resource_dict) + + after = self.record_details(user_id, package.id) # Find the new activity in the user's activity stream. user_new_activities = (find_new_activities( @@ -1120,7 +968,7 @@ def test_01_remove_tag(self): len(user_new_activities)) activity = user_new_activities[0] - # The same new activity should appear in the package's stream. + # The same new activity should appear in the package's activity stream. pkg_new_activities = (find_new_activities( before['package activity stream'], after['package activity stream'])) @@ -1134,15 +982,15 @@ def test_01_remove_tag(self): == user_new_activities # Check that the new activity has the right attributes. - assert activity['object_id'] == pkg_dict['id'], ( + assert activity['object_id'] == package.id, ( str(activity['object_id'])) - assert activity['user_id'] == user.id, str(activity['user_id']) + assert activity['user_id'] == user_id, str(activity['user_id']) assert activity['activity_type'] == 'changed package', ( str(activity['activity_type'])) - if not activity.has_key('id'): + if not activity['id']: assert False, "activity object has no id value" # TODO: Test for the _correct_ revision_id value. - if not activity.has_key('revision_id'): + if not activity['revision_id']: assert False, "activity has no revision_id value" timestamp = datetime_from_string(activity['timestamp']) assert (timestamp >= before['time'] and @@ -1152,22 +1000,33 @@ def test_01_remove_tag(self): details = self.activity_details(activity) assert len(details) == 1 detail = details[0] - assert detail['activity_id'] == activity['id'], \ - str(detail['activity_id']) - assert detail['object_type'] == "tag", ( + assert detail['activity_id'] == activity['id'], ( + str(detail['activity_id'])) + assert detail['object_id'] == resource.id, str(detail['object_id']) + assert detail['object_type'] == "Resource", ( str(detail['object_type'])) - assert detail['activity_type'] == "removed", ( + assert detail['activity_type'] == "changed", ( str(detail['activity_type'])) - def _create_activity(self, user, package, params): - before = self.record_details(user.id, package.id) + def _delete_package(self, package): + """ + Delete the given package and test that the correct activity stream + item and detail are emitted. - response = self.app.post('/api/action/activity_create', - params=json.dumps(params), - extra_environ={'Authorization': str(self.sysadmin_user.apikey)}) - assert response.json['success'] == True + """ + before = self.record_details(self.sysadmin_user.id, package.id) - after = self.record_details(user.id, package.id) + # Query for the package object again, as the session that it belongs to + # may have been closed. + package = model.Session.query(model.Package).get(package.id) + + # Delete the package. + context = {'model': model, 'session': model.Session, + 'user': self.sysadmin_user.name} + package_dict = {'id':package.id} + package_delete(context, package_dict) + + after = self.record_details(self.sysadmin_user.id, package.id) # Find the new activity in the user's activity stream. user_new_activities = (find_new_activities( @@ -1177,18 +1036,25 @@ def _create_activity(self, user, package, params): len(user_new_activities)) activity = user_new_activities[0] - # The same new activity should appear in the package's activity stream. + # The same new activity should appear in the package's stream. pkg_new_activities = (find_new_activities( before['package activity stream'], after['package activity stream'])) assert pkg_new_activities == user_new_activities + # The same new activity should appear in the recently changed datasets + # stream. + assert find_new_activities( + before['recently changed datasets stream'], + after['recently changed datasets stream']) \ + == user_new_activities + # Check that the new activity has the right attributes. - assert activity['object_id'] == params['object_id'], ( - str(activity['object_id'])) - assert activity['user_id'] == params['user_id'], ( + assert activity['object_id'] == package.id, ( + str(activity['object_id'])) + assert activity['user_id'] == self.sysadmin_user.id, ( str(activity['user_id'])) - assert activity['activity_type'] == params['activity_type'], ( + assert activity['activity_type'] == 'deleted package', ( str(activity['activity_type'])) if not activity.has_key('id'): assert False, "activity object has no id value" @@ -1199,120 +1065,577 @@ def _create_activity(self, user, package, params): assert (timestamp >= before['time'] and timestamp <= after['time']), str(activity['timestamp']) - def test_activity_create_successful_no_data(self): - """Test creating an activity via the API, without passing the optional - data dict. + # Test for the presence of a correct activity detail item. + details = self.activity_details(activity) + assert len(details) == 1 + detail = details[0] + assert detail['activity_id'] == activity['id'], \ + str(detail['activity_id']) + assert detail['object_id'] == package.id, str(detail['object_id']) + assert detail['object_type'] == "Package", ( + str(detail['object_type'])) + assert detail['activity_type'] == "deleted", ( + str(detail['activity_type'])) + def test_01_delete_resources(self): """ - params = { - 'user_id': self.sysadmin_user.id, - 'object_id': self.warandpeace.id, - 'activity_type': 'changed package', - } - self._create_activity(self.sysadmin_user, self.warandpeace, params) + Test deleted resource activity stream. - def test_activity_create_successful_with_data(self): - """Test creating an activity via the API, with the optional data dict. + Test that correct activity stream item and detail items are created + when resources are deleted from packages. """ - params = { - 'user_id': self.sysadmin_user.id, - 'object_id': self.annakarenina.id, - 'activity_type': 'deleted package', - 'data': {'a': 1, 'b': 2, 'c': 3} - } - self._create_activity(self.sysadmin_user, self.annakarenina, params) - - def test_activity_create_no_authorization(self): - """Test the error response when the activity_create API is called - without an authorization header. + packages_with_resources = [] + for package in model.Session.query(model.Package).all(): + # Query for the package object again, as the session that it + # belongs to may have been closed. + package = model.Session.query(model.Package).get(package.id) + if len(package.resources) > 0: + packages_with_resources.append(package) + assert len(packages_with_resources) > 0, \ + "Need some packages with resources to test deleting resources." + for package in packages_with_resources: + self._delete_resources(package) + def test_01_update_group(self): """ - params = { - 'user_id': self.sysadmin_user.id, - 'object_id': self.warandpeace.id, - 'activity_type': 'changed package', - } - response = self.app.post('/api/action/activity_create', - params=json.dumps(params), status=403) - assert response.json['success'] == False + Test updated group activity stream. - def test_activity_create_not_authorized(self): - """Test the error response when the activity_create API is called - with an authorization header for a user who is not authorized to - create activities. + Test that correct activity stream item and detail items are created + when groups are updated. """ - params = { - 'user_id': self.normal_user.id, - 'object_id': self.warandpeace.id, - 'activity_type': 'changed package', - } - response = self.app.post('/api/action/activity_create', - params=json.dumps(params), - extra_environ={'Authorization': str(self.normal_user.apikey)}, - status=403) - assert response.json['success'] == False - - def test_activity_create_authorization_not_exists(self): - """Test the error response when the activity_create API is called - with an authorization header with an API key that doesn't exist in the - model. + for group in model.Session.query(model.Group).all(): + self._update_group(group, user=self.sysadmin_user) + def test_01_remove_tag(self): """ - params = { - 'user_id': self.normal_user.id, - 'object_id': self.warandpeace.id, - 'activity_type': 'changed package', - } - response = self.app.post('/api/action/activity_create', - params=json.dumps(params), - extra_environ={'Authorization': 'xxxxxxxxxx'}, - status=403) - assert response.json['success'] == False + Test remove tag activity. - def test_activity_create_with_id(self): - """Test that an ID passed to the activity_create API is ignored and not - used. + If a package is updated by removing one tag from it, a + 'changed package' activity with a single 'removed tag' activity detail + should be emitted. """ - activity_id = '1234567890' - user = self.sysadmin_user - package = self.warandpeace - params = { - 'id': activity_id, - 'user_id': user.id, - 'object_id': package.id, - 'activity_type': 'changed package', + # Get a package. + user = self.normal_user + pkg_name = u"warandpeace" + context = { + 'model': model, + 'session': model.Session, + 'user': user.name, } - self._create_activity(self.sysadmin_user, self.warandpeace, params) - assert activity_id not in [activity['id'] for activity in - self.user_activity_stream(user.id)] - assert activity_id not in [activity['id'] for activity in - self.package_activity_stream(package.id)] - - def test_activity_create_with_timestamp(self): - """Test that a timestamp passed to the activity_create API is ignored - and not used + pkg_dict = ckan.logic.action.get.package_show(context, + {'id': pkg_name}) - """ - params = { - 'user_id': self.sysadmin_user.id, - 'object_id': self.warandpeace.id, - 'activity_type': 'changed package', - 'timestamp': str(datetime.datetime.max), - } - self._create_activity(self.sysadmin_user, self.warandpeace, params) - params['timestamp'] = 'foobar' - self._create_activity(self.sysadmin_user, self.warandpeace, params) + # Remove one tag from the package. + assert len(pkg_dict['tags']) >= 1, ("The package has to have at least" + " one tag to test removing a tag.") + before = self.record_details(user.id, pkg_dict['id']) + data_dict = { + 'id': pkg_dict['id'], + 'tags': pkg_dict['tags'][0:-1], + } + package_update(context, data_dict) + after = self.record_details(user.id, pkg_dict['id']) - def test_activity_create_with_revision(self): - """Test that a revision_id passed to the activity_create API is ignored - and not used + # Find the new activity in the user's activity stream. + user_new_activities = (find_new_activities( + before['user activity stream'], after['user activity stream'])) + assert len(user_new_activities) == 1, ("There should be 1 new " + " activity in the user's activity stream, but found %i" % + len(user_new_activities)) + activity = user_new_activities[0] - """ - revision_id = '1234567890' - user = self.sysadmin_user + # The same new activity should appear in the package's stream. + pkg_new_activities = (find_new_activities( + before['package activity stream'], + after['package activity stream'])) + assert pkg_new_activities == user_new_activities + + # The same new activity should appear in the recently changed datasets + # stream. + assert find_new_activities( + before['recently changed datasets stream'], + after['recently changed datasets stream']) \ + == user_new_activities + + # Check that the new activity has the right attributes. + assert activity['object_id'] == pkg_dict['id'], ( + str(activity['object_id'])) + assert activity['user_id'] == user.id, str(activity['user_id']) + assert activity['activity_type'] == 'changed package', ( + str(activity['activity_type'])) + if not activity.has_key('id'): + assert False, "activity object has no id value" + # TODO: Test for the _correct_ revision_id value. + if not activity.has_key('revision_id'): + assert False, "activity has no revision_id value" + timestamp = datetime_from_string(activity['timestamp']) + assert (timestamp >= before['time'] and + timestamp <= after['time']), str(activity['timestamp']) + + # Test for the presence of a correct activity detail item. + details = self.activity_details(activity) + assert len(details) == 1 + detail = details[0] + assert detail['activity_id'] == activity['id'], \ + str(detail['activity_id']) + assert detail['object_type'] == "tag", ( + str(detail['object_type'])) + assert detail['activity_type'] == "removed", ( + str(detail['activity_type'])) + + def test_01_update_extras(self): + """ + Test changed package extra activity stream. + + Test that correct activity stream item and detail items are emitted + when a package extra is changed. + + """ + context = { + 'model': model, + 'session': model.Session, + 'user': self.normal_user.name, + 'extras_as_string': True, + } + packages_with_extras = [] + for package_name in package_list(context, {}): + package_dict = package_show(context, {'id': package_name}) + if len(package_dict['extras']) > 0: + packages_with_extras.append(package_dict) + assert len(packages_with_extras) > 0, ( + "Need some packages with extras to test") + for package_dict in packages_with_extras: + self._update_extra(package_dict, user=self.normal_user) + + def test_01_update_extras_not_logged_in(self): + """ + Test changed package extra activity stream when no user logged in. + + Test that correct activity stream item and detail items are emitted + when a package extra is changed by a user who is not logged in. + + """ + context = { + 'model': model, + 'session': model.Session, + 'user': self.normal_user.name, + 'extras_as_string': True, + } + packages_with_extras = [] + for package_name in package_list(context, {}): + package_dict = package_show(context, {'id': package_name}) + if len(package_dict['extras']) > 0: + packages_with_extras.append(package_dict) + assert len(packages_with_extras) > 0, ( + "Need some packages with extras to test") + for package_dict in packages_with_extras: + self._update_extra(package_dict, None) + + def test_01_update_package(self): + """ + Test updated package activity stream. + + Test that correct activity stream item and detail items are created + when packages are updated. + + """ + for package in model.Session.query(model.Package).all(): + self._update_package(package, user=self.normal_user) + + def test_01_update_package_not_logged_in(self): + """ + Test updated package activity stream when not logged in. + + Test that correct activity stream item and detail items are created + when packages are updated by a user who is not logged in. + + """ + for package in model.Session.query(model.Package).all(): + self._update_package(package, user=None) + + def test_01_update_resource(self): + """ + Test that a correct activity stream item and detail item are emitted + when a resource is updated. + + """ + packages = model.Session.query(model.Package).all() + for package in packages: + # Query the model for the Package object again, as the session that + # it belongs to may have been closed. + pkg = model.Session.query(model.Package).get(package.id) + for resource in pkg.resources: + self._update_resource(pkg, resource, user=self.normal_user) + + def test_01_update_resource_not_logged_in(self): + """ + Test that a correct activity stream item and detail item are emitted + when a resource is updated by a user who is not logged in. + + """ + packages = model.Session.query(model.Package).all() + for package in packages: + # Query the model for the Package object again, as the session that + # it belongs to may have been closed. + pkg = model.Session.query(model.Package).get(package.id) + for resource in pkg.resources: + self._update_resource(pkg, resource, user=None) + + def test_create_package(self): + """ + Test new package activity stream. + + Test that correct activity stream item and detail items are emitted + when a new package is created. + + """ + self._create_package(user=self.normal_user) + + def test_create_package_not_logged_in(self): + """ + Test new package activity stream when not logged in. + + Test that correct activity stream item and detail items are emitted + when a new package is created by a user who is not logged in. + + """ + self._create_package(user=None, name="not_logged_in_test_package") + + def test_add_resources(self): + """ + Test new resource activity stream. + + Test that correct activity stream item and detail items are emitted + when a resource is added to a package. + + """ + for package in model.Session.query(model.Package).all(): + self._add_resource(package, user=self.normal_user) + + def test_add_resources_not_logged_in(self): + """ + Test new resource activity stream when no user logged in. + + Test that correct activity stream item and detail items are emitted + when a resource is added to a package by a user who is not logged in. + + """ + for package in model.Session.query(model.Package).all(): + self._add_resource(package, user=None) + + def test_delete_package(self): + """ + Test deleted package activity stream. + + Test that correct activity stream item and detail items are created + when packages are deleted. + + """ + for package in model.Session.query(model.Package).all(): + self._delete_package(package) + + def test_create_user(self): + """ + Test new user activity stream. + + Test that correct activity stream item and detail item are created when + a new user is created. + + """ + before = datetime.datetime.now() + + # Create a new user. + user_dict = {'name': 'testuser', + 'about': 'Just a test user', 'email': 'me@test.org', + 'password': 'testpass'} + context = {'model': model, 'session': model.Session, + 'user': self.sysadmin_user.name} + user_created = user_create(context, user_dict) + + after = self.record_details(user_created['id']) + + user_activities = after['user activity stream'] + assert len(user_activities) == 1, ("There should be 1 activity in " + "the user's activity stream, but found %i" % len(user_activities)) + activity = user_activities[0] + + # Check that the new activity has the right attributes. + assert activity['object_id'] == user_created['id'], \ + str(activity['object_id']) + assert activity['user_id'] == user_created['id'], \ + str(activity['user_id']) + assert activity['activity_type'] == 'new user', \ + str(activity['activity_type']) + if not activity.has_key('id'): + assert False, "activity object should have an id value" + # TODO: Test for the _correct_ revision_id value. + if not activity.has_key('revision_id'): + assert False, "activity object should have a revision_id value" + timestamp = datetime_from_string(activity['timestamp']) + assert timestamp >= before and timestamp <= after['time'], \ + str(activity['timestamp']) + + details = self.activity_details(activity) + assert len(details) == 0, ("There shouldn't be any activity details" + " for a 'new user' activity") + + def test_update_user(self): + """ + Test updated user activity stream. + + Test that correct activity stream item is created when users are + updated. + + """ + for user in model.Session.query(model.User).all(): + self._update_user(user) + + def test_create_group(self): + + user = self.normal_user + + before = self.record_details(user.id) + + # Create a new group. + context = {'model': model, 'session': model.Session, 'user': user.name} + request_data = {'name': 'a-new-group', 'title': 'A New Group'} + group_created = group_create(context, request_data) + + after = self.record_details(user.id, group_id=group_created['id']) + + # Find the new activity. + new_activities = find_new_activities(before['user activity stream'], + after['user activity stream']) + assert len(new_activities) == 1, ("There should be 1 new activity in " + "the user's activity stream, but found %i" % len(new_activities)) + activity = new_activities[0] + + assert after['group activity stream'] == new_activities, ("The same " + "activity should also appear in the group's activity stream.") + + # Check that the new activity has the right attributes. + assert activity['object_id'] == group_created['id'], \ + str(activity['object_id']) + assert activity['user_id'] == user.id, str(activity['user_id']) + assert activity['activity_type'] == 'new group', \ + str(activity['activity_type']) + if not activity.has_key('id'): + assert False, "activity object should have an id value" + # TODO: Test for the _correct_ revision_id value. + if not activity.has_key('revision_id'): + assert False, "activity object should have a revision_id value" + timestamp = datetime_from_string(activity['timestamp']) + assert timestamp >= before['time'] and timestamp <= after['time'], \ + str(activity['timestamp']) + + def test_delete_group(self): + """ + Test deleted group activity stream. + + Test that correct activity stream item and detail items are created + when groups are deleted. + + """ + for group in model.Session.query(model.Group).all(): + self._delete_group(group, self.sysadmin_user) + + def test_add_tag(self): + """ + Test add tag activities. + + If a package is updated by adding one new tag to it, a + 'changed package' activity with a single 'added tag' activity detail + should be emitted. + + """ + # Get a package. + user = self.normal_user + pkg_name = u"warandpeace" + context = { + 'model': model, + 'session': model.Session, + 'user': user.name, + 'allow_partial_update': True + } + pkg_dict = ckan.logic.action.get.package_show(context, + {'id': pkg_name}) + + # Add one new tag to the package. + before = self.record_details(user.id, pkg_dict['id']) + new_tag_name = 'test tag' + assert new_tag_name not in [tag['name'] for tag in pkg_dict['tags']] + new_tag_list = pkg_dict['tags'] + [{'name': new_tag_name}] + data_dict = { + 'id': pkg_dict['id'], + 'tags': new_tag_list + } + package_update(context, data_dict) + after = self.record_details(user.id, pkg_dict['id']) + + # Find the new activity in the user's activity stream. + user_new_activities = (find_new_activities( + before['user activity stream'], after['user activity stream'])) + assert len(user_new_activities) == 1, ("There should be 1 new " + " activity in the user's activity stream, but found %i" % + len(user_new_activities)) + activity = user_new_activities[0] + + # The same new activity should appear in the package's stream. + pkg_new_activities = (find_new_activities( + before['package activity stream'], + after['package activity stream'])) + assert pkg_new_activities == user_new_activities + + # The same new activity should appear in the recently changed datasets + # stream. + assert find_new_activities( + before['recently changed datasets stream'], + after['recently changed datasets stream']) \ + == user_new_activities + + # Check that the new activity has the right attributes. + assert activity['object_id'] == pkg_dict['id'], ( + str(activity['object_id'])) + assert activity['user_id'] == user.id, str(activity['user_id']) + assert activity['activity_type'] == 'changed package', ( + str(activity['activity_type'])) + if not activity.has_key('id'): + assert False, "activity object has no id value" + # TODO: Test for the _correct_ revision_id value. + if not activity.has_key('revision_id'): + assert False, "activity has no revision_id value" + timestamp = datetime_from_string(activity['timestamp']) + assert (timestamp >= before['time'] and + timestamp <= after['time']), str(activity['timestamp']) + + # Test for the presence of a correct activity detail item. + details = self.activity_details(activity) + assert len(details) == 1 + detail = details[0] + assert detail['activity_id'] == activity['id'], \ + str(detail['activity_id']) + assert detail['object_type'] == "tag", ( + str(detail['object_type'])) + assert detail['activity_type'] == "added", ( + str(detail['activity_type'])) + + def test_activity_create_successful_no_data(self): + """Test creating an activity via the API, without passing the optional + data dict. + + """ + params = { + 'user_id': self.sysadmin_user.id, + 'object_id': self.warandpeace.id, + 'activity_type': 'changed package', + } + self._create_activity(self.sysadmin_user, self.warandpeace, params) + + def test_activity_create_successful_with_data(self): + """Test creating an activity via the API, with the optional data dict. + + """ + params = { + 'user_id': self.sysadmin_user.id, + 'object_id': self.annakarenina.id, + 'activity_type': 'deleted package', + 'data': {'a': 1, 'b': 2, 'c': 3} + } + self._create_activity(self.sysadmin_user, self.annakarenina, params) + + def test_activity_create_no_authorization(self): + """Test the error response when the activity_create API is called + without an authorization header. + + """ + params = { + 'user_id': self.sysadmin_user.id, + 'object_id': self.warandpeace.id, + 'activity_type': 'changed package', + } + response = self.app.post('/api/action/activity_create', + params=json.dumps(params), status=403) + assert response.json['success'] == False + + def test_activity_create_not_authorized(self): + """Test the error response when the activity_create API is called + with an authorization header for a user who is not authorized to + create activities. + + """ + params = { + 'user_id': self.normal_user.id, + 'object_id': self.warandpeace.id, + 'activity_type': 'changed package', + } + response = self.app.post('/api/action/activity_create', + params=json.dumps(params), + extra_environ={'Authorization': str(self.normal_user.apikey)}, + status=403) + assert response.json['success'] == False + + def test_activity_create_authorization_not_exists(self): + """Test the error response when the activity_create API is called + with an authorization header with an API key that doesn't exist in the + model. + + """ + params = { + 'user_id': self.normal_user.id, + 'object_id': self.warandpeace.id, + 'activity_type': 'changed package', + } + response = self.app.post('/api/action/activity_create', + params=json.dumps(params), + extra_environ={'Authorization': 'xxxxxxxxxx'}, + status=403) + assert response.json['success'] == False + + def test_activity_create_with_id(self): + """Test that an ID passed to the activity_create API is ignored and not + used. + + """ + activity_id = '1234567890' + user = self.sysadmin_user + package = self.warandpeace + params = { + 'id': activity_id, + 'user_id': user.id, + 'object_id': package.id, + 'activity_type': 'changed package', + } + self._create_activity(self.sysadmin_user, self.warandpeace, params) + assert activity_id not in [activity['id'] for activity in + self.user_activity_stream(user.id)] + assert activity_id not in [activity['id'] for activity in + self.package_activity_stream(package.id)] + + def test_activity_create_with_timestamp(self): + """Test that a timestamp passed to the activity_create API is ignored + and not used + + """ + params = { + 'user_id': self.sysadmin_user.id, + 'object_id': self.warandpeace.id, + 'activity_type': 'changed package', + 'timestamp': str(datetime.datetime.max), + } + self._create_activity(self.sysadmin_user, self.warandpeace, params) + params['timestamp'] = 'foobar' + self._create_activity(self.sysadmin_user, self.warandpeace, params) + + def test_activity_create_with_revision(self): + """Test that a revision_id passed to the activity_create API is ignored + and not used + + """ + revision_id = '1234567890' + user = self.sysadmin_user package = self.warandpeace params = { 'revision_id': revision_id, @@ -1509,119 +1832,29 @@ def test_activity_create_activity_type_empty(self): status=409) assert response.json['success'] == False assert response.json['error'][u'__type'] == u'Validation Error' - assert response.json['error'][u'activity_type'] == [ - u'Missing value'], ( - response.json['error'][u'activity_type']) - - def test_activity_create_activity_type_not_exists(self): - """Test the error response when the activity_create API is called - with an activity_type that does not exist. - - """ - params = { - 'user_id': self.normal_user.id, - 'object_id': self.warandpeace.id, - 'activity_type': 'foobar' - } - response = self.app.post('/api/action/activity_create', - params=json.dumps(params), - extra_environ={'Authorization': str(self.sysadmin_user.apikey)}, - status=409) - assert response.json['success'] == False - assert response.json['error'][u'__type'] == u'Validation Error' - assert response.json['error'][u'activity_type'] == [ - u"Not found: Activity type"], ( - response.json['error'][u'activity_type']) - - def _add_extra(self, package_dict, user, key=None): - if key is None: - key = 'quality' - if user: - user_name = user.name - user_id = user.id - else: - user_name = '127.0.0.1' - user_id = 'not logged in' - - before = self.record_details(user_id, package_dict['id']) - - extras_before = package_dict['extras'] - - # Create a new extra. - context = { - 'model': model, - 'session': model.Session, - 'user': user_name, - 'allow_partial_update': True, - 'extras_as_string': True, - } - extras = list(extras_before) - extras.append({'key': key, 'value': '10000'}) - request_data = { - 'id': package_dict['id'], - 'extras': extras - } - updated_package = package_update(context, request_data) - - after = self.record_details(user_id, package_dict['id']) - extras_after = updated_package['extras'] - assert len(extras_after) == len(extras_before) + 1, ( - "%s != %s" % (len(extras_after), len(extras_before) + 1)) - - # Find the new activity in the user's activity stream. - user_new_activities = (find_new_activities( - before['user activity stream'], after['user activity stream'])) - assert len(user_new_activities) == 1, ("There should be 1 new " - " activity in the user's activity stream, but found %i" % - len(user_new_activities)) - activity = user_new_activities[0] - - # The same new activity should appear in the package's activity stream. - pkg_new_activities = (find_new_activities( - before['package activity stream'], - after['package activity stream'])) - assert pkg_new_activities == user_new_activities - - # The same new activity should appear in the recently changed datasets - # stream. - assert find_new_activities( - before['recently changed datasets stream'], - after['recently changed datasets stream']) \ - == user_new_activities - - # Check that the new activity has the right attributes. - assert activity['object_id'] == updated_package['id'], \ - str(activity['object_id']) - assert activity['user_id'] == user_id, str(activity['user_id']) - assert activity['activity_type'] == 'changed package', \ - str(activity['activity_type']) - if not activity.has_key('id'): - assert False, "activity object should have an id value" - # TODO: Test for the _correct_ revision_id value. - if not activity.has_key('revision_id'): - assert False, "activity object should have a revision_id value" - timestamp = datetime_from_string(activity['timestamp']) - assert (timestamp >= before['time'] and - timestamp <= after['time']), str(activity['timestamp']) - - # Test for the presence of a correct activity detail item. - details = self.activity_details(activity) - assert len(details) == 1, ( - "There should be 1 activity detail but found %s" - % len(details)) - detail = details[0] - assert detail['activity_id'] == activity['id'], \ - str(detail['activity_id']) - new_extras = [extra for extra in extras_after if extra not in - extras_before] - assert len(new_extras) == 1, "%s != 1" % len(new_extras) - new_extra = new_extras[0] - assert detail['object_id'] == new_extra['id'], ( - str(detail['object_id'])) - assert detail['object_type'] == "PackageExtra", ( - str(detail['object_type'])) - assert detail['activity_type'] == "new", ( - str(detail['activity_type'])) + assert response.json['error'][u'activity_type'] == [ + u'Missing value'], ( + response.json['error'][u'activity_type']) + + def test_activity_create_activity_type_not_exists(self): + """Test the error response when the activity_create API is called + with an activity_type that does not exist. + + """ + params = { + 'user_id': self.normal_user.id, + 'object_id': self.warandpeace.id, + 'activity_type': 'foobar' + } + response = self.app.post('/api/action/activity_create', + params=json.dumps(params), + extra_environ={'Authorization': str(self.sysadmin_user.apikey)}, + status=409) + assert response.json['success'] == False + assert response.json['error'][u'__type'] == u'Validation Error' + assert response.json['error'][u'activity_type'] == [ + u"Not found: Activity type"], ( + response.json['error'][u'activity_type']) def test_add_extras(self): """ @@ -1659,239 +1892,6 @@ def test_add_extras_not_logged_in(self): package_dict = package_show(context, {'id': package_name}) self._add_extra(package_dict, None, key='not_logged_in_extra_key') - def _update_extra(self, package_dict, user): - if user: - user_name = user.name - user_id = user.id - else: - user_name = '127.0.0.1' - user_id = 'not logged in' - - before = self.record_details(user_id, package_dict['id']) - - extras_before = package_dict['extras'] - assert len(extras_before) > 0, ( - "Can't update an extra if the package doesn't have any") - - # Update the package's first extra. - context = { - 'model': model, - 'session': model.Session, - 'user': user_name, - 'allow_partial_update': True, - 'extras_as_string': True - } - extras = list(extras_before) - if extras[0]['value'] != 'edited': - extras[0]['value'] = 'edited' - else: - assert extras[0]['value'] != 'edited again' - extras[0]['value'] = 'edited again' - request_data = { - 'id': package_dict['id'], - 'extras': extras - } - updated_package = package_update(context, request_data) - - after = self.record_details(user_id, package_dict['id']) - extras_after = updated_package['extras'] - assert len(extras_after) == len(extras_before), ( - "%s != %s" % (len(extras_after), len(extras_before))) - - # Find the new activity in the user's activity stream. - user_new_activities = (find_new_activities( - before['user activity stream'], after['user activity stream'])) - assert len(user_new_activities) == 1, ("There should be 1 new " - " activity in the user's activity stream, but found %i" % - len(user_new_activities)) - activity = user_new_activities[0] - - # The same new activity should appear in the package's activity stream. - pkg_new_activities = (find_new_activities( - before['package activity stream'], - after['package activity stream'])) - assert pkg_new_activities == user_new_activities - - # The same new activity should appear in the recently changed datasets - # stream. - assert find_new_activities( - before['recently changed datasets stream'], - after['recently changed datasets stream']) \ - == user_new_activities - - # Check that the new activity has the right attributes. - assert activity['object_id'] == updated_package['id'], \ - str(activity['object_id']) - assert activity['user_id'] == user_id, str(activity['user_id']) - assert activity['activity_type'] == 'changed package', \ - str(activity['activity_type']) - if not activity.has_key('id'): - assert False, "activity object should have an id value" - # TODO: Test for the _correct_ revision_id value. - if not activity.has_key('revision_id'): - assert False, "activity object should have a revision_id value" - timestamp = datetime_from_string(activity['timestamp']) - assert (timestamp >= before['time'] and - timestamp <= after['time']), str(activity['timestamp']) - - # Test for the presence of a correct activity detail item. - details = self.activity_details(activity) - assert len(details) == 1, ( - "There should be 1 activity detail but found %s" - % len(details)) - detail = details[0] - assert detail['activity_id'] == activity['id'], \ - str(detail['activity_id']) - new_extras = [extra for extra in extras_after if extra not in - extras_before] - assert len(new_extras) == 1, "%s != 1" % len(new_extras) - new_extra = new_extras[0] - assert detail['object_id'] == new_extra['id'], ( - str(detail['object_id'])) - assert detail['object_type'] == "PackageExtra", ( - str(detail['object_type'])) - assert detail['activity_type'] == "changed", ( - str(detail['activity_type'])) - - def test_01_update_extras(self): - """ - Test changed package extra activity stream. - - Test that correct activity stream item and detail items are emitted - when a package extra is changed. - - """ - context = { - 'model': model, - 'session': model.Session, - 'user': self.normal_user.name, - 'extras_as_string': True, - } - packages_with_extras = [] - for package_name in package_list(context, {}): - package_dict = package_show(context, {'id': package_name}) - if len(package_dict['extras']) > 0: - packages_with_extras.append(package_dict) - assert len(packages_with_extras) > 0, ( - "Need some packages with extras to test") - for package_dict in packages_with_extras: - self._update_extra(package_dict, user=self.normal_user) - - def test_01_update_extras_not_logged_in(self): - """ - Test changed package extra activity stream when no user logged in. - - Test that correct activity stream item and detail items are emitted - when a package extra is changed by a user who is not logged in. - - """ - context = { - 'model': model, - 'session': model.Session, - 'user': self.normal_user.name, - 'extras_as_string': True, - } - packages_with_extras = [] - for package_name in package_list(context, {}): - package_dict = package_show(context, {'id': package_name}) - if len(package_dict['extras']) > 0: - packages_with_extras.append(package_dict) - assert len(packages_with_extras) > 0, ( - "Need some packages with extras to test") - for package_dict in packages_with_extras: - self._update_extra(package_dict, None) - - def _delete_extra(self, package_dict, user): - if user: - user_name = user.name - user_id = user.id - else: - user_name = '127.0.0.1' - user_id = 'not logged in' - - before = self.record_details(user_id, package_dict['id']) - - extras_before = package_dict['extras'] - assert len(extras_before) > 0, ( - "Can't update an extra if the package doesn't have any") - - # Update the package's first extra. - context = { - 'model': model, - 'session': model.Session, - 'user': user_name, - 'extras_as_string': True, - } - extras = list(extras_before) - del extras[0] - request_data = { - 'id': package_dict['id'], - 'extras': extras, - 'tags': package_dict['tags'], - 'resources': package_dict['resources'] - } - updated_package = package_update(context, request_data) - - after = self.record_details(user_id, package_dict['id']) - extras_after = updated_package['extras'] - assert len(extras_after) == len(extras_before) - 1, ( - "%s != %s" % (len(extras_after), len(extras_before) - 1)) - - # Find the new activity in the user's activity stream. - user_new_activities = (find_new_activities( - before['user activity stream'], after['user activity stream'])) - assert len(user_new_activities) == 1, ("There should be 1 new " - " activity in the user's activity stream, but found %i" % - len(user_new_activities)) - activity = user_new_activities[0] - - # The same new activity should appear in the package's activity stream. - pkg_new_activities = (find_new_activities( - before['package activity stream'], - after['package activity stream'])) - assert pkg_new_activities == user_new_activities - - # The same new activity should appear in the recently changed datasets - # stream. - assert find_new_activities( - before['recently changed datasets stream'], - after['recently changed datasets stream']) \ - == user_new_activities - - # Check that the new activity has the right attributes. - assert activity['object_id'] == updated_package['id'], \ - str(activity['object_id']) - assert activity['user_id'] == user_id, str(activity['user_id']) - assert activity['activity_type'] == 'changed package', \ - str(activity['activity_type']) - if not activity.has_key('id'): - assert False, "activity object should have an id value" - # TODO: Test for the _correct_ revision_id value. - if not activity.has_key('revision_id'): - assert False, "activity object should have a revision_id value" - timestamp = datetime_from_string(activity['timestamp']) - assert (timestamp >= before['time'] and - timestamp <= after['time']), str(activity['timestamp']) - - # Test for the presence of a correct activity detail item. - details = self.activity_details(activity) - assert len(details) == 1, ( - "There should be 1 activity detail but found %s" - % len(details)) - detail = details[0] - assert detail['activity_id'] == activity['id'], \ - str(detail['activity_id']) - deleted_extras = [extra for extra in extras_before if extra not in - extras_after] - assert len(deleted_extras) == 1, "%s != 1" % len(deleted_extras) - deleted_extra = deleted_extras[0] - assert detail['object_id'] == deleted_extra['id'], ( - str(detail['object_id'])) - assert detail['object_type'] == "PackageExtra", ( - str(detail['object_type'])) - assert detail['activity_type'] == "deleted", ( - str(detail['activity_type'])) - def test_delete_extras(self): """ Test deleted package extra activity stream.