sql: set ordering only if column exists (#50500)

This commit is contained in:
Lauréline Guérin 2021-02-11 15:03:13 +01:00
parent 19e07a88b1
commit 1831aff4b0
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
2 changed files with 77 additions and 3 deletions

View File

@ -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)

View File

@ -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