diff --git a/mayan/apps/dynamic_search/classes.py b/mayan/apps/dynamic_search/classes.py index a831121a5a..a37d1a3f21 100644 --- a/mayan/apps/dynamic_search/classes.py +++ b/mayan/apps/dynamic_search/classes.py @@ -107,6 +107,38 @@ class SearchModel(object): def __str__(self): return force_text(self.label) + def add_model_field(self, *args, **kwargs): + """ + Add a search field that directly belongs to the parent SearchModel + """ + search_field = SearchField(self, *args, **kwargs) + self.search_fields.append(search_field) + + def get_fields_simple_list(self): + """ + Returns a list of the fields for the SearchModel + """ + result = [] + for search_field in self.search_fields: + result.append((search_field.get_full_name(), search_field.label)) + + return result + + def get_full_name(self): + return '%s.%s' % (self.app_label, self.model_name) + + def get_search_field(self, full_name): + try: + return self.search_fields[full_name] + except KeyError: + raise KeyError('No search field named: %s' % full_name) + + def get_search_query(self, query_string, global_and_search=False): + return SearchQuery( + query_string=query_string, search_model=self, + global_and_search=global_and_search + ) + @property def label(self): if not self._label: @@ -123,38 +155,6 @@ class SearchModel(object): def pk(self): return self.get_full_name() - def add_model_field(self, *args, **kwargs): - """ - Add a search field that directly belongs to the parent SearchModel - """ - search_field = SearchField(self, *args, **kwargs) - self.search_fields.append(search_field) - - def get_full_name(self): - return '%s.%s' % (self.app_label, self.model_name) - - def get_fields_simple_list(self): - """ - Returns a list of the fields for the SearchModel - """ - result = [] - for search_field in self.search_fields: - result.append((search_field.get_full_name(), search_field.label)) - - return result - - def get_search_field(self, full_name): - try: - return self.search_fields[full_name] - except KeyError: - raise KeyError('No search field named: %s' % full_name) - - def get_search_query(self, query_string, global_and_search=False): - return SearchQuery( - query_string=query_string, search_model=self, - global_and_search=global_and_search - ) - def search(self, query_string, user, global_and_search=False): AccessControlList = apps.get_model( app_label='acls', model_name='AccessControlList' @@ -165,18 +165,14 @@ class SearchModel(object): ) queryset = self.model.objects.filter( - pk__in=set( - self.model.objects.filter(search_query.query).values_list( - 'pk', flat=True - )[ - :setting_limit.value - ] - ) + pk__in=self.model.objects.filter(search_query.query).values('pk')[ + :setting_limit.value + ] ) if self.permission: - queryset = AccessControlList.objects.filter_by_access( - permission=self.permission, user=user, queryset=queryset + queryset = AccessControlList.objects.restrict_queryset( + permission=self.permission, queryset=queryset, user=user ) return queryset diff --git a/mayan/apps/dynamic_search/links.py b/mayan/apps/dynamic_search/links.py index 4ef031a533..d23c47d8be 100644 --- a/mayan/apps/dynamic_search/links.py +++ b/mayan/apps/dynamic_search/links.py @@ -5,13 +5,14 @@ from django.utils.translation import ugettext_lazy as _ from mayan.apps.navigation import Link link_search = Link( - text=_('Search'), view='search:search', args='search_model.get_full_name' + kwargs={'search_model': 'search_model.get_full_name'}, text=_('Search'), + view='search:search' ) link_search_advanced = Link( - text=_('Advanced search'), view='search:search_advanced', - args='search_model.get_full_name' + kwargs={'search_model': 'search_model.get_full_name'}, + text=_('Advanced search'), view='search:search_advanced' ) link_search_again = Link( - text=_('Search again'), view='search:search_again', - args='search_model.get_full_name', keep_query=True + kwargs={'search_model': 'search_model.get_full_name'}, keep_query=True, + text=_('Search again'), view='search:search_again' ) diff --git a/mayan/apps/dynamic_search/settings.py b/mayan/apps/dynamic_search/settings.py index eaa47d5036..c6bff778a9 100644 --- a/mayan/apps/dynamic_search/settings.py +++ b/mayan/apps/dynamic_search/settings.py @@ -4,7 +4,8 @@ from django.utils.translation import ugettext_lazy as _ from mayan.apps.smart_settings import Namespace -namespace = Namespace(name='dynamic_search', label=_('Search')) +namespace = Namespace(label=_('Search'), name='dynamic_search') + setting_limit = namespace.add_setting( global_name='SEARCH_LIMIT', default=100, help_text=_('Maximum amount search hits to fetch and display.') diff --git a/mayan/apps/dynamic_search/tests/test_api.py b/mayan/apps/dynamic_search/tests/test_api.py index a47a73b8c4..9af5df8eea 100644 --- a/mayan/apps/dynamic_search/tests/test_api.py +++ b/mayan/apps/dynamic_search/tests/test_api.py @@ -23,9 +23,9 @@ class SearchAPITestCase(DocumentTestMixin, BaseAPITestCase): return self.get( path='{}?q={}'.format( reverse( - 'rest_api:search-view', args=( - document_search.get_full_name(), - ) + viewname='rest_api:search-view', kwargs={ + 'search_model': document_search.get_full_name() + } ), self.document.label ) ) diff --git a/mayan/apps/dynamic_search/tests/test_models.py b/mayan/apps/dynamic_search/tests/test_models.py index 38b1afac0a..c84c44e17d 100644 --- a/mayan/apps/dynamic_search/tests/test_models.py +++ b/mayan/apps/dynamic_search/tests/test_models.py @@ -9,6 +9,8 @@ from mayan.apps.documents.tests import ( class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase): auto_upload_document = False + create_test_case_superuser = True + create_test_case_user = False test_document_filename = TEST_DOCUMENT_FILENAME def test_simple_search_after_related_name_change(self): @@ -18,7 +20,7 @@ class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase): """ self.document = self.upload_document() queryset = document_search.search( - {'q': 'Mayan'}, user=self.admin_user + {'q': 'Mayan'}, user=self._test_case_superuser ) self.assertEqual(queryset.count(), 1) self.assertTrue(self.document in queryset) @@ -27,7 +29,7 @@ class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase): # Test versions__filename self.document = self.upload_document() queryset = document_search.search( - {'label': self.document.label}, user=self.admin_user + {'label': self.document.label}, user=self._test_case_superuser ) self.assertEqual(queryset.count(), 1) self.assertTrue(self.document in queryset) @@ -35,7 +37,7 @@ class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase): # Test versions__mimetype queryset = document_search.search( {'versions__mimetype': self.document.file_mimetype}, - user=self.admin_user + user=self._test_case_superuser ) self.assertEqual(queryset.count(), 1) self.assertTrue(self.document in queryset) @@ -48,7 +50,7 @@ class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase): self.document_2.save() queryset = document_search.search( - {'q': 'Mayan OR second'}, user=self.admin_user + {'q': 'Mayan OR second'}, user=self._test_case_superuser ) self.assertEqual(queryset.count(), 2) self.assertTrue(self.document in queryset) @@ -61,12 +63,12 @@ class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase): self.document_2.save() queryset = document_search.search( - {'q': 'non_valid second'}, user=self.admin_user + {'q': 'non_valid second'}, user=self._test_case_superuser ) self.assertEqual(queryset.count(), 0) queryset = document_search.search( - {'q': 'second non_valid'}, user=self.admin_user + {'q': 'second non_valid'}, user=self._test_case_superuser ) self.assertEqual(queryset.count(), 0) @@ -77,26 +79,26 @@ class DocumentSearchTestCase(DocumentTestMixin, BaseTestCase): self.document_2.save() queryset = document_search.search( - {'q': '-non_valid second'}, user=self.admin_user + {'q': '-non_valid second'}, user=self._test_case_superuser ) self.assertEqual(queryset.count(), 1) queryset = document_search.search( - {'label': '-second'}, user=self.admin_user + {'label': '-second'}, user=self._test_case_superuser ) self.assertEqual(queryset.count(), 0) queryset = document_search.search( - {'label': '-second -Mayan'}, user=self.admin_user + {'label': '-second -Mayan'}, user=self._test_case_superuser ) self.assertEqual(queryset.count(), 0) queryset = document_search.search( - {'label': '-second OR -Mayan'}, user=self.admin_user + {'label': '-second OR -Mayan'}, user=self._test_case_superuser ) self.assertEqual(queryset.count(), 1) queryset = document_search.search( - {'label': '-non_valid -second'}, user=self.admin_user + {'label': '-non_valid -second'}, user=self._test_case_superuser ) self.assertEqual(queryset.count(), 0) diff --git a/mayan/apps/dynamic_search/tests/test_views.py b/mayan/apps/dynamic_search/tests/test_views.py index 6319ae1faa..43bd7f4f59 100644 --- a/mayan/apps/dynamic_search/tests/test_views.py +++ b/mayan/apps/dynamic_search/tests/test_views.py @@ -1,44 +1,32 @@ from __future__ import unicode_literals from mayan.apps.common.tests import GenericViewTestCase -from mayan.apps.documents.models import DocumentType from mayan.apps.documents.search import document_search -from mayan.apps.documents.tests import ( - TEST_DOCUMENT_TYPE_LABEL, TEST_SMALL_DOCUMENT_PATH -) +from mayan.apps.documents.tests import DocumentTestMixin -class Issue46TestCase(GenericViewTestCase): +class Issue46TestCase(DocumentTestMixin, GenericViewTestCase): """ Functional tests to make sure issue 46 is fixed """ + auto_upload_document = False + auto_login_superuser = True + create_test_case_superuser = True + create_test_case_user = False + def setUp(self): super(Issue46TestCase, self).setUp() - self.login_admin_user() self.document_count = 4 - self.document_type = DocumentType.objects.create( - label=TEST_DOCUMENT_TYPE_LABEL - ) - # Upload many instances of the same test document for i in range(self.document_count): - with open(TEST_SMALL_DOCUMENT_PATH, mode='rb') as file_object: - self.document_type.new_document( - file_object=file_object, - label='test document', - ) - - def tearDown(self): - for document_type in DocumentType.objects.all(): - document_type.delete() - super(Issue46TestCase, self).tearDown() + self.test_document = self.upload_document() def test_advanced_search_past_first_page(self): # Make sure all documents are returned by the search queryset = document_search.search( - {'label': 'test document'}, user=self.admin_user + {'label': self.test_document.label}, user=self._test_case_superuser ) self.assertEqual(queryset.count(), self.document_count) @@ -46,7 +34,7 @@ class Issue46TestCase(GenericViewTestCase): # Functional test for the first page of advanced results response = self.get( viewname='search:results', - args=(document_search.get_full_name(),), + kwargs={'search_model': document_search.get_full_name()}, data={'label': 'test'} ) @@ -66,7 +54,7 @@ class Issue46TestCase(GenericViewTestCase): # Functional test for the second page of advanced results response = self.get( viewname='search:results', - args=(document_search.get_full_name(),), + kwargs={'search_model': document_search.get_full_name()}, data={'label': 'test', 'page': 2} ) diff --git a/mayan/apps/dynamic_search/urls.py b/mayan/apps/dynamic_search/urls.py index c19b27a663..a2fd2eb969 100644 --- a/mayan/apps/dynamic_search/urls.py +++ b/mayan/apps/dynamic_search/urls.py @@ -6,32 +6,35 @@ from .api_views import APIAdvancedSearchView, APISearchModelList, APISearchView from .views import AdvancedSearchView, ResultsView, SearchAgainView, SearchView urlpatterns = [ - url(r'^(?P[\.\w]+)/$', SearchView.as_view(), name='search'), url( - r'^advanced/(?P[\.\w]+)/$', AdvancedSearchView.as_view(), - name='search_advanced' + regex=r'^(?P[\.\w]+)/$', name='search', + view=SearchView.as_view() ), url( - r'^again/(?P[\.\w]+)/$', SearchAgainView.as_view(), - name='search_again' + regex=r'^advanced/(?P[\.\w]+)/$', name='search_advanced', + view=AdvancedSearchView.as_view() ), url( - r'^results/(?P[\.\w]+)/$', ResultsView.as_view(), - name='results' + regex=r'^again/(?P[\.\w]+)/$', name='search_again', + view=SearchAgainView.as_view() ), + url( + regex=r'^results/(?P[\.\w]+)/$', name='results', + view=ResultsView.as_view() + ) ] api_urls = [ url( - r'^search_models/$', APISearchModelList.as_view(), - name='searchmodel-list' + regex=r'^search_models/$', name='searchmodel-list', + view=APISearchModelList.as_view() ), url( - r'^search/(?P[\.\w]+)/$', APISearchView.as_view(), - name='search-view' + regex=r'^search/(?P[\.\w]+)/$', name='search-view', + view=APISearchView.as_view() ), url( - r'^search/advanced/(?P[\.\w]+)/$', APIAdvancedSearchView.as_view(), - name='advanced-search-view' + regex=r'^search/advanced/(?P[\.\w]+)/$', + name='advanced-search-view', view=APIAdvancedSearchView.as_view() ), ] diff --git a/mayan/apps/dynamic_search/views.py b/mayan/apps/dynamic_search/views.py index 6fc08a179e..5a475ce8ea 100644 --- a/mayan/apps/dynamic_search/views.py +++ b/mayan/apps/dynamic_search/views.py @@ -47,7 +47,8 @@ class ResultsView(SearchModelMixin, SingleObjectListView): global_and_search = False return self.search_model.get_search_query( - query_string=self.request.GET, global_and_search=global_and_search + global_and_search=global_and_search, + query_string=self.request.GET ) def get_object_list(self): @@ -63,8 +64,8 @@ class ResultsView(SearchModelMixin, SingleObjectListView): global_and_search = False queryset = self.search_model.search( - query_string=self.request.GET, user=self.request.user, - global_and_search=global_and_search + global_and_search=global_and_search, + query_string=self.request.GET, user=self.request.user ) return queryset @@ -79,7 +80,9 @@ class SearchView(SearchModelMixin, SimpleView): return { 'form': self.get_form(), 'form_action': reverse( - 'search:results', args=(self.search_model.get_full_name(),) + viewname='search:results', kwargs={ + 'search_model': self.search_model.get_full_name() + } ), 'search_model': self.search_model, 'submit_icon_class': icon_search_submit,