Fix bug with extend_params function

The OrganisationAgreementSignedForm class has a
bug causing it to render different HTML when the
page loads to when you subsequently refresh it.

This commit proposes a change to the extend_params
function to fix it.

extend_params, is used by the
OrganisationAgreementSignedForm, as well as all
the other WTForms field classes we added to wrap
GOVUK Frontend components. Fixing it should
therefore fix any similar bugs with them.

All of these fields send a dict of configuration
data to the GOVUK Frontend component when they
call it, at render time. This dict is 'JSON-like',
meaning it's values can be all the primitives as
well as lists and dicts. This also means it can go
quite deep.

Extending the default configuration

The classes have a default dict of this data kept
privately in the params variable. They let you
change it by passing in an argument called
param_extensions on instantiation, after that,
through an attribute of the same name and at
render time as the same argument (in templates).

The extend_params function

The param_extensions dict is used as a collection
of changes to make to the default params dict.
The changes are applied by the extend_params
function. Its code deletes part of the
param_extensions, a side effect that didn't seem a
problem because it isn't used after the function
has run.

The bug

The bug was only with the part of the HTML that
got its data from the part of the param_extensions
dict that was deleted by extend_params. The class
with the bug set param_extensions when the field
is instantiated, as part of its parent form
definition.

My guess is that param_extensions was stored in
memory, as part of the form class, and reused
when the page refreshed. At that point,
extend_params had deleted part of its data,
causing the bug.
This commit is contained in:
Tom Byers
2021-01-14 21:05:23 +00:00
parent 248406938f
commit e06c1f5daa

View File

@@ -649,16 +649,19 @@ def extend_params(params, extensions):
# merge dicts
merge_jsonlike(params, extensions)
# tidy up
extensions['items'] = items
# merge items
if items:
if 'items' not in params:
params['items'] = items
params['items'] = extensions['items']
else:
for idx, _item in enumerate(items):
for idx, _item in enumerate(extensions['items']):
if idx >= param_items:
params['items'].append(items[idx])
params['items'].append(extensions['items'][idx])
else:
params['items'][idx].update(items[idx])
params['items'][idx].update(extensions['items'][idx])
def govuk_checkbox_field_widget(self, field, param_extensions=None, **kwargs):