{% endblock %} - -{% block main_content %} -
-
- {% block form %} -

{{ _('Are you sure you want to delete related item - {name}?').format(name=c.related_dict.title) }}

-

-

- - -
-

- {% endblock %} -
-
-{% endblock %} diff --git a/ckan/templates/related/dashboard.html b/ckan/templates/related/dashboard.html deleted file mode 100644 index 841abe99d8b..00000000000 --- a/ckan/templates/related/dashboard.html +++ /dev/null @@ -1,94 +0,0 @@ -{% extends "page.html" %} - -{% set page = c.page %} -{% set item_count = c.page.item_count %} - -{% block subtitle %}{{ _('Apps & Ideas') }}{% endblock %} - -{% block breadcrumb_content %} -
  • {{ _('Apps & Ideas') }}
  • -{% endblock %} - -{% block primary_content %} -
    -
    -

    - {% block page_heading %}{{ _('Apps & Ideas') }}{% endblock %} -

    - - {% block related_items %} - {% if item_count %} - {% trans first=page.first_item, last=page.last_item, item_count=item_count %} -

    Showing items {{ first }} - {{ last }} of {{ item_count }} related items found

    - {% endtrans %} - {% elif c.filters.type %} - {% trans item_count=item_count %} -

    {{ item_count }} related items found

    - {% endtrans %} - {% else %} -

    {{ _('There have been no apps submitted yet.') }} - {% endif %} - {% endblock %} - - {% block related_list %} - {% if page.items %} - {% snippet "related/snippets/related_list.html", related_items=page.items %} - {% endif %} - {% endblock %} -

    - - {% block page_pagination %} - {{ page.pager() }} - {% endblock %} -
    -{% endblock %} - -{% block secondary_content %} -
    -

    {{ _('What are applications?') }}

    -
    - {% trans %} - These are applications built with the datasets as well as ideas for - things that could be done with them. - {% endtrans %} -
    -
    - -
    -

    {{ _('Filter Results') }}

    -
    - - -
    - - -
    - -
    - - -
    - -
    - -
    - -
    - -
    -
    -
    -{% endblock %} diff --git a/ckan/templates/related/edit.html b/ckan/templates/related/edit.html deleted file mode 100644 index 26c1e49b701..00000000000 --- a/ckan/templates/related/edit.html +++ /dev/null @@ -1,8 +0,0 @@ -{% extends "related/base_form_page.html" %} - -{% block subtitle %}{{ _('Edit related item') }}{% endblock %} - -{# TODO: pass the same context in here so we can create links #} -{% block breadcrumb_item %}{{ h.nav_link(_('Edit Related'), controller='related', action='edit', id=c.id, related_id="") }}{% endblock %} - -{% block page_heading %}{{ _('Edit Related Item') }}{% endblock %} diff --git a/ckan/templates/related/edit_form.html b/ckan/templates/related/edit_form.html deleted file mode 100644 index 92cb16696e8..00000000000 --- a/ckan/templates/related/edit_form.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "related/snippets/related_form.html" %} - -{% block button_text %} - {% if data.id %} - {{ _('Update') }} - {% else %} - {{ _('Create') }} - {% endif %} -{% endblock %} - -{% block delete_button %} - {% if data.id %} - {{ super() }} - {% endif %} -{% endblock %} diff --git a/ckan/templates/related/new.html b/ckan/templates/related/new.html deleted file mode 100644 index 7fb3ce90633..00000000000 --- a/ckan/templates/related/new.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "related/base_form_page.html" %} - -{% block subtitle %}{{ _('Create a related item') }}{% endblock %} - -{% block breadcrumb_item %}{{ h.nav_link(_('Create Related'), controller='related', action='new', id=c.id) }}{% endblock %} - -{% block page_heading %}{{ _('Create Related Item') }}{% endblock %} diff --git a/ckan/templates/related/snippets/related_form.html b/ckan/templates/related/snippets/related_form.html deleted file mode 100644 index 23ab88c1c84..00000000000 --- a/ckan/templates/related/snippets/related_form.html +++ /dev/null @@ -1,35 +0,0 @@ -{% import 'macros/form.html' as form %} - -
    - {% block error_summary %} - {% if error_summary | count %} -
    -

    {{ _('The form contains invalid entries:') }}

    -
      - {% for key, error in error_summary.items() %} -
    • {{ key }}: {{ error }}
    • - {% endfor %} -
    -
    - {% endif %} - {% endblock %} - - {% block fields %} - {{ form.input('title', label=_('Title'), id='field-title', placeholder=_('My Related Item'), value=data.title, error=errors.title, classes=['control-full']) }} - {{ form.input('url', label=_('URL'), id='field-url', placeholder=_('http://example.com/'), value=data.url, error=errors.url, classes=['control-full']) }} - {{ form.input('image_url', label=_('Image URL'), id='field-image-url', placeholder=_('http://example.com/image.png'), value=data.image_url, error=errors.image_url, classes=['control-full']) }} - {{ form.markdown('description', label=_('Description'), id='field-description', placeholder=_('A little information about the item...'), value=data.description, error=errors.description) }} - {{ form.select('type', label=_('Type'), id='field-types', selected=data.type, options=c.types, error=errors.type) }} - {% endblock %} - -
    - {% block delete_button %} - {% if h.check_access('related_delete', {'id': data.id}) %} - {% set locale = h.dump_json({'content': _('Are you sure you want to delete this related item?')}) %} - {% block delete_button_text %}{{ _('Delete') }}{% endblock %} - {% endif %} - {% endblock %} - {{ h.nav_link(_('Cancel'), controller='related', action='list', id=c.id, class_='btn') }} - -
    -
    diff --git a/ckan/templates/related/snippets/related_item.html b/ckan/templates/related/snippets/related_item.html deleted file mode 100644 index 2053f7c0406..00000000000 --- a/ckan/templates/related/snippets/related_item.html +++ /dev/null @@ -1,41 +0,0 @@ -{# -Displays a single related item. - -related - The related item dict. -pkg_id - The id of the owner package. If present the edit button will be - displayed. - -Example: - - - -#} -{% set placeholder_map = { -'application': h.url_for_static('/base/images/placeholder-application.png') -} %} -{% set tooltip = _('Go to {related_item_type}').format(related_item_type=related.type|replace('_', ' ')|title) %} - -{% if position is divisibleby 3 %} -
  • -{% endif %} diff --git a/ckan/templates/related/snippets/related_list.html b/ckan/templates/related/snippets/related_list.html deleted file mode 100644 index 7256ba97dc3..00000000000 --- a/ckan/templates/related/snippets/related_list.html +++ /dev/null @@ -1,18 +0,0 @@ -{# -Renders a list of related item elements - -related_items - A list of related items. -pkg_id - A package id for the items used to determine if the edit button - should be displayed. - -Example: - - - {% snippet "related/snippets/related_list.html", related_items=c.pkg.related, pkg_id=c.pkg.name %} - -#} - diff --git a/ckan/templates/snippets/related.html b/ckan/templates/snippets/related.html deleted file mode 100644 index b18c3b79dad..00000000000 --- a/ckan/templates/snippets/related.html +++ /dev/null @@ -1,22 +0,0 @@ -
    -

    {{ _('Related') }}

    -
    - {% if item %} - {% with url = h.url_for(controller='related', action='list', id=pkg_name) %} - -
    -

    {{ item.title }}

    -

    {{ h.markdown_extract(item.description, 70) }}

    -
    - {% endwith %} - {% else %} -

    {% trans %}No apps, ideas, news stories or images have been - related to this dataset yet.{% endtrans %}

    - {% if h.check_access('related_create') %} -

    {% link_for _('Add Item'), controller='related', action='new', id=pkg_name, icon='plus', class_='btn' %}

    - {% endif %} - {% endif %} -
    -
    diff --git a/ckan/tests/factories.py b/ckan/tests/factories.py index 18d6fa2f710..df4be214b82 100644 --- a/ckan/tests/factories.py +++ b/ckan/tests/factories.py @@ -305,32 +305,6 @@ def _create(cls, target_class, *args, **kwargs): return group_dict -class Related(factory.Factory): - '''A factory class for creating related items.''' - - FACTORY_FOR = ckan.model.Related - - type = 'idea' - description = 'Look, a description!' - url = 'http://example.com' - - title = factory.Sequence(lambda n: 'test title {n}'.format(n=n)) - - @classmethod - def _build(cls, target_class, *args, **kwargs): - raise NotImplementedError(".build() isn't supported in CKAN") - - @classmethod - def _create(cls, target_class, *args, **kwargs): - if args: - assert False, "Positional args aren't supported, use keyword args." - - context = {'user': _get_action_user_name(kwargs)} - related_dict = helpers.call_action('related_create', context=context, - **kwargs) - return related_dict - - class Dataset(factory.Factory): '''A factory class for creating CKAN datasets.''' diff --git a/ckan/tests/legacy/__init__.py b/ckan/tests/legacy/__init__.py index 982461a46bc..f3fc02e0997 100644 --- a/ckan/tests/legacy/__init__.py +++ b/ckan/tests/legacy/__init__.py @@ -343,13 +343,6 @@ def is_datastore_supported(): is_supported_db = model.engine_is_pg() return is_supported_db -def search_related(test): - def skip_test(*args): - raise SkipTest("Search not supported") - if not is_search_supported(): - return make_decorator(test)(skip_test) - return test - def regex_related(test): def skip_test(*args): raise SkipTest("Regex not supported") diff --git a/ckan/tests/legacy/functional/api/test_activity.py b/ckan/tests/legacy/functional/api/test_activity.py index 2a6d1bb5538..99510b1d507 100644 --- a/ckan/tests/legacy/functional/api/test_activity.py +++ b/ckan/tests/legacy/functional/api/test_activity.py @@ -2064,92 +2064,6 @@ def test_organization_activity_list_by_name(self): 'organization_activity_list', id=organization['name']) assert len(activities) > 0 - def test_related_item_new(self): - user = self.normal_user - data = {'title': 'random', 'type': 'Application', 'url': - 'http://example.com/application'} - extra_environ = {'Authorization': str(user['apikey'])} - response = self.app.post('/api/action/related_create', - json.dumps(data), - extra_environ=extra_environ) - response_dict = json.loads(response.body) - assert response_dict['success'] is True - - activity_response = self.app.post('/api/3/action/user_activity_list', - json.dumps({'id': user['id']})) - activity_response_dict = json.loads(activity_response.body) - assert (activity_response_dict['result'][0]['activity_type'] == 'new ' - 'related item') - assert activity_response_dict['result'][0]['user_id'] == user['id'] - assert (activity_response_dict['result'][0]['data']['related']['id'] == - response_dict['result']['id']) - assert activity_response_dict['result'][0]['data']['dataset'] is None - - def test_related_item_changed(self): - # Create related item - user = self.normal_user - data = {'title': 'random', 'type': 'Application', 'url': - 'http://example.com/application'} - extra_environ = {'Authorization': str(user['apikey'])} - response = self.app.post('/api/action/related_create', - json.dumps(data), - extra_environ=extra_environ) - response_dict = json.loads(response.body) - assert response_dict['success'] is True - - # Modify it - data = {'id': response_dict['result']['id'], 'title': 'random2', - 'owner_id': str(user['id']), 'type': 'Application'} - response = self.app.post('/api/action/related_update', - json.dumps(data), extra_environ=extra_environ) - response_dict = json.loads(response.body) - assert response_dict['success'] is True - - # Test for activity stream entries - activity_response = self.app.post('/api/3/action/user_activity_list', - json.dumps({'id': user['id']})) - activity_response_dict = json.loads(activity_response.body) - assert (activity_response_dict['result'][0]['activity_type'] == - 'changed related item') - assert (activity_response_dict['result'][0]['object_id'] == - response_dict['result']['id']) - assert activity_response_dict['result'][0]['user_id'] == user['id'] - assert (activity_response_dict['result'][0]['data']['related']['id'] == - response_dict['result']['id']) - assert activity_response_dict['result'][0]['data']['dataset'] is None - - def test_related_item_deleted(self): - # Create related item - user = self.normal_user - data = {'title': 'random', 'type': 'Application', 'url': - 'http://example.com/application'} - extra_environ = {'Authorization': str(user['apikey'])} - response = self.app.post('/api/action/related_create', - json.dumps(data), - extra_environ=extra_environ) - response_dict = json.loads(response.body) - assert response_dict['success'] is True - - # Delete related item - data = {'id': response_dict['result']['id']} - deleted_response = self.app.post('/api/action/related_delete', - json.dumps(data), - extra_environ=extra_environ) - deleted_response_dict = json.loads(deleted_response.body) - assert deleted_response_dict['success'] is True - - # Test for activity stream entries - activity_response = self.app.post('/api/3/action/user_activity_list', - json.dumps({'id': user['id']})) - activity_response_dict = json.loads(activity_response.body) - assert (activity_response_dict['result'][0]['activity_type'] == - 'deleted related item') - assert (activity_response_dict['result'][0]['object_id'] == - response_dict['result']['id']) - assert activity_response_dict['result'][0]['user_id'] == user['id'] - assert (activity_response_dict['result'][0]['data']['related']['id'] == - response_dict['result']['id']) - def test_no_activity_when_creating_private_dataset(self): '''There should be no activity when a private dataset is created.''' diff --git a/ckan/tests/legacy/functional/test_home.py b/ckan/tests/legacy/functional/test_home.py index 1c7769a5540..dff99d5bfa8 100644 --- a/ckan/tests/legacy/functional/test_home.py +++ b/ckan/tests/legacy/functional/test_home.py @@ -7,7 +7,7 @@ from ckan.tests.legacy import * from ckan.tests.legacy.html_check import HtmlCheckMethods from ckan.tests.legacy.pylons_controller import PylonsTestCase -from ckan.tests.legacy import search_related, setup_test_search_index +from ckan.tests.legacy import setup_test_search_index from ckan.common import c, session diff --git a/ckan/tests/legacy/functional/test_related.py b/ckan/tests/legacy/functional/test_related.py deleted file mode 100644 index bb67323520f..00000000000 --- a/ckan/tests/legacy/functional/test_related.py +++ /dev/null @@ -1,533 +0,0 @@ -import json - -from nose.tools import assert_equal, assert_raises - -import ckan.tests.legacy as tests -import ckan.model as model -import ckan.logic as logic -import ckan.lib.helpers as h -import ckan.tests.legacy.functional.base as base -import ckan.tests.legacy.functional.api.base as apibase - - -class TestRelatedUI(base.FunctionalTestCase): - @classmethod - def setup_class(self): - model.Session.remove() - tests.CreateTestData.create() - - @classmethod - def teardown_class(self): - model.repo.rebuild_db() - - def test_related_new(self): - offset = h.url_for(controller='related', - action='new', id='warandpeace') - res = self.app.get(offset, status=200, - extra_environ={"REMOTE_USER": "testsysadmin"}) - assert 'URL' in res, "URL missing in response text" - assert 'Title' in res, "Title missing in response text" - - data = { - "title": "testing_create", - "url": u"http://ckan.org/feed/", - } - res = self.app.post(offset, params=data, - status=[200,302], - extra_environ={"REMOTE_USER": "testsysadmin"}) - - def test_related_new_missing(self): - offset = h.url_for(controller='related', - action='new', id='non-existent dataset') - res = self.app.get(offset, status=404, - extra_environ={"REMOTE_USER": "testsysadmin"}) - - def test_related_new_fail(self): - offset = h.url_for(controller='related', - action='new', id='warandpeace') - print '@@@@', offset - res = self.app.get(offset, status=200, - extra_environ={"REMOTE_USER": "testsysadmin"}) - assert 'URL' in res, "URL missing in response text" - assert 'Title' in res, "Title missing in response text" - - data = { - "title": "testing_create", - } - res = self.app.post(offset, params=data, - status=[200,302], - extra_environ={"REMOTE_USER": "testsysadmin"}) - assert 'error' in res, res - - - -class TestRelated: - - @classmethod - def setup_class(self): - model.Session.remove() - tests.CreateTestData.create() - - @classmethod - def teardown_class(self): - model.repo.rebuild_db() - - def test_create(self): - p = model.Package.get('warandpeace') - r = model.Related() - p.related.append(r) - - assert len(p.related) == 1, p.related - assert len(r.datasets) == 1, r.datasets - - model.Session.add(p) - model.Session.add(r) - model.Session.commit() - - # To get the RelatedDataset objects (for state change) - assert p.related_count == 1, p.related_count - assert len(model.Related.get_for_dataset(p)) == 1 - assert len(model.Related.get_for_dataset(p,status='inactive')) == 0 - p.related.remove(r) - model.Session.delete(r) - model.Session.commit() - - assert len(p.related) == 0 - assert p.related_count == 0, p.related_count - - - def test_inactive_related(self): - p = model.Package.get('warandpeace') - r = model.Related() - p.related.append(r) - assert len(p.related) == 1, p.related - model.Session.add(r) - model.Session.commit() - - # To get the RelatedDataset objects (for state change) - assert p.related_count == 1, p.related_count - assert len(model.Related.get_for_dataset(p,status='active')) == 1 - assert len(model.Related.get_for_dataset(p,status='inactive')) == 0 - r.deactivate( p ) - r.deactivate( p ) # Does nothing. - model.Session.refresh(p) - assert p.related_count == 0, p.related_count - assert len(model.Related.get_for_dataset(p,status='active')) == 0 - assert len(model.Related.get_for_dataset(p,status='inactive')) == 1 - - model.Session.refresh(p) # Would like to get rid of the need for this - assert len(p.related) == 0, p.related # not sure inactive item ... - model.Session.delete(r) - - - def _related_create(self, title, description, type, url, image_url): - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = dict(title=title,description=description, - url=url,image_url=image_url,type=type) - return logic.get_action("related_create")( context, data_dict ) - - def test_related_create(self): - rel = self._related_create("Title", "Description", - "visualization", - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - assert rel['title'] == "Title", rel - assert rel['description'] == "Description", rel - assert rel['type'] == "visualization", rel - assert rel['url'] == "http://ckan.org", rel - assert rel['image_url'] == "http://ckan.org/files/2012/03/ckanlogored.png", rel - - def test_related_create_fail(self): - try: - rel = self._related_create("Title", "Description", - None, - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - assert False, "Create succeeded with missing field" - except logic.ValidationError, e: - assert 'type' in e.error_dict and e.error_dict['type'] == [u'Missing value'] - - def test_related_create_featured_as_sysadmin(self): - '''Sysadmin can create featured related items''' - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - - context = { - 'model': model, - 'user': usr['name'], - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - 'featured': 1, - } - - result = logic.get_action("related_create")(context, data_dict) - - assert_equal(result['featured'], 1) - - def test_related_create_featured_as_non_sysadmin_fails(self): - '''Non-sysadmin users should not be able to create featured relateds''' - - context = { - 'model': model, - 'user': 'annafan', - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - 'featured': 1, - } - - assert_raises( - logic.NotAuthorized, - logic.get_action('related_create'), - context, - data_dict) - - def test_related_create_not_featured_as_non_sysadmin_succeeds(self): - '''Non-sysadmins can set featured to false''' - - context = { - 'model': model, - 'user': 'annafan', - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - 'featured': 0, - } - - result = logic.get_action("related_create")(context, data_dict) - - assert_equal(result['featured'], 0) - - def test_related_create_featured_empty_as_non_sysadmin_succeeds(self): - '''Non-sysadmins can leave featured empty.''' - - context = { - 'model': model, - 'user': 'annafan', - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - } - - result = logic.get_action("related_create")(context, data_dict) - - assert_equal(result['featured'], 0) - - def test_related_delete(self): - rel = self._related_create("Title", "Description", - "visualization", - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = dict(id=rel['id']) - logic.get_action('related_delete')(context, data_dict) - - r = model.Related.get(rel['id']) - assert r is None, r # Ensure it doesn't exist - - def test_related_update(self): - rel = self._related_create("Title", "Description", - "visualization", - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = rel - data_dict['title'] = "New Title" - result = logic.get_action('related_update')(context,data_dict) - assert result['title'] == 'New Title' - - def test_sysadmin_changes_related_items_featured_field(self): - '''Sysadmins can change featured field''' - rel = self._related_create( - "Title", - "Description", - "visualization", - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = { - 'model': model, - 'user': usr['name'], - 'session': model.Session - } - - data_dict = rel - data_dict['title'] = "New Title" - data_dict['featured'] = 1 - result = logic.get_action('related_update')(context,data_dict) - assert_equal(result['title'], 'New Title') - assert_equal(result['featured'], 1) - - def test_non_sysadmin_changes_related_items_featured_field_fails(self): - '''Non-sysadmins cannot change featured field''' - - context = { - 'model': model, - 'user': 'annafan', - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - } - - # Create the related item as annafan - result = logic.get_action('related_create')(context, data_dict) - - # Try to change it to a featured item - result['featured'] = 1 - - try: - logic.get_action('related_update')(context, result) - except logic.NotAuthorized, e: - # Check it's the correct authorization error - assert 'featured' in str(e) - - def test_non_sysadmin_can_update_related_item(self): - '''Non-sysadmins can change related item. - - If they don't change the featured field. - ''' - - context = { - 'model': model, - 'user': 'annafan', - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - } - - # Create the related item as annafan - result = logic.get_action('related_create')(context, data_dict) - - # Try to change it to a featured item - result['title'] = 'New Title' - - result = logic.get_action('related_update')(context, result) - assert_equal(result['title'], 'New Title') - - def test_update_related_item_check_owner_status(self): - '''After edit of a related item by a sysadmin, check that the owner id is unchanged - ''' - offset = h.url_for(controller='related', - action='new', id='warandpeace') - data = { - "title": "testing_create", - "url": u"http://ckan.org/feed/", - } - user = model.User.by_name('tester') - admin = model.User.by_name('testsysadmin') - - #create related item - context = dict(model=model, user=user.name, session=model.Session) - data_dict = dict(title="testing_create",description="description", - url="http://ckan.org/feed/",image_url="",type="visualization") - res = logic.get_action("related_create")( context, data_dict ) - - #edit related item - data_dict = dict(id=res['id'],title="testing_update",description="description", - url="http://ckan.org/feed/",image_url="",type="visualization") - - context = dict(model=model, user=admin.name, session=model.Session) - result = logic.get_action('related_update')(context,data_dict) - #Confirm related item owner status - assert result['owner_id'] == user.id - - def test_related_show(self): - rel = self._related_create("Title", "Description", - "visualization", - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = {'id': rel['id']} - - result = logic.get_action('related_show')(context,data_dict) - assert rel['id'] == result['id'], result - assert rel['title'] == result['title'], result - assert rel['description'] == result['description'], result - assert rel['description'] == result['description'], result - - def test_related_list_missing_id_and_name(self): - p = model.Package.get('warandpeace') - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = {} - related_list = logic.get_action('related_list')(context, data_dict) - assert len(related_list) == 8 - related_keys = set(['view_count', 'description', 'title', 'url', - 'created', 'featured', 'image_url', 'type', 'id', 'owner_id']) - for related in related_list: - assert set(related.keys()) == related_keys - - - def test_related_list(self): - p = model.Package.get('warandpeace') - r = model.Related(title="Title", type="idea") - p.related.append(r) - r = model.Related(title="Title 2", type="idea") - p.related.append(r) - model.Session.add(r) - model.Session.commit() - - assert len(p.related) == 2 - assert p.related_count == 2, p.related_count - - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = {'id': p.id} - - result = logic.get_action('related_list')(context,data_dict) - assert len(result) == len(p.related) - -class TestRelatedActionAPI(apibase.BaseModelApiTestCase): - - @classmethod - def setup_class(cls): - model.Session.remove() - tests.CreateTestData.create() - cls.user_name = u'russianfan' # created in CreateTestData - cls.init_extra_environ(cls.user_name) - - @classmethod - def teardown_class(self): - model.repo.rebuild_db() - - def test_api_create_invalid(self): - res = self.app.post("/api/3/action/related_create", params="{}=1", - status=self.STATUS_409_CONFLICT, - extra_environ=self.extra_environ) - r = json.loads(res.body) - assert r['success'] == False, r - - - def _create(self, rtype="visualization", title="Test related item"): - r = { - "type": rtype, - "title": title - } - postparams = '%s=1' % json.dumps(r) - res = self.app.post("/api/3/action/related_create", params=postparams, - status=self.STATUS_200_OK, - extra_environ=self.extra_environ) - r = json.loads(res.body) - return r - - def test_api_create_valid(self): - r = self._create() - assert r['success'] == True, r - assert r['result']['type'] == "visualization" - assert r['result']['title'] == "Test related item" - - def test_api_show(self): - existing = self._create() - - r = { - "id": existing["result"]["id"] - } - postparams = '%s=1' % json.dumps(r) - res = self.app.post("/api/3/action/related_show", params=postparams, - status=self.STATUS_200_OK, - extra_environ=self.extra_environ) - r = json.loads(res.body) - assert r['success'] == True, r - assert r['result']['type'] == "visualization" - assert r['result']['title'] == "Test related item" - - - def test_api_list(self): - p = model.Package.get('warandpeace') - one = model.Related(type="idea", title="one") - two = model.Related(type="idea", title="two") - p.related.append(one) - p.related.append(two) - model.Session.commit() - - r = { - "id": p.id - } - postparams = '%s=1' % json.dumps(r) - res = self.app.post("/api/3/action/related_list", params=postparams, - status=self.STATUS_200_OK, - extra_environ=self.extra_environ) - r = json.loads(res.body) - assert r['success'] == True, r - assert r['result'][0]['type'] == "idea" - assert r['result'][0]['title'] == "two", r - - p.related.remove(one) - p.related.remove(two) - model.Session.delete(one) - model.Session.delete(two) - - def test_api_delete(self): - existing = self._create() - - r = { - "id": existing["result"]["id"] - } - postparams = '%s=1' % json.dumps(r) - res = self.app.post("/api/3/action/related_delete", params=postparams, - status=self.STATUS_200_OK, - extra_environ=self.extra_environ) - r = json.loads(res.body) - assert r['success'] == True, r - assert r['result'] is None, r - - def test_api_delete_fail(self): - existing = self._create() - r = { - "id": existing["result"]["id"] - } - - usr = model.User.by_name("annafan") - extra={'Authorization' : str(usr.apikey)} - - postparams = '%s=1' % json.dumps(r) - res = self.app.post("/api/3/action/related_delete", params=postparams, - status=self.STATUS_403_ACCESS_DENIED, - extra_environ=extra) - r = json.loads(res.body) - assert r['success'] == False, r - assert r[u'error'][u'__type'] == "Authorization Error", r diff --git a/ckan/tests/legacy/functional/test_revision.py b/ckan/tests/legacy/functional/test_revision.py index 23763aa4862..5cc1374d8a0 100644 --- a/ckan/tests/legacy/functional/test_revision.py +++ b/ckan/tests/legacy/functional/test_revision.py @@ -1,4 +1,4 @@ -from ckan.tests.legacy import search_related, TestController, CreateTestData, url_for +from ckan.tests.legacy import TestController, CreateTestData, url_for import ckan.model as model # TODO: purge revisions after creating them diff --git a/ckan/tests/legacy/functional/test_user.py b/ckan/tests/legacy/functional/test_user.py index a338afeec63..0a54a62516a 100644 --- a/ckan/tests/legacy/functional/test_user.py +++ b/ckan/tests/legacy/functional/test_user.py @@ -3,7 +3,7 @@ from pylons import config import hashlib -from ckan.tests.legacy import search_related, CreateTestData +from ckan.tests.legacy import CreateTestData from ckan.tests.legacy.html_check import HtmlCheckMethods from ckan.tests.legacy.pylons_controller import PylonsTestCase from ckan.tests.legacy.mock_mail_server import SmtpServerHarness diff --git a/ckan/tests/legacy/logic/test_action.py b/ckan/tests/legacy/logic/test_action.py index 156c80f70ca..d1ec655d731 100644 --- a/ckan/tests/legacy/logic/test_action.py +++ b/ckan/tests/legacy/logic/test_action.py @@ -16,7 +16,7 @@ import ckan.tests.legacy as tests from ckan.tests.legacy import WsgiAppCase from ckan.tests.legacy.functional.api import assert_dicts_equal_ignoring_ordering -from ckan.tests.legacy import setup_test_search_index, search_related +from ckan.tests.legacy import setup_test_search_index from ckan.tests.legacy import StatusCodes from ckan.logic import get_action, NotAuthorized from ckan.logic.action import get_domain_object @@ -1529,69 +1529,3 @@ def _assert_we_can_add_user_to_group(self, user_id, group_id): group_ids = [g.id for g in groups] assert res['success'] is True, res assert group.id in group_ids, (group, user_groups) - - -class TestRelatedAction(WsgiAppCase): - - sysadmin_user = None - - normal_user = None - - @classmethod - def setup_class(cls): - search.clear() - CreateTestData.create() - cls.sysadmin_user = model.User.get('testsysadmin') - - @classmethod - def teardown_class(cls): - model.repo.rebuild_db() - - def _add_basic_package(self, package_name=u'test_package', **kwargs): - package = { - 'name': package_name, - 'title': u'A Novel By Tolstoy', - 'resources': [{ - 'description': u'Full text.', - 'format': u'plain text', - 'url': u'http://datahub.io/download/' - }] - } - package.update(kwargs) - - postparams = '%s=1' % json.dumps(package) - res = self.app.post('/api/action/package_create', params=postparams, - extra_environ={'Authorization': 'tester'}) - return json.loads(res.body)['result'] - - def test_update_add_related_item(self): - package = self._add_basic_package() - related_item = { - "description": "Testing a Description", - "url": "http://example.com/image.png", - "title": "Testing", - "featured": 0, - "image_url": "http://example.com/image.png", - "type": "idea", - "dataset_id": package['id'], - } - related_item_json = json.dumps(related_item) - res_create = self.app.post('/api/action/related_create', - params=related_item_json, - extra_environ={'Authorization': 'tester'}) - assert res_create.json['success'] - - related_update = res_create.json['result'] - related_update = {'id': related_update['id'], 'title': 'Updated'} - related_update_json = json.dumps(related_update) - res_update = self.app.post('/api/action/related_update', - params=related_update_json, - extra_environ={'Authorization': 'tester'}) - assert res_update.json['success'] - res_update_json = res_update.json['result'] - assert res_update_json['title'] == related_update['title'] - - related_item.pop('title') - related_item.pop('dataset_id') - for field in related_item: - assert related_item[field] == res_update_json[field] diff --git a/ckan/tests/legacy/test_coding_standards.py b/ckan/tests/legacy/test_coding_standards.py index ad587cc2b15..bbd93df17e9 100644 --- a/ckan/tests/legacy/test_coding_standards.py +++ b/ckan/tests/legacy/test_coding_standards.py @@ -513,7 +513,6 @@ class TestPep8(object): 'ckan/model/package_extra.py', 'ckan/model/package_relationship.py', 'ckan/model/rating.py', - 'ckan/model/related.py', 'ckan/model/resource.py', 'ckan/model/system_info.py', 'ckan/model/tag.py', @@ -566,7 +565,6 @@ class TestPep8(object): 'ckan/tests/legacy/functional/test_package_relationships.py', 'ckan/tests/legacy/functional/test_pagination.py', 'ckan/tests/legacy/functional/test_preview_interface.py', - 'ckan/tests/legacy/functional/test_related.py', 'ckan/tests/legacy/functional/test_revision.py', 'ckan/tests/legacy/functional/test_search.py', 'ckan/tests/legacy/functional/test_storage.py', @@ -744,7 +742,6 @@ class TestActionAuth(object): 'get: package_activity_list_html', 'get: recently_changed_packages_activity_list', 'get: recently_changed_packages_activity_list_html', - 'get: related_list', 'get: resource_search', 'get: roles_show', 'get: status_show', diff --git a/ckan/tests/logic/action/test_get.py b/ckan/tests/logic/action/test_get.py index 629fe7293c1..c8c38719cb9 100644 --- a/ckan/tests/logic/action/test_get.py +++ b/ckan/tests/logic/action/test_get.py @@ -683,69 +683,6 @@ def test_user_show_include_datasets_includes_draft_sysadmin(self): eq(got_user['number_created_packages'], 3) -class TestRelatedList(helpers.FunctionalTestBase): - - def test_related_list_with_no_params(self): - ''' - Test related_list with no parameters and default sort - ''' - user = factories.User() - related1 = factories.Related(user=user, featured=True) - related2 = factories.Related(user=user, type='application') - - related_list = helpers.call_action('related_list') - assert len(related_list) == 2 - assert related1 in related_list - assert related2 in related_list - - def test_related_list_type_filter(self): - ''' - Test related_list with type filter - ''' - user = factories.User() - related1 = factories.Related(user=user, featured=True) - related2 = factories.Related(user=user, type='application') - - related_list = helpers.call_action('related_list', - type_filter='application') - assert ([related2] == related_list) - - def test_related_list_sorted(self): - ''' - Test related_list with sort parameter - ''' - user = factories.User() - related1 = factories.Related(user=user, featured=True) - related2 = factories.Related(user=user, type='application') - - related_list = helpers.call_action('related_list', sort='created_desc') - assert ([related2, related1] == related_list) - - def test_related_list_invalid_sort_parameter(self): - ''' - Test related_list with invalid value for sort parameter - ''' - user = factories.User() - related1 = factories.Related(user=user, featured=True) - related2 = factories.Related(user=user, type='application') - - related_list = helpers.call_action('related_list', sort='invalid') - assert ([related1, related2] == related_list) - - def test_related_list_featured(self): - ''' - Test related_list with no featured filter - ''' - user = factories.User() - related1 = factories.Related(user=user, featured=True) - related2 = factories.Related(user=user, type='application') - - related_list = helpers.call_action('related_list', featured=True) - assert ([related1] == related_list) - # TODO: Create related items associated with a dataset and test - # related_list with them - - class TestCurrentPackageList(helpers.FunctionalTestBase): def test_current_package_list(self): diff --git a/ckan/tests/logic/auth/test_init.py b/ckan/tests/logic/auth/test_init.py index 701713a9f00..96fbcb1adbc 100644 --- a/ckan/tests/logic/auth/test_init.py +++ b/ckan/tests/logic/auth/test_init.py @@ -12,7 +12,6 @@ def _get_function(self, obj_type): _get_object_functions = { 'package': logic_auth.get_package_object, 'resource': logic_auth.get_resource_object, - 'related': logic_auth.get_related_object, 'user': logic_auth.get_user_object, 'group': logic_auth.get_group_object, } @@ -48,9 +47,6 @@ def test_get_package_object_in_context(self): def test_get_resource_object_in_context(self): self._get_object_in_context('resource') - def test_get_related_object_in_context(self): - self._get_object_in_context('related') - def test_get_user_object_in_context(self): self._get_object_in_context('user') @@ -63,9 +59,6 @@ def test_get_package_object_id_not_found(self): def test_get_resource_object_id_not_found(self): self._get_object_id_not_found('resource') - def test_get_related_object_id_not_found(self): - self._get_object_id_not_found('related') - def test_get_user_object_id_not_found(self): self._get_object_id_not_found('user') @@ -78,9 +71,6 @@ def test_get_package_object_id_none(self): def test_get_resource_object_id_none(self): self._get_object_id_none('resource') - def test_get_related_object_id_none(self): - self._get_object_id_none('related') - def test_get_user_object_id_none(self): self._get_object_id_none('user') @@ -129,18 +119,6 @@ def test_get_resource_object_with_id(self): assert obj.id == resource['id'] assert context['resource'] == obj - def test_get_related_object_with_id(self): - - user_name = helpers.call_action('get_site_user')['name'] - related = helpers.call_action('related_create', - context={'user': user_name}, - title='test related', type='app') - context = {'model': core_model} - obj = logic_auth.get_related_object(context, {'id': related['id']}) - - assert obj.id == related['id'] - assert context['related'] == obj - def test_get_user_object_with_id(self): user_name = helpers.call_action('get_site_user')['name'] diff --git a/ckan/tests/test_factories.py b/ckan/tests/test_factories.py index a16c8d60a0f..85f051c8d04 100644 --- a/ckan/tests/test_factories.py +++ b/ckan/tests/test_factories.py @@ -52,11 +52,6 @@ def test_organization_factory(self): organization2 = factories.Organization() assert_not_equals(organization1['id'], organization2['id']) - def test_related_factory(self): - related1 = factories.Related() - related2 = factories.Related() - assert_not_equals(related1['id'], related2['id']) - def test_dataset_factory(self): dataset1 = factories.Dataset() dataset2 = factories.Dataset() From 340d5bcd6ca651b0e86bbbd6ed911ba0977835d0 Mon Sep 17 00:00:00 2001 From: Ross Jones Date: Wed, 23 Dec 2015 10:46:32 +0000 Subject: [PATCH 2/4] Remove test_home from legacy tests as was removed in master --- ckan/controllers/package.py | 5 +- ckan/tests/legacy/functional/test_home.py | 138 ------ ckan/tests/legacy/functional/test_related.py | 482 ------------------- ckan/tests/legacy/logic/test_action.py | 69 --- 4 files changed, 2 insertions(+), 692 deletions(-) delete mode 100644 ckan/tests/legacy/functional/test_home.py delete mode 100644 ckan/tests/legacy/functional/test_related.py diff --git a/ckan/controllers/package.py b/ckan/controllers/package.py index 3a00ee34e07..4f877de7160 100644 --- a/ckan/controllers/package.py +++ b/ckan/controllers/package.py @@ -1107,7 +1107,6 @@ def resource_read(self, id, resource_id): c.datastore_api = '%s/api/action' % \ config.get('ckan.site_url', '').rstrip('/') - c.resource['can_be_previewed'] = self._resource_preview( {'resource': c.resource, 'package': c.package}) @@ -1310,8 +1309,8 @@ def activity(self, id): c.pkg_dict = get_action('package_show')(context, data_dict) c.pkg = context['package'] c.package_activity_stream = get_action( - 'package_activity_list_html')(context, - {'id': c.pkg_dict['id']}) + 'package_activity_list_html')( + context, {'id': c.pkg_dict['id']}) dataset_type = c.pkg_dict['type'] or 'dataset' except NotFound: abort(404, _('Dataset not found')) diff --git a/ckan/tests/legacy/functional/test_home.py b/ckan/tests/legacy/functional/test_home.py deleted file mode 100644 index 2e3add427dd..00000000000 --- a/ckan/tests/legacy/functional/test_home.py +++ /dev/null @@ -1,138 +0,0 @@ -from pylons.i18n import set_lang - -from ckan.lib.create_test_data import CreateTestData -from ckan.controllers.home import HomeController -import ckan.model as model - -from ckan.tests.legacy import * -from ckan.tests.legacy.html_check import HtmlCheckMethods -from ckan.tests.legacy.pylons_controller import PylonsTestCase -from ckan.tests.legacy import setup_test_search_index - -from ckan.common import c, session - -class TestHomeController(TestController, PylonsTestCase, HtmlCheckMethods): - @classmethod - def setup_class(cls): - setup_test_search_index() - PylonsTestCase.setup_class() - model.repo.init_db() - CreateTestData.create() - - @classmethod - def teardown_class(self): - model.repo.rebuild_db() - - def test_template_head_end(self): - offset = url_for('home') - res = self.app.get(offset) - assert 'ckan.template_head_end = ' - - def test_template_footer_end(self): - offset = url_for('home') - res = self.app.get(offset) - assert 'TEST TEMPLATE_FOOTER_END TEST' - - - def test_update_profile_notice(self): - edit_url = url_for(controller='user', action='edit') - email_notice = 'Please update your profile' \ - ' and add your email address.' % (edit_url) - fullname_notice = 'Please update your profile' \ - ' and add your full name' % (edit_url) - email_and_fullname_notice ='Please update your' \ - ' profile and add your email address and your full name.' \ - % (edit_url) - url = url_for('home') - - # No update profile notices should be flashed if no one is logged in. - response = self.app.get(url) - assert email_notice not in response - assert fullname_notice not in response - assert email_and_fullname_notice not in response - - # Make some test users. - user1 = model.user.User(name='user1', fullname="user 1's full name", - email='user1@testusers.org') - user2 = model.user.User(name='user2', fullname="user 2's full name") - user3 = model.user.User(name='user3', email='user3@testusers.org') - user4 = model.user.User(name='user4') - - # Some test users with Google OpenIDs. - user5 = model.user.User( - name='https://www.google.com/accounts/o8/id/id=ACyQatixLeL' - 'ODscWvwqsCXWQ2sa3RRaBhaKTkcsvUElI6tNHIQ1_egX_wt1x3fA' - 'Y983DpW4UQV_U', - fullname="user 5's full name", email="user5@testusers.org") - user6 = model.user.User( - name='https://www.google.com/accounts/o8/id/id=ACyQatixLeL' - 'ODscWvwqsCXWQ2sa3RRaBhaKTkcsvUElI6tNHIQ1_egX_wt1x3fA' - 'Y983DpW4UQV_J', - fullname="user 6's full name") - user7 = model.user.User( - name='https://www.google.com/accounts/o8/id/id=AItOawl27F2' - 'M92ry4jTdjiVx06tuFNA', - email='user7@testusers.org') - user8 = model.user.User( - name='https://www.google.com/accounts/o8/id/id=AItOawl27F2' - 'M92ry4jTdjiVx06tuFNs' - ) - - users = (user1, user2, user3, user4, user5, user6, user7, user8) - google_users = (user5, user6, user7, user8) - - for user in users: - model.repo.new_revision() - model.Session.add(user) - model.Session.commit() - - response = self.app.get(url, extra_environ={'REMOTE_USER': - user.name.encode('utf-8')}) - - model.repo.new_revision() - model.Session.add(user) - - if user in google_users: - # Users with Google OpenIDs are asked to give their email if - # they don't have one and to enter a full name if they don't - # have one. - if not user.email and not user.fullname: - assert email_and_fullname_notice in response - assert email_notice not in response - assert fullname_notice not in response - elif user.email and not user.fullname: - assert email_notice not in response - assert fullname_notice in response, response - assert email_and_fullname_notice not in response - elif not user.email and user.fullname: - assert email_notice in response - assert fullname_notice not in response - assert email_and_fullname_notice not in response - elif user.email and user.fullname: - assert email_notice not in response - assert fullname_notice not in response - assert email_and_fullname_notice not in response - else: - # Users without Google OpenIDs are just asked to give their - # email if they don't have one. - if not user.email: - assert email_notice in response - assert email_and_fullname_notice not in response - assert fullname_notice not in response - elif user.email: - assert email_notice not in response - assert fullname_notice not in response - assert email_and_fullname_notice not in response - - if not user.email: - user.email = "mr_tusks@tusk_family.org" - if not user.fullname: - user.fullname = "Mr. Tusks" - model.Session.commit() - - response = self.app.get(url, extra_environ={'REMOTE_USER': - user.name.encode('utf-8')}) - assert email_notice not in response - assert fullname_notice not in response - assert email_and_fullname_notice not in response - diff --git a/ckan/tests/legacy/functional/test_related.py b/ckan/tests/legacy/functional/test_related.py deleted file mode 100644 index aa636a8957d..00000000000 --- a/ckan/tests/legacy/functional/test_related.py +++ /dev/null @@ -1,482 +0,0 @@ -import json - -from nose.tools import assert_equal, assert_raises - -import ckan.tests.legacy as tests -import ckan.model as model -import ckan.logic as logic -import ckan.lib.helpers as h -import ckan.tests.legacy.functional.base as base -import ckan.tests.legacy.functional.api.base as apibase - - -class TestRelated: - - @classmethod - def setup_class(self): - model.Session.remove() - tests.CreateTestData.create() - - @classmethod - def teardown_class(self): - model.repo.rebuild_db() - - def test_create(self): - p = model.Package.get('warandpeace') - r = model.Related() - p.related.append(r) - - assert len(p.related) == 1, p.related - assert len(r.datasets) == 1, r.datasets - - model.Session.add(p) - model.Session.add(r) - model.Session.commit() - - # To get the RelatedDataset objects (for state change) - assert p.related_count == 1, p.related_count - assert len(model.Related.get_for_dataset(p)) == 1 - assert len(model.Related.get_for_dataset(p,status='inactive')) == 0 - p.related.remove(r) - model.Session.delete(r) - model.Session.commit() - - assert len(p.related) == 0 - assert p.related_count == 0, p.related_count - - - def test_inactive_related(self): - p = model.Package.get('warandpeace') - r = model.Related() - p.related.append(r) - assert len(p.related) == 1, p.related - model.Session.add(r) - model.Session.commit() - - # To get the RelatedDataset objects (for state change) - assert p.related_count == 1, p.related_count - assert len(model.Related.get_for_dataset(p,status='active')) == 1 - assert len(model.Related.get_for_dataset(p,status='inactive')) == 0 - r.deactivate( p ) - r.deactivate( p ) # Does nothing. - model.Session.refresh(p) - assert p.related_count == 0, p.related_count - assert len(model.Related.get_for_dataset(p,status='active')) == 0 - assert len(model.Related.get_for_dataset(p,status='inactive')) == 1 - - model.Session.refresh(p) # Would like to get rid of the need for this - assert len(p.related) == 0, p.related # not sure inactive item ... - model.Session.delete(r) - - - def _related_create(self, title, description, type, url, image_url): - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = dict(title=title,description=description, - url=url,image_url=image_url,type=type) - return logic.get_action("related_create")( context, data_dict ) - - def test_related_create(self): - rel = self._related_create("Title", "Description", - "visualization", - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - assert rel['title'] == "Title", rel - assert rel['description'] == "Description", rel - assert rel['type'] == "visualization", rel - assert rel['url'] == "http://ckan.org", rel - assert rel['image_url'] == "http://ckan.org/files/2012/03/ckanlogored.png", rel - - def test_related_create_fail(self): - try: - rel = self._related_create("Title", "Description", - None, - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - assert False, "Create succeeded with missing field" - except logic.ValidationError, e: - assert 'type' in e.error_dict and e.error_dict['type'] == [u'Missing value'] - - def test_related_create_featured_as_sysadmin(self): - '''Sysadmin can create featured related items''' - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - - context = { - 'model': model, - 'user': usr['name'], - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - 'featured': 1, - } - - result = logic.get_action("related_create")(context, data_dict) - - assert_equal(result['featured'], 1) - - def test_related_create_featured_as_non_sysadmin_fails(self): - '''Non-sysadmin users should not be able to create featured relateds''' - - context = { - 'model': model, - 'user': 'annafan', - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - 'featured': 1, - } - - assert_raises( - logic.NotAuthorized, - logic.get_action('related_create'), - context, - data_dict) - - def test_related_create_not_featured_as_non_sysadmin_succeeds(self): - '''Non-sysadmins can set featured to false''' - - context = { - 'model': model, - 'user': 'annafan', - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - 'featured': 0, - } - - result = logic.get_action("related_create")(context, data_dict) - - assert_equal(result['featured'], 0) - - def test_related_create_featured_empty_as_non_sysadmin_succeeds(self): - '''Non-sysadmins can leave featured empty.''' - - context = { - 'model': model, - 'user': 'annafan', - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - } - - result = logic.get_action("related_create")(context, data_dict) - - assert_equal(result['featured'], 0) - - def test_related_delete(self): - rel = self._related_create("Title", "Description", - "visualization", - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = dict(id=rel['id']) - logic.get_action('related_delete')(context, data_dict) - - r = model.Related.get(rel['id']) - assert r is None, r # Ensure it doesn't exist - - def test_related_update(self): - rel = self._related_create("Title", "Description", - "visualization", - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = rel - data_dict['title'] = "New Title" - result = logic.get_action('related_update')(context,data_dict) - assert result['title'] == 'New Title' - - def test_sysadmin_changes_related_items_featured_field(self): - '''Sysadmins can change featured field''' - rel = self._related_create( - "Title", - "Description", - "visualization", - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = { - 'model': model, - 'user': usr['name'], - 'session': model.Session - } - - data_dict = rel - data_dict['title'] = "New Title" - data_dict['featured'] = 1 - result = logic.get_action('related_update')(context,data_dict) - assert_equal(result['title'], 'New Title') - assert_equal(result['featured'], 1) - - def test_non_sysadmin_changes_related_items_featured_field_fails(self): - '''Non-sysadmins cannot change featured field''' - - context = { - 'model': model, - 'user': 'annafan', - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - } - - # Create the related item as annafan - result = logic.get_action('related_create')(context, data_dict) - - # Try to change it to a featured item - result['featured'] = 1 - - try: - logic.get_action('related_update')(context, result) - except logic.NotAuthorized, e: - # Check it's the correct authorization error - assert 'featured' in str(e) - - def test_non_sysadmin_can_update_related_item(self): - '''Non-sysadmins can change related item. - - If they don't change the featured field. - ''' - - context = { - 'model': model, - 'user': 'annafan', - 'session': model.Session - } - - data_dict = { - 'title': 'Title', - 'description': 'Description', - 'type': 'visualization', - 'url': 'http://ckan.org', - 'image_url': 'http://ckan.org/files/2012/03/ckanlogored.png', - } - - # Create the related item as annafan - result = logic.get_action('related_create')(context, data_dict) - - # Try to change it to a featured item - result['title'] = 'New Title' - - result = logic.get_action('related_update')(context, result) - assert_equal(result['title'], 'New Title') - - def test_update_related_item_check_owner_status(self): - '''After edit of a related item by a sysadmin, check that the owner id is unchanged - ''' - offset = h.url_for(controller='related', - action='new', id='warandpeace') - data = { - "title": "testing_create", - "url": u"http://ckan.org/feed/", - } - user = model.User.by_name('tester') - admin = model.User.by_name('testsysadmin') - - #create related item - context = dict(model=model, user=user.name, session=model.Session) - data_dict = dict(title="testing_create",description="description", - url="http://ckan.org/feed/",image_url="",type="visualization") - res = logic.get_action("related_create")( context, data_dict ) - - #edit related item - data_dict = dict(id=res['id'],title="testing_update",description="description", - url="http://ckan.org/feed/",image_url="",type="visualization") - - context = dict(model=model, user=admin.name, session=model.Session) - result = logic.get_action('related_update')(context,data_dict) - #Confirm related item owner status - assert result['owner_id'] == user.id - - def test_related_show(self): - rel = self._related_create("Title", "Description", - "visualization", - "http://ckan.org", - "http://ckan.org/files/2012/03/ckanlogored.png") - - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = {'id': rel['id']} - - result = logic.get_action('related_show')(context,data_dict) - assert rel['id'] == result['id'], result - assert rel['title'] == result['title'], result - assert rel['description'] == result['description'], result - assert rel['description'] == result['description'], result - - def test_related_list_missing_id_and_name(self): - p = model.Package.get('warandpeace') - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = {} - related_list = logic.get_action('related_list')(context, data_dict) - assert len(related_list) == 8 - related_keys = set(['view_count', 'description', 'title', 'url', - 'created', 'featured', 'image_url', 'type', 'id', 'owner_id']) - for related in related_list: - assert set(related.keys()) == related_keys - - - def test_related_list(self): - p = model.Package.get('warandpeace') - r = model.Related(title="Title", type="idea") - p.related.append(r) - r = model.Related(title="Title 2", type="idea") - p.related.append(r) - model.Session.add(r) - model.Session.commit() - - assert len(p.related) == 2 - assert p.related_count == 2, p.related_count - - usr = logic.get_action('get_site_user')({'model':model,'ignore_auth': True},{}) - context = dict(model=model, user=usr['name'], session=model.Session) - data_dict = {'id': p.id} - - result = logic.get_action('related_list')(context,data_dict) - assert len(result) == len(p.related) - -class TestRelatedActionAPI(apibase.BaseModelApiTestCase): - - @classmethod - def setup_class(cls): - model.Session.remove() - tests.CreateTestData.create() - cls.user_name = u'russianfan' # created in CreateTestData - cls.init_extra_environ(cls.user_name) - - @classmethod - def teardown_class(self): - model.repo.rebuild_db() - - def test_api_create_invalid(self): - res = self.app.post("/api/3/action/related_create", params="{}=1", - status=self.STATUS_409_CONFLICT, - extra_environ=self.extra_environ) - r = json.loads(res.body) - assert r['success'] == False, r - - - def _create(self, rtype="visualization", title="Test related item"): - r = { - "type": rtype, - "title": title - } - postparams = '%s=1' % json.dumps(r) - res = self.app.post("/api/3/action/related_create", params=postparams, - status=self.STATUS_200_OK, - extra_environ=self.extra_environ) - r = json.loads(res.body) - return r - - def test_api_create_valid(self): - r = self._create() - assert r['success'] == True, r - assert r['result']['type'] == "visualization" - assert r['result']['title'] == "Test related item" - - def test_api_show(self): - existing = self._create() - - r = { - "id": existing["result"]["id"] - } - postparams = '%s=1' % json.dumps(r) - res = self.app.post("/api/3/action/related_show", params=postparams, - status=self.STATUS_200_OK, - extra_environ=self.extra_environ) - r = json.loads(res.body) - assert r['success'] == True, r - assert r['result']['type'] == "visualization" - assert r['result']['title'] == "Test related item" - - - def test_api_list(self): - p = model.Package.get('warandpeace') - one = model.Related(type="idea", title="one") - two = model.Related(type="idea", title="two") - p.related.append(one) - p.related.append(two) - model.Session.commit() - - r = { - "id": p.id - } - postparams = '%s=1' % json.dumps(r) - res = self.app.post("/api/3/action/related_list", params=postparams, - status=self.STATUS_200_OK, - extra_environ=self.extra_environ) - r = json.loads(res.body) - assert r['success'] == True, r - assert r['result'][0]['type'] == "idea" - assert r['result'][0]['title'] == "two", r - - p.related.remove(one) - p.related.remove(two) - model.Session.delete(one) - model.Session.delete(two) - - def test_api_delete(self): - existing = self._create() - - r = { - "id": existing["result"]["id"] - } - postparams = '%s=1' % json.dumps(r) - res = self.app.post("/api/3/action/related_delete", params=postparams, - status=self.STATUS_200_OK, - extra_environ=self.extra_environ) - r = json.loads(res.body) - assert r['success'] == True, r - assert r['result'] is None, r - - def test_api_delete_fail(self): - existing = self._create() - r = { - "id": existing["result"]["id"] - } - - usr = model.User.by_name("annafan") - extra={'Authorization' : str(usr.apikey)} - - postparams = '%s=1' % json.dumps(r) - res = self.app.post("/api/3/action/related_delete", params=postparams, - status=self.STATUS_403_ACCESS_DENIED, - extra_environ=extra) - r = json.loads(res.body) - assert r['success'] == False, r - assert r[u'error'][u'__type'] == "Authorization Error", r diff --git a/ckan/tests/legacy/logic/test_action.py b/ckan/tests/legacy/logic/test_action.py index 164eb42d72a..2c109002bea 100644 --- a/ckan/tests/legacy/logic/test_action.py +++ b/ckan/tests/legacy/logic/test_action.py @@ -1362,72 +1362,3 @@ def _assert_we_can_add_user_to_group(self, user_id, group_id): group_ids = [g.id for g in groups] assert res['success'] is True, res assert group.id in group_ids, (group, user_groups) -<<<<<<< HEAD -======= - - -class TestRelatedAction(WsgiAppCase): - - sysadmin_user = None - - normal_user = None - - @classmethod - def setup_class(cls): - search.clear_all() - CreateTestData.create() - cls.sysadmin_user = model.User.get('testsysadmin') - - @classmethod - def teardown_class(cls): - model.repo.rebuild_db() - - def _add_basic_package(self, package_name=u'test_package', **kwargs): - package = { - 'name': package_name, - 'title': u'A Novel By Tolstoy', - 'resources': [{ - 'description': u'Full text.', - 'format': u'plain text', - 'url': u'http://datahub.io/download/' - }] - } - package.update(kwargs) - - postparams = '%s=1' % json.dumps(package) - res = self.app.post('/api/action/package_create', params=postparams, - extra_environ={'Authorization': 'tester'}) - return json.loads(res.body)['result'] - - def test_update_add_related_item(self): - package = self._add_basic_package() - related_item = { - "description": "Testing a Description", - "url": "http://example.com/image.png", - "title": "Testing", - "featured": 0, - "image_url": "http://example.com/image.png", - "type": "idea", - "dataset_id": package['id'], - } - related_item_json = json.dumps(related_item) - res_create = self.app.post('/api/action/related_create', - params=related_item_json, - extra_environ={'Authorization': 'tester'}) - assert res_create.json['success'] - - related_update = res_create.json['result'] - related_update = {'id': related_update['id'], 'title': 'Updated'} - related_update_json = json.dumps(related_update) - res_update = self.app.post('/api/action/related_update', - params=related_update_json, - extra_environ={'Authorization': 'tester'}) - assert res_update.json['success'] - res_update_json = res_update.json['result'] - assert res_update_json['title'] == related_update['title'] - - related_item.pop('title') - related_item.pop('dataset_id') - for field in related_item: - assert related_item[field] == res_update_json[field] ->>>>>>> master From e225985c82e007746aed67ab3504d52d958f86dd Mon Sep 17 00:00:00 2001 From: Ross Jones Date: Wed, 23 Dec 2015 11:48:13 +0000 Subject: [PATCH 3/4] Change migration to emit a warning if data exists If there is related data, it is not deleted but the user is given a warning to allow them to migrate to ckanext-showcase and how to manually delete the tables. --- .../versions/083_remove_related_items.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ckan/migration/versions/083_remove_related_items.py b/ckan/migration/versions/083_remove_related_items.py index a80fa7c6532..befb3b13d6c 100644 --- a/ckan/migration/versions/083_remove_related_items.py +++ b/ckan/migration/versions/083_remove_related_items.py @@ -1,5 +1,24 @@ +WARNING = """ + +WARNING: The 'related' tables were not deleted as they currently contain data. +Once you have archived the existing data or migrated the data to +ckanext-showcase, you can safely delete the 'related' and 'related_dataset' +tables using: + + psql ckan_default -c 'BEGIN; DROP TABLE related_dataset; \\ + DROP TABLE related; COMMIT;' + +""" + + def upgrade(migrate_engine): + existing = migrate_engine.execute("SELECT COUNT(*) FROM related;")\ + .fetchone() + if existing[0] > 0: + print WARNING + return + migrate_engine.execute(''' BEGIN; DROP TABLE related_dataset; From 6441e0cf83814ea643cf62123d105a59a1559e15 Mon Sep 17 00:00:00 2001 From: Ross Jones Date: Wed, 20 Jan 2016 18:03:18 +0000 Subject: [PATCH 4/4] Remove un-needed related item templates --- .../base/javascript/modules/related-item.js | 80 ----------------- ckan/public/base/javascript/resource.config | 1 - .../test/spec/modules/related-item.spec.js | 87 ------------------- ckan/templates/package/related_list.html | 22 ----- 4 files changed, 190 deletions(-) delete mode 100644 ckan/public/base/javascript/modules/related-item.js delete mode 100644 ckan/public/base/test/spec/modules/related-item.spec.js delete mode 100644 ckan/templates/package/related_list.html diff --git a/ckan/public/base/javascript/modules/related-item.js b/ckan/public/base/javascript/modules/related-item.js deleted file mode 100644 index 4c16ec41fcf..00000000000 --- a/ckan/public/base/javascript/modules/related-item.js +++ /dev/null @@ -1,80 +0,0 @@ -/* Module that handles related item elements, at the moment this consists of - * truncating the descriptions and allowing them to be toggled. - * - * truncate - The max number of characters in the description element. - * truncateMore - A locale string for the "more" text. - * truncateLess - A locale string for the "less" text. - * truncatePrefix - A prefix for the more/less strings. - * truncateSuffix - A suffix for the more/less strings. - * truncateSelector - A selector for the element to truncate. - * expandedClass - A class to apply to the element when expanded. - */ -this.ckan.module('related-item', function (jQuery, _) { - return { - /* options object can be extended using data-module-* attributes */ - options: { - truncate: 55, - truncateMore: null, - truncateLess: null, - truncatePrefix: '', - truncateSuffix: '', - truncateSelector: '.prose', - expandedClass: 'expanded', - hasExpanderClass: 'is-expander', - i18n: { - more: _('show more'), - less: _('show less') - } - }, - - /* Initialises the module setting up elements and event listeners. - * - * Returns nothing. - */ - initialize: function () { - jQuery.proxyAll(this, /_on/); - - var options = this.options; - this.description = this.$(options.truncateSelector); - this.truncated = this.description.truncate({ - max_length: options.truncate, - more: options.truncateMore || this.i18n('more'), - less: options.truncateLess || this.i18n('less'), - link_prefix: options.truncatePrefix, - link_suffix: options.truncateSuffix - }); - - this.collapsedHeight = this.el.height(); - this.truncated.on('expand.truncate', this._onExpand); - this.truncated.on('collapse.truncate', this._onCollapse); - - if ($('.truncator-link', this.description).length > 0) { - this.el.addClass(options.hasExpanderClass); - } - - }, - - /* Event handler called when the truncated text expands. - * - * event - An event object. - * - * Returns nothing. - */ - _onExpand: function () { - var diff = this.el.height() - this.collapsedHeight; - this.el.addClass(this.options.expandedClass); - this.el.css('margin-bottom', diff * -1); - }, - - /* Event handler called when the truncated text is collapsed. - * - * event - An event object. - * - * Returns nothing. - */ - _onCollapse: function () { - this.el.removeClass(this.options.expandedClass); - this.el.css('margin-bottom', ''); - } - }; -}); diff --git a/ckan/public/base/javascript/resource.config b/ckan/public/base/javascript/resource.config index fbf6996d19c..0e3c535081f 100644 --- a/ckan/public/base/javascript/resource.config +++ b/ckan/public/base/javascript/resource.config @@ -27,7 +27,6 @@ ckan = modules/api-info.js modules/autocomplete.js modules/custom-fields.js - modules/related-item.js modules/data-viewer.js modules/table-selectable-rows.js modules/resource-form.js diff --git a/ckan/public/base/test/spec/modules/related-item.spec.js b/ckan/public/base/test/spec/modules/related-item.spec.js deleted file mode 100644 index b1486e90040..00000000000 --- a/ckan/public/base/test/spec/modules/related-item.spec.js +++ /dev/null @@ -1,87 +0,0 @@ -/*globals describe before beforeEach afterEach it assert sinon ckan jQuery */ -describe('ckan.module.RelatedItemModule()', function () { - var RelatedItemModule = ckan.module.registry['related-item']; - - before(function (done) { - // Load our fixture into the this.fixture element. - this.loadFixture('related-item.html', function (html) { - this.template = html; - done(); - }); - }); - - beforeEach(function () { - this.truncated = jQuery('
    '); - jQuery.fn.truncate = sinon.stub().returns(this.truncated); - - // Grab the loaded fixture. - this.el = this.fixture.html(this.template).children(); - this.sandbox = ckan.sandbox(); - this.sandbox.body = this.fixture; - this.module = new RelatedItemModule(this.el, {}, this.sandbox); - }); - - afterEach(function () { - this.module.teardown(); - delete jQuery.fn.truncate; - }); - - describe('.initialize()', function () { - it('should truncate the .prose element', function () { - this.module.initialize(); - assert.called(jQuery.fn.truncate); - }); - - it('should pass the various options into the truncate plugin'); - - it('should cache the collapsed height of the plugin', function () { - this.module.initialize(); - assert.ok(this.module.collapsedHeight); - }); - - it('should listen for the "truncate" events', function () { - var target = sinon.stub(this.truncated, 'on'); - this.module.initialize(); - - assert.called(target); - assert.calledWith(target, 'expand.truncate', this.module._onExpand); - assert.calledWith(target, 'collapse.truncate', this.module._onCollapse); - }); - }); - - describe('._onExpand(event)', function () { - it('should add the "expanded" class to the element', function () { - this.module._onExpand(jQuery.Event()); - assert.isTrue(this.el.hasClass(this.module.options.expandedClass)); - }); - - it('should add a bottom margin to the element', function () { - this.module._onExpand(jQuery.Event()); - assert.ok(this.el.css('margin-bottom')); - }); - - it('should calcualte the difference between the current and cached height', function () { - var target = sinon.stub(this.el, 'css'); - sinon.stub(this.el, 'height').returns(30); - this.module.collapsedHeight = 10; - this.module._onExpand(jQuery.Event()); - - assert.called(target); - assert.calledWith(target, 'margin-bottom', -20); - }); - }); - - describe('._onCollapse(event)', function () { - it('should remove the "expanded" class from the element', function () { - this.el.addClass(this.module.options.expandedClass); - this.module._onCollapse(jQuery.Event()); - assert.isFalse(this.el.hasClass(this.module.options.expandedClass)); - }); - - it('should remove the bottom margin from the element', function () { - this.el.css('margin-bottom', -90); - this.module._onCollapse(jQuery.Event()); - assert.equal(this.el.css('margin-bottom'), '0px'); - }); - }); -}); diff --git a/ckan/templates/package/related_list.html b/ckan/templates/package/related_list.html deleted file mode 100644 index 75576b8d707..00000000000 --- a/ckan/templates/package/related_list.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "package/read_base.html" %} - - -{% block subtitle %}{{ _('Related') }} - {{ super() }}{% endblock %} - -{% block primary_content_inner %} -

    {% block page_heading %}{{ _('Related Media for {dataset}').format(dataset=h.dataset_display_name(c.pkg)) }}{% endblock %}

    - {% block related_list %} - {% if c.related_list %} - {% snippet "related/snippets/related_list.html", related_items=c.related_list, pkg_id=c.pkg_dict.name %} - {% else %} -

    {{ _('No related items') }}

    - {% endif %} - {% endblock %} - {% block form_actions %} - {% if h.check_access('related_create') %} -
    - {% link_for _('Add Related Item'), controller='related', action='new', id=pkg.name, class_='btn btn-primary' %} -
    - {% endif %} - {% endblock %} -{% endblock %}