diff --git a/combo/apps/search/forms.py b/combo/apps/search/forms.py index 44735c67..a3f47acf 100644 --- a/combo/apps/search/forms.py +++ b/combo/apps/search/forms.py @@ -27,7 +27,7 @@ from .models import SearchCell class SearchCellForm(forms.ModelForm): class Meta: model = SearchCell - fields = ('autofocus', 'input_placeholder') + fields = ('title', 'autofocus', 'input_placeholder') class SelectWithDisabled(forms.Select): diff --git a/combo/apps/search/migrations/0011_title.py b/combo/apps/search/migrations/0011_title.py new file mode 100644 index 00000000..24dadcef --- /dev/null +++ b/combo/apps/search/migrations/0011_title.py @@ -0,0 +1,16 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('search', '0010_searchcell_template_name'), + ] + + operations = [ + migrations.AddField( + model_name='searchcell', + name='title', + field=models.CharField(blank=True, max_length=150, verbose_name='Title'), + ), + ] diff --git a/combo/apps/search/models.py b/combo/apps/search/models.py index 0fae2505..c11ba844 100644 --- a/combo/apps/search/models.py +++ b/combo/apps/search/models.py @@ -53,6 +53,7 @@ class SearchCell(CellBase): exclude_from_search = True _search_services = JSONField(_('Search Services'), default=dict, blank=True) + title = models.CharField(_('Title'), max_length=150, blank=True) autofocus = models.BooleanField(_('Autofocus'), default=False) input_placeholder = models.CharField(_('Placeholder'), max_length=64, default="", blank=True) diff --git a/combo/apps/search/templates/combo/search-cell.html b/combo/apps/search/templates/combo/search-cell.html index ddf08298..68126676 100644 --- a/combo/apps/search/templates/combo/search-cell.html +++ b/combo/apps/search/templates/combo/search-cell.html @@ -1,5 +1,8 @@ {% load i18n %} {% block cell-content %} +{% if cell.title %} +

{{ cell.title }}

+{% endif %} {% block search-form %}
diff --git a/tests/test_search.py b/tests/test_search.py index 83ce2685..8b2f0797 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -57,7 +57,8 @@ class SearchServices: settings.COMBO_SEARCH_SERVICES = {} -def test_search_cell(app): +def test_search_cell(settings, app): + settings.COMBO_SEARCH_SERVICES = SEARCH_SERVICES page = Page(title='Search', slug='search_page', template_name='standard') page.save() @@ -69,105 +70,103 @@ def test_search_cell(app): # unknown cell pk resp = app.get('/ajax/search/0/search1/?q=foo', status=404) - with SearchServices(SEARCH_SERVICES): - resp = cell.render({}) - assert 'input' in resp - assert 'id="combo-search-input-%s"' % cell.pk in resp - assert 'autofocus' not in resp - assert 'placeholder="my placeholder"' in resp + resp = cell.render({}) + assert 'input' in resp + assert 'id="combo-search-input-%s"' % cell.pk in resp + assert 'autofocus' not in resp + assert 'placeholder="my placeholder"' in resp - cell.autofocus = True + cell.autofocus = True + cell.save() + resp = cell.render({}) + assert 'h2' not in resp + assert 'autofocus' in resp + + cell.slug = 'var-name' + cell.title = 'Custom Title' + context = {'request': RequestFactory().get('/?q_var_name=searchme')} + resp = cell.render(context) + assert '

Custom Title

