Skip to content

Conversation

@JVickery-TBS
Copy link
Contributor

No description provided.

- Tearing out all unnecessary code.
- Tearing out all unnecessary code.
# Conflicts:
#	ckanext/canada/tests/test_trim_package.py
### RESOLVED.
# Conflicts:
#	ckanext/canada/tests/test_trim_package.py
### RESOLVED.
@codecov
Copy link

codecov bot commented Oct 7, 2025

❌ 16 Tests Failed:

Tests completed Failed Passed Skipped
204 16 188 0
View the top 3 failed test(s) by shortest run time
ckanext/canada/tests/test_search.py::TestRegistrySearch::test_editor_package_search
Stack Traces | 0.029s run time
self = <ckanext.canada.tests.test_search.TestRegistrySearch object at 0x7f00adc0b040>

    def test_editor_package_search(self):
        "A user with editor access to an Org should see those organization's packages."
        response = self.editor_lc.action.package_search(
            q='*:*',
            include_private=self.include_private)
    
        assert 'count' in response
>       assert response['count'] == 4
E       assert 10 == 4

.../canada/tests/test_search.py:112: AssertionError
ckanext/canada/tests/test_search.py::TestRegistrySearch::test_editor_package_search_another_org
Stack Traces | 0.032s run time
self = <ckanext.canada.tests.test_search.TestRegistrySearch object at 0x7fc54ef287c0>

    def test_editor_package_search_another_org(self):
        "A user with editor access to an Org should NOT be able to see another organization's packages."
        response = self.editor_lc.action.package_search(
            fq='owner_org:%s' % self.org2['id'],
            include_private=self.include_private)
    
        assert 'count' in response
>       assert response['count'] == 0
E       assert 2 == 0

.../canada/tests/test_search.py:121: AssertionError
ckanext/canada/tests/test_validators.py::TestSysadminUpdate::test_cannot_update_self_sysadmin
Stack Traces | 0.153s run time
self = <ckanext.canada.tests.test_validators.TestSysadminUpdate object at 0x7f09ac5e3970>

    def test_cannot_update_self_sysadmin(self):
        """cannot change your own sysadmin privs"""
        with pytest.raises(ValidationError) as err:
>           self.sysadmin_action.user_patch(id=self.sysadmin_user.get('id'), sysadmin=False)

.../canada/tests/test_validators.py:553: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckanapi/ckanapi/common.py:51: in action
    return self._ckan.call_action(name, data_dict=kwargs)
