sql: set ordering only if column exists (#50500)
This commit is contained in:
parent
19e07a88b1
commit
1831aff4b0
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import re
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -467,6 +468,73 @@ def test_backoffice_missing_custom_view(pub):
|
|||
assert resp.location == 'http://example.net/backoffice/management/form-title/1/?plop'
|
||||
|
||||
|
||||
def test_backoffice_custom_view_sort_field(pub):
|
||||
if not pub.is_using_postgresql():
|
||||
pytest.skip('this requires SQL')
|
||||
return
|
||||
|
||||
create_superuser(pub)
|
||||
|
||||
FormDef.wipe()
|
||||
pub.custom_view_class.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'form title'
|
||||
formdef.fields = [
|
||||
fields.ItemField(
|
||||
id='1',
|
||||
label='field 1',
|
||||
type='item',
|
||||
items=['foo', 'bar', 'baz'],
|
||||
display_locations=['validation', 'summary', 'listings'],
|
||||
),
|
||||
]
|
||||
formdef.workflow_roles = {'_receiver': 1}
|
||||
formdef.store()
|
||||
|
||||
formdef.data_class().wipe()
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {'1': 'foo', '1_display': 'foo'}
|
||||
formdata.jump_status('new')
|
||||
formdata.store()
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {'1': 'bar', '1_display': 'bar'}
|
||||
formdata.jump_status('new')
|
||||
formdata.store()
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {'1': 'baz', '1_display': 'baz'}
|
||||
formdata.jump_status('new')
|
||||
formdata.store()
|
||||
|
||||
custom_view = pub.custom_view_class()
|
||||
custom_view.title = 'shared custom test view'
|
||||
custom_view.formdef = formdef
|
||||
custom_view.visibility = 'any'
|
||||
custom_view.columns = {'list': [{'id': 'id'}]}
|
||||
custom_view.filters = {}
|
||||
custom_view.order_by = 'f1'
|
||||
custom_view.is_default = True
|
||||
custom_view.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/management/form-title/shared-custom-test-view/')
|
||||
assert resp.text.count('<tr') == 4
|
||||
# bar, baz, foo
|
||||
assert re.findall(r'<a href="(\d)/">1-(\d)</a>', resp.text) == [('2', '2'), ('3', '3'), ('1', '1')]
|
||||
|
||||
custom_view.order_by = '-f1'
|
||||
custom_view.store()
|
||||
resp = app.get('/backoffice/management/form-title/shared-custom-test-view/')
|
||||
assert resp.text.count('<tr') == 4
|
||||
# foo, baz, bar
|
||||
assert re.findall(r'<a href="(\d)/">1-(\d)</a>', resp.text) == [('1', '1'), ('3', '3'), ('2', '2')]
|
||||
|
||||
custom_view.order_by = 'unknown'
|
||||
custom_view.store()
|
||||
# unknown sort field, ignore it
|
||||
resp = app.get('/backoffice/management/form-title/shared-custom-test-view/')
|
||||
assert resp.text.count('<tr') == 4
|
||||
|
||||
|
||||
def test_carddata_custom_view(pub):
|
||||
user = create_user(pub)
|
||||
|
||||
|
|
12
wcs/sql.py
12
wcs/sql.py
|
@ -1516,11 +1516,17 @@ class SqlMixin(object):
|
|||
# [SEC_ORDER] security note: it is not possible to use
|
||||
# prepared statements for ORDER BY clauses, therefore input
|
||||
# is controlled beforehand (see misc.get_order_by_or_400).
|
||||
direction = 'ASC'
|
||||
if order_by.startswith('-'):
|
||||
order_by = order_by[1:]
|
||||
return ' ORDER BY %s DESC' % order_by.replace('-', '_')
|
||||
else:
|
||||
return ' ORDER BY %s' % order_by.replace('-', '_')
|
||||
direction = 'DESC'
|
||||
order_by = order_by.replace('-', '_')
|
||||
|
||||
fields = [x[0] for x in cls._table_static_fields] + cls.get_data_fields()
|
||||
if order_by not in fields:
|
||||
return ''
|
||||
|
||||
return ' ORDER BY %s %s' % (order_by, direction)
|
||||
|
||||
@classmethod
|
||||
@guard_postgres
|
||||
|
|
Loading…
Reference in New Issue