search: title for search cell (#57323)
This commit is contained in:
parent
8e577d006f
commit
bee691aa15
|
@ -27,7 +27,7 @@ from .models import SearchCell
|
||||||
class SearchCellForm(forms.ModelForm):
|
class SearchCellForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SearchCell
|
model = SearchCell
|
||||||
fields = ('autofocus', 'input_placeholder')
|
fields = ('title', 'autofocus', 'input_placeholder')
|
||||||
|
|
||||||
|
|
||||||
class SelectWithDisabled(forms.Select):
|
class SelectWithDisabled(forms.Select):
|
||||||
|
|
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -53,6 +53,7 @@ class SearchCell(CellBase):
|
||||||
exclude_from_search = True
|
exclude_from_search = True
|
||||||
|
|
||||||
_search_services = JSONField(_('Search Services'), default=dict, blank=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)
|
autofocus = models.BooleanField(_('Autofocus'), default=False)
|
||||||
input_placeholder = models.CharField(_('Placeholder'), max_length=64, default="", blank=True)
|
input_placeholder = models.CharField(_('Placeholder'), max_length=64, default="", blank=True)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block cell-content %}
|
{% block cell-content %}
|
||||||
|
{% if cell.title %}
|
||||||
|
<h2>{{ cell.title }}</h2>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% block search-form %}
|
{% block search-form %}
|
||||||
<form id="combo-search-form-{{ cell.pk }}" class="combo-search-form">
|
<form id="combo-search-form-{{ cell.pk }}" class="combo-search-form">
|
||||||
|
|
|
@ -57,7 +57,8 @@ class SearchServices:
|
||||||
settings.COMBO_SEARCH_SERVICES = {}
|
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 = Page(title='Search', slug='search_page', template_name='standard')
|
||||||
page.save()
|
page.save()
|
||||||
|
|
||||||
|
@ -69,105 +70,103 @@ def test_search_cell(app):
|
||||||
# unknown cell pk
|
# unknown cell pk
|
||||||
resp = app.get('/ajax/search/0/search1/?q=foo', status=404)
|
resp = app.get('/ajax/search/0/search1/?q=foo', status=404)
|
||||||
|
|
||||||
with SearchServices(SEARCH_SERVICES):
|
resp = cell.render({})
|
||||||
resp = cell.render({})
|
assert 'input' in resp
|
||||||
assert 'input' in resp
|
assert 'id="combo-search-input-%s"' % cell.pk in resp
|
||||||
assert 'id="combo-search-input-%s"' % cell.pk in resp
|
assert 'autofocus' not in resp
|
||||||
assert 'autofocus' not in resp
|
assert 'placeholder="my placeholder"' 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 '<h2>Custom Title</h2>' 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 '<li>' 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 '<li>' 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('<li>') == 1
|
||||||
|
assert '<li><a href="http://test">barbarbar</a>' in resp.text
|
||||||
|
assert 'no result found' not in resp.text
|
||||||
|
|
||||||
|
response['data'] = [{'url': 'http://test', 'text': 'barbarbar', 'description': 'this is <b>html</b>'}]
|
||||||
|
resp = app.get('/ajax/search/%s/search1/?q=foo' % cell.pk, status=200)
|
||||||
|
assert resp.text.count('<li>') == 1
|
||||||
|
assert '<li><a href="http://test">barbarbar</a>' in resp.text
|
||||||
|
assert 'this is <b>html</b>' in resp.text
|
||||||
|
assert 'no result found' not in resp.text
|
||||||
|
|
||||||
|
resp = app.get('/ajax/search/%s/search1/?q=' % cell.pk, status=200)
|
||||||
|
assert '<li>' not in resp.text
|
||||||
|
assert 'no result found' not in resp.text
|
||||||
|
|
||||||
|
cell._search_services = {'data': ['search_alternate_key']}
|
||||||
cell.save()
|
cell.save()
|
||||||
resp = cell.render({})
|
response = {'results': [{'url': 'http://test', 'text': 'barbarbar'}]}
|
||||||
assert 'autofocus' in resp
|
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('<li>') == 1
|
||||||
|
assert '<li><a href="http://test">barbarbar</a>' in resp.text
|
||||||
|
|
||||||
cell.slug = 'var-name'
|
# search engine does not return valid JSON
|
||||||
context = {'request': RequestFactory().get('/?q_var_name=searchme')}
|
class FakedResponse(mock.Mock):
|
||||||
resp = cell.render(context)
|
def json(self):
|
||||||
assert "$input.val('searchme');" in resp
|
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 '<li>' 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 '<li>' not in resp.text
|
||||||
|
assert 'no result found' in resp.text
|
||||||
|
|
||||||
response = {'err': 0, 'data': []}
|
settings.TEMPLATE_VARS = TEMPLATE_VARS
|
||||||
mock_json = mock.Mock()
|
cell._search_services = {'data': ['search_tmpl']}
|
||||||
mock_json.json.return_value = response
|
cell.save()
|
||||||
requests_get.return_value = mock_json
|
with mock.patch('combo.apps.search.models.requests.get') as requests_get:
|
||||||
resp = app.get('/ajax/search/%s/search1/?q=foo' % cell.pk, status=200)
|
response = {'err': 0, 'data': []}
|
||||||
assert requests_get.call_args[0][0] == 'http://www.example.net/search/?q=foo'
|
mock_json = mock.Mock()
|
||||||
assert '<li>' not in resp.text
|
mock_json.json.return_value = response
|
||||||
assert 'no result found' in resp.text
|
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)
|
# TEMPLATE_VARS are accessible in template
|
||||||
assert requests_get.call_args[0][0] == 'http://www.example.net/search/?q=foo%23bar'
|
cell.slug = 'searchfoo'
|
||||||
assert '<li>' not in resp.text
|
cell.save()
|
||||||
assert 'no result found' in resp.text
|
templates_settings = [settings.TEMPLATES[0].copy()]
|
||||||
|
templates_settings[0]['DIRS'] = ['%s/templates-1' % os.path.abspath(os.path.dirname(__file__))]
|
||||||
response['data'] = [{'url': 'http://test', 'text': 'barbarbar'}]
|
with override_settings(TEMPLATES=templates_settings):
|
||||||
resp = app.get('/ajax/search/%s/search1/?q=foo' % cell.pk, status=200)
|
resp = app.get('/ajax/search/%s/search_tmpl/?q=bar' % cell.pk, status=200)
|
||||||
assert resp.text.count('<li>') == 1
|
assert requests_get.call_args[0][0] == 'http://search.example.net/?q=bar'
|
||||||
assert '<li><a href="http://test">barbarbar</a>' in resp.text
|
assert 'searchfoo results.data=[]' in resp.text
|
||||||
assert 'no result found' not in resp.text
|
assert 'search_url=http://search.example.net/' in resp.text
|
||||||
|
|
||||||
response['data'] = [
|
|
||||||
{'url': 'http://test', 'text': 'barbarbar', 'description': 'this is <b>html</b>'}
|
|
||||||
]
|
|
||||||
resp = app.get('/ajax/search/%s/search1/?q=foo' % cell.pk, status=200)
|
|
||||||
assert resp.text.count('<li>') == 1
|
|
||||||
assert '<li><a href="http://test">barbarbar</a>' in resp.text
|
|
||||||
assert 'this is <b>html</b>' in resp.text
|
|
||||||
assert 'no result found' not in resp.text
|
|
||||||
|
|
||||||
resp = app.get('/ajax/search/%s/search1/?q=' % cell.pk, status=200)
|
|
||||||
assert '<li>' 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('<li>') == 1
|
|
||||||
assert '<li><a href="http://test">barbarbar</a>' 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 '<li>' 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 '<li>' 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
|
|
||||||
|
|
||||||
|
|
||||||
def test_search_cell_urlsplit(settings, app):
|
def test_search_cell_urlsplit(settings, app):
|
||||||
|
|
Loading…
Reference in New Issue