diff --git a/netbox/extras/tests/test_views.py b/netbox/extras/tests/test_views.py index f97b3581b..8dd82c239 100644 --- a/netbox/extras/tests/test_views.py +++ b/netbox/extras/tests/test_views.py @@ -408,6 +408,9 @@ class BookmarkTestCase( def test_list_objects_anonymous(self): return + def test_export_objects_anonymous(self): + return + def test_list_objects_with_constrained_permission(self): return @@ -962,6 +965,9 @@ class SubscriptionTestCase( login_url = reverse('login') self.assertRedirects(self.client.get(url), f'{login_url}?next={url}') + def test_export_objects_anonymous(self): + return + def test_list_objects_with_permission(self): return @@ -1070,6 +1076,9 @@ class NotificationTestCase( login_url = reverse('login') self.assertRedirects(self.client.get(url), f'{login_url}?next={url}') + def test_export_objects_anonymous(self): + return + def test_list_objects_with_permission(self): return diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index 65e2a58ae..eef9e490b 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -181,7 +181,7 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin): if request.GET['export'] == 'table': table = self.get_table(self.queryset, request, has_table_actions) columns = [name for name, _ in table.selected_columns] - delimiter = request.user.config.get('csv_delimiter') + delimiter = request.user.config.get('csv_delimiter') if request.user.is_authenticated else None return self.export_table(table, columns, delimiter=delimiter) # Render an ExportTemplate @@ -202,7 +202,7 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin): # Fall back to default table/YAML export table = self.get_table(self.queryset, request, has_table_actions) - delimiter = request.user.config.get('csv_delimiter') + delimiter = request.user.config.get('csv_delimiter') if request.user.is_authenticated else None return self.export_table(table, delimiter=delimiter) # Render the objects table diff --git a/netbox/utilities/testing/views.py b/netbox/utilities/testing/views.py index ac24c61d5..33c9ac25d 100644 --- a/netbox/utilities/testing/views.py +++ b/netbox/utilities/testing/views.py @@ -517,6 +517,31 @@ class ViewTestCases: self.assertHttpStatus(response, 200) self.assertEqual(response.get('Content-Type'), 'text/csv; charset=utf-8') + @override_settings(EXEMPT_VIEW_PERMISSIONS=['*'], LOGIN_REQUIRED=False) + def test_export_objects_anonymous(self): + # Ensure we are logged out. + self.client.logout() + + # Some models (e.g. the users model) always require to be logged in, so we skip them here. + ct = ContentType.objects.get_for_model(self.model) + if (ct.app_label, ct.model) in settings.EXEMPT_EXCLUDE_MODELS: + return + + url = self._get_url('list') + + # Test default CSV (or sometimes YAML) export + response = self.client.get(f'{url}?export') + self.assertHttpStatus(response, 200) + if hasattr(self.model, 'to_yaml'): + self.assertEqual(response.get('Content-Type'), 'text/yaml') + else: + self.assertEqual(response.get('Content-Type'), 'text/csv; charset=utf-8') + + # Test table-based export + response = self.client.get(f'{url}?export=table') + self.assertHttpStatus(response, 200) + self.assertEqual(response.get('Content-Type'), 'text/csv; charset=utf-8') + class CreateMultipleObjectsViewTestCase(ModelViewTestCase): """ Create multiple instances using a single form. Expects the creation of three new instances by default.