mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-04-09 11:54:14 -04:00
Remove extend_params in favour of merge_jsonlike
A comment on the pull request for this branch pointed out that it's not clear why the 'items' list is deleted and then reassigned in extend_params: https://github.com/alphagov/notifications-admin/pull/3770#pullrequestreview-573067465 The simple reason is that we want to use merge_jsonlike to merge params and param_extensions (passed in as extensions) but merge_jsonlike doesn't merge lists correctly. I realised that if we just make merge_jsonlike merge lists correctly, we can use it for everything extend_params does. This commit does that, and replaces all calls to extend_params with merge_jsonlike. Because extend_params is used across many form field classes, and so many pages, I took the following precautions after making those changes: 1. found every use of param_extensions 2. looked at the merges onto params that each would cause and deduped them to a final list of 6(!) 3. tested pages containing fields from that list 4. added new testcases to the merge_jsonlike tests for any merges that exist in our codebase but not in our tests
This commit is contained in:
@@ -637,33 +637,6 @@ class RegisterUserFromOrgInviteForm(StripWhitespaceForm):
|
||||
auth_type = HiddenField('auth_type', validators=[DataRequired()])
|
||||
|
||||
|
||||
def extend_params(params, extensions):
|
||||
items = None
|
||||
param_items = len(params['items']) if 'items' in params else 0
|
||||
|
||||
# split items off from params to make it a pure dict
|
||||
if 'items' in extensions:
|
||||
items = extensions['items']
|
||||
del extensions['items']
|
||||
|
||||
# merge dicts
|
||||
merge_jsonlike(params, extensions)
|
||||
|
||||
# tidy up
|
||||
extensions['items'] = items
|
||||
|
||||
# merge items
|
||||
if items:
|
||||
if 'items' not in params:
|
||||
params['items'] = extensions['items']
|
||||
else:
|
||||
for idx, _item in enumerate(extensions['items']):
|
||||
if idx >= param_items:
|
||||
params['items'].append(extensions['items'][idx])
|
||||
else:
|
||||
params['items'][idx].update(extensions['items'][idx])
|
||||
|
||||
|
||||
def govuk_checkbox_field_widget(self, field, param_extensions=None, **kwargs):
|
||||
|
||||
# error messages
|
||||
@@ -695,11 +668,11 @@ def govuk_checkbox_field_widget(self, field, param_extensions=None, **kwargs):
|
||||
|
||||
# extend default params with any sent in during instantiation
|
||||
if self.param_extensions:
|
||||
extend_params(params, self.param_extensions)
|
||||
merge_jsonlike(params, self.param_extensions)
|
||||
|
||||
# add any sent in though use in templates
|
||||
if param_extensions:
|
||||
extend_params(params, param_extensions)
|
||||
merge_jsonlike(params, param_extensions)
|
||||
|
||||
return Markup(
|
||||
render_template('forms/fields/checkboxes/macro.njk', params=params))
|
||||
@@ -751,11 +724,11 @@ def govuk_checkboxes_field_widget(self, field, wrap_in_collapsible=False, param_
|
||||
|
||||
# extend default params with any sent in during instantiation
|
||||
if self.param_extensions:
|
||||
extend_params(params, self.param_extensions)
|
||||
merge_jsonlike(params, self.param_extensions)
|
||||
|
||||
# add any sent in though use in templates
|
||||
if param_extensions:
|
||||
extend_params(params, param_extensions)
|
||||
merge_jsonlike(params, param_extensions)
|
||||
|
||||
if wrap_in_collapsible:
|
||||
|
||||
@@ -805,11 +778,11 @@ def govuk_radios_field_widget(self, field, param_extensions=None, **kwargs):
|
||||
|
||||
# extend default params with any sent in during instantiation
|
||||
if self.param_extensions:
|
||||
extend_params(params, self.param_extensions)
|
||||
merge_jsonlike(params, self.param_extensions)
|
||||
|
||||
# add any sent in though use in templates
|
||||
if param_extensions:
|
||||
extend_params(params, param_extensions)
|
||||
merge_jsonlike(params, param_extensions)
|
||||
|
||||
return Markup(
|
||||
render_template('components/radios/template.njk', params=params))
|
||||
|
||||
@@ -616,6 +616,8 @@ def test_get_sample_template_returns_template(template_type):
|
||||
({"a": {"b": "c"}}, {"a": {"e": "f"}}, {"a": {"b": "c", "e": "f"}}),
|
||||
# same key in both dicts, value is a string, destination supercedes source:
|
||||
({"a": "b"}, {"a": "c"}, {"a": "c"}),
|
||||
# nested dict added to new key of dict, additive behaviour:
|
||||
({"a": "b"}, {"c": {"d": "e"}}, {"a": "b", "c": {"d": "e"}}),
|
||||
# lists with same length but different items, destination supercedes source:
|
||||
(["b", "c", "d"], ["b", "e", "f"], ["b", "e", "f"]),
|
||||
# lists in dicts behave as top level lists
|
||||
@@ -626,8 +628,14 @@ def test_get_sample_template_returns_template(template_type):
|
||||
([{"b": "c"}], [{"b": "c"}], [{"b": "c"}]),
|
||||
# if dicts in lists have different values, they are not merged
|
||||
([{"b": "c"}], [{"b": "e"}], [{"b": "e"}]),
|
||||
# if nested dicts in lists have different keys, additive behaviour
|
||||
([{"b": "c"}], [{"d": {"e": "f"}}], [{"b": "c", "d": {"e": "f"}}]),
|
||||
# merge a dict with a null object returns that dict (does not work the other way round)
|
||||
({"a": {"b": "c"}}, None, {"a": {"b": "c"}})
|
||||
({"a": {"b": "c"}}, None, {"a": {"b": "c"}}),
|
||||
# double nested dicts, new adds new Boolean key: value, additive behaviour
|
||||
({"a": {"b": {"c": "d"}}}, {"a": {"b": {"e": True}}}, {"a": {"b": {"c": "d", "e": True}}}),
|
||||
# double nested dicts, both have same key, different values, destination supercedes source
|
||||
({"a": {"b": {"c": "d"}}}, {"a": {"b": {"c": "e"}}}, {"a": {"b": {"c": "e"}}})
|
||||
])
|
||||
def test_merge_jsonlike_merges_jsonlike_objects_correctly(source_object, destination_object, expected_result):
|
||||
merge_jsonlike(source_object, destination_object)
|
||||
|
||||
Reference in New Issue
Block a user