' in resp + assert "$input.val('searchme');" in resp + + with mock.patch('combo.apps.search.models.requests.get') as requests_get: + + response = {'err': 0, 'data': []} + mock_json = mock.Mock() + mock_json.json.return_value = response + requests_get.return_value = mock_json + resp = app.get('/ajax/search/%s/search1/?q=foo' % cell.pk, status=200) + assert requests_get.call_args[0][0] == 'http://www.example.net/search/?q=foo' + assert '
  • ' not in resp.text + assert 'no result found' in resp.text + + resp = app.get('/ajax/search/%s/search1/?q=foo%%23bar' % cell.pk, status=200) + assert requests_get.call_args[0][0] == 'http://www.example.net/search/?q=foo%23bar' + assert '
  • ' not in resp.text + assert 'no result found' in resp.text + + response['data'] = [{'url': 'http://test', 'text': 'barbarbar'}] + resp = app.get('/ajax/search/%s/search1/?q=foo' % cell.pk, status=200) + assert resp.text.count('
  • ') == 1 + assert '
  • barbarbar' in resp.text + assert 'no result found' not in resp.text + + response['data'] = [{'url': 'http://test', 'text': 'barbarbar', 'description': 'this is html'}] + resp = app.get('/ajax/search/%s/search1/?q=foo' % cell.pk, status=200) + assert resp.text.count('
  • ') == 1 + assert '
  • barbarbar' in resp.text + assert 'this is html' in resp.text + assert 'no result found' not in resp.text + + resp = app.get('/ajax/search/%s/search1/?q=' % cell.pk, status=200) + assert '
  • ' not in resp.text + assert 'no result found' not in resp.text + + cell._search_services = {'data': ['search_alternate_key']} cell.save() - resp = cell.render({}) - assert 'autofocus' in resp + response = {'results': [{'url': 'http://test', 'text': 'barbarbar'}]} + mock_json.json.return_value = response + resp = app.get('/ajax/search/%s/search_alternate_key/?q=foo' % cell.pk, status=200) + assert resp.text.count('
  • ') == 1 + assert '
  • barbarbar' in resp.text - cell.slug = 'var-name' - context = {'request': RequestFactory().get('/?q_var_name=searchme')} - resp = cell.render(context) - assert "$input.val('searchme');" in resp + # search engine does not return valid JSON + class FakedResponse(mock.Mock): + def json(self): + return json.loads(self.content) - with mock.patch('combo.apps.search.models.requests.get') as requests_get: + requests_get.return_value = FakedResponse(content='notjson', status_code=200) + resp = app.get('/ajax/search/%s/search_alternate_key/?q=bar' % cell.pk, status=200) + assert requests_get.call_args[0][0] == 'http://www.example.net/search/?q=bar' + assert '
  • ' not in resp.text + assert 'no result found' in resp.text + requests_get.return_value = FakedResponse(content='500withbadjson', status_code=500) + resp = app.get('/ajax/search/%s/search_alternate_key/?q=foo' % cell.pk, status=200) + assert requests_get.call_args[0][0] == 'http://www.example.net/search/?q=foo' + assert '
  • ' not in resp.text + assert 'no result found' in resp.text - response = {'err': 0, 'data': []} - mock_json = mock.Mock() - mock_json.json.return_value = response - requests_get.return_value = mock_json - resp = app.get('/ajax/search/%s/search1/?q=foo' % cell.pk, status=200) - assert requests_get.call_args[0][0] == 'http://www.example.net/search/?q=foo' - assert '
  • ' not in resp.text - assert 'no result found' in resp.text + settings.TEMPLATE_VARS = TEMPLATE_VARS + cell._search_services = {'data': ['search_tmpl']} + cell.save() + with mock.patch('combo.apps.search.models.requests.get') as requests_get: + response = {'err': 0, 'data': []} + mock_json = mock.Mock() + mock_json.json.return_value = response + requests_get.return_value = mock_json + resp = app.get('/ajax/search/%s/search_tmpl/?q=foo' % cell.pk, status=200) + assert requests_get.call_args[0][0] == 'http://search.example.net/?q=foo' - resp = app.get('/ajax/search/%s/search1/?q=foo%%23bar' % cell.pk, status=200) - assert requests_get.call_args[0][0] == 'http://www.example.net/search/?q=foo%23bar' - assert '
  • ' not in resp.text - assert 'no result found' in resp.text - - response['data'] = [{'url': 'http://test', 'text': 'barbarbar'}] - resp = app.get('/ajax/search/%s/search1/?q=foo' % cell.pk, status=200) - assert resp.text.count('
  • ') == 1 - assert '
  • barbarbar' in resp.text - assert 'no result found' not in resp.text - - response['data'] = [ - {'url': 'http://test', 'text': 'barbarbar', 'description': 'this is html'} - ] - resp = app.get('/ajax/search/%s/search1/?q=foo' % cell.pk, status=200) - assert resp.text.count('
  • ') == 1 - assert '
  • barbarbar' in resp.text - assert 'this is html' in resp.text - assert 'no result found' not in resp.text - - resp = app.get('/ajax/search/%s/search1/?q=' % cell.pk, status=200) - assert '
  • ' not in resp.text - assert 'no result found' not in resp.text - - cell._search_services = {'data': ['search_alternate_key']} - cell.save() - response = {'results': [{'url': 'http://test', 'text': 'barbarbar'}]} - mock_json.json.return_value = response - resp = app.get('/ajax/search/%s/search_alternate_key/?q=foo' % cell.pk, status=200) - assert resp.text.count('
  • ') == 1 - assert '
  • barbarbar' in resp.text - - # search engine does not return valid JSON - class FakedResponse(mock.Mock): - def json(self): - return json.loads(self.content) - - requests_get.return_value = FakedResponse(content='notjson', status_code=200) - resp = app.get('/ajax/search/%s/search_alternate_key/?q=bar' % cell.pk, status=200) - assert requests_get.call_args[0][0] == 'http://www.example.net/search/?q=bar' - assert '
  • ' not in resp.text - assert 'no result found' in resp.text - requests_get.return_value = FakedResponse(content='500withbadjson', status_code=500) - resp = app.get('/ajax/search/%s/search_alternate_key/?q=foo' % cell.pk, status=200) - assert requests_get.call_args[0][0] == 'http://www.example.net/search/?q=foo' - assert '
  • ' not in resp.text - assert 'no result found' in resp.text - - with override_settings(TEMPLATE_VARS=TEMPLATE_VARS): - cell._search_services = {'data': ['search_tmpl']} - cell.save() - with mock.patch('combo.apps.search.models.requests.get') as requests_get: - response = {'err': 0, 'data': []} - mock_json = mock.Mock() - mock_json.json.return_value = response - requests_get.return_value = mock_json - resp = app.get('/ajax/search/%s/search_tmpl/?q=foo' % cell.pk, status=200) - assert requests_get.call_args[0][0] == 'http://search.example.net/?q=foo' - - # TEMPLATE_VARS are accessible in template - cell.slug = 'searchfoo' - cell.save() - templates_settings = [settings.TEMPLATES[0].copy()] - templates_settings[0]['DIRS'] = [ - '%s/templates-1' % os.path.abspath(os.path.dirname(__file__)) - ] - with override_settings(TEMPLATES=templates_settings): - resp = app.get('/ajax/search/%s/search_tmpl/?q=bar' % cell.pk, status=200) - assert requests_get.call_args[0][0] == 'http://search.example.net/?q=bar' - assert 'searchfoo results.data=[]' in resp.text - assert 'search_url=http://search.example.net/' in resp.text + # TEMPLATE_VARS are accessible in template + cell.slug = 'searchfoo' + cell.save() + templates_settings = [settings.TEMPLATES[0].copy()] + templates_settings[0]['DIRS'] = ['%s/templates-1' % os.path.abspath(os.path.dirname(__file__))] + with override_settings(TEMPLATES=templates_settings): + resp = app.get('/ajax/search/%s/search_tmpl/?q=bar' % cell.pk, status=200) + assert requests_get.call_args[0][0] == 'http://search.example.net/?q=bar' + assert 'searchfoo results.data=[]' in resp.text + assert 'search_url=http://search.example.net/' in resp.text def test_search_cell_urlsplit(settings, app):