diff --git a/netbox/extras/tables/tables.py b/netbox/extras/tables/tables.py index 3738f3102..8c78ad0de 100644 --- a/netbox/extras/tables/tables.py +++ b/netbox/extras/tables/tables.py @@ -1,10 +1,10 @@ import json import django_tables2 as tables -from django.conf import settings from django.utils.translation import gettext_lazy as _ from extras.models import * +from netbox.constants import EMPTY_TABLE_TEXT from netbox.tables import BaseTable, NetBoxTable, columns from .template_code import * @@ -550,7 +550,7 @@ class ScriptResultsTable(BaseTable): ) class Meta(BaseTable.Meta): - empty_text = _('No results found') + empty_text = _(EMPTY_TABLE_TEXT) fields = ( 'index', 'time', 'status', 'message', ) @@ -581,7 +581,7 @@ class ReportResultsTable(BaseTable): ) class Meta(BaseTable.Meta): - empty_text = _('No results found') + empty_text = _(EMPTY_TABLE_TEXT) fields = ( 'index', 'method', 'time', 'status', 'object', 'url', 'message', ) diff --git a/netbox/netbox/constants.py b/netbox/netbox/constants.py index 6a6928021..e797f4f29 100644 --- a/netbox/netbox/constants.py +++ b/netbox/netbox/constants.py @@ -41,3 +41,6 @@ DEFAULT_ACTION_PERMISSIONS = { # General-purpose tokens CENSOR_TOKEN = '********' CENSOR_TOKEN_CHANGED = '***CHANGED***' + +# Placeholder text for empty tables +EMPTY_TABLE_TEXT = 'No results found' diff --git a/netbox/netbox/tables/tables.py b/netbox/netbox/tables/tables.py index 38f7248e6..2697c4bc0 100644 --- a/netbox/netbox/tables/tables.py +++ b/netbox/netbox/tables/tables.py @@ -14,6 +14,7 @@ from django_tables2.data import TableQuerysetData from core.models import ObjectType from extras.choices import * from extras.models import CustomField, CustomLink +from netbox.constants import EMPTY_TABLE_TEXT from netbox.registry import registry from netbox.tables import columns from utilities.paginator import EnhancedPaginator, get_paginate_count @@ -258,7 +259,7 @@ class SearchTable(tables.Table): attrs = { 'class': 'table table-hover object-list', } - empty_text = _('No results found') + empty_text = _(EMPTY_TABLE_TEXT) def __init__(self, data, highlight=None, **kwargs): self.highlight = highlight diff --git a/netbox/netbox/tests/test_views.py b/netbox/netbox/tests/test_views.py index 1942471b0..ccba73baa 100644 --- a/netbox/netbox/tests/test_views.py +++ b/netbox/netbox/tests/test_views.py @@ -1,24 +1,76 @@ import urllib.parse -from utilities.testing import TestCase from django.urls import reverse +from django.test import override_settings + +from dcim.models import Site +from netbox.constants import EMPTY_TABLE_TEXT +from netbox.search.backends import search_backend +from utilities.testing import TestCase class HomeViewTestCase(TestCase): def test_home(self): - url = reverse('home') - response = self.client.get(url) self.assertHttpStatus(response, 200) - def test_search(self): +class SearchViewTestCase(TestCase): + + @classmethod + def setUpTestData(cls): + sites = ( + Site(name='Site Alpha', slug='alpha', description='Red'), + Site(name='Site Bravo', slug='bravo', description='Red'), + Site(name='Site Charlie', slug='charlie', description='Green'), + Site(name='Site Delta', slug='delta', description='Green'), + Site(name='Site Echo', slug='echo', description='Blue'), + Site(name='Site Foxtrot', slug='foxtrot', description='Blue'), + ) + Site.objects.bulk_create(sites) + search_backend.cache(sites) + + def test_search(self): + url = reverse('search') + response = self.client.get(url) + self.assertHttpStatus(response, 200) + + def test_search_query(self): url = reverse('search') params = { - 'q': 'foo', + 'q': 'red', } + query = urllib.parse.urlencode(params) - response = self.client.get('{}?{}'.format(url, urllib.parse.urlencode(params))) + # Test without view permission + response = self.client.get(f'{url}?{query}') self.assertHttpStatus(response, 200) + content = str(response.content) + self.assertIn(EMPTY_TABLE_TEXT, content) + + # Add view permissions & query again. Only matching objects should be listed + self.add_permissions('dcim.view_site') + response = self.client.get(f'{url}?{query}') + self.assertHttpStatus(response, 200) + content = str(response.content) + self.assertIn('Site Alpha', content) + self.assertIn('Site Bravo', content) + self.assertNotIn('Site Charlie', content) + self.assertNotIn('Site Delta', content) + self.assertNotIn('Site Echo', content) + self.assertNotIn('Site Foxtrot', content) + + @override_settings(EXEMPT_VIEW_PERMISSIONS=['*']) + def test_search_no_results(self): + url = reverse('search') + params = { + 'q': 'xxxxxxxxx', # Matches nothing + } + query = urllib.parse.urlencode(params) + + response = self.client.get(f'{url}?{query}') + self.assertHttpStatus(response, 200) + content = str(response.content) + self.assertIn(EMPTY_TABLE_TEXT, content)