From 9370ceb3097db7183ed1e156c62f143b6ec1c359 Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 14 Apr 2016 11:43:16 +0100 Subject: [PATCH 01/11] [#2955] Fix group feeds returning no datasets --- ckan/controllers/feed.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ckan/controllers/feed.py b/ckan/controllers/feed.py index 8720e5d2535..236b4c4c507 100644 --- a/ckan/controllers/feed.py +++ b/ckan/controllers/feed.py @@ -169,12 +169,17 @@ def _alternate_url(self, params, **kwargs): def _group_or_organization(self, obj_dict, is_org): data_dict, params = self._parse_url_params() - key = 'owner_org' if is_org else 'groups' - data_dict['fq'] = '%s:"%s"' % (key, obj_dict['id'],) - group_type = 'organization' - if not is_org: + if is_org: + key = 'owner_org' + value = obj_dict['id'] + group_type = 'organization' + else: + key = 'groups' + value = obj_dict['name'] group_type = 'group' + data_dict['fq'] = '{0}:"{1}"'.format(key, value) + item_count, results = _package_search(data_dict) navigation_urls = self._navigation_urls(params, From 5722d3d6bcf59585106baf42e5fd31c3962c72fc Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 14 Apr 2016 11:43:40 +0100 Subject: [PATCH 02/11] [#2955] Add tests for feed controller --- ckan/tests/controllers/test_feed.py | 51 ++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/ckan/tests/controllers/test_feed.py b/ckan/tests/controllers/test_feed.py index 2293ae5118a..fb48a9548bb 100644 --- a/ckan/tests/controllers/test_feed.py +++ b/ckan/tests/controllers/test_feed.py @@ -1,12 +1,15 @@ from routes import url_for -from ckan import model import ckan.tests.helpers as helpers import ckan.tests.factories as factories class TestFeedNew(helpers.FunctionalTestBase): + @classmethod + def teardown_class(cls): + helpers.reset_db() + def test_atom_feed_page_zero_gives_error(self): group = factories.Group() offset = url_for(controller='feed', action='group', @@ -30,3 +33,49 @@ def test_atom_feed_page_not_int_gives_error(self): app = self._get_test_app() res = app.get(offset, status=400) assert '"page" parameter must be a positive integer' in res, res + + def test_general_atom_feed_works(self): + dataset = factories.Dataset() + offset = url_for(controller='feed', action='general') + app = self._get_test_app() + res = app.get(offset) + + assert '{0}'.format(dataset['title']) in res.body + + def test_group_atom_feed_works(self): + group = factories.Group() + dataset = factories.Dataset(groups=[{'id': group['id']}]) + offset = url_for(controller='feed', action='group', + id=group['name']) + app = self._get_test_app() + res = app.get(offset) + + assert '{0}'.format(dataset['title']) in res.body + + def test_organization_atom_feed_works(self): + group = factories.Organization() + dataset = factories.Dataset(owner_org=group['id']) + offset = url_for(controller='feed', action='organization', + id=group['name']) + app = self._get_test_app() + res = app.get(offset) + + assert '{0}'.format(dataset['title']) in res.body + + def test_custom_atom_feed_works(self): + dataset1 = factories.Dataset( + title='Test weekly', + extras=[{'key': 'frequency', 'value': 'weekly'}]) + dataset2 = factories.Dataset( + title='Test daily', + extras=[{'key': 'frequency', 'value': 'daily'}]) + offset = url_for(controller='feed', action='custom') + params = { + 'q': 'frequency:weekly' + } + app = self._get_test_app() + res = app.get(offset, params=params) + + assert '{0}'.format(dataset1['title']) in res.body + + assert '{0}'.format(dataset2['title']) not in res.body From d970bb949da8d0a1cf8f2c56a243dccf466d29eb Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 18 Aug 2016 15:49:05 +0100 Subject: [PATCH 03/11] [#3204] Remove unsupported simple search This hasn't been supported for ages, and will hopefully be replaced by #3118 --- ckan/config/deployment.ini_tmpl | 2 - ckan/lib/search/__init__.py | 21 ++--------- ckan/lib/search/sql.py | 42 --------------------- ckan/tests/legacy/lib/test_simple_search.py | 37 ------------------ doc/maintaining/configuration.rst | 13 ------- 5 files changed, 4 insertions(+), 111 deletions(-) delete mode 100644 ckan/lib/search/sql.py delete mode 100644 ckan/tests/legacy/lib/test_simple_search.py diff --git a/ckan/config/deployment.ini_tmpl b/ckan/config/deployment.ini_tmpl index 50c58ecedbf..73acd9bb6d7 100644 --- a/ckan/config/deployment.ini_tmpl +++ b/ckan/config/deployment.ini_tmpl @@ -78,8 +78,6 @@ ckan.auth.roles_that_cascade_to_sub_groups = admin ckan.site_id = default #solr_url = http://127.0.0.1:8983/solr -#ckan.simple_search = 1 - ## CORS Settings diff --git a/ckan/lib/search/__init__.py b/ckan/lib/search/__init__.py index 65f064093a2..398158d6bc2 100644 --- a/ckan/lib/search/__init__.py +++ b/ckan/lib/search/__init__.py @@ -7,7 +7,6 @@ import xml.dom.minidom import urllib2 -from ckan.common import config from paste.deploy.converters import asbool import ckan.model as model @@ -23,7 +22,6 @@ log = logging.getLogger(__name__) - def text_traceback(): with warnings.catch_warnings(): warnings.simplefilter("ignore") @@ -32,7 +30,6 @@ def text_traceback(): ).strip() return res -SIMPLE_SEARCH = asbool(config.get('ckan.simple_search', False)) SUPPORTED_SCHEMA_VERSIONS = ['2.3'] @@ -60,11 +57,6 @@ def text_traceback(): SOLR_SCHEMA_FILE_OFFSET = '/admin/file/?file=schema.xml' -if SIMPLE_SEARCH: - import sql as sql - _INDICES['package'] = NoopSearchIndex - _QUERIES['package'] = sql.PackageSearchQuery - def _normalize_type(_type): if isinstance(_type, model.domain_object.DomainObject): @@ -219,6 +211,7 @@ def commit(): package_index.commit() log.info('Commited pending changes on the search index') + def check(): package_query = query_for(model.Package) @@ -249,10 +242,9 @@ def clear(package_reference): def clear_all(): - if not SIMPLE_SEARCH: - package_index = index_for(model.Package) - log.debug("Clearing search index...") - package_index.clear() + package_index = index_for(model.Package) + log.debug("Clearing search index...") + package_index.clear() def check_solr_schema_version(schema_file=None): @@ -276,11 +268,6 @@ def check_solr_schema_version(schema_file=None): be only used for testing purposes (Default is None) ''' - - if SIMPLE_SEARCH: - # Not using the SOLR search backend - return False - if not is_available(): # Something is wrong with the SOLR server log.warn('Problems were found while connecting to the SOLR server') diff --git a/ckan/lib/search/sql.py b/ckan/lib/search/sql.py deleted file mode 100644 index 6db022815b9..00000000000 --- a/ckan/lib/search/sql.py +++ /dev/null @@ -1,42 +0,0 @@ -# encoding: utf-8 - -from sqlalchemy import or_ -from ckan.lib.search.query import SearchQuery -import ckan.model as model - -class PackageSearchQuery(SearchQuery): - def get_all_entity_ids(self, max_results=100): - """ - Return a list of the IDs of all indexed packages. - """ - # could make this a pure sql query which would be much more efficient! - q = model.Session.query(model.Package).filter_by(state='active').limit(max_results) - - return [r.id for r in q] - - def run(self, query): - assert isinstance(query, dict) - # no support for faceting atm - self.facets = {} - limit = min(1000, int(query.get('rows', 10))) - - q = query.get('q') - ourq = model.Session.query(model.Package.id).filter_by(state='active') - - def makelike(field): - _attr = getattr(model.Package, field) - return _attr.ilike('%' + term + '%') - if q and q not in ('""', "''", '*:*'): - terms = q.split() - # TODO: tags ...? - fields = ['name', 'title', 'notes'] - for term in terms: - args = [makelike(field) for field in fields] - subq = or_(*args) - ourq = ourq.filter(subq) - self.count = ourq.count() - ourq = ourq.limit(limit) - self.results = [{'id': r[0]} for r in ourq.all()] - - return {'results': self.results, 'count': self.count} - diff --git a/ckan/tests/legacy/lib/test_simple_search.py b/ckan/tests/legacy/lib/test_simple_search.py deleted file mode 100644 index d271b31cf2f..00000000000 --- a/ckan/tests/legacy/lib/test_simple_search.py +++ /dev/null @@ -1,37 +0,0 @@ -# encoding: utf-8 - -from nose.tools import assert_equal - -from ckan import model -from ckan.lib.create_test_data import CreateTestData -from ckan.lib.search.sql import PackageSearchQuery - -class TestSimpleSearch: - @classmethod - def setup_class(cls): - CreateTestData.create() - - @classmethod - def teardown_class(cls): - model.repo.rebuild_db() - - def test_get_all_entity_ids(self): - ids = PackageSearchQuery().get_all_entity_ids() - anna = model.Package.by_name(u'annakarenina') - assert anna.id in ids - assert len(ids) >= 2, len(ids) - - def test_run_query_basic(self): - res = PackageSearchQuery().run({'q':'annakarenina'}) - anna = model.Package.by_name(u'annakarenina') - assert_equal(res, {'results': [{'id': anna.id}], 'count': 1}) - - def test_run_query_home(self): - # This is the query from the CKAN home page - res = PackageSearchQuery().run({'q': '*:*'}) - assert res['count'] >= 2, res['count'] - - def test_run_query_all(self): - # This is the default query from the search page - res = PackageSearchQuery().run({'q': u''}) - assert res['count'] >= 2, res['count'] diff --git a/doc/maintaining/configuration.rst b/doc/maintaining/configuration.rst index e3ed4423bd7..52910fdb1c6 100644 --- a/doc/maintaining/configuration.rst +++ b/doc/maintaining/configuration.rst @@ -581,19 +581,6 @@ a single CKAN instance then this can be ignored. Note, if you change this value, you need to rebuild the search index. -.. _ckan.simple_search: - -ckan.simple_search -^^^^^^^^^^^^^^^^^^ - -Example:: - - ckan.simple_search = true - -Default value: ``false`` - -Switching this on tells CKAN search functionality to just query the database, (rather than using Solr). In this setup, search is crude and limited, e.g. no full-text search, no faceting, etc. However, this might be very useful for getting up and running quickly with CKAN. - .. _solr_url: solr_url From f45f6fff7470a6caa271a8b6c6bf6e86bf83fb1a Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 25 Aug 2016 13:56:29 +0100 Subject: [PATCH 04/11] [#2842] Update the main CKAN config object with the Flask specific keys These were autogenerated or set during `make_flask_stack`, so they would be lost when doing config.clear() (and updating with a previous copy, as done extensively in the tests) --- ckan/config/middleware/flask_app.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ckan/config/middleware/flask_app.py b/ckan/config/middleware/flask_app.py index 6a3e80b4369..2bbb4939354 100644 --- a/ckan/config/middleware/flask_app.py +++ b/ckan/config/middleware/flask_app.py @@ -32,6 +32,12 @@ def hello_world(): def hello_world_post(): return 'Hello World, this was posted to Flask' + # Update the main CKAN config object with the Flask specific keys + # that were set here or autogenerated + flask_config_keys = set(flask_app.config.keys()) - set(config.keys()) + for key in flask_config_keys: + config[key] = flask_app.config[key] + # Add a reference to the actual Flask app so it's easier to access app._wsgi_app = flask_app From 7483164274a88a201c51170b0b88fea04cb1e62b Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 25 Aug 2016 14:03:07 +0100 Subject: [PATCH 05/11] [#2842] Fix some remainig direct pylons config imports --- ckan/config/routing.py | 2 +- ckan/lib/render.py | 2 +- ckanext/example_theme/custom_config_setting/plugin.py | 2 +- ckanext/example_theme/custom_emails/tests.py | 2 +- ckanext/reclineview/plugin.py | 3 +-- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ckan/config/routing.py b/ckan/config/routing.py index c5f12df9f7c..03aa50f625b 100644 --- a/ckan/config/routing.py +++ b/ckan/config/routing.py @@ -9,10 +9,10 @@ """ import re -from pylons import config from routes.mapper import SubMapper, Mapper as _Mapper import ckan.plugins as p +from ckan.common import config named_routes = {} diff --git a/ckan/lib/render.py b/ckan/lib/render.py index fa2507c2192..c22c35680d1 100644 --- a/ckan/lib/render.py +++ b/ckan/lib/render.py @@ -4,7 +4,7 @@ import re import logging -from pylons import config +from ckan.common import config log = logging.getLogger(__name__) diff --git a/ckanext/example_theme/custom_config_setting/plugin.py b/ckanext/example_theme/custom_config_setting/plugin.py index 74439633949..c89f4e6296f 100644 --- a/ckanext/example_theme/custom_config_setting/plugin.py +++ b/ckanext/example_theme/custom_config_setting/plugin.py @@ -1,9 +1,9 @@ # encoding: utf-8 -import pylons.config as config import ckan.plugins as plugins import ckan.plugins.toolkit as toolkit +from ckan.common import config def show_most_popular_groups(): diff --git a/ckanext/example_theme/custom_emails/tests.py b/ckanext/example_theme/custom_emails/tests.py index 5c72852d15a..66a095e4590 100644 --- a/ckanext/example_theme/custom_emails/tests.py +++ b/ckanext/example_theme/custom_emails/tests.py @@ -1,12 +1,12 @@ # encoding: utf-8 import os -from pylons import config from ckan import plugins import ckan.model as model import ckan.lib.mailer as mailer from ckan.tests import factories from ckan.lib.base import render_jinja2 +from ckan.common import config from ckan.tests.lib.test_mailer import MailerBase import ckan.tests.helpers as helpers diff --git a/ckanext/reclineview/plugin.py b/ckanext/reclineview/plugin.py index 6320acc25e2..d6ac44f2b98 100644 --- a/ckanext/reclineview/plugin.py +++ b/ckanext/reclineview/plugin.py @@ -2,10 +2,9 @@ from logging import getLogger -from ckan.common import json +from ckan.common import json, config import ckan.plugins as p import ckan.plugins.toolkit as toolkit -from pylons import config log = getLogger(__name__) ignore_empty = p.toolkit.get_validator('ignore_empty') From 73c5a110ffd142c1f5632b040f0271c394f1bc15 Mon Sep 17 00:00:00 2001 From: Florian Brucker Date: Fri, 26 Aug 2016 11:46:01 +0200 Subject: [PATCH 06/11] Document how to run automated JS tests. Updates the documentation with instructions on how to run the the Mocha JavaScript tests, including how to install the necessary packages. --- doc/contributing/test.rst | 74 ++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 17 deletions(-) diff --git a/doc/contributing/test.rst b/doc/contributing/test.rst index 37f7c26d4c8..0258c2be0ef 100644 --- a/doc/contributing/test.rst +++ b/doc/contributing/test.rst @@ -6,10 +6,20 @@ If you're a CKAN developer, if you're developing an extension for CKAN, or if you're just installing CKAN from source, you should make sure that CKAN's tests pass for your copy of CKAN. This section explains how to run CKAN's tests. +CKAN's testsuite contains automated tests for both the back-end (Python) and +the front-end (JavaScript). In addition, the correct functionality of the +complete front-end (HTML, CSS, JavaScript) on all supported browsers should be +tested manually. -------------------------------- +-------------- +Back-end tests +-------------- + +Most of CKAN's testsuite is for the backend Python code. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Install additional dependencies -------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Some additional dependencies are needed to run the tests. Make sure you've created a config file at |development.ini|, then activate your @@ -31,9 +41,9 @@ environment: pip install -r |virtualenv|/src/ckan/dev-requirements.txt -------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~ Set up the test databases -------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionchanged:: 2.1 Previously |postgres| tests used the databases defined in your @@ -51,9 +61,9 @@ This database connection is specified in the ``test-core.ini`` file by the ``sqlalchemy.url`` parameter. -------------- +~~~~~~~~~~~~~ Run the tests -------------- +~~~~~~~~~~~~~ To run CKAN's tests using PostgreSQL as the database, you have to give the ``--with-pylons=test-core.ini`` option on the command line. This command will @@ -75,9 +85,9 @@ option:: .. _migrationtesting: ------------------ +~~~~~~~~~~~~~~~~~ Migration testing ------------------ +~~~~~~~~~~~~~~~~~ If you're a CKAN developer or extension developer and your new code requires a change to CKAN's model, you'll need to write a migration script. To ensure that @@ -98,9 +108,9 @@ is how the database is created and upgraded in production. is that these are versioned files and people have checked in these by mistake, creating problems for other developers. ---------------------- +~~~~~~~~~~~~~~~~~~~~~ Common error messages ---------------------- +~~~~~~~~~~~~~~~~~~~~~ ConfigError =========== @@ -150,10 +160,39 @@ nosetests pip freeze | grep -i nose ------------------ -Front-end Testing ------------------ +--------------- +Front-end tests +--------------- +Front-end testing consists of both automated tests (for the JavaScript code) +and manual tests (for the complete front-end consisting of HTML, CSS and +JavaScript). + +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Automated JavaScript tests +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The JS tests are written using the Mocha_ test framework and run via +PhantomJS_. First you need to install the necessary packages:: + + sudo apt-get install npm nodejs-legacy + sudo npm install -g mocha-phantomjs@3.5.0 phantomjs@~1.9.1 + +.. _Mocha: https://mochajs.org/ +.. _PhantomJS: http://phantomjs.org//ckan + +To run the tests, make sure that a test server is running:: + + . /usr/lib/ckan/default/bin/activate + paster serve test-core.ini + +Once the test server is running switch to another terminal and execute the +tests:: + + mocha-phantomjs http://localhost:5000/base/test/index.html +~~~~~~~~~~~~ +Manual tests +~~~~~~~~~~~~ All new CKAN features should be coded so that they work in the following browsers: @@ -191,14 +230,15 @@ Thirdly you should fully test all new features that have a front-end element in all browsers before making your pull request into CKAN master. -Common pitfalls & their fixes -============================= +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Common front-end pitfalls & their fixes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here's a few of the most common front end bugs and a list of their fixes. Reserved JS keywords --------------------- +==================== Since IE has a stricter language definition in JS it really doesn't like you using JS reserved keywords method names, variables, etc... @@ -221,7 +261,7 @@ https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Reserved_Words }; Unclosed JS arrays / objects ----------------------------- +============================ Internet Explorer doesn't like it's JS to have unclosed JS objects and arrays. For example: From 1fa8a348acc8b352fd4f5e87e7e25e6815e24ab4 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Fri, 26 Aug 2016 08:43:51 -0700 Subject: [PATCH 07/11] Fix typo in 'paster datastore resubmit' "resources_ids" should be "resource_ids". Causes resubmit command to fail. --- ckanext/datapusher/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ckanext/datapusher/cli.py b/ckanext/datapusher/cli.py index 76eaaf89d6c..fd4adf27003 100644 --- a/ckanext/datapusher/cli.py +++ b/ckanext/datapusher/cli.py @@ -60,7 +60,7 @@ def _confirm_or_abort(self): sys.exit(0) def _resubmit_all(self): - resources_ids = datastore_db.get_all_resources_ids_in_datastore() + resource_ids = datastore_db.get_all_resources_ids_in_datastore() self._submit(resource_ids) def _submit_all_packages(self): From 43767c78390f389b62767f7e38cfdba7d68a958b Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 1 Sep 2016 11:49:18 +0100 Subject: [PATCH 08/11] [#3196] Fix ckan/ tests (no legacy) depending on url_for The Flask url_for function requires an application context to be present when generating a url_for. This is obviously not the case when calling it from a test, so we need to wrap the function on a test_request_context (which will create an app context): with app.flask_app.test_request_context(): url_for(...) For tests that don't require an app like helpers or mailer this is done automatically in the tests setup. Note that all URLs generated now take ckan.site_url into account, so tests checking for `http://localhost/some-url` will fail as the correct url is `http://test.ckan.net/some-url`, as this is the site_url used on test-core.ini. --- ckan/lib/alphabet_paginate.py | 2 +- ckan/tests/config/test_middleware.py | 5 +- ckan/tests/config/test_sessions.py | 4 +- ckan/tests/controllers/test_admin.py | 36 +- ckan/tests/controllers/test_api.py | 101 ++-- ckan/tests/controllers/test_feed.py | 42 +- ckan/tests/controllers/test_group.py | 249 +++++--- ckan/tests/controllers/test_home.py | 49 +- ckan/tests/controllers/test_organization.py | 247 +++++--- ckan/tests/controllers/test_package.py | 638 +++++++++++++------- ckan/tests/controllers/test_tags.py | 20 +- ckan/tests/controllers/test_user.py | 173 ++++-- ckan/tests/controllers/test_util.py | 28 +- ckan/tests/lib/test_helpers.py | 1 - ckan/tests/lib/test_mailer.py | 39 +- ckan/tests/logic/action/test_create.py | 6 +- 16 files changed, 1091 insertions(+), 549 deletions(-) diff --git a/ckan/lib/alphabet_paginate.py b/ckan/lib/alphabet_paginate.py index 0fdf8d60cf8..99e570af055 100644 --- a/ckan/lib/alphabet_paginate.py +++ b/ckan/lib/alphabet_paginate.py @@ -21,7 +21,7 @@ from sqlalchemy import __version__ as sqav from sqlalchemy.orm.query import Query from webhelpers.html.builder import HTML -from routes import url_for +from ckan.lib.helpers import url_for class AlphaPage(object): diff --git a/ckan/tests/config/test_middleware.py b/ckan/tests/config/test_middleware.py index d5faf4a3590..e1f9538d44f 100644 --- a/ckan/tests/config/test_middleware.py +++ b/ckan/tests/config/test_middleware.py @@ -3,7 +3,6 @@ import mock import wsgiref from nose.tools import assert_equals, assert_not_equals, eq_, assert_raises -from routes import url_for from flask import Blueprint import flask @@ -30,7 +29,9 @@ def test_homepage_with_middleware_activated(self): We are just testing the home page renders without any troubles and that the middleware has not done anything strange to the response string''' app = self._get_test_app() - response = app.get(url=url_for(controller='home', action='index')) + with app.flask_app.test_request_context(): + response = app.get( + url=h.url_for(controller='home', action='index')) assert_equals(200, response.status_int) # make sure we haven't overwritten the response too early. diff --git a/ckan/tests/config/test_sessions.py b/ckan/tests/config/test_sessions.py index bb0d2a847bf..6a861e70b99 100644 --- a/ckan/tests/config/test_sessions.py +++ b/ckan/tests/config/test_sessions.py @@ -5,7 +5,6 @@ from flask import Blueprint from flask import render_template from flask import redirect as flask_redirect -from flask import url_for from ckan.lib.base import render as pylons_render import ckan.plugins as p @@ -73,7 +72,8 @@ def flash_message_view(self): def add_flash_message_view_redirect_to_flask(self): u'''Add flash message, then redirect to Flask view to render it.''' h.flash_success(u'This is a success message populated by Flask') - return flask_redirect(url_for(u'test_flash_plugin.flash_message_view')) + return flask_redirect( + h.url_for(u'test_flash_plugin.flash_message_view')) def add_flash_message_view_redirect_to_pylons(self): u'''Add flash message, then redirect to view that renders it''' diff --git a/ckan/tests/controllers/test_admin.py b/ckan/tests/controllers/test_admin.py index 8915c489d92..7b1c6067839 100644 --- a/ckan/tests/controllers/test_admin.py +++ b/ckan/tests/controllers/test_admin.py @@ -3,7 +3,7 @@ from nose.tools import assert_true, assert_equal from bs4 import BeautifulSoup -from routes import url_for +from ckan.lib.helpers import url_for from ckan.common import config import ckan.model as model @@ -19,8 +19,10 @@ def _get_admin_config_page(app): user = factories.Sysadmin() env = {'REMOTE_USER': user['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for(controller='admin', action='config') response = app.get( - url=url_for(controller='admin', action='config'), + url=url, extra_environ=env, ) return env, response @@ -30,8 +32,10 @@ def _reset_config(app): '''Reset config via action''' user = factories.Sysadmin() env = {'REMOTE_USER': user['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for(controller='admin', action='reset_config') app.post( - url=url_for(controller='admin', action='reset_config'), + url=url, extra_environ=env, ) @@ -262,9 +266,9 @@ class TestTrashView(helpers.FunctionalTestBase): def test_trash_view_anon_user(self): '''An anon user shouldn't be able to access trash view.''' app = self._get_test_app() - - trash_url = url_for(controller='admin', action='trash') - trash_response = app.get(trash_url, status=403) + with app.flask_app.test_request_context(): + trash_url = url_for(controller='admin', action='trash') + app.get(trash_url, status=403) def test_trash_view_normal_user(self): '''A normal logged in user shouldn't be able to access trash view.''' @@ -272,7 +276,9 @@ def test_trash_view_normal_user(self): app = self._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} - trash_url = url_for(controller='admin', action='trash') + + with app.flask_app.test_request_context(): + trash_url = url_for(controller='admin', action='trash') trash_response = app.get(trash_url, extra_environ=env, status=403) assert_true('Need to be system administrator to administer' in trash_response) @@ -283,7 +289,9 @@ def test_trash_view_sysadmin(self): app = self._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} - trash_url = url_for(controller='admin', action='trash') + + with app.flask_app.test_request_context(): + trash_url = url_for(controller='admin', action='trash') trash_response = app.get(trash_url, extra_environ=env, status=200) # On the purge page assert_true('form-purge-packages' in trash_response) @@ -296,7 +304,8 @@ def test_trash_no_datasets(self): app = self._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} - trash_url = url_for(controller='admin', action='trash') + with app.flask_app.test_request_context(): + trash_url = url_for(controller='admin', action='trash') trash_response = app.get(trash_url, extra_environ=env, status=200) trash_response_html = BeautifulSoup(trash_response.body) @@ -315,7 +324,8 @@ def test_trash_with_deleted_datasets(self): app = self._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} - trash_url = url_for(controller='admin', action='trash') + with app.flask_app.test_request_context(): + trash_url = url_for(controller='admin', action='trash') trash_response = app.get(trash_url, extra_environ=env, status=200) trash_response_html = BeautifulSoup(trash_response.body) @@ -338,7 +348,8 @@ def test_trash_purge_deleted_datasets(self): assert_equal(pkgs_before_purge, 3) env = {'REMOTE_USER': user['name'].encode('ascii')} - trash_url = url_for(controller='admin', action='trash') + with app.flask_app.test_request_context(): + trash_url = url_for(controller='admin', action='trash') trash_response = app.get(trash_url, extra_environ=env, status=200) # submit the purge form @@ -364,7 +375,8 @@ def _update_config_option(self): sysadmin = factories.Sysadmin() env = {'REMOTE_USER': sysadmin['name'].encode('ascii')} app = self._get_test_app() - url = url_for(controller='admin', action='config') + with app.flask_app.test_request_context(): + url = url_for(controller='admin', action='config') response = app.get(url=url, extra_environ=env) form = response.forms[1] diff --git a/ckan/tests/controllers/test_api.py b/ckan/tests/controllers/test_api.py index d674bb02f66..def1a1aaea0 100644 --- a/ckan/tests/controllers/test_api.py +++ b/ckan/tests/controllers/test_api.py @@ -7,7 +7,7 @@ import json import re -from routes import url_for +from ckan.lib.helpers import url_for from nose.tools import assert_equal, assert_in, eq_ import ckan.tests.helpers as helpers @@ -30,9 +30,12 @@ def test_unicode_in_error_message_works_ok(self): def test_dataset_autocomplete_name(self): dataset = factories.Dataset(name='rivers') - url = url_for(controller='api', action='dataset_autocomplete', ver='/2') - assert_equal(url, '/api/2/util/dataset/autocomplete') + app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='api', action='dataset_autocomplete', + ver='/2') + assert_equal(url, '/api/2/util/dataset/autocomplete') response = app.get( url=url, @@ -54,7 +57,11 @@ def test_dataset_autocomplete_name(self): def test_dataset_autocomplete_title(self): dataset = factories.Dataset(name='test_ri', title='Rivers') - url = url_for(controller='api', action='dataset_autocomplete', ver='/2') + + app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='api', action='dataset_autocomplete', + ver='/2') assert_equal(url, '/api/2/util/dataset/autocomplete') app = self._get_test_app() @@ -78,9 +85,12 @@ def test_dataset_autocomplete_title(self): def test_tag_autocomplete(self): factories.Dataset(tags=[{'name': 'rivers'}]) - url = url_for(controller='api', action='tag_autocomplete', ver='/2') - assert_equal(url, '/api/2/util/tag/autocomplete') + app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='api', action='tag_autocomplete', + ver='/2') + assert_equal(url, '/api/2/util/tag/autocomplete') response = app.get( url=url, @@ -96,10 +106,12 @@ def test_tag_autocomplete(self): 'application/json;charset=utf-8') def test_group_autocomplete_by_name(self): - org = factories.Group(name='rivers', title='Bridges') - url = url_for(controller='api', action='group_autocomplete', ver='/2') - assert_equal(url, '/api/2/util/group/autocomplete') + factories.Group(name='rivers', title='Bridges') app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='api', action='group_autocomplete', + ver='/2') + assert_equal(url, '/api/2/util/group/autocomplete') response = app.get( url=url, @@ -117,9 +129,11 @@ def test_group_autocomplete_by_name(self): 'application/json;charset=utf-8') def test_group_autocomplete_by_title(self): - org = factories.Group(name='frogs', title='Bugs') - url = url_for(controller='api', action='group_autocomplete', ver='/2') + factories.Group(name='frogs', title='Bugs') app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='api', action='group_autocomplete', + ver='/2') response = app.get( url=url, @@ -135,9 +149,12 @@ def test_group_autocomplete_by_title(self): def test_organization_autocomplete_by_name(self): org = factories.Organization(name='simple-dummy-org') - url = url_for(controller='api', action='organization_autocomplete', ver='/2') - assert_equal(url, '/api/2/util/organization/autocomplete') + app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='api', action='organization_autocomplete', + ver='/2') + assert_equal(url, '/api/2/util/organization/autocomplete') response = app.get( url=url, @@ -155,9 +172,12 @@ def test_organization_autocomplete_by_name(self): 'application/json;charset=utf-8') def test_organization_autocomplete_by_title(self): - org = factories.Organization(title='Simple dummy org') - url = url_for(controller='api', action='organization_autocomplete', ver='/2') + factories.Organization(title='Simple dummy org') + app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='api', action='organization_autocomplete', + ver='/2') response = app.get( url=url, @@ -173,12 +193,14 @@ def test_organization_autocomplete_by_title(self): def test_config_option_list_access_sysadmin(self): user = factories.Sysadmin() - url = url_for( - controller='api', - action='action', - logic_function='config_option_list', - ver='/3') + app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for( + controller='api', + action='action', + logic_function='config_option_list', + ver='/3') app.get( url=url, @@ -189,12 +211,14 @@ def test_config_option_list_access_sysadmin(self): def test_config_option_list_access_sysadmin_jsonp(self): user = factories.Sysadmin() - url = url_for( - controller='api', - action='action', - logic_function='config_option_list', - ver='/3') + app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for( + controller='api', + action='action', + logic_function='config_option_list', + ver='/3') app.get( url=url, @@ -208,12 +232,13 @@ def test_jsonp_works_on_get_requests(self): dataset1 = factories.Dataset() dataset2 = factories.Dataset() - url = url_for( - controller='api', - action='action', - logic_function='package_list', - ver='/3') app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for( + controller='api', + action='action', + logic_function='package_list', + ver='/3') res = app.get( url=url, params={'callback': 'my_callback'}, @@ -230,15 +255,15 @@ def test_jsonp_does_not_work_on_post_requests(self): dataset1 = factories.Dataset() dataset2 = factories.Dataset() - - url = url_for( - controller='api', - action='action', - logic_function='package_list', - ver='/3', - callback='my_callback', - ) app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for( + controller='api', + action='action', + logic_function='package_list', + ver='/3', + callback='my_callback', + ) res = app.post( url=url, ) diff --git a/ckan/tests/controllers/test_feed.py b/ckan/tests/controllers/test_feed.py index 1e4c516e029..6643d06ad7c 100644 --- a/ckan/tests/controllers/test_feed.py +++ b/ckan/tests/controllers/test_feed.py @@ -1,6 +1,6 @@ # encoding: utf-8 -from routes import url_for +from ckan.lib.helpers import url_for import ckan.tests.helpers as helpers import ckan.tests.factories as factories @@ -14,32 +14,40 @@ def teardown_class(cls): def test_atom_feed_page_zero_gives_error(self): group = factories.Group() - offset = url_for(controller='feed', action='group', - id=group['name']) + '?page=0' + app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='feed', action='group', + id=group['name']) + '?page=0' res = app.get(offset, status=400) assert '"page" parameter must be a positive integer' in res, res def test_atom_feed_page_negative_gives_error(self): group = factories.Group() - offset = url_for(controller='feed', action='group', - id=group['name']) + '?page=-2' + app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='feed', action='group', + id=group['name']) + '?page=-2' res = app.get(offset, status=400) assert '"page" parameter must be a positive integer' in res, res def test_atom_feed_page_not_int_gives_error(self): group = factories.Group() - offset = url_for(controller='feed', action='group', - id=group['name']) + '?page=abc' + app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='feed', action='group', + id=group['name']) + '?page=abc' res = app.get(offset, status=400) assert '"page" parameter must be a positive integer' in res, res def test_general_atom_feed_works(self): dataset = factories.Dataset() - offset = url_for(controller='feed', action='general') + app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='feed', action='general') res = app.get(offset) assert '{0}'.format(dataset['title']) in res.body @@ -47,9 +55,11 @@ def test_general_atom_feed_works(self): def test_group_atom_feed_works(self): group = factories.Group() dataset = factories.Dataset(groups=[{'id': group['id']}]) - offset = url_for(controller='feed', action='group', - id=group['name']) + app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='feed', action='group', + id=group['name']) res = app.get(offset) assert '{0}'.format(dataset['title']) in res.body @@ -57,9 +67,11 @@ def test_group_atom_feed_works(self): def test_organization_atom_feed_works(self): group = factories.Organization() dataset = factories.Dataset(owner_org=group['id']) - offset = url_for(controller='feed', action='organization', - id=group['name']) + app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='feed', action='organization', + id=group['name']) res = app.get(offset) assert '{0}'.format(dataset['title']) in res.body @@ -71,11 +83,13 @@ def test_custom_atom_feed_works(self): dataset2 = factories.Dataset( title='Test daily', extras=[{'key': 'frequency', 'value': 'daily'}]) - offset = url_for(controller='feed', action='custom') + + app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='feed', action='custom') params = { 'q': 'frequency:weekly' } - app = self._get_test_app() res = app.get(offset, params=params) assert '{0}'.format(dataset1['title']) in res.body diff --git a/ckan/tests/controllers/test_group.py b/ckan/tests/controllers/test_group.py index 67e06c92ce9..4fc9d9b8bc4 100644 --- a/ckan/tests/controllers/test_group.py +++ b/ckan/tests/controllers/test_group.py @@ -3,7 +3,7 @@ from bs4 import BeautifulSoup from nose.tools import assert_equal, assert_true, assert_in -from routes import url_for +from ckan.lib.helpers import url_for import ckan.tests.helpers as helpers import ckan.model as model @@ -19,17 +19,22 @@ def setup(self): model.repo.rebuild_db() def test_bulk_process_throws_404_for_nonexistent_org(self): + app = self._get_test_app() - bulk_process_url = url_for(controller='organization', - action='bulk_process', id='does-not-exist') + with app.flask_app.test_request_context(): + bulk_process_url = url_for( + controller='organization', action='bulk_process', + id='does-not-exist') app.get(url=bulk_process_url, status=404) def test_page_thru_list_of_orgs_preserves_sort_order(self): orgs = [factories.Organization() for _ in range(35)] app = self._get_test_app() - org_url = url_for(controller='organization', - action='index', - sort='name desc') + + with app.flask_app.test_request_context(): + org_url = url_for(controller='organization', + action='index', + sort='name desc') response = app.get(url=org_url) assert orgs[-1]['name'] in response assert orgs[0]['name'] not in response @@ -41,9 +46,11 @@ def test_page_thru_list_of_orgs_preserves_sort_order(self): def test_page_thru_list_of_groups_preserves_sort_order(self): groups = [factories.Group() for _ in range(35)] app = self._get_test_app() - group_url = url_for(controller='group', - action='index', - sort='title desc') + + with app.flask_app.test_request_context(): + group_url = url_for(controller='group', + action='index', + sort='title desc') response = app.get(url=group_url) assert groups[-1]['title'] in response @@ -57,8 +64,11 @@ def test_page_thru_list_of_groups_preserves_sort_order(self): def _get_group_new_page(app): user = factories.User() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='group', action='new') response = app.get( - url=url_for(controller='group', action='new'), + url=url, extra_environ=env, ) return env, response @@ -67,7 +77,9 @@ def _get_group_new_page(app): class TestGroupControllerNew(helpers.FunctionalTestBase): def test_not_logged_in(self): app = self._get_test_app() - app.get(url=url_for(controller='group', action='new'), + with app.flask_app.test_request_context(): + url = url_for(controller='group', action='new') + app.get(url=url, status=403) def test_form_renders(self): @@ -117,9 +129,11 @@ def _get_group_edit_page(app, group_name=None): group = factories.Group(user=user) group_name = group['name'] env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for(controller='group', - action='edit', - id=group_name) + + with app.flask_app.test_request_context(): + url = url_for(controller='group', + action='edit', + id=group_name) response = app.get(url=url, extra_environ=env) return env, response, group_name @@ -127,16 +141,21 @@ def _get_group_edit_page(app, group_name=None): class TestGroupControllerEdit(helpers.FunctionalTestBase): def test_not_logged_in(self): app = self._get_test_app() - app.get(url=url_for(controller='group', action='new'), + + with app.flask_app.test_request_context(): + url = url_for(controller='group', action='new') + app.get(url=url, status=403) def test_group_doesnt_exist(self): app = self._get_test_app() user = factories.User() env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for(controller='group', - action='edit', - id='doesnt_exist') + + with app.flask_app.test_request_context(): + url = url_for(controller='group', + action='edit', + id='doesnt_exist') app.get(url=url, extra_environ=env, status=404) @@ -173,17 +192,19 @@ def test_all_fields_saved(self): class TestGroupRead(helpers.FunctionalTestBase): def setup(self): super(TestGroupRead, self).setup() - self.app = helpers._get_test_app() self.user = factories.User() self.user_env = {'REMOTE_USER': self.user['name'].encode('ascii')} self.group = factories.Group(user=self.user) def test_group_read(self): - response = self.app.get(url=url_for(controller='group', - action='read', - id=self.group['id']), - status=200, - extra_environ=self.user_env) + + app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='group', action='read', + id=self.group['id']) + response = app.get(url=url, + status=200, + extra_environ=self.user_env) assert_in(self.group['title'], response) assert_in(self.group['description'], response) @@ -197,53 +218,69 @@ def setup(self): self.group = factories.Group(user=self.user) def test_owner_delete(self): - response = self.app.get(url=url_for(controller='group', - action='delete', - id=self.group['id']), - status=200, - extra_environ=self.user_env) + + app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='group', action='delete', + id=self.group['id']) + + response = app.get(url=url, + status=200, + extra_environ=self.user_env) form = response.forms['group-confirm-delete-form'] - response = submit_and_follow(self.app, form, name='delete', + response = submit_and_follow(app, form, name='delete', extra_environ=self.user_env) group = helpers.call_action('group_show', id=self.group['id']) assert_equal(group['state'], 'deleted') def test_sysadmin_delete(self): + + app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='group', action='delete', + id=self.group['id']) + sysadmin = factories.Sysadmin() extra_environ = {'REMOTE_USER': sysadmin['name'].encode('ascii')} - response = self.app.get(url=url_for(controller='group', - action='delete', - id=self.group['id']), - status=200, - extra_environ=extra_environ) + response = app.get(url=url, + status=200, + extra_environ=extra_environ) form = response.forms['group-confirm-delete-form'] - response = submit_and_follow(self.app, form, name='delete', + response = submit_and_follow(app, form, name='delete', extra_environ=self.user_env) group = helpers.call_action('group_show', id=self.group['id']) assert_equal(group['state'], 'deleted') def test_non_authorized_user_trying_to_delete_fails(self): + + app = self._get_test_app() user = factories.User() extra_environ = {'REMOTE_USER': user['name'].encode('ascii')} - self.app.get(url=url_for(controller='group', - action='delete', - id=self.group['id']), - status=403, - extra_environ=extra_environ) + with app.flask_app.test_request_context(): + url = url_for(controller='group', action='delete', + id=self.group['id']) + + app.get(url=url, + status=403, + extra_environ=extra_environ) group = helpers.call_action('group_show', id=self.group['id']) assert_equal(group['state'], 'active') def test_anon_user_trying_to_delete_fails(self): - self.app.get(url=url_for(controller='group', - action='delete', - id=self.group['id']), - status=403) + + app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='group', action='delete', + id=self.group['id']) + + app.get(url=url, + status=403) group = helpers.call_action('group_show', id=self.group['id']) @@ -264,9 +301,11 @@ def _create_group(self, owner_username, users=None): def _get_group_add_member_page(self, app, user, group_name): env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for(controller='group', - action='member_new', - id=group_name) + + with app.flask_app.test_request_context(): + url = url_for(controller='group', + action='member_new', + id=group_name) response = app.get(url=url, extra_environ=env) return env, response @@ -282,8 +321,9 @@ def test_membership_list(self): group = self._create_group(user_one['name'], other_users) - member_list_url = url_for(controller='group', action='members', - id=group['id']) + with app.flask_app.test_request_context(): + member_list_url = url_for(controller='group', action='members', + id=group['id']) member_list_response = app.get(member_list_url) assert_true('2 members' in member_list_response) @@ -369,8 +409,9 @@ def test_remove_member(self): group = self._create_group(user_one['name'], other_users) - remove_url = url_for(controller='group', action='member_delete', - user=user_two['id'], id=group['id']) + with app.flask_app.test_request_context(): + remove_url = url_for(controller='group', action='member_delete', + user=user_two['id'], id=group['id']) env = {'REMOTE_USER': user_one['name'].encode('ascii')} remove_response = app.post(remove_url, extra_environ=env, status=302) @@ -402,9 +443,11 @@ def test_group_follow(self): group = factories.Group() env = {'REMOTE_USER': user['name'].encode('ascii')} - follow_url = url_for(controller='group', - action='follow', - id=group['id']) + + with app.flask_app.test_request_context(): + follow_url = url_for(controller='group', + action='follow', + id=group['id']) response = app.post(follow_url, extra_environ=env, status=302) response = response.follow() assert_true('You are now following {0}' @@ -418,9 +461,11 @@ def test_group_follow_not_exist(self): user_one = factories.User() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - follow_url = url_for(controller='group', - action='follow', - id='not-here') + + with app.flask_app.test_request_context(): + follow_url = url_for(controller='group', + action='follow', + id='not-here') response = app.post(follow_url, extra_environ=env, status=404) assert_true('Group not found' in response) @@ -431,13 +476,16 @@ def test_group_unfollow(self): group = factories.Group() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - follow_url = url_for(controller='group', - action='follow', - id=group['id']) + + with app.flask_app.test_request_context(): + follow_url = url_for(controller='group', + action='follow', + id=group['id']) + unfollow_url = url_for(controller='group', action='unfollow', + id=group['id']) + app.post(follow_url, extra_environ=env, status=302) - unfollow_url = url_for(controller='group', action='unfollow', - id=group['id']) unfollow_response = app.post(unfollow_url, extra_environ=env, status=302) unfollow_response = unfollow_response.follow() @@ -454,8 +502,10 @@ def test_group_unfollow_not_following(self): group = factories.Group() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - unfollow_url = url_for(controller='group', action='unfollow', - id=group['id']) + + with app.flask_app.test_request_context(): + unfollow_url = url_for(controller='group', action='unfollow', + id=group['id']) unfollow_response = app.post(unfollow_url, extra_environ=env, status=302) unfollow_response = unfollow_response.follow() @@ -470,8 +520,10 @@ def test_group_unfollow_not_exist(self): user_one = factories.User() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - unfollow_url = url_for(controller='group', action='unfollow', - id='not-here') + + with app.flask_app.test_request_context(): + unfollow_url = url_for(controller='group', action='unfollow', + id='not-here') unfollow_response = app.post(unfollow_url, extra_environ=env, status=404) assert_true('Group not found' in unfollow_response) @@ -484,13 +536,15 @@ def test_group_follower_list(self): group = factories.Group() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - follow_url = url_for(controller='group', - action='follow', - id=group['id']) - app.post(follow_url, extra_environ=env, status=302) - followers_url = url_for(controller='group', action='followers', - id=group['id']) + with app.flask_app.test_request_context(): + follow_url = url_for(controller='group', + action='follow', + id=group['id']) + followers_url = url_for(controller='group', action='followers', + id=group['id']) + + app.post(follow_url, extra_environ=env, status=302) # Only sysadmins can view the followers list pages followers_response = app.get(followers_url, extra_environ=env, @@ -504,17 +558,20 @@ class TestGroupSearch(helpers.FunctionalTestBase): def setup(self): super(TestGroupSearch, self).setup() - self.app = self._get_test_app() factories.Group(name='grp-one', title='AGrp One') factories.Group(name='grp-two', title='AGrp Two') factories.Group(name='grp-three', title='Grp Three') - self.search_url = url_for(controller='group', action='index') + + app = self._get_test_app() + with app.flask_app.test_request_context(): + self.search_url = url_for(controller='group', action='index') def test_group_search(self): '''Requesting group search (index) returns list of groups and search form.''' - index_response = self.app.get(self.search_url) + app = self._get_test_app() + index_response = app.get(self.search_url) index_response_html = BeautifulSoup(index_response.body) grp_names = index_response_html.select('ul.media-grid ' 'li.media-item ' @@ -529,7 +586,8 @@ def test_group_search(self): def test_group_search_results(self): '''Searching via group search form returns list of expected groups.''' - index_response = self.app.get(self.search_url) + app = self._get_test_app() + index_response = app.get(self.search_url) search_form = index_response.forms['group-search-form'] search_form['q'] = 'AGrp' search_response = webtest_submit(search_form) @@ -548,7 +606,8 @@ def test_group_search_results(self): def test_group_search_no_results(self): '''Searching with a term that doesn't apply returns no results.''' - index_response = self.app.get(self.search_url) + app = self._get_test_app() + index_response = app.get(self.search_url) search_form = index_response.forms['group-search-form'] search_form['q'] = 'No Results Here' search_response = webtest_submit(search_form) @@ -580,8 +639,9 @@ def test_group_search_within_org(self): factories.Dataset(name="ds-three", title="Dataset Three", groups=[{'id': grp['id']}]) - grp_url = url_for(controller='group', action='read', - id=grp['id']) + with app.flask_app.test_request_context(): + grp_url = url_for(controller='group', action='read', + id=grp['id']) grp_response = app.get(grp_url) grp_response_html = BeautifulSoup(grp_response.body) @@ -608,8 +668,9 @@ def test_group_search_within_org_results(self): factories.Dataset(name="ds-three", title="Dataset Three", groups=[{'id': grp['id']}]) - grp_url = url_for(controller='group', action='read', - id=grp['id']) + with app.flask_app.test_request_context(): + grp_url = url_for(controller='group', action='read', + id=grp['id']) grp_response = app.get(grp_url) search_form = grp_response.forms['group-datasets-search-form'] search_form['q'] = 'One' @@ -641,8 +702,9 @@ def test_group_search_within_org_no_results(self): factories.Dataset(name="ds-three", title="Dataset Three", groups=[{'id': grp['id']}]) - grp_url = url_for(controller='group', action='read', - id=grp['id']) + with app.flask_app.test_request_context(): + grp_url = url_for(controller='group', action='read', + id=grp['id']) grp_response = app.get(grp_url) search_form = grp_response.forms['group-datasets-search-form'] search_form['q'] = 'Nout' @@ -671,8 +733,9 @@ def test_group_index(self): name='test-group-{0}'.format(_i), title='Test Group {0}'.format(_i)) - url = url_for(controller='group', - action='index') + with app.flask_app.test_request_context(): + url = url_for(controller='group', + action='index') response = app.get(url) for i in xrange(1, 22): @@ -681,9 +744,10 @@ def test_group_index(self): assert 'Test Group 22' not in response - url = url_for(controller='group', - action='index', - page=1) + with app.flask_app.test_request_context(): + url = url_for(controller='group', + action='index', + page=1) response = app.get(url) for i in xrange(1, 22): @@ -692,9 +756,10 @@ def test_group_index(self): assert 'Test Group 22' not in response - url = url_for(controller='group', - action='index', - page=2) + with app.flask_app.test_request_context(): + url = url_for(controller='group', + action='index', + page=2) response = app.get(url) for i in xrange(22, 26): diff --git a/ckan/tests/controllers/test_home.py b/ckan/tests/controllers/test_home.py index 44731868635..34c02739840 100644 --- a/ckan/tests/controllers/test_home.py +++ b/ckan/tests/controllers/test_home.py @@ -12,7 +12,11 @@ class TestHome(helpers.FunctionalTestBase): def test_home_renders(self): app = self._get_test_app() - response = app.get(url_for('home')) + + with app.flask_app.test_request_context(): + url = url_for('home') + + response = app.get(url) assert 'Welcome to CKAN' in response.body def test_template_head_end(self): @@ -20,14 +24,22 @@ def test_template_head_end(self): # test-core.ini sets ckan.template_head_end to this: test_link = '' - response = app.get(url_for('home')) + + with app.flask_app.test_request_context(): + url = url_for('home') + + response = app.get(url) assert test_link in response.body def test_template_footer_end(self): app = self._get_test_app() # test-core.ini sets ckan.template_footer_end to this: test_html = 'TEST TEMPLATE_FOOTER_END TEST' - response = app.get(url_for('home')) + + with app.flask_app.test_request_context(): + url = url_for('home') + + response = app.get(url) assert test_html in response.body def test_email_address_nag(self): @@ -41,10 +53,14 @@ def test_email_address_nag(self): model.Session.commit() env = {'REMOTE_USER': user.name.encode('ascii')} - response = app.get(url=url_for('home'), extra_environ=env) + with app.flask_app.test_request_context(): + url = url_for('home') + user_edit_url = url_for(controller='user', action='edit') + + response = app.get(url, extra_environ=env) assert 'update your profile' in response.body - assert url_for(controller='user', action='edit') in response.body + assert user_edit_url in response.body assert ' and add your email address.' in response.body def test_email_address_no_nag(self): @@ -52,7 +68,10 @@ def test_email_address_no_nag(self): user = factories.User(email='filled_in@nicely.com') env = {'REMOTE_USER': user['name'].encode('ascii')} - response = app.get(url=url_for('home'), extra_environ=env) + with app.flask_app.test_request_context(): + url = url_for('home') + + response = app.get(url, extra_environ=env) assert 'add your email address' not in response @@ -61,7 +80,11 @@ class TestI18nURLs(helpers.FunctionalTestBase): def test_right_urls_are_rendered_on_language_selector(self): app = self._get_test_app() - response = app.get(url_for('home')) + + with app.flask_app.test_request_context(): + url = url_for('home') + + response = app.get(url) html = BeautifulSoup(response.body) select = html.find(id='field-lang-select') @@ -77,7 +100,11 @@ def test_right_urls_are_rendered_on_language_selector(self): def test_default_english_option_is_selected_on_language_selector(self): app = self._get_test_app() - response = app.get(url_for('home')) + + with app.flask_app.test_request_context(): + url = url_for('home') + + response = app.get(url) html = BeautifulSoup(response.body) select = html.find(id='field-lang-select') @@ -89,7 +116,11 @@ def test_default_english_option_is_selected_on_language_selector(self): def test_right_option_is_selected_on_language_selector(self): app = self._get_test_app() - response = app.get(url_for('home', locale='ca')) + + with app.flask_app.test_request_context(): + url = url_for('home', locale='ca') + + response = app.get(url) html = BeautifulSoup(response.body) select = html.find(id='field-lang-select') diff --git a/ckan/tests/controllers/test_organization.py b/ckan/tests/controllers/test_organization.py index ed8da4a48a8..65db01c9f6f 100644 --- a/ckan/tests/controllers/test_organization.py +++ b/ckan/tests/controllers/test_organization.py @@ -1,8 +1,8 @@ # encoding: utf-8 from bs4 import BeautifulSoup +from ckan.lib.helpers import url_for from nose.tools import assert_equal, assert_true, assert_in -from routes import url_for from mock import patch from ckan.tests import factories, helpers @@ -12,19 +12,29 @@ class TestOrganizationNew(helpers.FunctionalTestBase): def setup(self): super(TestOrganizationNew, self).setup() - self.app = helpers._get_test_app() + self.user = factories.User() self.user_env = {'REMOTE_USER': self.user['name'].encode('ascii')} - self.organization_new_url = url_for(controller='organization', - action='new') + + app = helpers._get_test_app() + with app.flask_app.test_request_context(): + self.organization_new_url = url_for(controller='organization', + action='new') def test_not_logged_in(self): - self.app.get(url=url_for(controller='group', action='new'), - status=403) + + app = helpers._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='group', action='new') + app.get(url, status=403) def test_name_required(self): - response = self.app.get(url=self.organization_new_url, - extra_environ=self.user_env) + + app = helpers._get_test_app() + + response = app.get(url=self.organization_new_url, + extra_environ=self.user_env) form = response.forms['organization-edit-form'] response = webtest_submit(form, name='save', extra_environ=self.user_env) @@ -33,13 +43,16 @@ def test_name_required(self): assert_true('Name: Missing value' in response) def test_saved(self): - response = self.app.get(url=self.organization_new_url, - extra_environ=self.user_env) + + app = helpers._get_test_app() + + response = app.get(url=self.organization_new_url, + extra_environ=self.user_env) form = response.forms['organization-edit-form'] form['name'] = u'saved' - response = submit_and_follow(self.app, form, name='save', + response = submit_and_follow(app, form, name='save', extra_environ=self.user_env) group = helpers.call_action('organization_show', id='saved') assert_equal(group['title'], u'') @@ -47,6 +60,7 @@ def test_saved(self): assert_equal(group['state'], 'active') def test_all_fields_saved(self): + app = helpers._get_test_app() response = app.get(url=self.organization_new_url, extra_environ=self.user_env) @@ -57,7 +71,7 @@ def test_all_fields_saved(self): form['description'] = 'Sciencey datasets' form['image_url'] = 'http://example.com/image.png' - response = submit_and_follow(self.app, form, name='save', + response = submit_and_follow(app, form, name='save', extra_environ=self.user_env) group = helpers.call_action('organization_show', id='all-fields-saved') assert_equal(group['title'], u'Science') @@ -67,33 +81,44 @@ def test_all_fields_saved(self): class TestOrganizationList(helpers.FunctionalTestBase): def setup(self): super(TestOrganizationList, self).setup() - self.app = helpers._get_test_app() + self.user = factories.User() self.user_env = {'REMOTE_USER': self.user['name'].encode('ascii')} - self.organization_list_url = url_for(controller='organization', - action='index') + app = helpers._get_test_app() + with app.flask_app.test_request_context(): + self.organization_list_url = url_for(controller='organization', + action='index') + + @patch('ckan.logic.auth.get.organization_list', + return_value={'success': False}) + def test_error_message_shown_when_no_organization_list_permission( + self, mock_check_access): - @patch('ckan.logic.auth.get.organization_list', return_value={'success': False}) - def test_error_message_shown_when_no_organization_list_permission(self, mock_check_access): - response = self.app.get(url=self.organization_list_url, - extra_environ=self.user_env, - status=403) + app = helpers._get_test_app() + + app.get(url=self.organization_list_url, + extra_environ=self.user_env, + status=403) class TestOrganizationRead(helpers.FunctionalTestBase): def setup(self): super(TestOrganizationRead, self).setup() - self.app = helpers._get_test_app() + self.user = factories.User() self.user_env = {'REMOTE_USER': self.user['name'].encode('ascii')} self.organization = factories.Organization(user=self.user) def test_organization_read(self): - response = self.app.get(url=url_for(controller='organization', - action='read', - id=self.organization['id']), - status=200, - extra_environ=self.user_env) + + app = helpers._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='organization', action='read', + id=self.organization['id']) + response = app.get(url=url, + status=200, + extra_environ=self.user_env) assert_in(self.organization['title'], response) assert_in(self.organization['description'], response) @@ -101,24 +126,33 @@ def test_organization_read(self): class TestOrganizationEdit(helpers.FunctionalTestBase): def setup(self): super(TestOrganizationEdit, self).setup() - self.app = helpers._get_test_app() + self.user = factories.User() self.user_env = {'REMOTE_USER': self.user['name'].encode('ascii')} self.organization = factories.Organization(user=self.user) - self.organization_edit_url = url_for(controller='organization', - action='edit', - id=self.organization['id']) + app = helpers._get_test_app() + with app.flask_app.test_request_context(): + self.organization_edit_url = url_for(controller='organization', + action='edit', + id=self.organization['id']) def test_group_doesnt_exist(self): - url = url_for(controller='organization', - action='edit', - id='doesnt_exist') - self.app.get(url=url, extra_environ=self.user_env, - status=404) + + app = helpers._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='organization', + action='edit', + id='doesnt_exist') + app.get(url=url, extra_environ=self.user_env, + status=404) def test_saved(self): - response = self.app.get(url=self.organization_edit_url, - extra_environ=self.user_env) + + app = helpers._get_test_app() + + response = app.get(url=self.organization_edit_url, + extra_environ=self.user_env) form = response.forms['organization-edit-form'] response = webtest_submit(form, name='save', @@ -130,8 +164,11 @@ def test_saved(self): assert_equal(group['state'], 'active') def test_all_fields_saved(self): - response = self.app.get(url=self.organization_edit_url, - extra_environ=self.user_env) + + app = helpers._get_test_app() + + response = app.get(url=self.organization_edit_url, + extra_environ=self.user_env) form = response.forms['organization-edit-form'] form['name'] = u'all-fields-edited' @@ -151,59 +188,79 @@ def test_all_fields_saved(self): class TestOrganizationDelete(helpers.FunctionalTestBase): def setup(self): super(TestOrganizationDelete, self).setup() - self.app = helpers._get_test_app() + self.user = factories.User() self.user_env = {'REMOTE_USER': self.user['name'].encode('ascii')} self.organization = factories.Organization(user=self.user) def test_owner_delete(self): - response = self.app.get(url=url_for(controller='organization', - action='delete', - id=self.organization['id']), - status=200, - extra_environ=self.user_env) + + app = helpers._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='organization', + action='delete', + id=self.organization['id']) + response = app.get(url, status=200, extra_environ=self.user_env) form = response.forms['organization-confirm-delete-form'] - response = submit_and_follow(self.app, form, name='delete', + response = submit_and_follow(app, form, name='delete', extra_environ=self.user_env) organization = helpers.call_action('organization_show', id=self.organization['id']) assert_equal(organization['state'], 'deleted') def test_sysadmin_delete(self): + + app = helpers._get_test_app() + sysadmin = factories.Sysadmin() extra_environ = {'REMOTE_USER': sysadmin['name'].encode('ascii')} - response = self.app.get(url=url_for(controller='organization', - action='delete', - id=self.organization['id']), - status=200, - extra_environ=extra_environ) + with app.flask_app.test_request_context(): + url = url_for(controller='organization', + action='delete', + id=self.organization['id']) + + response = app.get(url=url, + status=200, + extra_environ=extra_environ) form = response.forms['organization-confirm-delete-form'] - response = submit_and_follow(self.app, form, name='delete', + response = submit_and_follow(app, form, name='delete', extra_environ=self.user_env) organization = helpers.call_action('organization_show', id=self.organization['id']) assert_equal(organization['state'], 'deleted') def test_non_authorized_user_trying_to_delete_fails(self): + + app = helpers._get_test_app() + user = factories.User() extra_environ = {'REMOTE_USER': user['name'].encode('ascii')} - self.app.get(url=url_for(controller='organization', - action='delete', - id=self.organization['id']), - status=403, - extra_environ=extra_environ) + with app.flask_app.test_request_context(): + url = url_for(controller='organization', + action='delete', + id=self.organization['id']) + + app.get(url=url, + status=403, + extra_environ=extra_environ) organization = helpers.call_action('organization_show', id=self.organization['id']) assert_equal(organization['state'], 'active') def test_anon_user_trying_to_delete_fails(self): - self.app.get(url=url_for(controller='organization', - action='delete', - id=self.organization['id']), - status=403) + + app = helpers._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='organization', + action='delete', + id=self.organization['id']) + + app.get(url=url, + status=403) organization = helpers.call_action('organization_show', id=self.organization['id']) @@ -213,19 +270,24 @@ def test_anon_user_trying_to_delete_fails(self): class TestOrganizationBulkProcess(helpers.FunctionalTestBase): def setup(self): super(TestOrganizationBulkProcess, self).setup() - self.app = helpers._get_test_app() + self.user = factories.User() self.user_env = {'REMOTE_USER': self.user['name'].encode('ascii')} self.organization = factories.Organization(user=self.user) - self.organization_bulk_url = url_for(controller='organization', - action='bulk_process', - id=self.organization['id']) + app = helpers._get_test_app() + with app.flask_app.test_request_context(): + self.organization_bulk_url = url_for(controller='organization', + action='bulk_process', + id=self.organization['id']) def test_make_private(self): + + app = helpers._get_test_app() + datasets = [factories.Dataset(owner_org=self.organization['id']) for i in range(0, 5)] - response = self.app.get(url=self.organization_bulk_url, - extra_environ=self.user_env) + response = app.get(url=self.organization_bulk_url, + extra_environ=self.user_env) form = response.forms[1] for v in form.fields.values(): try: @@ -241,11 +303,14 @@ def test_make_private(self): assert_equal(d['private'], True) def test_make_public(self): + + app = helpers._get_test_app() + datasets = [factories.Dataset(owner_org=self.organization['id'], private=True) for i in range(0, 5)] - response = self.app.get(url=self.organization_bulk_url, - extra_environ=self.user_env) + response = app.get(url=self.organization_bulk_url, + extra_environ=self.user_env) form = response.forms[1] for v in form.fields.values(): try: @@ -261,11 +326,14 @@ def test_make_public(self): assert_equal(d['private'], False) def test_delete(self): + + app = helpers._get_test_app() + datasets = [factories.Dataset(owner_org=self.organization['id'], private=True) for i in range(0, 5)] - response = self.app.get(url=self.organization_bulk_url, - extra_environ=self.user_env) + response = app.get(url=self.organization_bulk_url, + extra_environ=self.user_env) form = response.forms[1] for v in form.fields.values(): try: @@ -287,17 +355,23 @@ class TestOrganizationSearch(helpers.FunctionalTestBase): def setup(self): super(TestOrganizationSearch, self).setup() - self.app = self._get_test_app() factories.Organization(name='org-one', title='AOrg One') factories.Organization(name='org-two', title='AOrg Two') factories.Organization(name='org-three', title='Org Three') - self.search_url = url_for(controller='organization', action='index') + + app = helpers._get_test_app() + with app.flask_app.test_request_context(): + self.search_url = url_for(controller='organization', + action='index') def test_organization_search(self): + + app = helpers._get_test_app() + '''Requesting organization search (index) returns list of organizations and search form.''' - index_response = self.app.get(self.search_url) + index_response = app.get(self.search_url) index_response_html = BeautifulSoup(index_response.body) org_names = index_response_html.select('ul.media-grid ' 'li.media-item ' @@ -310,10 +384,13 @@ def test_organization_search(self): assert_true('Org Three' in org_names) def test_organization_search_results(self): + + app = helpers._get_test_app() + '''Searching via organization search form returns list of expected organizations.''' - index_response = self.app.get(self.search_url) + index_response = app.get(self.search_url) search_form = index_response.forms['organization-search-form'] search_form['q'] = 'AOrg' search_response = webtest_submit(search_form) @@ -330,9 +407,12 @@ def test_organization_search_results(self): assert_true('Org Three' not in org_names) def test_organization_search_no_results(self): + + app = helpers._get_test_app() + '''Searching with a term that doesn't apply returns no results.''' - index_response = self.app.get(self.search_url) + index_response = app.get(self.search_url) search_form = index_response.forms['organization-search-form'] search_form['q'] = 'No Results Here' search_response = webtest_submit(search_form) @@ -365,8 +445,9 @@ def test_organization_search_within_org(self): factories.Dataset(name="ds-three", title="Dataset Three", owner_org=org['id']) - org_url = url_for(controller='organization', action='read', - id=org['id']) + with app.flask_app.test_request_context(): + org_url = url_for(controller='organization', action='read', + id=org['id']) org_response = app.get(org_url) org_response_html = BeautifulSoup(org_response.body) @@ -394,8 +475,9 @@ def test_organization_search_within_org_results(self): factories.Dataset(name="ds-three", title="Dataset Three", owner_org=org['id']) - org_url = url_for(controller='organization', action='read', - id=org['id']) + with app.flask_app.test_request_context(): + org_url = url_for(controller='organization', action='read', + id=org['id']) org_response = app.get(org_url) search_form = org_response.forms['organization-datasets-search-form'] search_form['q'] = 'One' @@ -427,8 +509,9 @@ def test_organization_search_within_org_no_results(self): factories.Dataset(name="ds-three", title="Dataset Three", owner_org=org['id']) - org_url = url_for(controller='organization', action='read', - id=org['id']) + with app.flask_app.test_request_context(): + org_url = url_for(controller='organization', action='read', + id=org['id']) org_response = app.get(org_url) search_form = org_response.forms['organization-datasets-search-form'] search_form['q'] = 'Nout' diff --git a/ckan/tests/controllers/test_package.py b/ckan/tests/controllers/test_package.py index d4cc8b379ed..6489d7fe33f 100644 --- a/ckan/tests/controllers/test_package.py +++ b/ckan/tests/controllers/test_package.py @@ -9,12 +9,10 @@ assert_in ) -from mock import patch, MagicMock -from routes import url_for +from ckan.lib.helpers import url_for import ckan.model as model import ckan.plugins as p -from ckan.lib import search import ckan.tests.helpers as helpers import ckan.tests.factories as factories @@ -27,8 +25,10 @@ def _get_package_new_page(app): user = factories.User() env = {'REMOTE_USER': user['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='new') response = app.get( - url=url_for(controller='package', action='new'), + url=url, extra_environ=env, ) return env, response @@ -50,12 +50,18 @@ def test_needs_organization_but_no_organizations_has_button(self): sysadmin = factories.Sysadmin() env = {'REMOTE_USER': sysadmin['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='new') + response = app.get( - url=url_for(controller='package', action='new'), + url=url, extra_environ=env ) assert 'dataset-edit' not in response.forms - assert url_for(controller='organization', action='new') in response + + with app.flask_app.test_request_context(): + assert url_for(controller='organization', action='new') in response @helpers.mock_auth('ckan.logic.auth.create.package_create') @helpers.change_config('ckan.auth.create_unowned_dataset', 'false') @@ -73,13 +79,19 @@ def test_needs_organization_but_no_organizations_no_button(self, user = factories.User() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='new') + response = app.get( - url=url_for(controller='package', action='new'), + url=url, extra_environ=env ) assert 'dataset-edit' not in response.forms - assert url_for(controller='organization', action='new') not in response + + with app.flask_app.test_request_context(): + assert url_for(controller='organization', action='new') not in response assert 'Ask a system administrator' in response def test_name_required(self): @@ -240,8 +252,11 @@ def test_dataset_edit_org_dropdown_visible_to_normal_user_with_orgs_available(se app = self._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='new') response = app.get( - url=url_for(controller='package', action='new'), + url=url, extra_environ=env, ) @@ -262,9 +277,11 @@ def test_dataset_edit_org_dropdown_visible_to_normal_user_with_orgs_available(se assert_equal(pkg.state, 'active') # edit package page response - url = url_for(controller='package', - action='edit', - id=pkg.id) + + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='edit', + id=pkg.id) pkg_edit_response = app.get(url=url, extra_environ=env) # A field with the correct id is in the response form = pkg_edit_response.forms['dataset-edit'] @@ -285,8 +302,10 @@ def test_dataset_edit_org_dropdown_normal_user_can_remove_org(self): app = self._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='new') response = app.get( - url=url_for(controller='package', action='new'), + url=url, extra_environ=env, ) @@ -306,9 +325,10 @@ def test_dataset_edit_org_dropdown_normal_user_can_remove_org(self): assert_not_equal(pkg.owner_org, None) # edit package page response - url = url_for(controller='package', - action='edit', - id=pkg.id) + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='edit', + id=pkg.id) pkg_edit_response = app.get(url=url, extra_environ=env) # edit dataset @@ -331,8 +351,11 @@ def test_dataset_edit_org_dropdown_not_visible_to_normal_user_with_no_orgs_avail app = self._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='new') response = app.get( - url=url_for(controller='package', action='new'), + url=url, extra_environ=env, ) @@ -352,9 +375,10 @@ def test_dataset_edit_org_dropdown_not_visible_to_normal_user_with_no_orgs_avail assert_equal(pkg.state, 'active') # edit package response - url = url_for(controller='package', - action='edit', - id=model.Package.by_name(u'my-dataset').id) + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='edit', + id=model.Package.by_name(u'my-dataset').id) pkg_edit_response = app.get(url=url, extra_environ=env) # A field with the correct id is in the response form = pkg_edit_response.forms['dataset-edit'] @@ -376,8 +400,10 @@ def test_dataset_edit_org_dropdown_visible_to_sysadmin_with_no_orgs_available(se app = self._get_test_app() # user in env is sysadmin env = {'REMOTE_USER': sysadmin['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='new') response = app.get( - url=url_for(controller='package', action='new'), + url=url, extra_environ=env, ) @@ -398,9 +424,10 @@ def test_dataset_edit_org_dropdown_visible_to_sysadmin_with_no_orgs_available(se assert_equal(pkg.state, 'active') # edit package page response - url = url_for(controller='package', - action='edit', - id=pkg.id) + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='edit', + id=pkg.id) pkg_edit_response = app.get(url=url, extra_environ=env) # A field with the correct id is in the response assert 'id="field-organizations"' in pkg_edit_response @@ -410,11 +437,14 @@ def test_dataset_edit_org_dropdown_visible_to_sysadmin_with_no_orgs_available(se def test_unauthed_user_creating_dataset(self): app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='new') # provide REMOTE_ADDR to idenfity as remote user, see # ckan.views.identify_user() for details - response = app.post(url=url_for(controller='package', action='new'), - extra_environ={'REMOTE_ADDR': '127.0.0.1'}, - status=403) + + app.post(url=url, + extra_environ={'REMOTE_ADDR': '127.0.0.1'}, + status=403) class TestPackageEdit(helpers.FunctionalTestBase): @@ -426,10 +456,13 @@ def test_organization_admin_can_edit(self): dataset = factories.Dataset(owner_org=organization['id']) app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='edit', + id=dataset['name']) response = app.get( - url_for(controller='package', - action='edit', - id=dataset['name']), + url, extra_environ=env, ) form = response.forms['dataset-edit'] @@ -447,10 +480,12 @@ def test_organization_editor_can_edit(self): dataset = factories.Dataset(owner_org=organization['id']) app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='edit', + id=dataset['name']) response = app.get( - url_for(controller='package', - action='edit', - id=dataset['name']), + url, extra_environ=env, ) form = response.forms['dataset-edit'] @@ -468,10 +503,12 @@ def test_organization_member_cannot_edit(self): dataset = factories.Dataset(owner_org=organization['id']) app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} - response = app.get( - url_for(controller='package', - action='edit', - id=dataset['name']), + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='edit', + id=dataset['name']) + app.get( + url, extra_environ=env, status=403, ) @@ -482,19 +519,20 @@ def test_user_not_in_organization_cannot_edit(self): dataset = factories.Dataset(owner_org=organization['id']) app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} - response = app.get( - url_for(controller='package', - action='edit', - id=dataset['name']), + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='edit', + id=dataset['name']) + app.get( + url, extra_environ=env, status=403, ) env = {'REMOTE_USER': user['name'].encode('ascii')} - response = app.post( - url_for(controller='package', - action='edit', - id=dataset['name']), + + app.post( + url, {'notes': 'edited description'}, extra_environ=env, status=403, @@ -504,17 +542,17 @@ def test_anonymous_user_cannot_edit(self): organization = factories.Organization() dataset = factories.Dataset(owner_org=organization['id']) app = helpers._get_test_app() - response = app.get( - url_for(controller='package', - action='edit', - id=dataset['name']), + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='edit', + id=dataset['name']) + app.get( + url, status=403, ) - response = app.post( - url_for(controller='package', - action='edit', - id=dataset['name']), + app.post( + url, {'notes': 'edited description'}, status=403, ) @@ -528,10 +566,13 @@ def test_validation_errors_for_dataset_name_appear(self): dataset = factories.Dataset(owner_org=organization['id']) app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='edit', + id=dataset['name']) + response = app.get( - url_for(controller='package', - action='edit', - id=dataset['name']), + url, extra_environ=env, ) form = response.forms['dataset-edit'] @@ -546,10 +587,13 @@ def test_edit_a_dataset_that_does_not_exist_404s(self): user = factories.User() app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='edit', + id='does-not-exist') + response = app.get( - url_for(controller='package', - action='edit', - id='does-not-exist'), + url, extra_environ=env, expect_errors=True ) @@ -560,8 +604,11 @@ class TestPackageRead(helpers.FunctionalTestBase): def test_read(self): dataset = factories.Dataset() app = helpers._get_test_app() - response = app.get(url_for(controller='package', action='read', - id=dataset['name'])) + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='read', + id=dataset['name']) + response = app.get(url) response.mustcontain('Test Dataset') response.mustcontain('Just another test dataset') @@ -585,13 +632,13 @@ def test_organization_members_can_read_private_datasets(self): ) app = helpers._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='read', + id=dataset['name']) for user, user_dict in members.items(): response = app.get( - url_for( - controller='package', - action='read', - id=dataset['name'] - ), + url, extra_environ={ 'REMOTE_USER': user_dict['name'].encode('ascii'), }, @@ -606,8 +653,13 @@ def test_anonymous_users_cannot_read_private_datasets(self): private=True, ) app = helpers._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='read', + id=dataset['name']) + response = app.get( - url_for(controller='package', action='read', id=dataset['name']), + url, status=404 ) assert_equal(404, response.status_int) @@ -620,8 +672,13 @@ def test_user_not_in_organization_cannot_read_private_datasets(self): private=True, ) app = helpers._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='read', + id=dataset['name']) + response = app.get( - url_for(controller='package', action='read', id=dataset['name']), + url, extra_environ={'REMOTE_USER': user['name'].encode('ascii')}, status=404 ) @@ -631,18 +688,20 @@ def test_read_rdf(self): ''' The RDF outputs now live in ckanext-dcat''' dataset1 = factories.Dataset() - offset = url_for(controller='package', action='read', - id=dataset1['name']) + ".rdf" app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='package', action='read', + id=dataset1['name']) + ".rdf" app.get(offset, status=404) def test_read_n3(self): ''' The RDF outputs now live in ckanext-dcat''' dataset1 = factories.Dataset() - offset = url_for(controller='package', action='read', - id=dataset1['name']) + ".n3" app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='package', action='read', + id=dataset1['name']) + ".n3" app.get(offset, status=404) @@ -656,8 +715,12 @@ def test_owner_delete(self): app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='delete', id=dataset['name']) + response = app.post( - url_for(controller='package', action='delete', id=dataset['name']), + url, extra_environ=env, ) response = response.follow() @@ -668,9 +731,13 @@ def test_owner_delete(self): def test_delete_on_non_existing_dataset(self): app = helpers._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='delete', + id='schrodingersdatset') + response = app.post( - url_for(controller='package', action='delete', - id='schrodingersdatset'), + url, expect_errors=True, ) assert_equal(404, response.status_int) @@ -683,8 +750,11 @@ def test_sysadmin_can_delete_any_dataset(self): user = factories.Sysadmin() env = {'REMOTE_USER': user['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='delete', id=dataset['name']) + response = app.post( - url_for(controller='package', action='delete', id=dataset['name']), + url, extra_environ=env, ) response = response.follow() @@ -701,8 +771,12 @@ def test_anon_user_cannot_delete_owned_dataset(self): dataset = factories.Dataset(owner_org=owner_org['id']) app = helpers._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='delete', id=dataset['name']) + response = app.post( - url_for(controller='package', action='delete', id=dataset['name']), + url, status=403, ) response.mustcontain('Unauthorized to delete package') @@ -720,8 +794,12 @@ def test_logged_in_user_cannot_delete_owned_dataset(self): app = helpers._get_test_app() user = factories.User() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='delete', id=dataset['name']) + response = app.post( - url_for(controller='package', action='delete', id=dataset['name']), + url, extra_environ=env, expect_errors=True ) @@ -741,8 +819,12 @@ def test_confirm_cancel_delete(self): app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='delete', id=dataset['name']) + response = app.get( - url_for(controller='package', action='delete', id=dataset['name']), + url, extra_environ=env, ) assert_equal(200, response.status_int) @@ -766,12 +848,16 @@ def test_manage_dataset_resource_listing_page(self): resource = factories.Resource(package_id=dataset['id']) app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} - response = app.get( - url_for( + + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='resources', id=dataset['name'], - ), + ) + + response = app.get( + url, extra_environ=env ) assert_in(resource['name'], response) @@ -785,12 +871,16 @@ def test_unauth_user_cannot_view_manage_dataset_resource_listing_page(self): resource = factories.Resource(package_id=dataset['id']) app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} - response = app.get( - url_for( + + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='resources', id=dataset['name'], - ), + ) + + response = app.get( + url, extra_environ=env ) assert_in(resource['name'], response) @@ -801,12 +891,16 @@ def test_404_on_manage_dataset_resource_listing_page_that_does_not_exist(self): user = factories.User() app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} - response = app.get( - url_for( + + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='resources', id='does-not-exist' - ), + ) + + response = app.get( + url, extra_environ=env, expect_errors=True ) @@ -818,12 +912,15 @@ def test_add_new_resource_with_link_and_download(self): env = {'REMOTE_USER': user['name'].encode('ascii')} app = helpers._get_test_app() - response = app.get( - url_for( + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='new_resource', id=dataset['id'], - ), + ) + + response = app.get( + url, extra_environ=env ) @@ -833,13 +930,17 @@ def test_add_new_resource_with_link_and_download(self): 'go-dataset-complete') result = helpers.call_action('package_show', id=dataset['id']) - response = app.get( - url_for( + + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='resource_download', id=dataset['id'], resource_id=result['resources'][0]['id'] - ), + ) + + response = app.get( + url, extra_environ=env, ) assert_equal(302, response.status_int) @@ -855,12 +956,15 @@ def test_editor_can_add_new_resource(self): env = {'REMOTE_USER': user['name'].encode('ascii')} app = helpers._get_test_app() - response = app.get( - url_for( + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='new_resource', id=dataset['id'], - ), + ) + + response = app.get( + url, extra_environ=env ) @@ -885,12 +989,15 @@ def test_admin_can_add_new_resource(self): env = {'REMOTE_USER': user['name'].encode('ascii')} app = helpers._get_test_app() - response = app.get( - url_for( + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='new_resource', id=dataset['id'], - ), + ) + + response = app.get( + url, extra_environ=env ) @@ -915,22 +1022,28 @@ def test_member_cannot_add_new_resource(self): env = {'REMOTE_USER': user['name'].encode('ascii')} app = helpers._get_test_app() - response = app.get( - url_for( + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='new_resource', id=dataset['id'], - ), + ) + + response = app.get( + url, extra_environ=env, status=403, ) - response = app.post( - url_for( + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='new_resource', id=dataset['id'], - ), + ) + + response = app.post( + url, {'name': 'test', 'url': 'test', 'save': 'save', 'id': ''}, extra_environ=env, status=403, @@ -946,22 +1059,28 @@ def test_non_organization_users_cannot_add_new_resource(self): env = {'REMOTE_USER': user['name'].encode('ascii')} app = helpers._get_test_app() - response = app.get( - url_for( + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='new_resource', id=dataset['id'], - ), + ) + + response = app.get( + url, extra_environ=env, status=403, ) - response = app.post( - url_for( + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='new_resource', id=dataset['id'], - ), + ) + + response = app.post( + url, {'name': 'test', 'url': 'test', 'save': 'save', 'id': ''}, extra_environ=env, status=403, @@ -974,21 +1093,27 @@ def test_anonymous_users_cannot_add_new_resource(self): ) app = helpers._get_test_app() - response = app.get( - url_for( + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='new_resource', id=dataset['id'], - ), + ) + + response = app.get( + url, status=403, ) - response = app.post( - url_for( + with app.flask_app.test_request_context(): + url = url_for( controller='package', action='new_resource', id=dataset['id'], - ), + ) + + response = app.post( + url, {'name': 'test', 'url': 'test', 'save': 'save', 'id': ''}, status=403, ) @@ -1011,35 +1136,41 @@ def teardown_class(cls): def test_existent_resource_view_page_returns_ok_code(self): resource_view = factories.ResourceView() - url = url_for(controller='package', - action='resource_read', - id=resource_view['package_id'], - resource_id=resource_view['resource_id'], - view_id=resource_view['id']) - app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='resource_read', + id=resource_view['package_id'], + resource_id=resource_view['resource_id'], + view_id=resource_view['id']) + app.get(url, status=200) def test_inexistent_resource_view_page_returns_not_found_code(self): resource_view = factories.ResourceView() - url = url_for(controller='package', - action='resource_read', - id=resource_view['package_id'], - resource_id=resource_view['resource_id'], - view_id='inexistent-view-id') - app = self._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='resource_read', + id=resource_view['package_id'], + resource_id=resource_view['resource_id'], + view_id='inexistent-view-id') + app.get(url, status=404) def test_resource_view_description_is_rendered_as_markdown(self): resource_view = factories.ResourceView(description="Some **Markdown**") - url = url_for(controller='package', - action='resource_read', - id=resource_view['package_id'], - resource_id=resource_view['resource_id'], - view_id=resource_view['id']) + app = self._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='resource_read', + id=resource_view['package_id'], + resource_id=resource_view['resource_id'], + view_id=resource_view['id']) response = app.get(url) response.mustcontain('Some Markdown') @@ -1050,12 +1181,12 @@ def test_existing_resource_with_not_associated_dataset(self): dataset = factories.Dataset() resource = factories.Resource() - url = url_for(controller='package', - action='resource_read', - id=dataset['id'], - resource_id=resource['id']) - app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='resource_read', + id=dataset['id'], + resource_id=resource['id']) app.get(url, status=404) def test_resource_read_logged_in_user(self): @@ -1067,12 +1198,12 @@ def test_resource_read_logged_in_user(self): dataset = factories.Dataset() resource = factories.Resource(package_id=dataset['id']) - url = url_for(controller='package', - action='resource_read', - id=dataset['id'], - resource_id=resource['id']) - app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='resource_read', + id=dataset['id'], + resource_id=resource['id']) app.get(url, status=200, extra_environ=env) def test_resource_read_anon_user(self): @@ -1082,12 +1213,12 @@ def test_resource_read_anon_user(self): dataset = factories.Dataset() resource = factories.Resource(package_id=dataset['id']) - url = url_for(controller='package', - action='resource_read', - id=dataset['id'], - resource_id=resource['id']) - app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='resource_read', + id=dataset['id'], + resource_id=resource['id']) app.get(url, status=200) def test_resource_read_sysadmin(self): @@ -1099,12 +1230,12 @@ def test_resource_read_sysadmin(self): dataset = factories.Dataset() resource = factories.Resource(package_id=dataset['id']) - url = url_for(controller='package', - action='resource_read', - id=dataset['id'], - resource_id=resource['id']) - app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='resource_read', + id=dataset['id'], + resource_id=resource['id']) app.get(url, status=200, extra_environ=env) def test_user_not_in_organization_cannot_read_private_dataset(self): @@ -1117,12 +1248,12 @@ def test_user_not_in_organization_cannot_read_private_dataset(self): ) resource = factories.Resource(package_id=dataset['id']) - url = url_for(controller='package', - action='resource_read', - id=dataset['id'], - resource_id=resource['id']) - app = self._get_test_app() + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='resource_read', + id=dataset['id'], + resource_id=resource['id']) response = app.get(url, status=404, extra_environ=env) @@ -1149,14 +1280,16 @@ def test_organization_members_can_read_resources_in_private_datasets(self): app = helpers._get_test_app() + with app.flask_app.test_request_context(): + url = url_for( + controller='package', + action='resource_read', + id=dataset['name'], + resource_id=resource['id'], + ) for user, user_dict in members.items(): response = app.get( - url_for( - controller='package', - action='resource_read', - id=dataset['name'], - resource_id=resource['id'], - ), + url, extra_environ={ 'REMOTE_USER': user_dict['name'].encode('ascii'), }, @@ -1170,8 +1303,12 @@ def test_anonymous_users_cannot_read_private_datasets(self): private=True, ) app = helpers._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='read', id=dataset['name']) + response = app.get( - url_for(controller='package', action='read', id=dataset['name']), + url, status=404 ) assert_equal(404, response.status_int) @@ -1187,9 +1324,13 @@ def test_dataset_owners_can_delete_resources(self): resource = factories.Resource(package_id=dataset['id']) app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='resource_delete', + id=dataset['name'], resource_id=resource['id']) + response = app.post( - url_for(controller='package', action='resource_delete', - id=dataset['name'], resource_id=resource['id']), + url, extra_environ=env, ) response = response.follow() @@ -1207,9 +1348,13 @@ def test_deleting_non_existing_resource_404s(self): dataset = factories.Dataset(owner_org=owner_org['id']) env = {'REMOTE_USER': user['name'].encode('ascii')} app = helpers._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='resource_delete', + id=dataset['name'], resource_id='doesnotexist') + response = app.post( - url_for(controller='package', action='resource_delete', - id=dataset['name'], resource_id='doesnotexist'), + url, extra_environ=env, expect_errors=True ) @@ -1224,9 +1369,13 @@ def test_anon_users_cannot_delete_owned_resources(self): resource = factories.Resource(package_id=dataset['id']) app = helpers._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='resource_delete', + id=dataset['name'], resource_id=resource['id']) + response = app.post( - url_for(controller='package', action='resource_delete', - id=dataset['name'], resource_id=resource['id']), + url, status=403, ) response.mustcontain('Unauthorized to delete package') @@ -1244,9 +1393,13 @@ def test_logged_in_users_cannot_delete_resources_they_do_not_own(self): user = factories.User() env = {'REMOTE_USER': user['name'].encode('ascii')} app = helpers._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='resource_delete', + id=dataset['name'], resource_id=resource['id']) + response = app.post( - url_for(controller='package', action='resource_delete', - id=dataset['name'], resource_id=resource['id']), + url, extra_environ=env, expect_errors=True ) @@ -1261,9 +1414,13 @@ def test_sysadmins_can_delete_any_resource(self): sysadmin = factories.Sysadmin() app = helpers._get_test_app() env = {'REMOTE_USER': sysadmin['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='resource_delete', + id=dataset['name'], resource_id=resource['id']) + response = app.post( - url_for(controller='package', action='resource_delete', - id=dataset['name'], resource_id=resource['id']), + url, extra_environ=env, ) response = response.follow() @@ -1286,9 +1443,13 @@ def test_confirm_and_cancel_deleting_a_resource(self): resource = factories.Resource(package_id=dataset['id']) app = helpers._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='resource_delete', + id=dataset['name'], resource_id=resource['id']) + response = app.get( - url_for(controller='package', action='resource_delete', - id=dataset['name'], resource_id=resource['id']), + url, extra_environ=env, ) assert_equal(200, response.status_int) @@ -1306,8 +1467,9 @@ class TestSearch(helpers.FunctionalTestBase): def test_search_basic(self): dataset1 = factories.Dataset() - offset = url_for(controller='package', action='search') app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='package', action='search') page = app.get(offset) assert dataset1['name'] in page.body.decode('utf8') @@ -1316,8 +1478,10 @@ def test_search_sort_by_blank(self): factories.Dataset() # ?sort has caused an exception in the past - offset = url_for(controller='package', action='search') + '?sort' + app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='package', action='search') + '?sort' app.get(offset) def test_search_sort_by_bad(self): @@ -1326,9 +1490,11 @@ def test_search_sort_by_bad(self): # bad spiders try all sorts of invalid values for sort. They should get # a 400 error with specific error message. No need to alert the # administrator. - offset = url_for(controller='package', action='search') + \ - '?sort=gvgyr_fgevat+nfp' + app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='package', action='search') + \ + '?sort=gvgyr_fgevat+nfp' response = app.get(offset, status=[200, 400]) if response.status == 200: import sys @@ -1344,9 +1510,10 @@ def test_search_solr_syntax_error(self): # Whilst this could be due to a bad user input, it could also be # because CKAN mangled things somehow and therefore we flag it up to # the administrator and give a meaningless error, just in case - offset = url_for(controller='package', action='search') + \ - '?q=--included' app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='package', action='search') + \ + '?q=--included' search_response = app.get(offset) search_response_html = BeautifulSoup(search_response.body) @@ -1357,8 +1524,9 @@ def test_search_solr_syntax_error(self): def test_search_plugin_hooks(self): with p.use_plugin('test_package_controller_plugin') as plugin: - offset = url_for(controller='package', action='search') app = self._get_test_app() + with app.flask_app.test_request_context(): + offset = url_for(controller='package', action='search') app.get(offset) # get redirected ... @@ -1372,7 +1540,8 @@ def test_search_page_request(self): factories.Dataset(name="dataset-two", title='Dataset Two') factories.Dataset(name="dataset-three", title='Dataset Three') - search_url = url_for(controller='package', action='search') + with app.flask_app.test_request_context(): + search_url = url_for(controller='package', action='search') search_response = app.get(search_url) assert_true('3 datasets found' in search_response) @@ -1395,7 +1564,8 @@ def test_search_page_results(self): factories.Dataset(name="dataset-two", title='Dataset Two') factories.Dataset(name="dataset-three", title='Dataset Three') - search_url = url_for(controller='package', action='search') + with app.flask_app.test_request_context(): + search_url = url_for(controller='package', action='search') search_response = app.get(search_url) search_form = search_response.forms['dataset-search-form'] @@ -1420,7 +1590,8 @@ def test_search_page_no_results(self): factories.Dataset(name="dataset-two", title='Dataset Two') factories.Dataset(name="dataset-three", title='Dataset Three') - search_url = url_for(controller='package', action='search') + with app.flask_app.test_request_context(): + search_url = url_for(controller='package', action='search') search_response = app.get(search_url) search_form = search_response.forms['dataset-search-form'] @@ -1445,7 +1616,8 @@ def test_search_page_results_tag(self): factories.Dataset(name="dataset-two", title='Dataset Two') factories.Dataset(name="dataset-three", title='Dataset Three') - search_url = url_for(controller='package', action='search') + with app.flask_app.test_request_context(): + search_url = url_for(controller='package', action='search') search_response = app.get(search_url) assert_true('/dataset?tags=my-tag' in search_response) @@ -1473,7 +1645,8 @@ def test_search_page_results_private(self): factories.Dataset(name="dataset-two", title='Dataset Two') factories.Dataset(name="dataset-three", title='Dataset Three') - search_url = url_for(controller='package', action='search') + with app.flask_app.test_request_context(): + search_url = url_for(controller='package', action='search') search_response = app.get(search_url) search_response_html = BeautifulSoup(search_response.body) @@ -1496,7 +1669,9 @@ def test_user_not_in_organization_cannot_search_private_datasets(self): private=True, ) env = {'REMOTE_USER': user['name'].encode('ascii')} - search_url = url_for(controller='package', action='search') + + with app.flask_app.test_request_context(): + search_url = url_for(controller='package', action='search') search_response = app.get(search_url, extra_environ=env) search_response_html = BeautifulSoup(search_response.body) @@ -1516,7 +1691,9 @@ def test_user_in_organization_can_search_private_datasets(self): private=True, ) env = {'REMOTE_USER': user['name'].encode('ascii')} - search_url = url_for(controller='package', action='search') + + with app.flask_app.test_request_context(): + search_url = url_for(controller='package', action='search') search_response = app.get(search_url, extra_environ=env) search_response_html = BeautifulSoup(search_response.body) @@ -1537,7 +1714,9 @@ def test_user_in_different_organization_cannot_search_private_datasets(self): private=True, ) env = {'REMOTE_USER': user['name'].encode('ascii')} - search_url = url_for(controller='package', action='search') + + with app.flask_app.test_request_context(): + search_url = url_for(controller='package', action='search') search_response = app.get(search_url, extra_environ=env) search_response_html = BeautifulSoup(search_response.body) @@ -1557,7 +1736,9 @@ def test_search_default_include_private_false(self): private=True, ) env = {'REMOTE_USER': user['name'].encode('ascii')} - search_url = url_for(controller='package', action='search') + + with app.flask_app.test_request_context(): + search_url = url_for(controller='package', action='search') search_response = app.get(search_url, extra_environ=env) search_response_html = BeautifulSoup(search_response.body) @@ -1576,7 +1757,9 @@ def test_sysadmin_can_search_private_datasets(self): private=True, ) env = {'REMOTE_USER': user['name'].encode('ascii')} - search_url = url_for(controller='package', action='search') + + with app.flask_app.test_request_context(): + search_url = url_for(controller='package', action='search') search_response = app.get(search_url, extra_environ=env) search_response_html = BeautifulSoup(search_response.body) @@ -1595,9 +1778,11 @@ def test_package_follow(self): package = factories.Dataset() env = {'REMOTE_USER': user['name'].encode('ascii')} - follow_url = url_for(controller='package', - action='follow', - id=package['id']) + + with app.flask_app.test_request_context(): + follow_url = url_for(controller='package', + action='follow', + id=package['id']) response = app.post(follow_url, extra_environ=env, status=302) response = response.follow() assert_true('You are now following {0}' @@ -1611,9 +1796,11 @@ def test_package_follow_not_exist(self): user_one = factories.User() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - follow_url = url_for(controller='package', - action='follow', - id='not-here') + + with app.flask_app.test_request_context(): + follow_url = url_for(controller='package', + action='follow', + id='not-here') response = app.post(follow_url, extra_environ=env, status=302) response = response.follow(status=404) assert_true('Dataset not found' in response) @@ -1625,13 +1812,16 @@ def test_package_unfollow(self): package = factories.Dataset() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - follow_url = url_for(controller='package', - action='follow', - id=package['id']) + + with app.flask_app.test_request_context(): + follow_url = url_for(controller='package', + action='follow', + id=package['id']) app.post(follow_url, extra_environ=env, status=302) - unfollow_url = url_for(controller='package', action='unfollow', - id=package['id']) + with app.flask_app.test_request_context(): + unfollow_url = url_for(controller='package', action='unfollow', + id=package['id']) unfollow_response = app.post(unfollow_url, extra_environ=env, status=302) unfollow_response = unfollow_response.follow() @@ -1648,8 +1838,10 @@ def test_package_unfollow_not_following(self): package = factories.Dataset() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - unfollow_url = url_for(controller='package', action='unfollow', - id=package['id']) + + with app.flask_app.test_request_context(): + unfollow_url = url_for(controller='package', action='unfollow', + id=package['id']) unfollow_response = app.post(unfollow_url, extra_environ=env, status=302) unfollow_response = unfollow_response.follow() @@ -1664,8 +1856,10 @@ def test_package_unfollow_not_exist(self): user_one = factories.User() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - unfollow_url = url_for(controller='package', action='unfollow', - id='not-here') + + with app.flask_app.test_request_context(): + unfollow_url = url_for(controller='package', action='unfollow', + id='not-here') unfollow_response = app.post(unfollow_url, extra_environ=env, status=302) unfollow_response = unfollow_response.follow(status=404) @@ -1679,13 +1873,16 @@ def test_package_follower_list(self): package = factories.Dataset() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - follow_url = url_for(controller='package', - action='follow', - id=package['id']) - app.post(follow_url, extra_environ=env, status=302) - followers_url = url_for(controller='package', action='followers', - id=package['id']) + with app.flask_app.test_request_context(): + follow_url = url_for(controller='package', + action='follow', + id=package['id']) + + followers_url = url_for(controller='package', action='followers', + id=package['id']) + + app.post(follow_url, extra_environ=env, status=302) # Only sysadmins can view the followers list pages followers_response = app.get(followers_url, extra_environ=env, @@ -1700,8 +1897,9 @@ def test_dataset_read(self): dataset = factories.Dataset() - url = url_for(controller='package', - action='read', - id=dataset['id']) + with app.flask_app.test_request_context(): + url = url_for(controller='package', + action='read', + id=dataset['id']) response = app.get(url) assert_in(dataset['title'], response) diff --git a/ckan/tests/controllers/test_tags.py b/ckan/tests/controllers/test_tags.py index 46b4b255b6f..3c34445e911 100644 --- a/ckan/tests/controllers/test_tags.py +++ b/ckan/tests/controllers/test_tags.py @@ -6,7 +6,7 @@ from nose.tools import assert_equal, assert_true, assert_false, assert_in from bs4 import BeautifulSoup -from routes import url_for +from ckan.lib.helpers import url_for import ckan.tests.helpers as helpers from ckan.tests import factories @@ -32,7 +32,8 @@ def test_tags_listed_under_50(self): expected_tags = _make_tag_list(49) factories.Dataset(tags=expected_tags) - tag_index_url = url_for(controller='tag', action='index') + with app.flask_app.test_request_context(): + tag_index_url = url_for(controller='tag', action='index') tag_response = app.get(tag_index_url) tag_response_html = BeautifulSoup(tag_response.body) @@ -53,7 +54,8 @@ def test_tags_listed_over_50(self): expected_tags = _make_tag_list(51) factories.Dataset(tags=expected_tags) - tag_index_url = url_for(controller='tag', action='index') + with app.flask_app.test_request_context(): + tag_index_url = url_for(controller='tag', action='index') tag_response = app.get(tag_index_url) tag_response_html = BeautifulSoup(tag_response.body) @@ -76,7 +78,8 @@ def test_tag_search(self): expected_tags.append({'name': 'find-me'}) factories.Dataset(tags=expected_tags) - tag_index_url = url_for(controller='tag', action='index') + with app.flask_app.test_request_context(): + tag_index_url = url_for(controller='tag', action='index') tag_response = app.get(tag_index_url) search_form = tag_response.forms[1] @@ -98,7 +101,8 @@ def test_tag_search_no_results(self): expected_tags = _make_tag_list(50) factories.Dataset(tags=expected_tags) - tag_index_url = url_for(controller='tag', action='index') + with app.flask_app.test_request_context(): + tag_index_url = url_for(controller='tag', action='index') tag_response = app.get(tag_index_url) search_form = tag_response.forms[1] @@ -121,7 +125,8 @@ def test_tag_read_redirects_to_dataset_search(self): app = self._get_test_app() factories.Dataset(title='My Other Dataset', tags=[{'name': 'find-me'}]) - tag_url = url_for(controller='tag', action='read', id='find-me') + with app.flask_app.test_request_context(): + tag_url = url_for(controller='tag', action='read', id='find-me') tag_response = app.get(tag_url, status=302) assert_equal(tag_response.headers['Location'], 'http://test.ckan.net/dataset?tags=find-me') @@ -131,5 +136,6 @@ def test_tag_read_not_found(self): app = self._get_test_app() factories.Dataset(title='My Other Dataset', tags=[{'name': 'find-me'}]) - tag_url = url_for(controller='tag', action='read', id='not-here') + with app.flask_app.test_request_context(): + tag_url = url_for(controller='tag', action='read', id='not-here') app.get(tag_url, status=404) diff --git a/ckan/tests/controllers/test_user.py b/ckan/tests/controllers/test_user.py index b3f63d12bc7..045ebf5d8d5 100644 --- a/ckan/tests/controllers/test_user.py +++ b/ckan/tests/controllers/test_user.py @@ -3,7 +3,7 @@ from bs4 import BeautifulSoup from nose.tools import assert_true, assert_false, assert_equal -from routes import url_for +from ckan.lib.helpers import url_for import ckan.tests.helpers as helpers import ckan.tests.factories as factories @@ -18,8 +18,11 @@ def _get_user_edit_page(app): user = factories.User() env = {'REMOTE_USER': user['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='edit') + response = app.get( - url=url_for(controller='user', action='edit'), + url=url, extra_environ=env, ) return env, response, user @@ -28,7 +31,11 @@ def _get_user_edit_page(app): class TestRegisterUser(helpers.FunctionalTestBase): def test_register_a_user(self): app = helpers._get_test_app() - response = app.get(url=url_for(controller='user', action='register')) + + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='register') + + response = app.get(url) form = response.forms['user-register-form'] form['name'] = 'newuser' @@ -47,7 +54,11 @@ def test_register_a_user(self): def test_register_user_bad_password(self): app = helpers._get_test_app() - response = app.get(url=url_for(controller='user', action='register')) + + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='register') + + response = app.get(url) form = response.forms['user-register-form'] form['name'] = 'newuser' @@ -77,9 +88,10 @@ def test_create_user_as_sysadmin(self): # submit it login_form.submit('save') - response = app.get( - url=url_for(controller='user', action='register'), - ) + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='register') + response = app.get(url) + assert "user-register-form" in response.forms form = response.forms['user-register-form'] form['name'] = 'newestuser' @@ -166,7 +178,8 @@ def test_user_logout_url_redirect(self): ''' app = self._get_test_app() - logout_url = url_for(controller='user', action='logout') + with app.flask_app.test_request_context(): + logout_url = url_for(controller='user', action='logout') logout_response = app.get(logout_url, status=302) final_response = helpers.webtest_maybe_follow(logout_response) @@ -183,7 +196,10 @@ def test_non_root_user_logout_url_redirect(self): ''' app = self._get_test_app() - logout_url = url_for(controller='user', action='logout') + with app.flask_app.test_request_context(): + logout_url = url_for(controller='user', action='logout') + # Remove the prefix otherwise the test app won't find the correct route + logout_url = logout_url.replace('/my/prefix', '') logout_response = app.get(logout_url, status=302) assert_equal(logout_response.status_int, 302) assert_true('/my/prefix/user/logout' in logout_response.location) @@ -200,8 +216,12 @@ def test_own_datasets_show_up_on_user_dashboard(self): app = self._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='dashboard_datasets') + response = app.get( - url=url_for(controller='user', action='dashboard_datasets'), + url, extra_environ=env, ) @@ -217,8 +237,12 @@ def test_other_datasets_dont_show_up_on_user_dashboard(self): app = self._get_test_app() env = {'REMOTE_USER': user2['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='dashboard_datasets') + response = app.get( - url=url_for(controller='user', action='dashboard_datasets'), + url, extra_environ=env, ) @@ -229,8 +253,12 @@ class TestUserEdit(helpers.FunctionalTestBase): def test_user_edit_no_user(self): app = self._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='edit', id=None) + response = app.get( - url_for(controller='user', action='edit', id=None), + url, status=400 ) assert_true('No user specified' in response) @@ -239,8 +267,12 @@ def test_user_edit_unknown_user(self): '''Attempt to read edit user for an unknown user redirects to login page.''' app = self._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='edit', id='unknown_person') + response = app.get( - url_for(controller='user', action='edit', id='unknown_person'), + url, status=403 ) @@ -250,8 +282,12 @@ def test_user_edit_not_logged_in(self): app = self._get_test_app() user = factories.User() username = user['name'] + + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='edit', id=username) + response = app.get( - url_for(controller='user', action='edit', id=username), + url, status=403 ) @@ -259,8 +295,12 @@ def test_edit_user(self): user = factories.User(password='pass') app = self._get_test_app() env = {'REMOTE_USER': user['name'].encode('ascii')} + + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='edit') + response = app.get( - url=url_for(controller='user', action='edit'), + url, extra_environ=env, ) # existing values in the form @@ -340,8 +380,12 @@ def test_edit_user_logged_in_username_change(self): login_form.submit() # Now the cookie is set, run the test + + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='edit') + response = app.get( - url=url_for(controller='user', action='edit'), + url, ) # existing values in the form form = response.forms['user-edit-form'] @@ -351,7 +395,8 @@ def test_edit_user_logged_in_username_change(self): response = submit_and_follow(app, form, name='save') response = helpers.webtest_maybe_follow(response) - expected_url = url_for(controller='user', action='read', id='new-name') + with app.flask_app.test_request_context(): + expected_url = url_for(controller='user', action='read', id='new-name') assert response.request.path == expected_url def test_edit_user_logged_in_username_change_by_name(self): @@ -371,8 +416,12 @@ def test_edit_user_logged_in_username_change_by_name(self): login_form.submit() # Now the cookie is set, run the test + + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='edit', id=user['name']) + response = app.get( - url=url_for(controller='user', action='edit', id=user['name']), + url, ) # existing values in the form form = response.forms['user-edit-form'] @@ -382,7 +431,8 @@ def test_edit_user_logged_in_username_change_by_name(self): response = submit_and_follow(app, form, name='save') response = helpers.webtest_maybe_follow(response) - expected_url = url_for(controller='user', action='read', id='new-name') + with app.flask_app.test_request_context(): + expected_url = url_for(controller='user', action='read', id='new-name') assert response.request.path == expected_url def test_edit_user_logged_in_username_change_by_id(self): @@ -402,8 +452,12 @@ def test_edit_user_logged_in_username_change_by_id(self): login_form.submit() # Now the cookie is set, run the test + + with app.flask_app.test_request_context(): + url = url_for(controller='user', action='edit', id=user['id']) + response = app.get( - url=url_for(controller='user', action='edit', id=user['id']), + url, ) # existing values in the form form = response.forms['user-edit-form'] @@ -413,7 +467,8 @@ def test_edit_user_logged_in_username_change_by_id(self): response = submit_and_follow(app, form, name='save') response = helpers.webtest_maybe_follow(response) - expected_url = url_for(controller='user', action='read', id='new-name') + with app.flask_app.test_request_context(): + expected_url = url_for(controller='user', action='read', id='new-name') assert response.request.path == expected_url def test_perform_reset_for_key_change(self): @@ -425,10 +480,12 @@ def test_perform_reset_for_key_change(self): key = user_obj.reset_key app = self._get_test_app() - offset = url_for(controller='user', - action='perform_reset', - id=user_obj.id, - key=user_obj.reset_key) + + with app.flask_app.test_request_context(): + offset = url_for(controller='user', + action='perform_reset', + id=user_obj.id, + key=user_obj.reset_key) response = app.post(offset, params=params, status=302) user_obj = helpers.model.User.by_name(user['name']) # Update user_obj @@ -479,9 +536,10 @@ def test_user_follow(self): user_two = factories.User() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - follow_url = url_for(controller='user', - action='follow', - id=user_two['id']) + with app.flask_app.test_request_context(): + follow_url = url_for(controller='user', + action='follow', + id=user_two['id']) response = app.post(follow_url, extra_environ=env, status=302) response = response.follow() assert_true('You are now following {0}' @@ -495,9 +553,10 @@ def test_user_follow_not_exist(self): user_one = factories.User() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - follow_url = url_for(controller='user', - action='follow', - id='not-here') + with app.flask_app.test_request_context(): + follow_url = url_for(controller='user', + action='follow', + id='not-here') response = app.post(follow_url, extra_environ=env, status=302) response = response.follow(status=404) assert_true('User not found' in response) @@ -509,13 +568,15 @@ def test_user_unfollow(self): user_two = factories.User() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - follow_url = url_for(controller='user', - action='follow', - id=user_two['id']) + with app.flask_app.test_request_context(): + follow_url = url_for(controller='user', + action='follow', + id=user_two['id']) app.post(follow_url, extra_environ=env, status=302) - unfollow_url = url_for(controller='user', action='unfollow', - id=user_two['id']) + with app.flask_app.test_request_context(): + unfollow_url = url_for(controller='user', action='unfollow', + id=user_two['id']) unfollow_response = app.post(unfollow_url, extra_environ=env, status=302) unfollow_response = unfollow_response.follow() @@ -532,8 +593,9 @@ def test_user_unfollow_not_following(self): user_two = factories.User() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - unfollow_url = url_for(controller='user', action='unfollow', - id=user_two['id']) + with app.flask_app.test_request_context(): + unfollow_url = url_for(controller='user', action='unfollow', + id=user_two['id']) unfollow_response = app.post(unfollow_url, extra_environ=env, status=302) unfollow_response = unfollow_response.follow() @@ -548,8 +610,9 @@ def test_user_unfollow_not_exist(self): user_one = factories.User() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - unfollow_url = url_for(controller='user', action='unfollow', - id='not-here') + with app.flask_app.test_request_context(): + unfollow_url = url_for(controller='user', action='unfollow', + id='not-here') unfollow_response = app.post(unfollow_url, extra_environ=env, status=302) unfollow_response = unfollow_response.follow(status=404) @@ -564,13 +627,15 @@ def test_user_follower_list(self): user_two = factories.User() env = {'REMOTE_USER': user_one['name'].encode('ascii')} - follow_url = url_for(controller='user', - action='follow', - id=user_two['id']) + with app.flask_app.test_request_context(): + follow_url = url_for(controller='user', + action='follow', + id=user_two['id']) app.post(follow_url, extra_environ=env, status=302) - followers_url = url_for(controller='user', action='followers', - id=user_two['id']) + with app.flask_app.test_request_context(): + followers_url = url_for(controller='user', action='followers', + id=user_two['id']) # Only sysadmins can view the followers list pages followers_response = app.get(followers_url, extra_environ=env, @@ -584,7 +649,8 @@ def test_user_page_anon_access(self): '''Anon users can access the user list page''' app = self._get_test_app() - user_url = url_for(controller='user', action='index') + with app.flask_app.test_request_context(): + user_url = url_for(controller='user', action='index') user_response = app.get(user_url, status=200) assert_true('All Users - CKAN' in user_response) @@ -596,7 +662,8 @@ def test_user_page_lists_users(self): factories.User(fullname='User Two') factories.User(fullname='User Three') - user_url = url_for(controller='user', action='index') + with app.flask_app.test_request_context(): + user_url = url_for(controller='user', action='index') user_response = app.get(user_url, status=200) user_response_html = BeautifulSoup(user_response.body) @@ -615,7 +682,8 @@ def test_user_page_doesnot_list_deleted_users(self): factories.User(fullname='User Two') factories.User(fullname='User Three') - user_url = url_for(controller='user', action='index') + with app.flask_app.test_request_context(): + user_url = url_for(controller='user', action='index') user_response = app.get(user_url, status=200) user_response_html = BeautifulSoup(user_response.body) @@ -634,7 +702,8 @@ def test_user_page_anon_search(self): factories.User(fullname='Person Two') factories.User(fullname='Person Three') - user_url = url_for(controller='user', action='index') + with app.flask_app.test_request_context(): + user_url = url_for(controller='user', action='index') user_response = app.get(user_url, status=200) search_form = user_response.forms['user-search-form'] search_form['q'] = 'Person' @@ -656,7 +725,8 @@ def test_user_page_anon_search_not_by_email(self): factories.User(fullname='Person Two') factories.User(fullname='Person Three') - user_url = url_for(controller='user', action='index') + with app.flask_app.test_request_context(): + user_url = url_for(controller='user', action='index') user_response = app.get(user_url, status=200) search_form = user_response.forms['user-search-form'] search_form['q'] = 'useroneemail@example.com' @@ -676,7 +746,8 @@ def test_user_page_sysadmin_user(self): factories.User(fullname='Person Three') env = {'REMOTE_USER': sysadmin['name'].encode('ascii')} - user_url = url_for(controller='user', action='index') + with app.flask_app.test_request_context(): + user_url = url_for(controller='user', action='index') user_response = app.get(user_url, status=200, extra_environ=env) search_form = user_response.forms['user-search-form'] search_form['q'] = 'useroneemail@example.com' diff --git a/ckan/tests/controllers/test_util.py b/ckan/tests/controllers/test_util.py index db76196e677..45616b60d67 100644 --- a/ckan/tests/controllers/test_util.py +++ b/ckan/tests/controllers/test_util.py @@ -1,10 +1,8 @@ # encoding: utf-8 from nose.tools import assert_equal -from pylons.test import pylonsapp -import paste.fixture -from routes import url_for as url_for +from ckan.lib.helpers import url_for import ckan.tests.helpers as helpers @@ -12,8 +10,12 @@ class TestUtil(helpers.FunctionalTestBase): def test_redirect_ok(self): app = self._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='util', action='redirect') + response = app.get( - url=url_for(controller='util', action='redirect'), + url, params={'url': '/dataset'}, status=302, ) @@ -22,24 +24,36 @@ def test_redirect_ok(self): def test_redirect_external(self): app = self._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='util', action='redirect') + response = app.get( - url=url_for(controller='util', action='redirect'), + url, params={'url': 'http://nastysite.com'}, status=403, ) def test_redirect_no_params(self): app = self._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='util', action='redirect') + response = app.get( - url=url_for(controller='util', action='redirect'), + url, params={}, status=400, ) def test_redirect_no_params_2(self): app = self._get_test_app() + + with app.flask_app.test_request_context(): + url = url_for(controller='util', action='redirect') + response = app.get( - url=url_for(controller='util', action='redirect'), + url, params={'url': ''}, status=400, ) diff --git a/ckan/tests/lib/test_helpers.py b/ckan/tests/lib/test_helpers.py index 0b67f25c353..9b1ae39e3e4 100644 --- a/ckan/tests/lib/test_helpers.py +++ b/ckan/tests/lib/test_helpers.py @@ -204,7 +204,6 @@ def test_url_for_qualified_with_root_path_locale_and_script_name_env(self): eq_(generated_url, url) - class TestHelpersUrlForFlaskandPylons2(BaseUrlFor): def test_url_for_flask_route_new_syntax(self): diff --git a/ckan/tests/lib/test_mailer.py b/ckan/tests/lib/test_mailer.py index 2ea839371cb..8f467e7bf72 100644 --- a/ckan/tests/lib/test_mailer.py +++ b/ckan/tests/lib/test_mailer.py @@ -37,6 +37,9 @@ def setup_class(cls): model.Session.commit() SmtpServerHarness.setup_class() + # Used to provide a context for url_for + cls.app = helpers._get_test_app() + @classmethod def teardown_class(cls): SmtpServerHarness.teardown_class() @@ -45,6 +48,13 @@ def teardown_class(cls): def setup(self): self.clear_smtp_messages() + self.request_context = self.app.flask_app.test_request_context() + self.request_context.push() + + def teardown(self): + + self.request_context.pop() + def mime_encode(self, msg, recipient_name): text = MIMEText(msg.encode('utf-8'), 'plain', 'utf-8') encoded_body = text.get_payload().strip() @@ -154,7 +164,9 @@ def test_send_reset_email(self): user = factories.User() user_obj = model.User.by_name(user['name']) - mailer.send_reset_link(user_obj) + # We need to provide a context as url_for is used internally + with self.app.flask_app.test_request_context(): + mailer.send_reset_link(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() @@ -163,7 +175,9 @@ def test_send_reset_email(self): assert_equal(msg[1], config['smtp.mail_from']) assert_equal(msg[2], [user['email']]) assert 'Reset' in msg[3], msg[3] - test_msg = mailer.get_reset_link_body(user_obj) + # We need to provide a context as url_for is used internally + with self.app.flask_app.test_request_context(): + test_msg = mailer.get_reset_link_body(user_obj) expected_body = self.mime_encode(test_msg, user['name']) @@ -174,8 +188,12 @@ def test_send_invite_email(self): user_obj = model.User.by_name(user['name']) assert user_obj.reset_key is None, user_obj - # send email - mailer.send_invite(user_obj) + # We need to provide a context as url_for is used internally + with self.app.flask_app.test_request_context(): + # send email + mailer.send_invite(user_obj) + + test_msg = mailer.get_invite_body(user_obj) # check it went to the mock smtp server msgs = self.get_smtp_messages() @@ -183,7 +201,6 @@ def test_send_invite_email(self): msg = msgs[0] assert_equal(msg[1], config['smtp.mail_from']) assert_equal(msg[2], [user['email']]) - test_msg = mailer.get_invite_body(user_obj) expected_body = self.mime_encode(test_msg, user['name']) @@ -197,8 +214,10 @@ def test_send_invite_email_with_group(self): group = factories.Group() role = 'member' - # send email - mailer.send_invite(user_obj, group_dict=group, role=role) + # We need to provide a context as url_for is used internally + with self.app.flask_app.test_request_context(): + # send email + mailer.send_invite(user_obj, group_dict=group, role=role) # check it went to the mock smtp server msgs = self.get_smtp_messages() @@ -214,8 +233,10 @@ def test_send_invite_email_with_org(self): org = factories.Organization() role = 'admin' - # send email - mailer.send_invite(user_obj, group_dict=org, role=role) + # We need to provide a context as url_for is used internally + with self.app.flask_app.test_request_context(): + # send email + mailer.send_invite(user_obj, group_dict=org, role=role) # check it went to the mock smtp server msgs = self.get_smtp_messages() diff --git a/ckan/tests/logic/action/test_create.py b/ckan/tests/logic/action/test_create.py index 41bad556f69..5aad45d74fe 100644 --- a/ckan/tests/logic/action/test_create.py +++ b/ckan/tests/logic/action/test_create.py @@ -114,8 +114,10 @@ def test_smtp_error_returns_error_message(self): 'role': 'editor' } - assert_raises(logic.ValidationError, helpers.call_action, - 'user_invite', context, **params) + app = helpers._get_test_app() + with app.flask_app.test_request_context(): + assert_raises(logic.ValidationError, helpers.call_action, + 'user_invite', context, **params) # Check that the pending user was deleted user = model.Session.query(model.User).filter( From 2d83e0d1366a76c8f83fd316301b9976f38fab62 Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 1 Sep 2016 12:56:28 +0100 Subject: [PATCH 09/11] [#3196] Fix legacy tests dependant on url_for Wrapping calls to url_for (and functions that call it firther down the line) with the Flask test_request_context, update functional tests to use the helpers._get_test_app function rather than old paster ones. --- ckan/tests/controllers/test_package.py | 4 +- ckan/tests/legacy/__init__.py | 5 +- ckan/tests/legacy/functional/api/base.py | 2 +- .../functional/api/model/test_package.py | 23 ++-- .../api/model/test_relationships.py | 16 +-- .../functional/api/model/test_vocabulary.py | 6 +- .../legacy/functional/api/test_activity.py | 4 +- .../legacy/functional/api/test_dashboard.py | 4 +- .../api/test_email_notifications.py | 13 +-- .../legacy/functional/api/test_follow.py | 8 +- .../legacy/functional/api/test_resource.py | 4 +- ckan/tests/legacy/functional/api/test_user.py | 29 +++-- ckan/tests/legacy/functional/api/test_util.py | 62 ++++++++--- ckan/tests/legacy/functional/test_activity.py | 16 ++- ckan/tests/legacy/functional/test_admin.py | 3 +- ckan/tests/legacy/functional/test_group.py | 14 ++- ckan/tests/legacy/functional/test_package.py | 66 ++++++++--- .../legacy/functional/test_pagination.py | 47 ++++++-- .../functional/test_preview_interface.py | 32 +++--- ckan/tests/legacy/functional/test_revision.py | 12 +- ckan/tests/legacy/functional/test_tag.py | 25 ++++- ckan/tests/legacy/functional/test_tracking.py | 56 +++++++--- ckan/tests/legacy/functional/test_user.py | 49 ++++++--- ckan/tests/legacy/html_check.py | 10 +- .../legacy/lib/test_alphabet_pagination.py | 5 +- ckan/tests/legacy/logic/test_action.py | 23 ++-- ckan/tests/legacy/logic/test_auth.py | 7 +- ckan/tests/legacy/misc/test_format_text.py | 103 +++++++++++++----- ckan/tests/legacy/models/test_package.py | 9 +- ckan/tests/legacy/test_coding_standards.py | 2 +- 30 files changed, 457 insertions(+), 202 deletions(-) diff --git a/ckan/tests/controllers/test_package.py b/ckan/tests/controllers/test_package.py index 6489d7fe33f..ceaec0e16d0 100644 --- a/ckan/tests/controllers/test_package.py +++ b/ckan/tests/controllers/test_package.py @@ -734,7 +734,7 @@ def test_delete_on_non_existing_dataset(self): with app.flask_app.test_request_context(): url = url_for(controller='package', action='delete', - id='schrodingersdatset') + id='schrodingersdatset') response = app.post( url, @@ -1815,7 +1815,7 @@ def test_package_unfollow(self): with app.flask_app.test_request_context(): follow_url = url_for(controller='package', - action='follow', + action='follow', id=package['id']) app.post(follow_url, extra_environ=env, status=302) diff --git a/ckan/tests/legacy/__init__.py b/ckan/tests/legacy/__init__.py index 3a056855f95..a647c147899 100644 --- a/ckan/tests/legacy/__init__.py +++ b/ckan/tests/legacy/__init__.py @@ -35,6 +35,7 @@ import ckan.model as model from ckan import ckan_nose_plugin from ckan.common import json +from ckan.tests import helpers # evil hack as url_for is passed out url_for = h.url_for @@ -237,7 +238,8 @@ class WsgiAppCase(BaseCase): # Either that, or this file got imported somehow before the tests started # running, meaning the pylonsapp wasn't setup yet (which is done in # pylons.test.py:begin()) - app = paste.fixture.TestApp(wsgiapp) + #app = paste.fixture.TestApp(wsgiapp) + app = helpers._get_test_app() def config_abspath(file_path): @@ -415,6 +417,7 @@ def call_action_api(app, action, apikey=None, status=200, **kwargs): params = json.dumps(kwargs) response = app.post('/api/action/{0}'.format(action), params=params, extra_environ={'Authorization': str(apikey)}, status=status) + assert '/api/3/action/help_show?name={0}'.format(action) \ in response.json['help'] diff --git a/ckan/tests/legacy/functional/api/base.py b/ckan/tests/legacy/functional/api/base.py index fefedae0f65..1a11b53c196 100644 --- a/ckan/tests/legacy/functional/api/base.py +++ b/ckan/tests/legacy/functional/api/base.py @@ -190,7 +190,7 @@ def loads(self, chars): raise Exception, "Couldn't loads string '%s': %s" % (chars, inst) def assert_json_response(self, res, expected_in_body=None): - content_type = res.header_dict['Content-Type'] + content_type = res.headers['Content-Type'] assert 'application/json' in content_type, content_type res_json = self.loads(res.body) if expected_in_body: diff --git a/ckan/tests/legacy/functional/api/model/test_package.py b/ckan/tests/legacy/functional/api/model/test_package.py index 22472d7dac3..593f49d7612 100644 --- a/ckan/tests/legacy/functional/api/model/test_package.py +++ b/ckan/tests/legacy/functional/api/model/test_package.py @@ -13,6 +13,7 @@ from ckan.tests.legacy.functional.api.base import Api2TestCase as Version2TestCase import ckan.tests.legacy as tests +from ckan.tests import helpers # Todo: Remove this ckan.model stuff. import ckan.model as model @@ -65,7 +66,7 @@ def test_register_post_ok(self): assert_equal(pkg['extras'], self.package_fixture_data['extras']) # Check the value of the Location header. - location = res.header('Location') + location = res.headers['Location'] assert offset in location res = self.app.get(location, status=self.STATUS_200_OK) @@ -133,7 +134,7 @@ def test_register_post_with_group(self): package_fixture_data = self.package_fixture_data package_fixture_data['groups'] = groups data = self.dumps(package_fixture_data) - res = self.post_json(offset, data, status=self.STATUS_201_CREATED, + res = self.app.post(offset, data, status=self.STATUS_201_CREATED, extra_environ={'Authorization':str(user.apikey)}) # Check the database record. @@ -159,7 +160,7 @@ def test_register_post_with_group_not_authorized(self): package_fixture_data = self.package_fixture_data package_fixture_data['groups'] = groups data = self.dumps(package_fixture_data) - res = self.post_json(offset, data, status=self.STATUS_403_ACCESS_DENIED, + res = self.app.post(offset, data, status=self.STATUS_403_ACCESS_DENIED, extra_environ=self.extra_environ) del package_fixture_data['groups'] @@ -173,7 +174,7 @@ def test_register_post_with_group_not_found(self): package_fixture_data = self.package_fixture_data package_fixture_data['groups'] = groups data = self.dumps(package_fixture_data) - res = self.post_json(offset, data, status=self.STATUS_404_NOT_FOUND, + res = self.app.post(offset, data, status=self.STATUS_404_NOT_FOUND, extra_environ=self.extra_environ) del package_fixture_data['groups'] @@ -187,7 +188,7 @@ def test_register_post_with_group_sysadmin(self): package_fixture_data = self.package_fixture_data package_fixture_data['groups'] = groups data = self.dumps(package_fixture_data) - res = self.post_json(offset, data, status=self.STATUS_201_CREATED, + res = self.app.post(offset, data, status=self.STATUS_201_CREATED, extra_environ={'Authorization':str(user.apikey)}) # Check the database record. model.Session.remove() @@ -207,7 +208,7 @@ def test_register_post_json(self): assert not self.get_package_by_name(self.package_fixture_data['name']) offset = self.package_offset() data = self.dumps(self.package_fixture_data) - res = self.post_json(offset, data, status=self.STATUS_201_CREATED, + res = self.app.post(offset, data, status=self.STATUS_201_CREATED, extra_environ=self.admin_extra_environ) # Check the database record. model.Session.remove() @@ -219,7 +220,7 @@ def test_register_post_bad_content_type(self): assert not self.get_package_by_name(self.package_fixture_data['name']) offset = self.package_offset() data = self.dumps(self.package_fixture_data) - res = self.http_request(offset, data, + res = self.app.post(offset, data, content_type='something/unheard_of', status=[self.STATUS_400_BAD_REQUEST, self.STATUS_201_CREATED], @@ -262,7 +263,7 @@ def test_register_post_indexerror(self): offset = self.package_offset() data = self.dumps(self.package_fixture_data) - self.post_json(offset, data, status=500, extra_environ=self.admin_extra_environ) + self.app.post(offset, data, status=500, extra_environ=self.admin_extra_environ) model.Session.remove() finally: SolrSettings.init(original_settings) @@ -273,7 +274,7 @@ def test_register_post_tag_too_long(self): assert not self.get_package_by_name(pkg['name']) offset = self.package_offset() data = self.dumps(pkg) - res = self.post_json(offset, data, status=self.STATUS_409_CONFLICT, + res = self.app.post(offset, data, status=self.STATUS_409_CONFLICT, extra_environ=self.admin_extra_environ) assert 'length is more than maximum 100' in res.body, res.body assert 'tagok' not in res.body @@ -714,8 +715,8 @@ def test_entity_delete_ok_without_request_headers(self): assert self.get_package_by_name(self.package_fixture_data['name']) # delete it offset = self.package_offset(self.package_fixture_data['name']) - res = self.delete_request(offset, status=self.STATUS_200_OK, - extra_environ=self.admin_extra_environ) + res = self.app.delete(offset, status=self.STATUS_200_OK, + extra_environ=self.admin_extra_environ) package = self.get_package_by_name(self.package_fixture_data['name']) self.assert_equal(package.state, 'deleted') model.Session.remove() diff --git a/ckan/tests/legacy/functional/api/model/test_relationships.py b/ckan/tests/legacy/functional/api/model/test_relationships.py index 0bdc30c84e5..069776d663d 100644 --- a/ckan/tests/legacy/functional/api/model/test_relationships.py +++ b/ckan/tests/legacy/functional/api/model/test_relationships.py @@ -1,14 +1,14 @@ # encoding: utf-8 -from nose.tools import assert_equal +from nose.tools import assert_equal from nose.plugins.skip import SkipTest from ckan import model from ckan.lib.create_test_data import CreateTestData from ckan.tests.legacy.functional.api.base import BaseModelApiTestCase -from ckan.tests.legacy.functional.api.base import Api1TestCase as Version1TestCase -from ckan.tests.legacy.functional.api.base import Api2TestCase as Version2TestCase +from ckan.tests.legacy.functional.api.base import Api1TestCase as Version1TestCase +from ckan.tests.legacy.functional.api.base import Api2TestCase as Version2TestCase class RelationshipsTestCase(BaseModelApiTestCase): @@ -115,7 +115,7 @@ def test_01_create_and_read_relationship(self): assert len(rels) == 1 self.check_relationship_dict(rels[0], 'annakarenina', 'parent_of', 'warandpeace', self.comment) - + def test_02_create_relationship_way_2(self): # Create a relationship using 2nd way self.create_annakarenina_parent_of_war_and_peace(way=2) @@ -189,7 +189,7 @@ def test_create_relationship_unknown(self): def create_annakarenina_parent_of_war_and_peace(self, way=1): # Create package relationship. # More than one 'way' to create a package. - # Todo: Redesign this in a RESTful style, so that a relationship is + # Todo: Redesign this in a RESTful style, so that a relationship is # created by posting a relationship to a relationship **register**. assert way in (1, 2, 3, 4) if way == 1: @@ -220,7 +220,7 @@ def create_annakarenina_parent_of_war_and_peace(self, way=1): assert_equal(rel['type'], 'child_of') assert_equal(rel['subject'], self.ref_package(self.war)) assert_equal(rel['object'], self.ref_package(self.anna)) - + # Check the model, directly. rels = self.anna.get_relationships() assert len(rels) == 1, rels @@ -271,7 +271,7 @@ def get_relationships(self, package1_name=u'annakarenina', type='relationships', if type: allowable_statuses.append(404) res = self.app.get(offset, status=allowable_statuses) - if res.status == 200: + if res.status_int == 200: res_dict = self.data_from_res(res) if res.body else [] return res_dict else: @@ -300,7 +300,7 @@ def check_relationships_rest(self, pkg1_name, pkg2_name=None, expected_relationships=[]): rels = self.get_relationships(package1_name=pkg1_name, package2_name=pkg2_name) - self.assert_len_relationships(rels, expected_relationships) + self.assert_len_relationships(rels, expected_relationships) for rel in rels: the_expected_rel = None for expected_rel in expected_relationships: diff --git a/ckan/tests/legacy/functional/api/model/test_vocabulary.py b/ckan/tests/legacy/functional/api/model/test_vocabulary.py index feb03af3717..ab6bb25f6f2 100644 --- a/ckan/tests/legacy/functional/api/model/test_vocabulary.py +++ b/ckan/tests/legacy/functional/api/model/test_vocabulary.py @@ -1,17 +1,17 @@ # encoding: utf-8 import ckan -import pylons.test -import paste.fixture import ckan.lib.helpers as helpers import ckan.lib.dictization.model_dictize as model_dictize +from ckan.tests import helpers as test_helpers + class TestVocabulary(object): @classmethod def setup_class(self): - self.app = paste.fixture.TestApp(pylons.test.pylonsapp) + self.app = test_helpers._get_test_app() @classmethod def teardown_class(self): diff --git a/ckan/tests/legacy/functional/api/test_activity.py b/ckan/tests/legacy/functional/api/test_activity.py index 1350b7acaba..114d91b6723 100644 --- a/ckan/tests/legacy/functional/api/test_activity.py +++ b/ckan/tests/legacy/functional/api/test_activity.py @@ -22,6 +22,8 @@ from ckan.common import json import ckan.tests.legacy as tests +from ckan.tests import helpers + ##def package_update(context, data_dict): ## # These tests call package_update directly which is really bad @@ -204,7 +206,7 @@ def setup_class(self): 'id': annakarenina.id, } self.users = [self.sysadmin_user, self.normal_user] - self.app = paste.fixture.TestApp(pylons.test.pylonsapp) + self.app = helpers._get_test_app() @classmethod def teardown_class(self): diff --git a/ckan/tests/legacy/functional/api/test_dashboard.py b/ckan/tests/legacy/functional/api/test_dashboard.py index 7482dd1a839..7b7364aa57d 100644 --- a/ckan/tests/legacy/functional/api/test_dashboard.py +++ b/ckan/tests/legacy/functional/api/test_dashboard.py @@ -12,6 +12,8 @@ import paste import pylons.test from ckan.tests.legacy import CreateTestData +from ckan.tests import helpers + class TestDashboard(object): '''Tests for the logic action functions related to the user's dashboard.''' @@ -34,7 +36,7 @@ def user_create(cls): def setup_class(cls): ckan.lib.search.clear_all() CreateTestData.create() - cls.app = paste.fixture.TestApp(pylons.test.pylonsapp) + cls.app = helpers._get_test_app() joeadmin = ckan.model.User.get('joeadmin') cls.joeadmin = { 'id': joeadmin.id, diff --git a/ckan/tests/legacy/functional/api/test_email_notifications.py b/ckan/tests/legacy/functional/api/test_email_notifications.py index 35bea72dbcb..f8505201836 100644 --- a/ckan/tests/legacy/functional/api/test_email_notifications.py +++ b/ckan/tests/legacy/functional/api/test_email_notifications.py @@ -10,13 +10,12 @@ import ckan.tests.legacy.pylons_controller as pylons_controller import ckan.config.middleware -import paste -import paste.deploy -import pylons.test +from ckan.tests import helpers from ckan.common import config + class TestEmailNotifications(mock_mail_server.SmtpServerHarness, pylons_controller.PylonsTestCase): @@ -25,7 +24,7 @@ def setup_class(cls): mock_mail_server.SmtpServerHarness.setup_class() pylons_controller.PylonsTestCase.setup_class() tests.CreateTestData.create() - cls.app = paste.fixture.TestApp(pylons.test.pylonsapp) + cls.app = helpers._get_test_app() joeadmin = model.User.get('joeadmin') cls.joeadmin = {'id': joeadmin.id, 'apikey': joeadmin.apikey, @@ -198,7 +197,7 @@ def setup_class(cls): mock_mail_server.SmtpServerHarness.setup_class() pylons_controller.PylonsTestCase.setup_class() tests.CreateTestData.create() - cls.app = paste.fixture.TestApp(pylons.test.pylonsapp) + cls.app = helpers._get_test_app() joeadmin = model.User.get('joeadmin') cls.joeadmin = {'id': joeadmin.id, 'apikey': joeadmin.apikey, @@ -338,7 +337,7 @@ def setup_class(cls): wsgiapp = ckan.config.middleware.make_app(config['global_conf'], **config) - cls.app = paste.fixture.TestApp(wsgiapp) + cls.app = helpers._get_test_app() mock_mail_server.SmtpServerHarness.setup_class() pylons_controller.PylonsTestCase.setup_class() @@ -422,7 +421,7 @@ def setup_class(cls): wsgiapp = ckan.config.middleware.make_app(config['global_conf'], **config) - cls.app = paste.fixture.TestApp(wsgiapp) + cls.app = helpers._get_test_app() mock_mail_server.SmtpServerHarness.setup_class() pylons_controller.PylonsTestCase.setup_class() diff --git a/ckan/tests/legacy/functional/api/test_follow.py b/ckan/tests/legacy/functional/api/test_follow.py index 909b2e77606..98f4bd23073 100644 --- a/ckan/tests/legacy/functional/api/test_follow.py +++ b/ckan/tests/legacy/functional/api/test_follow.py @@ -18,6 +18,8 @@ import ckan from ckan.tests.legacy import are_foreign_keys_supported, SkipTest, CreateTestData, call_action_api +from ckan.tests import helpers + def datetime_from_string(s): '''Return a standard datetime.datetime object initialised from a string in @@ -295,7 +297,7 @@ def setup_class(self): 'id': ckan.model.Group.get('david').id, 'name': ckan.model.Group.get('david').name, } - self.app = paste.fixture.TestApp(pylons.test.pylonsapp) + self.app = helpers._get_test_app() @classmethod def teardown_class(self): @@ -804,7 +806,7 @@ def setup_class(self): 'id': ckan.model.Group.get('david').id, 'name': ckan.model.Group.get('david').name, } - self.app = paste.fixture.TestApp(pylons.test.pylonsapp) + self.app = helpers._get_test_app() follow_user(self.app, self.testsysadmin['id'], self.testsysadmin['apikey'], self.joeadmin['id'], self.joeadmin['id'], self.testsysadmin['apikey']) @@ -1154,7 +1156,7 @@ def setup_class(self): 'id': ckan.model.Group.get('david').id, 'name': ckan.model.Group.get('david').name, } - self.app = paste.fixture.TestApp(pylons.test.pylonsapp) + self.app = helpers._get_test_app() follow_user(self.app, self.joeadmin['id'], self.joeadmin['apikey'], self.testsysadmin['id'], self.testsysadmin['id'], diff --git a/ckan/tests/legacy/functional/api/test_resource.py b/ckan/tests/legacy/functional/api/test_resource.py index e8c53593bcd..28c3a6bed15 100644 --- a/ckan/tests/legacy/functional/api/test_resource.py +++ b/ckan/tests/legacy/functional/api/test_resource.py @@ -45,7 +45,7 @@ def teardown_class(self): def test_good_input(self): offset = self.base_url + '/format_autocomplete?incomplete=cs' result = self.app.get(offset, status=200) - content_type = result.header_dict['Content-Type'] + content_type = result.headers['Content-Type'] assert 'application/json' in content_type, content_type res_json = self.loads(result.body) assert 'ResultSet' in res_json, res_json @@ -58,7 +58,7 @@ def test_good_input(self): def test_missing_format(self): offset = self.base_url + '/format_autocomplete?incomplete=incorrectformat' result = self.app.get(offset, status=200) - content_type = result.header_dict['Content-Type'] + content_type = result.headers['Content-Type'] assert 'application/json' in content_type, content_type res_json = self.loads(result.body) assert 'ResultSet' in res_json, res_json diff --git a/ckan/tests/legacy/functional/api/test_user.py b/ckan/tests/legacy/functional/api/test_user.py index e470ce2d8bd..b58daface79 100644 --- a/ckan/tests/legacy/functional/api/test_user.py +++ b/ckan/tests/legacy/functional/api/test_user.py @@ -13,6 +13,7 @@ from ckan.tests.legacy import url_for import ckan.config.middleware from ckan.common import json +from ckan.tests import helpers class TestUserApi(ControllerTestCase): @@ -25,8 +26,12 @@ def teardown_class(cls): model.repo.rebuild_db() def test_autocomplete(self): + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='user_autocomplete', ver=2) + response = self.app.get( - url=url_for(controller='api', action='user_autocomplete', ver=2), + url, params={ 'q': u'sysadmin', }, @@ -35,11 +40,15 @@ def test_autocomplete(self): print response.json assert set(response.json[0].keys()) == set(['id', 'name', 'fullname']) assert_equal(response.json[0]['name'], u'testsysadmin') - assert_equal(response.header('Content-Type'), 'application/json;charset=utf-8') + assert_equal(response.headers['Content-Type'], 'application/json;charset=utf-8') def test_autocomplete_multiple(self): + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='user_autocomplete', ver=2) + response = self.app.get( - url=url_for(controller='api', action='user_autocomplete', ver=2), + url, params={ 'q': u'tes', }, @@ -49,8 +58,12 @@ def test_autocomplete_multiple(self): assert_equal(len(response.json), 2) def test_autocomplete_limit(self): + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='user_autocomplete', ver=2) + response = self.app.get( - url=url_for(controller='api', action='user_autocomplete', ver=2), + url, params={ 'q': u'tes', 'limit': 1 @@ -72,7 +85,7 @@ def setup_class(cls): cls._original_config = config.copy() wsgiapp = ckan.config.middleware.make_app( config['global_conf'], **config) - cls.app = paste.fixture.TestApp(wsgiapp) + cls.app = helpers._get_test_app() cls.sysadmin_user = model.User.get('testsysadmin') PylonsTestCase.setup_class() @@ -122,7 +135,7 @@ def setup_class(cls): config['ckan.auth.create_user_via_api'] = True wsgiapp = ckan.config.middleware.make_app( config['global_conf'], **config) - cls.app = paste.fixture.TestApp(wsgiapp) + cls.app = helpers._get_test_app() PylonsTestCase.setup_class() cls.sysadmin_user = model.User.get('testsysadmin') @@ -170,7 +183,7 @@ def setup_class(cls): config['ckan.auth.create_user_via_web'] = False wsgiapp = ckan.config.middleware.make_app( config['global_conf'], **config) - cls.app = paste.fixture.TestApp(wsgiapp) + cls.app = helpers._get_test_app() cls.sysadmin_user = model.User.get('testsysadmin') PylonsTestCase.setup_class() @@ -206,7 +219,7 @@ def setup_class(cls): config['ckan.auth.create_user_via_web'] = True wsgiapp = ckan.config.middleware.make_app( config['global_conf'], **config) - cls.app = paste.fixture.TestApp(wsgiapp) + cls.app = helpers._get_test_app() cls.sysadmin_user = model.User.get('testsysadmin') PylonsTestCase.setup_class() diff --git a/ckan/tests/legacy/functional/api/test_util.py b/ckan/tests/legacy/functional/api/test_util.py index 9ba2adb9afe..9065d00e7da 100644 --- a/ckan/tests/legacy/functional/api/test_util.py +++ b/ckan/tests/legacy/functional/api/test_util.py @@ -18,8 +18,12 @@ def teardown_class(cls): model.repo.rebuild_db() def test_package_slug_invalid(self): + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='is_slug_valid', ver=2) + response = self.app.get( - url=url_for(controller='api', action='is_slug_valid', ver=2), + url, params={ 'type': u'package', 'slug': u'edit', @@ -27,10 +31,14 @@ def test_package_slug_invalid(self): status=200, ) assert_equal(response.body, '{"valid": false}') - assert_equal(response.header('Content-Type'), 'application/json;charset=utf-8') + assert_equal(response.headers['Content-Type'], 'application/json;charset=utf-8') + + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='is_slug_valid', ver=2) response = self.app.get( - url=url_for(controller='api', action='is_slug_valid', ver=2), + url, params={ 'type': u'package', 'slug': u'new', @@ -38,11 +46,15 @@ def test_package_slug_invalid(self): status=200, ) assert_equal(response.body, '{"valid": false}') - assert_equal(response.header('Content-Type'), 'application/json;charset=utf-8') + assert_equal(response.headers['Content-Type'], 'application/json;charset=utf-8') def test_package_slug_valid(self): + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='is_slug_valid', ver=2) + response = self.app.get( - url=url_for(controller='api', action='is_slug_valid', ver=2), + url, params={ 'type': u'package', 'slug': u'A New Title * With & Funny CHARacters', @@ -50,10 +62,14 @@ def test_package_slug_valid(self): status=200, ) assert_equal(response.body, '{"valid": true}') - assert_equal(response.header('Content-Type'), 'application/json;charset=utf-8') + assert_equal(response.headers['Content-Type'], 'application/json;charset=utf-8') + + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='is_slug_valid', ver=2) response = self.app.get( - url=url_for(controller='api', action='is_slug_valid', ver=2), + url, params={ 'type': u'package', 'slug': u'warandpeace', @@ -61,44 +77,64 @@ def test_package_slug_valid(self): status=200, ) assert_equal(response.body, '{"valid": false}') - assert_equal(response.header('Content-Type'), 'application/json;charset=utf-8') + assert_equal(response.headers['Content-Type'], 'application/json;charset=utf-8') def test_markdown(self): markdown = '''##Title''' + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='markdown', ver=2) + response = self.app.get( - url=url_for(controller='api', action='markdown', ver=2), + url, params={'q': markdown}, status=200, ) assert_equal(response.body, '"

Title

"') def test_munge_package_name(self): + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='munge_package_name', ver=2) + response = self.app.get( - url=url_for(controller='api', action='munge_package_name', ver=2), + url, params={'name': 'test name'}, status=200, ) assert_equal(response.body, '"test-name"') def test_munge_title_to_package_name(self): + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='munge_title_to_package_name', ver=2) + response = self.app.get( - url=url_for(controller='api', action='munge_title_to_package_name', ver=2), + url, params={'name': 'Test title'}, status=200, ) assert_equal(response.body, '"test-title"') def test_munge_tag(self): + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='munge_tag', ver=2) + response = self.app.get( - url=url_for(controller='api', action='munge_tag', ver=2), + url, params={'name': 'Test subject'}, status=200, ) assert_equal(response.body, '"test-subject"') def test_status(self): + + with self.app.flask_app.test_request_context(): + url = url_for(controller='api', action='status', ver=2) + response = self.app.get( - url=url_for(controller='api', action='status', ver=2), + url, params={}, status=200, ) diff --git a/ckan/tests/legacy/functional/test_activity.py b/ckan/tests/legacy/functional/test_activity.py index f40f1397d78..61eab03ea0d 100644 --- a/ckan/tests/legacy/functional/test_activity.py +++ b/ckan/tests/legacy/functional/test_activity.py @@ -4,7 +4,7 @@ from pylons.test import pylonsapp from paste.deploy.converters import asbool import paste.fixture -from routes import url_for +from ckan.lib.helpers import url_for from nose import SkipTest import ckan @@ -14,9 +14,10 @@ from ckan.logic.action.update import user_update, group_update from ckan.logic.action.delete import package_delete from ckan.tests.legacy.html_check import HtmlCheckMethods -from ckan.tests.legacy import CreateTestData +from ckan.tests.legacy import CreateTestData, WsgiAppCase -class TestActivity(HtmlCheckMethods): + +class TestActivity(WsgiAppCase, HtmlCheckMethods): """Test the rendering of activity streams into HTML pages. Activity streams are tested in detail elsewhere, this class just briefly @@ -29,7 +30,6 @@ def setup(cls): raise SkipTest('Activity streams not enabled') CreateTestData.create() cls.sysadmin_user = ckan.model.User.get('testsysadmin') - cls.app = paste.fixture.TestApp(pylonsapp) @classmethod def teardown(cls): @@ -52,7 +52,9 @@ def test_user_activity(self): 'allow_partial_update': True, } user = user_create(context, user_dict) - offset = url_for(controller='user', action='activity', id=user['id']) + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='user', action='activity', id=user['id']) result = self.app.get(offset, status=200) stripped = self.strip_tags(result) assert '%s signed up' % user['fullname'] in stripped, stripped @@ -239,7 +241,9 @@ def test_user_activity(self): # The user's dashboard page should load successfully and have the # latest 15 activities on it. - offset = url_for(controller='user', action='dashboard') + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='user', action='dashboard') extra_environ = {'Authorization': str(ckan.model.User.get('billybeane').apikey)} result = self.app.post(offset, extra_environ=extra_environ, diff --git a/ckan/tests/legacy/functional/test_admin.py b/ckan/tests/legacy/functional/test_admin.py index 7737f036650..41ba685fc38 100644 --- a/ckan/tests/legacy/functional/test_admin.py +++ b/ckan/tests/legacy/functional/test_admin.py @@ -15,7 +15,8 @@ def teardown_class(self): #test that only sysadmins can access the /ckan-admin page def test_index(self): - url = url_for('ckanadmin', action='index') + with self.app.flask_app.test_request_context(): + url = url_for('ckanadmin', action='index') response = self.app.get(url, status=[403]) # random username response = self.app.get(url, status=[403], diff --git a/ckan/tests/legacy/functional/test_group.py b/ckan/tests/legacy/functional/test_group.py index 0223375f232..1e952879ad1 100644 --- a/ckan/tests/legacy/functional/test_group.py +++ b/ckan/tests/legacy/functional/test_group.py @@ -95,7 +95,9 @@ def test_sorting(self): def test_read_non_existent(self): name = u'group_does_not_exist' - offset = url_for(controller='group', action='read', id=name) + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='group', action='read', id=name) res = self.app.get(offset, status=404) @@ -131,8 +133,10 @@ def teardown_class(self): model.repo.rebuild_db() def test_2_atom_feed(self): - offset = url_for(controller='group', action='history', - id=self.grp.name) + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='group', action='history', + id=self.grp.name) offset = "%s?format=atom" % offset res = self.app.get(offset) assert ']') # edit the package - self.offset = url_for(controller='package', action='edit', id=self.editpkg_name) + + with self.app.flask_app.test_request_context(): + self.offset = url_for(controller='package', action='edit', id=self.editpkg_name) self.res = self.app.get(self.offset, extra_environ=self.extra_environ_admin) fv = self.res.forms['dataset-edit'] fv['title'] = u'New Title' @@ -547,7 +564,8 @@ def test_delete(self): plugins.load('test_package_controller_plugin') plugin = plugins.get_plugin('test_package_controller_plugin') - offset = url_for(controller='package', action='delete', + with self.app.flask_app.test_request_context(): + offset = url_for(controller='package', action='delete', id='warandpeace') # Since organizations, any owned dataset can be edited/deleted by any # user @@ -582,7 +600,9 @@ def teardown_class(self): def test_new_plugin_hook(self): plugins.load('test_package_controller_plugin') plugin = plugins.get_plugin('test_package_controller_plugin') - offset = url_for(controller='package', action='new') + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='package', action='new') res = self.app.get(offset, extra_environ=self.extra_environ_tester) new_name = u'plugged' fv = res.forms['dataset-edit'] @@ -597,7 +617,9 @@ def test_new_plugin_hook(self): def test_after_create_plugin_hook(self): plugins.load('test_package_controller_plugin') plugin = plugins.get_plugin('test_package_controller_plugin') - offset = url_for(controller='package', action='new') + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='package', action='new') res = self.app.get(offset, extra_environ=self.extra_environ_tester) new_name = u'plugged2' fv = res.forms['dataset-edit'] @@ -617,8 +639,8 @@ def test_new_indexerror(self): try: SolrSettings.init(bad_solr_url) new_package_name = u'new-package-missing-solr' - - offset = url_for(controller='package', action='new') + with self.app.flask_app.test_request_context(): + offset = url_for(controller='package', action='new') res = self.app.get(offset, extra_environ=self.extra_environ_tester) fv = res.forms['dataset-edit'] fv['name'] = new_package_name @@ -633,7 +655,9 @@ def test_new_indexerror(self): SolrSettings.init(solr_url) def test_change_locale(self): - offset = url_for(controller='package', action='new') + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='package', action='new') res = self.app.get(offset, extra_environ=self.extra_environ_tester) res = self.app.get('/de/dataset/new', extra_environ=self.extra_environ_tester) @@ -683,12 +707,16 @@ def teardown_class(self): model.repo.rebuild_db() def test_read(self): - offset = url_for(controller='package', action='read', id=self.non_active_name) + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='package', action='read', id=self.non_active_name) res = self.app.get(offset, status=[404]) def test_read_as_admin(self): - offset = url_for(controller='package', action='read', id=self.non_active_name) + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='package', action='read', id=self.non_active_name) res = self.app.get(offset, status=200, extra_environ={'REMOTE_USER':'testsysadmin'}) @@ -718,7 +746,9 @@ def setup_class(cls): cls.revision_ids = [rev[0].id for rev in cls.pkg1.all_related_revisions] # revision ids are newest first cls.revision_timestamps = [rev[0].timestamp for rev in cls.pkg1.all_related_revisions] - cls.offset = url_for(controller='package', action='history', id=cls.pkg1.name) + + with cls.app.flask_app.test_request_context(): + cls.offset = url_for(controller='package', action='history', id=cls.pkg1.name) @classmethod def teardown_class(cls): diff --git a/ckan/tests/legacy/functional/test_pagination.py b/ckan/tests/legacy/functional/test_pagination.py index 596bc5fa453..3a4fc7912c7 100644 --- a/ckan/tests/legacy/functional/test_pagination.py +++ b/ckan/tests/legacy/functional/test_pagination.py @@ -59,25 +59,41 @@ def teardown_class(self): model.repo.rebuild_db() def test_package_search_p1(self): - res = self.app.get(url_for(controller='package', action='search', q='groups:group_00')) + + with self.app.flask_app.test_request_context(): + url = url_for(controller='package', action='search', q='groups:group_00') + + res = self.app.get(url) assert 'href="/dataset?q=groups%3Agroup_00&page=2"' in res pkg_numbers = scrape_search_results(res, 'dataset') assert_equal(['50', '49', '48', '47', '46', '45', '44', '43', '42', '41', '40', '39', '38', '37', '36', '35', '34', '33', '32', '31'], pkg_numbers) def test_package_search_p2(self): - res = self.app.get(url_for(controller='package', action='search', q='groups:group_00', page=2)) + + with self.app.flask_app.test_request_context(): + url = url_for(controller='package', action='search', q='groups:group_00', page=2) + + res = self.app.get(url) assert 'href="/dataset?q=groups%3Agroup_00&page=1"' in res pkg_numbers = scrape_search_results(res, 'dataset') assert_equal(['30', '29', '28', '27', '26', '25', '24', '23', '22', '21', '20', '19', '18', '17', '16', '15', '14', '13', '12', '11'], pkg_numbers) def test_group_datasets_read_p1(self): - res = self.app.get(url_for(controller='group', action='read', id='group_00')) + + with self.app.flask_app.test_request_context(): + url = url_for(controller='group', action='read', id='group_00') + + res = self.app.get(url) assert 'href="/group/group_00?page=2' in res, res pkg_numbers = scrape_search_results(res, 'group_dataset') assert_equal(['50', '49', '48', '47', '46', '45', '44', '43', '42', '41', '40', '39', '38', '37', '36', '35', '34', '33', '32', '31'], pkg_numbers) def test_group_datasets_read_p2(self): - res = self.app.get(url_for(controller='group', action='read', id='group_00', page=2)) + + with self.app.flask_app.test_request_context(): + url = url_for(controller='group', action='read', id='group_00', page=2) + + res = self.app.get(url) assert 'href="/group/group_00?page=1' in res, res pkg_numbers = scrape_search_results(res, 'group_dataset') assert_equal(['30', '29', '28', '27', '26', '25', '24', '23', '22', '21', '20', '19', '18', '17', '16', '15', '14', '13', '12', '11'], pkg_numbers) @@ -101,12 +117,20 @@ def teardown_class(self): model.repo.rebuild_db() def test_group_index(self): - res = self.app.get(url_for(controller='group', action='index')) + + with self.app.flask_app.test_request_context(): + url = url_for(controller='group', action='index') + + res = self.app.get(url) assert 'href="/group?q=&sort=&page=2"' in res, res grp_numbers = scrape_search_results(res, 'group') assert_equal(['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20'], grp_numbers) - res = self.app.get(url_for(controller='group', action='index', page=2)) + + with self.app.flask_app.test_request_context(): + url = url_for(controller='group', action='index', page=2) + + res = self.app.get(url) assert 'href="/group?q=&sort=&page=1"' in res grp_numbers = scrape_search_results(res, 'group') assert_equal(['21'], grp_numbers) @@ -130,12 +154,19 @@ def teardown_class(self): model.repo.rebuild_db() def test_users_index(self): - res = self.app.get(url_for(controller='user', action='index')) + + with self.app.flask_app.test_request_context(): + url = url_for(controller='user', action='index') + + res = self.app.get(url) assert 'href="/user?q=&order_by=name&page=2"' in res user_numbers = scrape_search_results(res, 'user') assert_equal(['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'], user_numbers) - res = self.app.get(url_for(controller='user', action='index', page=2)) + with self.app.flask_app.test_request_context(): + url = url_for(controller='user', action='index', page=2) + + res = self.app.get(url) assert 'href="/user?q=&order_by=name&page=1"' in res user_numbers = scrape_search_results(res, 'user') assert_equal(['20'], user_numbers) diff --git a/ckan/tests/legacy/functional/test_preview_interface.py b/ckan/tests/legacy/functional/test_preview_interface.py index deb7aa6f965..747834446e3 100644 --- a/ckan/tests/legacy/functional/test_preview_interface.py +++ b/ckan/tests/legacy/functional/test_preview_interface.py @@ -19,14 +19,16 @@ def setup_class(cls): cls.package = model.Package.get('annakarenina') cls.resource = cls.package.resources[0] - cls.url = h.url_for(controller='package', - action='resource_read', - id=cls.package.name, - resource_id=cls.resource.id) - cls.preview_url = h.url_for(controller='package', - action='resource_datapreview', - id=cls.package.id, - resource_id=cls.resource.id) + + with cls.app.flask_app.test_request_context(): + cls.url = h.url_for(controller='package', + action='resource_read', + id=cls.package.name, + resource_id=cls.resource.id) + cls.preview_url = h.url_for(controller='package', + action='resource_datapreview', + id=cls.package.id, + resource_id=cls.resource.id) @classmethod def teardown_class(cls): @@ -35,7 +37,9 @@ def teardown_class(cls): def test_hook(self): testpackage = self.package - resource_dict = model_dictize.resource_dictize(self.resource, {'model': model}) + + with self.app.flask_app.test_request_context(): + resource_dict = model_dictize.resource_dictize(self.resource, {'model': model}) context = { 'model': model, @@ -70,10 +74,12 @@ def test_hook(self): assert self.plugin.calls['preview_templates'] == 1, self.plugin.calls # test whether the json preview is used - preview_url = h.url_for(controller='package', - action='resource_datapreview', - id=testpackage.id, - resource_id=testpackage.resources[1].id) + + with self.app.flask_app.test_request_context(): + preview_url = h.url_for(controller='package', + action='resource_datapreview', + id=testpackage.id, + resource_id=testpackage.resources[1].id) result = self.app.get(preview_url, status=200) assert 'mock-json-preview' in result.body diff --git a/ckan/tests/legacy/functional/test_revision.py b/ckan/tests/legacy/functional/test_revision.py index af0f653fa1c..5312aad7c29 100644 --- a/ckan/tests/legacy/functional/test_revision.py +++ b/ckan/tests/legacy/functional/test_revision.py @@ -90,7 +90,9 @@ def get_package(self, name): def test_read(self): anna = model.Package.by_name(u'annakarenina') rev_id = anna.revision.id - offset = url_for(controller='revision', action='read', id='%s' % rev_id) + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='revision', action='read', id='%s' % rev_id) res = self.app.get(offset) assert 'Revision %s' % rev_id in res assert 'Revision: %s' % rev_id in res @@ -132,14 +134,18 @@ def test_list_format_atom(self): # Todo: Test for first revision on last page. # Todo: Test for last revision minus 50 on second page. # Page 1. (Implied id=1) - offset = url_for(controller='revision', action='list', format='atom') + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='revision', action='list', format='atom') res = self.app.get(offset) assert '' in res, res # Todo: Better test for 'days' request param. # - fake some older revisions and check they aren't included. - offset = url_for(controller='revision', action='list', format='atom', + + with self.app.flask_app.test_request_context(): + offset = url_for(controller='revision', action='list', format='atom', days=30) res = self.app.get(offset) assert ' section' the_html = self._get_html_from_res(html) @@ -33,13 +34,13 @@ def strip_tags(self, res): '''Call strip_tags on a TestResponse object to strip any and all HTML and normalise whitespace.''' if not isinstance(res, basestring): res = res.body.decode('utf-8') - return Stripper().strip(res) + return Stripper().strip(res) def check_named_element(self, html, tag_name, *html_to_find): '''Searches in the html and returns True if it can find a particular tag and all its subtags & data which contains all the of the html_to_find''' - named_element_re = re.compile('(<(%(tag)s\w*).*?(>.*?)' % {'tag':tag_name}) + named_element_re = re.compile('(<(%(tag)s\w*).*?(>.*?)' % {'tag':tag_name}) html_str = self._get_html_from_res(html) self._check_html(named_element_re, html_str.replace('\n', ''), html_to_find) @@ -60,13 +61,14 @@ def check_tag(self, html, *html_to_find): self._check_html(self.tag_re, html, html_to_find) def _get_html_from_res(self, html): - if isinstance(html, paste.fixture.TestResponse): + if isinstance(html, (paste.fixture.TestResponse, webtest.app.TestResponse)): html_str = html.body.decode('utf8') elif isinstance(html, unicode): html_str = html elif isinstance(html, str): html_str = html.decode('utf8') else: + import ipdb; ipdb.set_trace() raise TypeError return html_str # always unicode diff --git a/ckan/tests/legacy/lib/test_alphabet_pagination.py b/ckan/tests/legacy/lib/test_alphabet_pagination.py index 97d2773c634..c3f4cdaa428 100644 --- a/ckan/tests/legacy/lib/test_alphabet_pagination.py +++ b/ckan/tests/legacy/lib/test_alphabet_pagination.py @@ -8,6 +8,7 @@ from ckan.tests.legacy import regex_related from ckan.lib.create_test_data import CreateTestData from ckan import model +from ckan.tests import helpers other = 'Other' @@ -54,7 +55,9 @@ def test_01_package_page(self): page='A', other_text=other, ) - pager = page.pager() + app = helpers._get_test_app() + with app.flask_app.test_request_context(): + pager = page.pager() assert_true( pager.startswith( '