diff --git a/HISTORY.rst b/HISTORY.rst index fe0c85c4af..5d7b8a9f52 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,3 +1,8 @@ +2.1.1 (2016-05-17) +================== +- Fix navigation issue that make it impossible to add new sources. GitLab issue #288. + + 2.1 (2016-05-14) ================ - Upgrade to use Django 1.8.13. Issue #246. @@ -35,6 +40,7 @@ - Add roadmap documentation chapter. - API updates. + 2.0.2 (2016-02-09) ================== - Install testing dependencies when installing development dependencies. diff --git a/docs/releases/2.1.1.rst b/docs/releases/2.1.1.rst new file mode 100644 index 0000000000..1a13ef1b42 --- /dev/null +++ b/docs/releases/2.1.1.rst @@ -0,0 +1,77 @@ +=============================== +Mayan EDMS v2.1.1 release notes +=============================== + +Released: May 17, 2016 + +What's new +========== + +This is a bugfix release and all users are encouraged to upgrade. + +Fix object column resolution issue in navigation app +---------------------------------------------------- +Version 2.1 includes a navigation feature that allows model instances from a +queryset generated using the .defer() or .only() Django filter optimization +features to resolve to their parent class transparently. This optimization +caused problems with the sources app which uses a + + + +Removals +-------- +* None + +Upgrading from a previous version +--------------------------------- + +Using PIP +~~~~~~~~~ + +Type in the console:: + + $ pip install -U mayan-edms + +the requirements will also be updated automatically. + +Using Git +~~~~~~~~~ + +If you installed Mayan EDMS by cloning the Git repository issue the commands:: + + $ git reset --hard HEAD + $ git pull + +otherwise download the compressed archived and uncompress it overriding the +existing installation. + +Next upgrade/add the new requirements:: + + $ pip install --upgrade -r requirements.txt + +Common steps +~~~~~~~~~~~~ + +Migrate existing database schema with:: + + $ mayan-edms.py performupgrade + +Add new static media:: + + $ mayan-edms.py collectstatic --noinput + +The upgrade procedure is now complete. + + +Backward incompatible changes +============================= + +* None + +Bugs fixed or issues closed +=========================== + +* `GitLab issue #288 `_ Can't add sources in mayan-edms 2.1. + + +.. _PyPI: https://pypi.python.org/pypi/mayan-edms/ diff --git a/docs/releases/index.rst b/docs/releases/index.rst index e22b2d91ad..ef8f792541 100644 --- a/docs/releases/index.rst +++ b/docs/releases/index.rst @@ -22,6 +22,7 @@ versions of the documentation contain the release notes for any later releases. .. toctree:: :maxdepth: 1 + 2.1.1 2.1 2.0.2 2.0.1 diff --git a/mayan/apps/navigation/classes.py b/mayan/apps/navigation/classes.py index 04cc418a81..6edbf818dc 100644 --- a/mayan/apps/navigation/classes.py +++ b/mayan/apps/navigation/classes.py @@ -364,8 +364,10 @@ class SourceColumn(object): return cls._registry[source.__class__] except KeyError: try: + # Special case for queryset items produced from + # .defer() or .only() optimizations return cls._registry[source._meta.parents.items()[0][0]] - except IndexError: + except (KeyError, IndexError): return () except TypeError: # unhashable type: list diff --git a/mayan/apps/sources/tests/test_views.py b/mayan/apps/sources/tests/test_views.py index 038ccd0882..2ad5038f77 100644 --- a/mayan/apps/sources/tests/test_views.py +++ b/mayan/apps/sources/tests/test_views.py @@ -25,9 +25,12 @@ from user_management.tests import ( from ..links import link_upload_version from ..literals import SOURCE_CHOICE_WEB_FORM from ..models import StagingFolderSource, WebFormSource -from ..permissions import permission_staging_file_delete +from ..permissions import ( + permission_sources_setup_create, permission_sources_setup_delete, + permission_sources_setup_view, permission_staging_file_delete +) -TEST_SOURCE_LABEL = 'test' +TEST_SOURCE_LABEL = 'test source' TEST_SOURCE_UNCOMPRESS_N = 'n' TEST_STAGING_PREVIEW_WIDTH = 640 @@ -285,3 +288,125 @@ class StagingFolderTestCase(GenericViewTestCase): self.assertContains(response, 'deleted', status_code=200) self.assertEqual(len(list(staging_folder.get_files())), 0) + + +class SourcesTestCase(GenericDocumentViewTestCase): + def create_web_source(self): + self.source = WebFormSource.objects.create( + enabled=True, label=TEST_SOURCE_LABEL, + uncompress=TEST_SOURCE_UNCOMPRESS_N + ) + + def test_source_list_view_with_permission(self): + self.create_web_source() + + self.login( + username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD + ) + + self.role.permissions.add( + permission_sources_setup_view.stored_permission + ) + + response = self.get(viewname='sources:setup_source_list') + + self.assertContains(response, text=self.source.label, status_code=200) + + def test_source_list_view_no_permission(self): + self.create_web_source() + + self.login( + username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD + ) + + response = self.get(viewname='sources:setup_source_list') + + self.assertEqual(response.status_code, 403) + + def test_source_create_view_with_permission(self): + self.login( + username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD + ) + + self.role.permissions.add( + permission_sources_setup_create.stored_permission + ) + self.role.permissions.add( + permission_sources_setup_view.stored_permission + ) + + response = self.post( + args=(SOURCE_CHOICE_WEB_FORM,), follow=True, + viewname='sources:setup_source_create', data={ + 'enabled': True, 'label': TEST_SOURCE_LABEL, + 'uncompress': TEST_SOURCE_UNCOMPRESS_N + } + ) + + webform_source = WebFormSource.objects.first() + + self.assertEqual(webform_source.label, TEST_SOURCE_LABEL) + self.assertEqual(webform_source.uncompress, TEST_SOURCE_UNCOMPRESS_N) + + self.assertEquals(response.status_code, 200) + + def test_source_create_view_no_permission(self): + self.login( + username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD + ) + + self.role.permissions.add( + permission_sources_setup_view.stored_permission + ) + + response = self.post( + args=(SOURCE_CHOICE_WEB_FORM,), follow=True, + viewname='sources:setup_source_create', data={ + 'enabled': True, 'label': TEST_SOURCE_LABEL, + 'uncompress': TEST_SOURCE_UNCOMPRESS_N + } + ) + + self.assertEqual(response.status_code, 403) + self.assertEqual(WebFormSource.objects.count(), 0) + + def test_source_delete_view_with_permission(self): + self.create_web_source() + + self.login( + username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD + ) + + self.role.permissions.add( + permission_sources_setup_delete.stored_permission + ) + self.role.permissions.add( + permission_sources_setup_view.stored_permission + ) + + response = self.post( + args=(self.source.pk,), follow=True, + viewname='sources:setup_source_delete' + ) + + self.assertEqual(response.status_code, 200) + self.assertEqual(WebFormSource.objects.count(), 0) + + def test_source_delete_view_no_permission(self): + self.create_web_source() + + self.login( + username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD + ) + + self.role.permissions.add( + permission_sources_setup_view.stored_permission + ) + + response = self.post( + args=(self.source.pk,), follow=True, + viewname='sources:setup_source_delete' + ) + + self.assertEqual(response.status_code, 403) + self.assertEqual(WebFormSource.objects.count(), 1)