.../ckanapi/ckanapi/localckan.py:74: in call_action
    return self._get_action(action)(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
.../logic/action/patch.py:159: in user_patch
    user_dict = _get_action('user_show')(
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

up_func = <function user_show at 0x7f09ad275790>
context = {'__auth_audit': [], '__auth_user_obj_checked': True, 'auth_user_obj': <User id=6e4b6501-6227-454f-833b-c39a799574cc n...te=active image_url=https://placeimg..../22/727/any plugin_extras=None>, 'count_private_and_draft_datasets': True, ...}
data_dict = {'id': '6e4b6501-6227-454f-833b-c39a799574cc', 'include_plugin_extras': True}

    @chained_action
    @side_effect_free
    def canada_user_show(up_func: Action,
                         context: Context,
                         data_dict: DataDict) -> ChainedAction:
        """
        Return new fields in the User dictionary.
        """
        data_dict['include_plugin_extras'] = True
        user_dict = up_func(context, data_dict)
        extras = user_dict.pop('plugin_extras', {})
>       user_dict['default_dataset_visibility'] = extras.get(
            'default_dataset_visibility', 'private')
E       AttributeError: 'NoneType' object has no attribute 'get'

.../ckanext/canada/logic.py:693: AttributeError
ckanext/canada/tests/test_validators.py::TestSysadminUpdate::test_update_sysadmin_users
Stack Traces | 0.17s run time
self = <ckanext.canada.tests.test_validators.TestSysadminUpdate object at 0x7f741c970f40>

    def test_update_sysadmin_users(self):
        """tbs member w/ email sysadmin should be able to update"""
>       user_dict = self.sysadmin_action.user_patch(id=self.normal_user.get('id'), sysadmin=True)

.../canada/tests/test_validators.py:571: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckanapi/ckanapi/common.py:51: in action
    return self._ckan.call_action(name, data_dict=kwargs)
.../ckanapi/ckanapi/localckan.py:74: in call_action
    return self._get_action(action)(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
.../logic/action/patch.py:159: in user_patch
    user_dict = _get_action('user_show')(
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

up_func = <function user_show at 0x7f741c93b790>
context = {'__auth_audit': [], '__auth_user_obj_checked': True, 'auth_user_obj': <User id=2c613a0d-7d73-45fc-bd50-ebfef643dcd1 n...ate=active image_url=https://dummyimage.com/265x945 plugin_extras=None>, 'count_private_and_draft_datasets': True, ...}
data_dict = {'id': '530b9fcf-2574-4854-9334-6c27a2c5dc89', 'include_plugin_extras': True}

    @chained_action
    @side_effect_free
    def canada_user_show(up_func: Action,
                         context: Context,
                         data_dict: DataDict) -> ChainedAction:
        """
        Return new fields in the User dictionary.
        """
        data_dict['include_plugin_extras'] = True
        user_dict = up_func(context, data_dict)
        extras = user_dict.pop('plugin_extras', {})
>       user_dict['default_dataset_visibility'] = extras.get(
            'default_dataset_visibility', 'private')
E       AttributeError: 'NoneType' object has no attribute 'get'

.../ckanext/canada/logic.py:693: AttributeError
ckanext/canada/tests/test_validators.py::TestSysadminUpdate::test_update_system_sysadmin
Stack Traces | 0.173s run time
self = <ckanext.canada.tests.test_validators.TestSysadminUpdate object at 0x7f53d9ad0100>

    def test_update_system_sysadmin(self):
        """system user should be able to update"""
>       user_dict = self.action.user_patch(id=self.normal_user.get('id'), sysadmin=True)

.../canada/tests/test_validators.py:578: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckanapi/ckanapi/common.py:51: in action
    return self._ckan.call_action(name, data_dict=kwargs)
.../ckanapi/ckanapi/localckan.py:74: in call_action
    return self._get_action(action)(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
.../logic/action/patch.py:159: in user_patch
    user_dict = _get_action('user_show')(
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

up_func = <function user_show at 0x7f53dd958790>
context = {'__auth_audit': [], '__auth_user_obj_checked': True, 'auth_user_obj': <User id=766c9b8b-174a-4568-9ba9-9528e30e72ec n...ons=False sysadmin=True state=active image_url=None plugin_extras=None>, 'count_private_and_draft_datasets': True, ...}
data_dict = {'id': 'e2489ca0-d36b-47dd-8efa-b99624552f40', 'include_plugin_extras': True}

    @chained_action
    @side_effect_free
    def canada_user_show(up_func: Action,
                         context: Context,
                         data_dict: DataDict) -> ChainedAction:
        """
        Return new fields in the User dictionary.
        """
        data_dict['include_plugin_extras'] = True
        user_dict = up_func(context, data_dict)
        extras = user_dict.pop('plugin_extras', {})
>       user_dict['default_dataset_visibility'] = extras.get(
            'default_dataset_visibility', 'private')
E       AttributeError: 'NoneType' object has no attribute 'get'

.../ckanext/canada/logic.py:693: AttributeError
ckanext/canada/tests/test_validators.py::TestSysadminUpdate::test_cannot_update_system_sysadmin
Stack Traces | 0.186s run time
self = <ckanext.canada.tests.test_validators.TestSysadminUpdate object at 0x7fdf7bf03250>

    def test_cannot_update_system_sysadmin(self):
        """cannot change system user privs"""
        site_id = config.get('ckan.site_id')
        with pytest.raises(ValidationError) as err:
>           self.sysadmin_action.user_patch(id=site_id, sysadmin=False)

.../canada/tests/test_validators.py:563: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckanapi/ckanapi/common.py:51: in action
    return self._ckan.call_action(name, data_dict=kwargs)
.../ckanapi/ckanapi/localckan.py:74: in call_action
    return self._get_action(action)(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
.../logic/action/patch.py:159: in user_patch
    user_dict = _get_action('user_show')(
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

up_func = <function user_show at 0x7fdf7fd53790>
context = {'__auth_audit': [], '__auth_user_obj_checked': True, 'auth_user_obj': <User id=80b15dec-8886-432d-b96b-c9a57e4c3320 n...tate=active image_url=https://picsum.photos/611/515 plugin_extras=None>, 'count_private_and_draft_datasets': True, ...}
data_dict = {'id': 'test.ckan.net', 'include_plugin_extras': True}

    @chained_action
    @side_effect_free
    def canada_user_show(up_func: Action,
                         context: Context,
                         data_dict: DataDict) -> ChainedAction:
        """
        Return new fields in the User dictionary.
        """
        data_dict['include_plugin_extras'] = True
        user_dict = up_func(context, data_dict)
        extras = user_dict.pop('plugin_extras', {})
>       user_dict['default_dataset_visibility'] = extras.get(
            'default_dataset_visibility', 'private')
E       AttributeError: 'NoneType' object has no attribute 'get'

.../ckanext/canada/logic.py:693: AttributeError
ckanext/canada/tests/test_search.py::TestRegistrySearch::test_user_package_search
Stack Traces | 1.58s run time
self = <ckanext.canada.tests.test_search.TestRegistrySearch object at 0x7f00adc0bc10>

    def test_user_package_search(self):
        "A user with no access to Orgs should not see any packages."
        response = self.user_lc.action.package_search(
            q='*:*',
            include_private=self.include_private)
    
        assert 'count' in response
>       assert response['count'] == 0
E       assert 7 == 0

.../canada/tests/test_search.py:103: AssertionError
ckanext/canada/tests/test_xls_upload.py::TestXlsUpload::test_upload_empty
Stack Traces | 9.19s run time
self = <ckanext.canada.tests.test_xls_upload.TestXlsUpload object at 0x7f88957ca760>

    def test_upload_empty(self):
        current_user = model.User.get(self.editor['name'])
        with mock.patch('ckan.lib.helpers.current_user', current_user):
            flask.g.user = self.editor['name']
            wb = excel_template('wrongdoing', self.org)
            f = tempfile.NamedTemporaryFile(suffix=".xlsx")
            wb.save(f.name)
            with pytest.raises(BadExcelData) as e:
                _process_upload_file(
                    self.lc,
>                   self.lc.action.package_show(id=self.pkg_id),
                    f.name,
                    get_geno('wrongdoing'),
                    True)

.../canada/tests/test_xls_upload.py:72: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckanapi/ckanapi/common.py:51: in action
    return self._ckan.call_action(name, data_dict=kwargs)
.../ckanapi/ckanapi/localckan.py:74: in call_action
    return self._get_action(action)(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
.../logic/action/get.py:1097: in package_show
    item.after_dataset_show(context, package_dict)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Plugin CanadaDatasetsPlugin 'canada_datasets'>
context = {'__auth_audit': [], '__auth_user_obj_checked': True, 'auth_user_obj': <User id=6e2a1166-bc58-46c0-8f09-d47d20a85c8c n...mage_url=None plugin_extras=None>, 'model': <module 'ckan.model' from '.../ckan/model/__init__.py'>, ...}
pkg_dict = {'author': None, 'author_email': None, 'creator_user_id': '6e2a1166-bc58-46c0-8f09-d47d20a85c8c', 'extras': [], ...}

    def after_dataset_show(self, context: Context, pkg_dict: Dict[str, Any]):
        if has_request_context() and not h.is_registry_domain():
            if (
              pkg_dict.get('type') not in ['info', 'dataset', 'prop'] or
              not asbool(pkg_dict.get('imso_approval')) or
              not asbool(pkg_dict.get('ready_to_publish')) or
              not pkg_dict.get('portal_release_date') or
              asbool(pkg_dict.get('private')) or
              pkg_dict.get('state') != 'active'
            ):
>               raise ObjectNotFound()
E               ckan.logic.NotFound

.../canada/plugin/dataset_plugin.py:224: NotFound
ckanext/canada/tests/test_xls_upload.py::TestXlsUpload::test_upload_wrong_type
Stack Traces | 9.36s run time
self = <ckanext.canada.tests.test_xls_upload.TestXlsUpload object at 0x7fdf7bf030a0>

    def test_upload_wrong_type(self):
        flask.g.user = self.editor['name']
        wb = excel_template('travela', self.org)
        f = tempfile.NamedTemporaryFile(suffix=".xlsx")
        wb.save(f.name)
        with pytest.raises(BadExcelData) as e:
            _process_upload_file(
                self.lc,
>               self.lc.action.package_show(id=self.pkg_id),
                f.name,
                get_geno('wrongdoing'),
                True)

.../canada/tests/test_xls_upload.py:155: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckanapi/ckanapi/common.py:51: in action
    return self._ckan.call_action(name, data_dict=kwargs)
.../ckanapi/ckanapi/localckan.py:74: in call_action
    return self._get_action(action)(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
.../logic/action/get.py:1097: in package_show
    item.after_dataset_show(context, package_dict)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Plugin CanadaDatasetsPlugin 'canada_datasets'>
context = {'__auth_audit': [], '__auth_user_obj_checked': True, 'auth_user_obj': <User id=d9230e1e-efac-462d-b937-90ced10d70b9 n...mage_url=None plugin_extras=None>, 'model': <module 'ckan.model' from '.../ckan/model/__init__.py'>, ...}
pkg_dict = {'author': None, 'author_email': None, 'creator_user_id': 'd9230e1e-efac-462d-b937-90ced10d70b9', 'extras': [], ...}

    def after_dataset_show(self, context: Context, pkg_dict: Dict[str, Any]):
        if has_request_context() and not h.is_registry_domain():
            if (
              pkg_dict.get('type') not in ['info', 'dataset', 'prop'] or
              not asbool(pkg_dict.get('imso_approval')) or
              not asbool(pkg_dict.get('ready_to_publish')) or
              not pkg_dict.get('portal_release_date') or
              asbool(pkg_dict.get('private')) or
              pkg_dict.get('state') != 'active'
            ):
>               raise ObjectNotFound()
E               ckan.logic.NotFound

.../canada/plugin/dataset_plugin.py:224: NotFound
ckanext/canada/tests/test_webforms.py::TestPackageWebForms::test_new_dataset_missing_fields
Stack Traces | 9.39s run time
self = <ckanext.canada.tests.test_webforms.TestPackageWebForms object at 0x7f3ca2030be0>
app = <ckan.tests.helpers.CKANTestApp object at 0x7f3ca0c4aa90>

    @mock.patch.object(h, 'is_registry_domain', mock_is_registry_domain)
    def test_new_dataset_missing_fields(self, app):
        dataset_id = 'f3e4adb9-6e32-4cb4-bf68-1eab9d1288f4'
    
        offset = h.url_for('dataset.new')
        response = app.get(offset, extra_environ=self.extra_environ_tester,
                           environ_overrides=self.environ_overrides_tester)
    
        assert 'Create Dataset' in response.body
        assert 'Before you can create a dataset you need to create an organization' not in response.body
    
        incomplete_dataset_form = {
            'id': dataset_id,
            'save': '',
            '_ckan_phase': '1',
        }
>       response = app.post(offset,
                            data=incomplete_dataset_form,
                            extra_environ=self.extra_environ_tester,
                            environ_overrides=self.environ_overrides_tester,
                            follow_redirects=True)

.../canada/tests/test_webforms.py:110: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckan/tests/helpers.py:210: in post
    res = self.test_client().post(url, *args, **kwargs)
.../venv/lib/python3.9............/site-packages/werkzeug/test.py:1136: in post
    return self.open(*args, **kw)
.../ckan/tests/helpers.py:247: in open
    res = super(CKANTestClient, self).open(*args, **kwargs)
.../venv/lib/python3.9............/site-packages/werkzeug/test.py:1076: in open
    response = self.run_wsgi_app(request.environ, buffered=buffered)
.../venv/lib/python3.9............/site-packages/werkzeug/test.py:945: in run_wsgi_app
    rv = run_wsgi_app(self.application, environ, buffered=buffered)
.../venv/lib/python3.9............/site-packages/werkzeug/test.py:1233: in run_wsgi_app
    app_rv = app(environ, start_response)
.../config/middleware/common_middleware.py:68: in __call__
    return self.app(environ, start_response)
.../config/middleware/flask_app.py:82: in __call__
    return self.app(environ, start_response)
.../config/middleware/common_middleware.py:87: in __call__
    return self.app(environ, start_response)
.../canada/plugin/security_plugin.py:138: in __call__
    return self.app(environ, _start_response)
.../canada/plugin/public_plugin.py:283: in __call__
    return self.app(environ, _start_response)
.../venv/lib/python3.9................../site-packages/flask/app.py:2091: in __call__
    return self.wsgi_app(environ, start_response)
.../venv/lib/python3.9.../site-packages/beaker/middleware.py:156: in __call__
    return self.wrap_app(environ, session_start_response)
.../config/middleware/common_middleware.py:31: in __call__
    return self.app(environ, start_response)
.../venv/lib/python3.9................../site-packages/flask/app.py:2076: in wsgi_app
    response = self.handle_exception(e)
.../venv/lib/python3.9................../site-packages/flask/app.py:2073: in wsgi_app
    response = self.full_dispatch_request()
.../venv/lib/python3.9................../site-packages/flask/app.py:1518: in full_dispatch_request
    rv = self.handle_user_exception(e)
.../venv/lib/python3.9................../site-packages/flask/app.py:1516: in full_dispatch_request
    rv = self.dispatch_request()
.../venv/lib/python3.9................../site-packages/flask/app.py:1502: in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
.../venv/lib/python3.9....../site-packages/flask/views.py:84: in view
    return current_app.ensure_sync(self.dispatch_request)(*args, **kwargs)
.../venv/lib/python3.9....../site-packages/flask/views.py:158: in dispatch_request
    return current_app.ensure_sync(meth)(*args, **kwargs)
.../ckanext/canada/view.py:208: in post
    response = super(CanadaDatasetCreateView, self).post(package_type)
.../ckan/views/dataset.py:606: in post
    pkg_dict = get_action(u'package_create')(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
.../logic/action/create.py:195: in package_create
    data, errors = lib_plugins.plugin_validate(
.../ckan/lib/plugins.py:332: in plugin_validate
    result = plugin.validate(context, data_dict, schema, action)
.../ckanext/scheming/plugins.py:326: in validate
    return navl_validate(data_dict, schema, context)
.../lib/navl/dictization_functions.py:305: in validate
    flat_data, errors = _validate(flattened, schema, validators_context)
.../lib/navl/dictization_functions.py:374: in _validate
    convert(converter, key, converted_data, errors, context)
.../lib/navl/dictization_functions.py:262: in convert
    value = converter(*params)
.../ckanext/canada/validators.py:718: in canada_dataset_visibility
    current_user_dict = get_action('user_show')({'ignore_auth': True},
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

up_func = <function user_show at 0x7f3ca55da790>
context = {'__auth_audit': [], '__auth_user_obj_checked': True, 'auth_user_obj': <User id=e679bdfc-803e-4aba-aad1-dfce34a417c5 n...e=active image_url=https://placeimg..../823/946/any plugin_extras=None>, 'count_private_and_draft_datasets': True, ...}
data_dict = {'id': 'cgonzalez', 'include_plugin_extras': True}

    @chained_action
    @side_effect_free
    def canada_user_show(up_func: Action,
                         context: Context,
                         data_dict: DataDict) -> ChainedAction:
        """
        Return new fields in the User dictionary.
        """
        data_dict['include_plugin_extras'] = True
        user_dict = up_func(context, data_dict)
        extras = user_dict.pop('plugin_extras', {})
>       user_dict['default_dataset_visibility'] = extras.get(
            'default_dataset_visibility', 'private')
E       AttributeError: 'NoneType' object has no attribute 'get'

.../ckanext/canada/logic.py:693: AttributeError
ckanext/canada/tests/test_webforms.py::TestNewUserWebForms::test_new_user_required_fields
Stack Traces | 9.47s run time
self = <ckanext.canada.tests.test_webforms.TestNewUserWebForms object at 0x7f61837c1490>
app = <ckan.tests.helpers.CKANTestApp object at 0x7f61836e0d90>

    @mock.patch.object(h, 'flash_notice', flashes.mock_flash)
    @mock.patch.object(h, 'get_flashed_messages', flashes.mock_get_flashed_messages)
    @mock.patch.object(h, 'is_registry_domain', mock_is_registry_domain)
    def test_new_user_required_fields(self, app):
        offset = h.url_for('user.register')
        response = app.get(offset, extra_environ=self.extra_environ_tester,
                           environ_overrides=self.environ_overrides_tester)
    
        assert 'Request an Account' in response.body
    
        response = app.post(offset,
                            data=self._filled_new_user_form(),
                            extra_environ=self.extra_environ_tester,
                            environ_overrides=self.environ_overrides_tester,
                            follow_redirects=False)
    
        lc = LocalCKAN()
>       new_user = lc.action.user_show(name='newusername')

.../canada/tests/test_webforms.py:227: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckanapi/ckanapi/common.py:51: in action
    return self._ckan.call_action(name, data_dict=kwargs)
.../ckanapi/ckanapi/localckan.py:74: in call_action
    return self._get_action(action)(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

up_func = <function user_show at 0x7f6186b7d790>
context = {'__auth_audit': [], '__auth_user_obj_checked': True, 'auth_user_obj': <User id=aa4db373-ee82-496f-b096-d7837c8e546e n...ons=False sysadmin=True state=active image_url=None plugin_extras=None>, 'count_private_and_draft_datasets': True, ...}
data_dict = {'id': 'test.ckan.net', 'include_plugin_extras': True, 'name': 'newusername'}

    @chained_action
    @side_effect_free
    def canada_user_show(up_func: Action,
                         context: Context,
                         data_dict: DataDict) -> ChainedAction:
        """
        Return new fields in the User dictionary.
        """
        data_dict['include_plugin_extras'] = True
        user_dict = up_func(context, data_dict)
        extras = user_dict.pop('plugin_extras', {})
>       user_dict['default_dataset_visibility'] = extras.get(
            'default_dataset_visibility', 'private')
E       AttributeError: 'NoneType' object has no attribute 'get'

.../ckanext/canada/logic.py:693: AttributeError
ckanext/canada/tests/test_webforms.py::TestPackageWebForms::test_new_dataset_required_fields
Stack Traces | 9.58s run time
self = <ckanext.canada.tests.test_webforms.TestPackageWebForms object at 0x7f047445cc70>
app = <ckan.tests.helpers.CKANTestApp object at 0x7f0473898a90>

    @mock.patch.object(h, 'flash_success', flashes.mock_flash)
    @mock.patch.object(h, 'get_flashed_messages', flashes.mock_get_flashed_messages)
    @mock.patch.object(h, 'is_registry_domain', mock_is_registry_domain)
    def test_new_dataset_required_fields(self, app):
        dataset_id = 'f3e4adb9-6e32-4cb4-bf68-1eab9d1288f5'
    
        offset = h.url_for('dataset.new')
        response = app.get(offset, extra_environ=self.extra_environ_tester,
                           environ_overrides=self.environ_overrides_tester)
    
        assert 'Create Dataset' in response.body
        assert 'Before you can create a dataset you need to create an organization' not in response.body
    
>       response = app.post(offset,
                            data=self._filled_dataset_form(dataset_id),
                            extra_environ=self.extra_environ_tester,
                            environ_overrides=self.environ_overrides_tester,
                            follow_redirects=False)

.../canada/tests/test_webforms.py:70: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckan/tests/helpers.py:210: in post
    res = self.test_client().post(url, *args, **kwargs)
.../venv/lib/python3.9............/site-packages/werkzeug/test.py:1136: in post
    return self.open(*args, **kw)
.../ckan/tests/helpers.py:247: in open
    res = super(CKANTestClient, self).open(*args, **kwargs)
.../venv/lib/python3.9............/site-packages/werkzeug/test.py:1076: in open
    response = self.run_wsgi_app(request.environ, buffered=buffered)
.../venv/lib/python3.9............/site-packages/werkzeug/test.py:945: in run_wsgi_app
    rv = run_wsgi_app(self.application, environ, buffered=buffered)
.../venv/lib/python3.9............/site-packages/werkzeug/test.py:1233: in run_wsgi_app
    app_rv = app(environ, start_response)
.../config/middleware/common_middleware.py:68: in __call__
    return self.app(environ, start_response)
.../config/middleware/flask_app.py:82: in __call__
    return self.app(environ, start_response)
.../config/middleware/common_middleware.py:87: in __call__
    return self.app(environ, start_response)
.../canada/plugin/security_plugin.py:138: in __call__
    return self.app(environ, _start_response)
.../canada/plugin/public_plugin.py:283: in __call__
    return self.app(environ, _start_response)
.../venv/lib/python3.9................../site-packages/flask/app.py:2091: in __call__
    return self.wsgi_app(environ, start_response)
.../venv/lib/python3.9.../site-packages/beaker/middleware.py:156: in __call__
    return self.wrap_app(environ, session_start_response)
.../config/middleware/common_middleware.py:31: in __call__
    return self.app(environ, start_response)
.../venv/lib/python3.9................../site-packages/flask/app.py:2076: in wsgi_app
    response = self.handle_exception(e)
.../venv/lib/python3.9................../site-packages/flask/app.py:2073: in wsgi_app
    response = self.full_dispatch_request()
.../venv/lib/python3.9................../site-packages/flask/app.py:1518: in full_dispatch_request
    rv = self.handle_user_exception(e)
.../venv/lib/python3.9................../site-packages/flask/app.py:1516: in full_dispatch_request
    rv = self.dispatch_request()
.../venv/lib/python3.9................../site-packages/flask/app.py:1502: in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
.../venv/lib/python3.9....../site-packages/flask/views.py:84: in view
    return current_app.ensure_sync(self.dispatch_request)(*args, **kwargs)
.../venv/lib/python3.9....../site-packages/flask/views.py:158: in dispatch_request
    return current_app.ensure_sync(meth)(*args, **kwargs)
.../ckanext/canada/view.py:208: in post
    response = super(CanadaDatasetCreateView, self).post(package_type)
.../ckan/views/dataset.py:606: in post
    pkg_dict = get_action(u'package_create')(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
.../logic/action/create.py:195: in package_create
    data, errors = lib_plugins.plugin_validate(
.../ckan/lib/plugins.py:332: in plugin_validate
    result = plugin.validate(context, data_dict, schema, action)
.../ckanext/scheming/plugins.py:326: in validate
    return navl_validate(data_dict, schema, context)
.../lib/navl/dictization_functions.py:305: in validate
    flat_data, errors = _validate(flattened, schema, validators_context)
.../lib/navl/dictization_functions.py:374: in _validate
    convert(converter, key, converted_data, errors, context)
.../lib/navl/dictization_functions.py:262: in convert
    value = converter(*params)
.../ckanext/canada/validators.py:718: in canada_dataset_visibility
    current_user_dict = get_action('user_show')({'ignore_auth': True},
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

up_func = <function user_show at 0x7f0478461790>
context = {'__auth_audit': [], '__auth_user_obj_checked': True, 'auth_user_obj': <User id=1ef35b7f-d2f7-43f8-8d6a-a1df8805ea6a n...tate=active image_url=https://picsum.photos/676/421 plugin_extras=None>, 'count_private_and_draft_datasets': True, ...}
data_dict = {'id': 'howardstephanie', 'include_plugin_extras': True}

    @chained_action
    @side_effect_free
    def canada_user_show(up_func: Action,
                         context: Context,
                         data_dict: DataDict) -> ChainedAction:
        """
        Return new fields in the User dictionary.
        """
        data_dict['include_plugin_extras'] = True
        user_dict = up_func(context, data_dict)
        extras = user_dict.pop('plugin_extras', {})
>       user_dict['default_dataset_visibility'] = extras.get(
            'default_dataset_visibility', 'private')
E       AttributeError: 'NoneType' object has no attribute 'get'

.../ckanext/canada/logic.py:693: AttributeError
ckanext/canada/tests/test_xls_upload.py::TestXlsUpload::test_upload_example_dry_run
Stack Traces | 10.5s run time
self = <ckanext.canada.tests.test_xls_upload.TestXlsUpload object at 0x7f09a9f456a0>

    def test_upload_example_dry_run(self):
        current_user = model.User.get(self.editor['name'])
        with mock.patch('ckan.lib.helpers.current_user', current_user):
            flask.g.user = self.editor['name']
            wb = excel_template('wrongdoing', self.org)
            f = tempfile.NamedTemporaryFile(suffix=".xlsx")
    
            # Enter the example record into the excel template
            record = get_chromo('wrongdoing')['examples']['record']
            wb = append_data(wb, [record], get_chromo('wrongdoing'))
            wb.save(f.name)
    
            _process_upload_file(
                self.lc,
>               self.lc.action.package_show(id=self.pkg_id),
                f.name,
                get_geno('wrongdoing'),
                True)

.../canada/tests/test_xls_upload.py:138: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckanapi/ckanapi/common.py:51: in action
    return self._ckan.call_action(name, data_dict=kwargs)
.../ckanapi/ckanapi/localckan.py:74: in call_action
    return self._get_action(action)(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
.../logic/action/get.py:1097: in package_show
    item.after_dataset_show(context, package_dict)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Plugin CanadaDatasetsPlugin 'canada_datasets'>
context = {'__auth_audit': [], '__auth_user_obj_checked': True, 'auth_user_obj': <User id=c81bc2a9-3acf-4c73-bd47-128b1c5a3d2e n...mage_url=None plugin_extras=None>, 'model': <module 'ckan.model' from '.../ckan/model/__init__.py'>, ...}
pkg_dict = {'author': None, 'author_email': None, 'creator_user_id': 'c81bc2a9-3acf-4c73-bd47-128b1c5a3d2e', 'extras': [], ...}

    def after_dataset_show(self, context: Context, pkg_dict: Dict[str, Any]):
        if has_request_context() and not h.is_registry_domain():
            if (
              pkg_dict.get('type') not in ['info', 'dataset', 'prop'] or
              not asbool(pkg_dict.get('imso_approval')) or
              not asbool(pkg_dict.get('ready_to_publish')) or
              not pkg_dict.get('portal_release_date') or
              asbool(pkg_dict.get('private')) or
              pkg_dict.get('state') != 'active'
            ):
>               raise ObjectNotFound()
E               ckan.logic.NotFound

.../canada/plugin/dataset_plugin.py:224: NotFound
ckanext/canada/tests/test_xls_upload.py::TestXlsUpload::test_upload_example
Stack Traces | 10.6s run time
self = <ckanext.canada.tests.test_xls_upload.TestXlsUpload object at 0x7f39417c2bb0>

    def test_upload_example(self):
        current_user = model.User.get(self.editor['name'])
        with mock.patch('ckan.lib.helpers.current_user', current_user):
            flask.g.user = self.editor['name']
            wb = excel_template('wrongdoing', self.org)
            f = tempfile.NamedTemporaryFile(suffix=".xlsx")
    
            # Enter the example record into the excel template
            record = get_chromo('wrongdoing')['examples']['record']
            wb = append_data(wb, [record], get_chromo('wrongdoing'))
            wb.save(f.name)
    
            _process_upload_file(
                self.lc,
>               self.lc.action.package_show(id=self.pkg_id),
                f.name,
                get_geno('wrongdoing'),
                False)

.../canada/tests/test_xls_upload.py:92: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckanapi/ckanapi/common.py:51: in action
    return self._ckan.call_action(name, data_dict=kwargs)
.../ckanapi/ckanapi/localckan.py:74: in call_action
    return self._get_action(action)(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
.../logic/action/get.py:1097: in package_show
    item.after_dataset_show(context, package_dict)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Plugin CanadaDatasetsPlugin 'canada_datasets'>
context = {'__auth_audit': [], '__auth_user_obj_checked': True, 'auth_user_obj': <User id=ace2d956-1e80-4c53-a142-23ac73aa663d n...mage_url=None plugin_extras=None>, 'model': <module 'ckan.model' from '.../ckan/model/__init__.py'>, ...}
pkg_dict = {'author': None, 'author_email': None, 'creator_user_id': 'ace2d956-1e80-4c53-a142-23ac73aa663d', 'extras': [], ...}

    def after_dataset_show(self, context: Context, pkg_dict: Dict[str, Any]):
        if has_request_context() and not h.is_registry_domain():
            if (
              pkg_dict.get('type') not in ['info', 'dataset', 'prop'] or
              not asbool(pkg_dict.get('imso_approval')) or
              not asbool(pkg_dict.get('ready_to_publish')) or
              not pkg_dict.get('portal_release_date') or
              asbool(pkg_dict.get('private')) or
              pkg_dict.get('state') != 'active'
            ):
>               raise ObjectNotFound()
E               ckan.logic.NotFound

.../canada/plugin/dataset_plugin.py:224: NotFound
ckanext/canada/tests/test_search.py::TestPortalSearch::test_user_package_search
Stack Traces | 15s run time
self = <ckanext.canada.tests.test_search.TestPortalSearch object at 0x7fc54ef28be0>

    def test_user_package_search(self):
        response = self.lc.action.package_search(
            q='*:*',
            include_private=self.include_private)
    
        assert 'count' in response
>       assert response['count'] == 6
E       assert 9 == 6

.../canada/tests/test_search.py:186: AssertionError
View the full list of 1 ❄️ flaky test(s)
ckanext/canada/tests/test_validators.py::TestNAVLSchema::test_basic_package

Flake rate in main: 16.67% (Passed 5 times, Failed 1 times)

Stack Traces | 0.259s run time
self = <sqlalchemy.engine.base.Connection object at 0x7f0472eb5730>
dialect = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0x7f0473fa2100>
constructor = <bound method DefaultExecutionContext._init_compiled of <class 'sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2'>>
statement = 'UPDATE package SET id=%(id)s, owner_org=%(owner_org)s, creator_user_id=%(creator_user_id)s WHERE package.id = %(package_id)s'
parameters = {'creator_user_id': 'f20b4401-0954-4979-ba7c-917f0fa0ef24', 'id': '2905f084-6204-4069-a96c-83fda2811cdd', 'owner_org': 'a9226629-376d-446d-8f45-45ec9339da03', 'package_id': '21a2e092-d484-4764-beaf-b988903bd7c6'}
execution_options = immutabledict({'autocommit': True, 'compiled_cache': {(<sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 obj...age_id'), False, False), <sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0x7f0473022b50>, 15]}})
args = (<sqlalchemy.dialects.postgresql.psycopg2.PGCompiler_psycopg2 object at 0x7f0473022b50>, [{'creator_user_id': 'f20b440...7c6'}], <sqlalchemy.sql.dml.Update object at 0x7f0473f0d610>, [BindParameter('package_id', None, type_=UnicodeText())])
kw = {'cache_hit': symbol('CACHE_MISS')}
branched = <sqlalchemy.engine.base.Connection object at 0x7f0472eb5730>
yp = None
conn = <sqlalchemy.pool.base._ConnectionFairy object at 0x7f0472eb50a0>
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0x7f047300ff40>
cursor = <cursor object at 0x7f04742d68b0; closed: -1>, evt_handled = False

    def _execute_context(
        self,
        dialect,
        constructor,
        statement,
        parameters,
        execution_options,
        *args,
        **kw
    ):
        """Create an :class:`.ExecutionContext` and execute, returning
        a :class:`_engine.CursorResult`."""
    
        branched = self
        if self.__branch_from:
            # if this is a "branched" connection, do everything in terms
            # of the "root" connection, *except* for .close(), which is
            # the only feature that branching provides
            self = self.__branch_from
    
        if execution_options:
            yp = execution_options.get("yield_per", None)
            if yp:
                execution_options = execution_options.union(
                    {"stream_results": True, "max_row_buffer": yp}
                )
    
        try:
            conn = self._dbapi_connection
            if conn is None:
                conn = self._revalidate_connection()
    
            context = constructor(
                dialect, self, conn, execution_options, *args, **kw
            )
        except (exc.PendingRollbackError, exc.ResourceClosedError):
            raise
        except BaseException as e:
            self._handle_dbapi_exception(
                e, util.text_type(statement), parameters, None, None
            )
    
        if (
            self._transaction
            and not self._transaction.is_active
            or (
                self._nested_transaction
                and not self._nested_transaction.is_active
            )
        ):
            self._invalid_transaction()
    
        elif self._trans_context_manager:
            TransactionalContext._trans_ctx_check(self)
    
        if self._is_future and self._transaction is None:
            self._autobegin()
    
        context.pre_exec()
    
        if dialect.use_setinputsizes:
            context._set_input_sizes()
    
        cursor, statement, parameters = (
            context.cursor,
            context.statement,
            context.parameters,
        )
    
        if not context.executemany:
            parameters = parameters[0]
    
        if self._has_events or self.engine._has_events:
            for fn in self.dispatch.before_cursor_execute:
                statement, parameters = fn(
                    self,
                    cursor,
                    statement,
                    parameters,
                    context,
                    context.executemany,
                )
    
        if self._echo:
    
            self._log_info(statement)
    
            stats = context._get_cache_stats()
    
            if not self.engine.hide_parameters:
                self._log_info(
                    "[%s] %r",
                    stats,
                    sql_util._repr_params(
                        parameters, batches=10, ismulti=context.executemany
                    ),
                )
            else:
                self._log_info(
                    "[%s] [SQL parameters hidden due to hide_parameters=True]"
                    % (stats,)
                )
    
        evt_handled = False
        try:
            if context.executemany:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_executemany:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_executemany(
                        cursor, statement, parameters, context
                    )
            elif not parameters and context.no_parameters:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute_no_params:
                        if fn(cursor, statement, context):
                            evt_handled = True
                            break
                if not evt_handled:
                    self.dialect.do_execute_no_params(
                        cursor, statement, context
                    )
            else:
                if self.dialect._has_events:
                    for fn in self.dialect.dispatch.do_execute:
                        if fn(cursor, statement, parameters, context):
                            evt_handled = True
                            break
                if not evt_handled:
>                   self.dialect.do_execute(
                        cursor, statement, parameters, context
                    )

.../venv/lib/python3.9.../sqlalchemy/engine/base.py:1900: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0x7f0473fa2100>
cursor = <cursor object at 0x7f04742d68b0; closed: -1>
statement = 'UPDATE package SET id=%(id)s, owner_org=%(owner_org)s, creator_user_id=%(creator_user_id)s WHERE package.id = %(package_id)s'
parameters = {'creator_user_id': 'f20b4401-0954-4979-ba7c-917f0fa0ef24', 'id': '2905f084-6204-4069-a96c-83fda2811cdd', 'owner_org': 'a9226629-376d-446d-8f45-45ec9339da03', 'package_id': '21a2e092-d484-4764-beaf-b988903bd7c6'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0x7f047300ff40>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       psycopg2.errors.ForeignKeyViolation: update or delete on table "package" violates foreign key constraint "package_extra_package_id_fkey" on table "package_extra"
E       DETAIL:  Key (id)=(21a2e092-d484-4764-beaf-b988903bd7c6) is still referenced from table "package_extra".

.../venv/lib/python3.9.../sqlalchemy/engine/default.py:736: ForeignKeyViolation

The above exception was the direct cause of the following exception:

self = <ckanext.canada.tests.test_validators.TestNAVLSchema object at 0x7f04746e4490>

    def test_basic_package(self):
        with pytest.raises(ValidationError) as ve:
            self.normal_action.package_create(
                name='12345678-9abc-def0-1234-56789abcdef0',
                **self.incomplete_pkg)
        model.Session.rollback()
        err = ve.value.error_dict
        expected = {
            'notes_translated-en': ['Missing value'],
            'frequency': ['Missing value'],
            'subject': ['Select at least one'],
            'notes_translated-fr': ['Missing value'],
            'keywords-en': ['Missing value'],
            'title_translated': ['Required language "fr" missing'],
            'date_published': ['Missing value'],
            'keywords-fr': ['Missing value'],
            'owner_org': ['Missing value'],
        }
        assert isinstance(err, dict), err
        for k in set(err) | set(expected):
            assert k in err
            assert err[k] == expected[k]
        model.Session.rollback()
>       resp = self.normal_action.package_create(
            name='12345678-9abc-def0-1234-56789abcdef0', **self.complete_pkg)

.../canada/tests/test_validators.py:144: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.../ckanapi/ckanapi/common.py:51: in action
    return self._ckan.call_action(name, data_dict=kwargs)
.../ckanapi/ckanapi/localckan.py:74: in call_action
    return self._get_action(action)(context, data_dict)
.../ckan/logic/__init__.py:581: in wrapped
    result = _action(context, data_dict, **kw)
.../logic/action/create.py:213: in package_create
    pkg = model_save.package_dict_save(data, context, include_plugin_data)
.../lib/dictization/model_save.py:315: in package_dict_save
    package_membership_list_save(pkg_dict.get("groups"), pkg, context)
.../lib/dictization/model_save.py:230: in package_membership_list_save
    model.Session.flush()
<string>:2: in flush
    ???
.../venv/lib/python3.9.../sqlalchemy/orm/session.py:3386: in flush
    self._flush(objects)
.../venv/lib/python3.9.../sqlalchemy/orm/session.py:3526: in _flush
    transaction.rollback(_capture_exception=True)
.../venv/lib/python3.9.../sqlalchemy/util/langhelpers.py:70: in __exit__
    compat.raise_(
.../venv/lib/python3.9.../sqlalchemy/util/compat.py:208: in raise_
    raise exception
.../venv/lib/python3.9.../sqlalchemy/orm/session.py:3486: in _flush
    flush_context.execute()
.../venv/lib/python3.9.../sqlalchemy/orm/unitofwork.py:456: in execute
    rec.execute(self)
.../venv/lib/python3.9.../sqlalchemy/orm/unitofwork.py:630: in execute
    util.preloaded.orm_persistence.save_obj(
.../venv/lib/python3.9.../sqlalchemy/orm/persistence.py:237: in save_obj
    _emit_update_statements(
.../venv/lib/python3.9.../sqlalchemy/orm/persistence.py:1001: in _emit_update_statements
    c = connection._execute_20(
.../venv/lib/python3.9.../sqlalchemy/engine/base.py:1705: in _execute_20
    return meth(self, args_10style, kwargs_10style, execution_options)
.../venv/lib/python3.9.../sqlalchemy/sql/elements.py:333: in _execute_on_connection
    return connection._execute_clauseelement(
.../venv/lib/python3.9.../sqlalchemy/engine/base.py:1572: in _execute_clauseelement
    ret = self._execute_context(
.../venv/lib/python3.9.../sqlalchemy/engine/base.py:1943: in _execute_context
    self._handle_dbapi_exception(
.../venv/lib/python3.9.../sqlalchemy/engine/base.py:2124: in _handle_dbapi_exception
    util.raise_(
.../venv/lib/python3.9.../sqlalchemy/util/compat.py:208: in raise_
    raise exception
.../venv/lib/python3.9.../sqlalchemy/engine/base.py:1900: in _execute_context
    self.dialect.do_execute(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0x7f0473fa2100>
cursor = <cursor object at 0x7f04742d68b0; closed: -1>
statement = 'UPDATE package SET id=%(id)s, owner_org=%(owner_org)s, creator_user_id=%(creator_user_id)s WHERE package.id = %(package_id)s'
parameters = {'creator_user_id': 'f20b4401-0954-4979-ba7c-917f0fa0ef24', 'id': '2905f084-6204-4069-a96c-83fda2811cdd', 'owner_org': 'a9226629-376d-446d-8f45-45ec9339da03', 'package_id': '21a2e092-d484-4764-beaf-b988903bd7c6'}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0x7f047300ff40>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.IntegrityError: (psycopg2.errors.ForeignKeyViolation) update or delete on table "package" violates foreign key constraint "package_extra_package_id_fkey" on table "package_extra"
E       DETAIL:  Key (id)=(21a2e092-d484-4764-beaf-b988903bd7c6) is still referenced from table "package_extra".
E       
E       [SQL: UPDATE package SET id=%(id)s, owner_org=%(owner_org)s, creator_user_id=%(creator_user_id)s WHERE package.id = %(package_id)s]
E       [parameters: {'id': '2905f084-6204-4069-a96c-83fda2811cdd', 'owner_org': 'a9226629-376d-446d-8f45-45ec9339da03', 'creator_user_id': 'f20b4401-0954-4979-ba7c-917f0fa0ef24', 'package_id': '21a2e092-d484-4764-beaf-b988903bd7c6'}]
E       (Background on this error at: https://sqlalche..../e/14/gkpj)

.../venv/lib/python3.9.../sqlalchemy/engine/default.py:736: IntegrityError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

- Syntax fixes.
- Typing fixes.
- Started working on the dataset visibility validator.
- Added more validation to portal release date field.
- Changed the published search facet to capacity.
- Set capacity=private for non standard dataset types.
- After validator for dataset visibility.
- Added more sysadmin UI for user publishing perms.
- Side effect free.
- Removed geozoom.
- Fix different logic for single instance.
- Fix different logic for single instance.
- Force True for non portal package types.
- Override activity stuff for logged out users to show a dummy user.
- Minor template UI fixes.
- Added UI for private/public packages.
- Removed old logic methods.
- Removed anon actions.
- Use fq_list instead of complicated fq for package search.
- Handled remaining search issues between registry and portal.
- Added helper cli subcommand to set non portal package types to private.
- Added more bootstrap4+ classes.
- Improved some code.
- Language switcher for language domains.
- Minor remplate fixes.
- Pinned required dependency versions.
- Try/catch for dataset search.
- Flake8 fix.
@JVickery-TBS JVickery-TBS marked this pull request as ready for review October 17, 2025 14:54
Copy link
Member

@wardi wardi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, just a few minor suggestions

- Use filters.
- Combine internal and public.
- Use filters.
- Combine internal and public.
# Conflicts:
#	ckanext/canada/cli.py
#	ckanext/canada/tests/conftest.py
#	ckanext/canada/view.py
### RESOLVED.
- Start creating build front end assets.
- Sass and Gulp Terser building and watching.
- Install and build frontend dependencies.
- Moved canada custom css to scss;
- Started working on custom datatables css to scss.
- Removed source mapping from gulp.
- Finished sass for datatables.
- Removed registry file prefix for most JS scripts.
-
- Do not reuse ids.
- Track build files for deployment.
# Conflicts:
#	ckanext/canada/cli.py
#	requirements.txt
### RESOLVED.
- Fix missing inheritance.
- Package search ignore auth;
- Pyright fixes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants