Migrate from IRoute to IBlueprint

This commit is contained in:
Álvaro Arranz 2018-07-14 12:31:35 +02:00
parent c43c549539
commit f1341686c0
No known key found for this signature in database
GPG Key ID: A9BA9AAE8CF561AB
14 changed files with 351 additions and 193 deletions

View File

@ -1,2 +1,3 @@
recursive-include ckanext/privatedatasets/templates * recursive-include ckanext/privatedatasets/templates *
recursive-include ckanext/privatedatasets/fanstatic * recursive-include ckanext/privatedatasets/templates_2.8 *
recursive-include ckanext/privatedatasets/fanstatic *

View File

@ -1,51 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2014 CoNWeT Lab., Universidad Politécnica de Madrid
# This file is part of CKAN Private Dataset Extension.
# CKAN Private Dataset Extension is free software: you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# CKAN Private Dataset Extension is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with CKAN Private Dataset Extension. If not, see <http://www.gnu.org/licenses/>.
import ckanext.privatedatasets.constants as constants
import ckan.lib.base as base
import ckan.model as model
import ckan.plugins as plugins
import logging
from ckan.common import _
log = logging.getLogger(__name__)
class AcquiredDatasetsControllerUI(base.BaseController):
def user_acquired_datasets(self):
c = plugins.toolkit.c
context = {
'model': model,
'session': model.Session,
'user': plugins.toolkit.c.user,
}
# Get user information
try:
c.user_dict = plugins.toolkit.get_action('user_show')(context.copy(), {'user_obj': c.userobj})
c.user_dict['acquired_datasets'] = plugins.toolkit.get_action(constants.ACQUISITIONS_LIST)(context.copy(), None)
except plugins.toolkit.ObjectNotFound:
plugins.toolkit.abort(404, _('User not found'))
except plugins.toolkit.NotAuthorized:
plugins.toolkit.abort(401, _('Not authorized to see this page'))
return plugins.toolkit.render('user/dashboard_acquired.html')

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2014 - 2017 CoNWeT Lab., Universidad Politécnica de Madrid # Copyright (c) 2014 - 2017 CoNWeT Lab., Universidad Politécnica de Madrid
# Copyright (c) 2018 Future Internet Consulting and Development Solutions S.L.
# This file is part of CKAN Private Dataset Extension. # This file is part of CKAN Private Dataset Extension.
@ -17,15 +18,16 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with CKAN Private Dataset Extension. If not, see <http://www.gnu.org/licenses/>. # along with CKAN Private Dataset Extension. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import from __future__ import absolute_import, unicode_literals
from ckan import model, plugins as p from ckan import model, plugins as p
from ckan.lib import search from ckan.lib import search
from ckan.lib.plugins import DefaultPermissionLabels from ckan.lib.plugins import DefaultPermissionLabels
from ckan.plugins import toolkit as tk from ckan.plugins import toolkit as tk
from flask import Blueprint
from ckanext.privatedatasets import auth, actions, constants, converters_validators as conv_val, db, helpers from ckanext.privatedatasets import auth, actions, constants, converters_validators as conv_val, db, helpers
from ckanext.privatedatasets.views import acquired_datasets
HIDDEN_FIELDS = [constants.ALLOWED_USERS, constants.SEARCHABLE] HIDDEN_FIELDS = [constants.ALLOWED_USERS, constants.SEARCHABLE]
@ -35,7 +37,7 @@ class PrivateDatasets(p.SingletonPlugin, tk.DefaultDatasetForm, DefaultPermissio
p.implements(p.IDatasetForm) p.implements(p.IDatasetForm)
p.implements(p.IAuthFunctions) p.implements(p.IAuthFunctions)
p.implements(p.IConfigurer) p.implements(p.IConfigurer)
p.implements(p.IRoutes, inherit=True) p.implements(p.IBlueprint)
p.implements(p.IActions) p.implements(p.IActions)
p.implements(p.IPackageController, inherit=True) p.implements(p.IPackageController, inherit=True)
p.implements(p.ITemplateHelpers) p.implements(p.ITemplateHelpers)
@ -128,22 +130,22 @@ class PrivateDatasets(p.SingletonPlugin, tk.DefaultDatasetForm, DefaultPermissio
def update_config(self, config): def update_config(self, config):
# Add this plugin's templates dir to CKAN's extra_template_paths, so # Add this plugin's templates dir to CKAN's extra_template_paths, so
# that CKAN will use this plugin's custom templates. # that CKAN will use this plugin's custom templates.
tk.add_template_directory(config, 'templates') if p.toolkit.check_ckan_version(min_version='2.8'):
tk.add_template_directory(config, 'templates_2.8')
else:
tk.add_template_directory(config, 'templates')
# Register this plugin's fanstatic directory with CKAN. # Register this plugin's fanstatic directory with CKAN.
tk.add_resource('fanstatic', 'privatedatasets') tk.add_resource(b'fanstatic', b'privatedatasets')
###################################################################### ######################################################################
############################## IROUTES ############################### ############################# IBLUEPRINT #############################
###################################################################### ######################################################################
def before_map(self, m): def get_blueprint(self):
# DataSet acquired notification blueprint = Blueprint('privatedatasets', self.__module__)
m.connect('user_acquired_datasets', '/dashboard/acquired', ckan_icon='shopping-cart', blueprint.add_url_rule('/dashboard/acquired', 'acquired_datasets', acquired_datasets)
controller='ckanext.privatedatasets.controllers.ui_controller:AcquiredDatasetsControllerUI', return blueprint
action='user_acquired_datasets', conditions=dict(method=['GET']))
return m
###################################################################### ######################################################################
############################## IACTIONS ############################## ############################## IACTIONS ##############################

View File

@ -18,7 +18,7 @@
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
{{ h.build_nav_icon('user_dashboard', _('News feed')) }} {{ h.build_nav_icon('user_dashboard', _('News feed')) }}
{{ h.build_nav_icon('user_dashboard_datasets', _('My Datasets')) }} {{ h.build_nav_icon('user_dashboard_datasets', _('My Datasets')) }}
{{ h.build_nav_icon('user_acquired_datasets', _('Acquired Datasets')) }} {{ h.build_nav_icon('privatedatasets.acquired_datasets', _('Acquired Datasets')) }}
{{ h.build_nav_icon('user_dashboard_organizations', _('My Organizations')) }} {{ h.build_nav_icon('user_dashboard_organizations', _('My Organizations')) }}
{{ h.build_nav_icon('user_dashboard_groups', _('My Groups')) }} {{ h.build_nav_icon('user_dashboard_groups', _('My Groups')) }}
</ul> </ul>
@ -46,4 +46,4 @@
{% endblock %} {% endblock %}
</div> </div>
</article> </article>
{% endblock %} {% endblock %}

View File

@ -8,12 +8,12 @@
{% block primary_content_inner %} {% block primary_content_inner %}
<h2 class="hide-heading">{{ _('Acquired Datasets') }}</h2> <h2 class="hide-heading">{{ _('Acquired Datasets') }}</h2>
{% if c.user_dict.acquired_datasets %} {% if acquired_datasets %}
{% snippet 'snippets/package_list.html', packages=c.user_dict.acquired_datasets %} {% snippet 'snippets/package_list.html', packages=acquired_datasets %}
{% else %} {% else %}
<p class="empty"> <p class="empty">
{{ _('You haven\'t acquired any datasets.') }} {{ _('You haven\'t acquired any datasets.') }}
{% link_for _('Acquire one now?'), controller='package', action='search' %} {% link_for _('Acquire one now?'), controller='package', action='search' %}
</p> </p>
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View File

@ -0,0 +1,107 @@
{% ckan_extends %}
{% block package_basic_fields_org %}
{% resource 'privatedatasets/allowed_users.js' %}
{# if we have a default group then this wants remembering #}
{% if data.group_id %}
<input type="hidden" name="groups__0__id" value="{{ data.group_id }}" />
{% endif %}
{% set dataset_is_draft = data.get('state', 'draft').startswith('draft') or data.get('state', 'none') == 'none' %}
{% set dataset_has_organization = data.owner_org or data.group_id %}
{% set organizations_available = h.organizations_available('create_dataset') %}
{% set user_is_sysadmin = h.check_access('sysadmin') %}
{% set show_organizations_selector = organizations_available and (user_is_sysadmin or dataset_is_draft) %}
{% set editing = 'id' in data %}
{% if show_organizations_selector and show_visibility_selector %}
<div>
{% endif %}
{% if show_organizations_selector %}
{% set existing_org = data.owner_org or data.group_id %}
<div class="control-group">
<label for="field-organizations" class="control-label">{{ _('Organization') }}</label>
<div class="controls">
<select id="field-organizations" name="owner_org" data-module="autocomplete">
{% if h.check_config_permission('create_unowned_dataset') %}
<option value="" {% if not selected_org and data.id %} selected="selected" {% endif %}>{{ _('No organization') }}</option>
{% endif %}
{% for organization in organizations_available %}
{# get out first org from users list only if there is not an existing org #}
{% set selected_org = (existing_org and existing_org == organization.id) or (not existing_org and not data.id and organization.id == organizations_available[0].id) %}
<option value="{{ organization.id }}" {% if selected_org %} selected="selected" {% endif %}>{{ organization.name }}</option>
{% endfor %}
</select>
</div>
</div>
{% endif %}
{% block package_metadata_fields_visibility %}
<div class="control-group">
<label for="field-private" class="control-label">{{ _('Visibility') }}</label>
<div class="controls">
<select id="field-private" name="private" data-module="allowed-users">
{% for option in [('True', _('Private')), ('False', _('Public'))] %}
<option value="{{ option[0] }}" {% if option[0] == data.private|trim %}selected="selected"{% endif %}>{{ option[1] }}</option>
{% endfor %}
</select>
<span class="info-block info-inline">
<i class="icon-info-sign fa fa-info-circle"></i>
{% trans %}
Private datasets can only be accessed by certain users, while public datasets can be accessed by anyone.
{% endtrans %}
</span>
</div>
</div>
{% endblock %}
{% block package_metadata_fields_protected %}
<div class="control-group">
<label for="field-searchable" class="control-label">{{ _('Searchable') }}</label>
<div class="controls">
<select id="field-searchable" name="searchable">
{% for option in [('True', _('True')), ('False', _('False'))] %}
<option value="{{ option[0] }}" {% if option[0] == data.searchable|trim %}selected="selected"{% endif %}>{{ option[1] }}</option>
{% endfor %}
</select>
<span class="info-block info-inline">
<i class="icon-info-sign fa fa-info-circle"></i>
{% trans %}
Searchable datasets can be searched by anyone, while not-searchable datasets can only be accessed by entering directly its URL.
{% endtrans %}
</span>
</div>
</div>
{% endblock %}
{% if show_organizations_selector and show_visibility_selector %}
</div>
{% endif %}
{% set users_attrs = {'data-module': 'autocomplete', 'data-module-tags': '', 'data-module-source': '/api/2/util/user/autocomplete?q=?'} %}
{{ form.input('allowed_users_str', label=_('Allowed Users'), id='field-allowed_users_str', placeholder=_('Allowed Users'), value=h.get_allowed_users_str(data.allowed_users), error=errors.custom_text, classes=['control-full'], attrs=users_attrs) }}
{% if editing and h.show_acquire_url_on_edit() or not editing and h.show_acquire_url_on_create() %}
{{ form.input('acquire_url', label=_('Acquire URL'), id='field-acquire_url', placeholder=_('http://example.com/acquire/'), value=data.acquire_url, error=errors.custom_text, classes=['control-medium']) }}
{% else %}
<input type="hidden" name="acquire_url" id="acquire_url" value="{{ data.acquire_url }}" />
{% endif %}
{% if data.id and h.check_access('package_delete', {'id': data.id}) and data.state != 'active' %}
<div class="control-group">
<label for="field-state" class="control-label">{{ _('State') }}</label>
<div class="controls">
<select id="field-state" name="state">
<option value="active" {% if data.get('state', 'none') == 'active' %} selected="selected" {% endif %}>{{ _('Active') }}</option>
<option value="deleted" {% if data.get('state', 'none') == 'deleted' %} selected="selected" {% endif %}>{{ _('Deleted') }}</option>
</select>
</div>
</div>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,15 @@
{#
Displays a Get Access button to request access to a private dataset.
ulr_dest - target url
Example:
{% snippet 'snippets/acquire_button.html', url_dest=url %}
#}
<a href={{ url_dest }} class="btn btn-mini" target="_blank">
<i class="icon-shopping-cart fa fa-shopping-cart"></i>
{{ _('Acquire') }}
</a>

View File

@ -0,0 +1,82 @@
{#
Displays a single of dataset.
package - A package to display.
item_class - The class name to use on the list item.
hide_resources - If true hides the resources (default: false).
banner - If true displays a popular banner (default: false).
truncate - The length to trucate the description to (default: 180)
truncate_title - The length to truncate the title to (default: 80).
Example:
{% snippet 'snippets/package_item.html', package=c.datasets[0] %}
#}
{% set truncate = truncate or 180 %}
{% set truncate_title = truncate_title or 80 %}
{% set title = package.title or package.name %}
{% set notes = h.markdown_extract(package.notes, extract_length=truncate) %}
{% set acquired = h.is_dataset_acquired(package) %}
{% set owner = h.is_owner(package) %}
{% resource 'privatedatasets/custom.css' %}
<li class="{{ item_class or "dataset-item" }}">
{% block package_item_content %}
<div class="dataset-content">
<h3 class="dataset-heading">
{% if package.private and not h.can_read(package) %}
<span class="dataset-private label label-inverse">
<i class="icon-lock fa fa-lock"></i>
{{ _('Private') }}
</span>
{% endif %}
{% if acquired and not owner %}
<span class="dataset-private label label-acquired">
<i class="icon-shopping-cart fa fa-shopping-cart"></i>
{{ _('Acquired') }}
</span>
{% endif %}
{% if owner %}
<span class="dataset-private label label-owner">
<i class="icon-user fa fa-user"></i>
{{ _('Owner') }}
</span>
{% endif %}
<!-- Customizations Acquire Button -->
{% if package.private and not h.can_read(package) %}
{{ _(h.truncate(title, truncate_title)) }}
<div class="divider"/>
{{ h.acquire_button(package) }}
{% else %}
{{ h.link_to(h.truncate(title, truncate_title), h.url_for(controller='package', action='read', id=package.name)) }}
{% endif %}
<!-- End of customizations Acquire Button -->
{% if package.get('state', '').startswith('draft') %}
<span class="label label-info">{{ _('Draft') }}</span>
{% elif package.get('state', '').startswith('deleted') %}
<span class="label label-important">{{ _('Deleted') }}</span>
{% endif %}
{{ h.popular('recent views', package.tracking_summary.recent, min=10) if package.tracking_summary }}
</h3>
{% if banner %}
<span class="banner">{{ _('Popular') }}</span>
{% endif %}
{% if notes %}
<div>{{ notes|urlize }}</div>
{% endif %}
</div>
{% if package.resources and not hide_resources %}
<ul class="dataset-resources unstyled">
{% for resource in h.dict_list_reduce(package.resources, 'format') %}
<li>
<a href="{{ h.url_for(controller='package', action='read', id=package.name) }}" class="label" data-format="{{ resource.lower() }}">{{ resource }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
</li>

View File

@ -0,0 +1,49 @@
{% extends "user/edit_base.html" %}
{% set user = g.userobj %}
{% block breadcrumb_content %}
<li class="active"><a href="{{ h.url_for('dashboard.index') }}">{{ _('Dashboard') }}</a></li>
{% endblock %}
{% block secondary %}{% endblock %}
{% block primary %}
<article class="module">
{% block page_header %}
<header class="module-content page-header hug">
<div class="content_action">
{% link_for _('Edit settings'), named_route='user.edit', id=user.name, class_='btn btn-default', icon='cog' %}
</div>
<ul class="nav nav-tabs">
{{ h.build_nav_icon('dashboard.index', _('News feed')) }}
{{ h.build_nav_icon('dashboard.datasets', _('My Datasets')) }}
{{ h.build_nav_icon('privatedatasets.acquired_datasets', _('Acquired Datasets')) }}
{{ h.build_nav_icon('dashboard.organizations', _('My Organizations')) }}
{{ h.build_nav_icon('dashboard.groups', _('My Groups')) }}
</ul>
</header>
{% endblock %}
<div class="module-content">
{% if self.page_primary_action() | trim %}
<div class="page_primary_action">
{% block page_primary_action %}{% endblock %}
</div>
{% endif %}
{% block primary_content_inner %}
<div data-module="dashboard">
{% snippet 'user/snippets/followee_dropdown.html', context=dashboard_activity_stream_context, followees=followee_list %}
<h2 class="page-heading">
{% block page_heading %}
{{ _('News feed') }}
{% endblock %}
<small>{{ _("Activity from items that I'm following") }}</small>
</h2>
{% block activity_stream %}
{{ dashboard_activity_stream|safe }}
{% endblock %}
</div>
{% endblock %}
</div>
</article>
{% endblock %}

View File

@ -0,0 +1,19 @@
{% extends "user/dashboard.html" %}
{% block dashboard_activity_stream_context %}{% endblock %}
{% block page_primary_action %}
{% link_for _('Acquire Dataset'), controller='package', action='search', class_="btn btn-primary", icon="shopping-cart" %}
{% endblock %}
{% block primary_content_inner %}
<h2 class="hide-heading">{{ _('Acquired Datasets') }}</h2>
{% if acquired_datasets %}
{% snippet 'snippets/package_list.html', packages=acquired_datasets %}
{% else %}
<p class="empty">
{{ _('You haven\'t acquired any datasets.') }}
{% link_for _('Acquire one now?'), controller='package', action='search' %}
</p>
{% endif %}
{% endblock %}

View File

@ -1,110 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2014 CoNWeT Lab., Universidad Politécnica de Madrid
# This file is part of CKAN Private Dataset Extension.
# CKAN Private Dataset Extension is free software: you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# CKAN Private Dataset Extension is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with CKAN Private Dataset Extension. If not, see <http://www.gnu.org/licenses/>.
import ckanext.privatedatasets.controllers.ui_controller as controller
import unittest
from mock import MagicMock, ANY
from parameterized import parameterized
class UIControllerTest(unittest.TestCase):
def setUp(self):
# Get the instance
self.instanceUI = controller.AcquiredDatasetsControllerUI()
# Load the mocks
self._plugins = controller.plugins
controller.plugins = MagicMock()
self._model = controller.model
controller.model = MagicMock()
# Set exceptions
controller.plugins.toolkit.ObjectNotFound = self._plugins.toolkit.ObjectNotFound
controller.plugins.toolkit.NotAuthorized = self._plugins.toolkit.NotAuthorized
def tearDown(self):
# Unmock
controller.plugins = self._plugins
controller.model = self._model
@parameterized.expand([
(controller.plugins.toolkit.ObjectNotFound, 404),
(controller.plugins.toolkit.NotAuthorized, 401)
])
def test_exceptions_loading_users(self, exception, expected_status):
# Configure the mock
user_show = MagicMock(side_effect=exception)
controller.plugins.toolkit.get_action = MagicMock(return_value=user_show)
# Call the function
self.instanceUI.user_acquired_datasets()
# Assertations
expected_context = {
'model': controller.model,
'session': controller.model.Session,
'user': controller.plugins.toolkit.c.user
}
user_show.assert_called_once_with(expected_context, {'user_obj': controller.plugins.toolkit.c.userobj})
controller.plugins.toolkit.abort.assert_called_once_with(expected_status, ANY)
def test_no_error_loading_users(self):
user = 'example_user_test'
controller.plugins.toolkit.c.user = user
# actions
default_user = {'user_name': 'test', 'another_val': 'example value'}
user_show = MagicMock(return_value=default_user)
acquisitions_list = MagicMock()
def _get_action(action):
if action == 'user_show':
return user_show
else:
return acquisitions_list
controller.plugins.toolkit.get_action = MagicMock(side_effect=_get_action)
# Call the function
returned = self.instanceUI.user_acquired_datasets()
# User_show called correctly
expected_context = {
'model': controller.model,
'session': controller.model.Session,
'user': controller.plugins.toolkit.c.user
}
user_show.assert_called_once_with(expected_context, {'user_obj': controller.plugins.toolkit.c.userobj})
# Query called correctry
expected_user = default_user.copy()
expected_user['acquired_datasets'] = acquisitions_list.return_value
acquisitions_list.assert_called_with(expected_context, None)
self.assertEquals(expected_user, controller.plugins.toolkit.c.user_dict)
# Check that the render method has been called and that its result has been returned
self.assertEquals(controller.plugins.toolkit.render.return_value, returned)
controller.plugins.toolkit.render.assert_called_once_with('user/dashboard_acquired.html')

View File

@ -19,11 +19,13 @@
import unittest import unittest
import copy import copy
import ckanext.privatedatasets.plugin as plugin
from flask import Blueprint
from mock import MagicMock from mock import MagicMock
from parameterized import parameterized from parameterized import parameterized
import ckanext.privatedatasets.plugin as plugin
class PluginTest(unittest.TestCase): class PluginTest(unittest.TestCase):
@ -51,7 +53,7 @@ class PluginTest(unittest.TestCase):
(plugin.p.IDatasetForm,), (plugin.p.IDatasetForm,),
(plugin.p.IAuthFunctions,), (plugin.p.IAuthFunctions,),
(plugin.p.IConfigurer,), (plugin.p.IConfigurer,),
(plugin.p.IRoutes,), (plugin.p.IBlueprint,),
(plugin.p.IActions,), (plugin.p.IActions,),
(plugin.p.IPackageController,), (plugin.p.IPackageController,),
(plugin.p.ITemplateHelpers,) (plugin.p.ITemplateHelpers,)
@ -83,18 +85,15 @@ class PluginTest(unittest.TestCase):
self.privateDatasets.update_config(config) self.privateDatasets.update_config(config)
# Test that functions are called as expected # Test that functions are called as expected
plugin.tk.add_template_directory.assert_called_once_with(config, 'templates') if self._tk.check_ckan_version(min_version='2.8'):
plugin.tk.add_template_directory.assert_called_once_with(config, 'templates_2.8')
else:
plugin.tk.add_template_directory.assert_called_once_with(config, 'templates')
plugin.tk.add_resource('fanstatic', 'privatedatasets') plugin.tk.add_resource('fanstatic', 'privatedatasets')
def test_map(self): def test_get_blueprint(self):
# Call the method # Call the method
m = MagicMock() self.assertIsInstance(self.privateDatasets.get_blueprint(), Blueprint)
self.privateDatasets.before_map(m)
# Test that the connect method has been called
m.connect.assert_any_call('user_acquired_datasets', '/dashboard/acquired', ckan_icon='shopping-cart',
controller='ckanext.privatedatasets.controllers.ui_controller:AcquiredDatasetsControllerUI',
action='user_acquired_datasets', conditions=dict(method=['GET']))
@parameterized.expand([ @parameterized.expand([
('package_acquired', plugin.actions.package_acquired), ('package_acquired', plugin.actions.package_acquired),

View File

@ -47,7 +47,7 @@ class TestSelenium(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
env = os.environ.copy() env = os.environ.copy()
env['DEBUG'] = 'True' env['DEBUG'] = 'False'
cls._process = Popen(['paster', 'serve', 'test.ini'], env=env) cls._process = Popen(['paster', 'serve', 'test.ini'], env=env)
@classmethod @classmethod
@ -260,7 +260,7 @@ class TestSelenium(unittest.TestCase):
def check_acquired(self, dataset, dataset_url, acquired, private): def check_acquired(self, dataset, dataset_url, acquired, private):
driver = self.driver driver = self.driver
driver.get(self.base_url + 'dashboard') driver.get(self.base_url + 'dashboard')
driver.find_element_by_link_text('Acquired Datasets').click() WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, 'Acquired Datasets'))).click()
if acquired and private: if acquired and private:
# This message could not be shown when the user has acquired at least one dataset # This message could not be shown when the user has acquired at least one dataset

View File

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Future Internet Consulting and Development Solutions S.L.
# This file is part of CKAN Private Dataset Extension.
# CKAN Private Dataset Extension is free software: you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# CKAN Private Dataset Extension is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with CKAN Private Dataset Extension. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import, unicode_literals
from ckan import logic
from ckan.common import _, g
from ckan.lib import base
from ckan.plugins import toolkit
from ckanext.privatedatasets import constants
def acquired_datasets():
context = {'for_view': True, 'user': g.user, 'auth_user_obj': g.userobj}
data_dict = {'user_obj': g.userobj}
try:
user_dict = logic.get_action('user_show')(context, data_dict)
acquired_datasets = toolkit.get_action(constants.ACQUISITIONS_LIST)(context, None)
except logic.NotFound:
base.abort(404, _('User not found'))
except logic.NotAuthorized:
base.abort(403, _('Not authorized to see this page'))
extra_vars = {
'user_dict': user_dict,
'acquired_datasets': acquired_datasets,
}
return base.render('user/dashboard_acquired.html', extra_vars)