Correctly handle nulls in ListBlock validation errors

Fixes @cnk's test case from #7248. blockErrors within a ListBlockValidationError is an array (with nulls for the items with no errors), but setError was treating it as a dict keyed by block index, which meant it was erroneously passing nulls to the child setError method. FieldBlock handles this gracefully, but other blocks such as StructBlock don't.
pull/7298/head
Matt Westcott 2021-06-28 18:55:07 +01:00 zatwierdzone przez Matt Westcott
rodzic ac00945d3b
commit fa648116b2
2 zmienionych plików z 28 dodań i 7 usunięć

Wyświetl plik

@ -130,12 +130,13 @@ export class ListBlock extends BaseSequenceBlock {
}
const error = errorList[0];
// eslint-disable-next-line no-restricted-syntax
for (const blockIndex in error.blockErrors) {
if (error.blockErrors.hasOwnProperty(blockIndex)) {
this.children[blockIndex].setError(error.blockErrors[blockIndex]);
// error.blockErrors = a list with the same length as the data,
// with nulls for items without errors
error.blockErrors.forEach((blockError, blockIndex) => {
if (blockError) {
this.children[blockIndex].setError(blockError);
}
}
});
}
}

Wyświetl plik

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { FieldBlockDefinition } from './FieldBlock';
import { FieldBlock, FieldBlockDefinition } from './FieldBlock';
import { ListBlockDefinition, ListBlockValidationError } from './ListBlock';
import $ from 'jquery';
@ -43,6 +43,26 @@ class ValidationError {
}
}
/* ListBlock should not call setError on its children with a null value; FieldBlock handles this
gracefully, so define a custom one that doesn't
*/
class ParanoidFieldBlock extends FieldBlock {
setError(errorList) {
if (!errorList) {
throw new Error('ParanoidFieldBlock.setError was passed a null errorList');
}
return super.setError(errorList);
}
}
class ParanoidFieldBlockDefinition extends FieldBlockDefinition {
render(placeholder, prefix, initialState, initialError) {
return new ParanoidFieldBlock(this, placeholder, prefix, initialState, initialError);
}
}
describe('telepath: wagtail.blocks.ListBlock', () => {
let boundBlock;
@ -57,7 +77,7 @@ describe('telepath: wagtail.blocks.ListBlock', () => {
// Define a test block
const blockDef = new ListBlockDefinition(
'test_listblock',
new FieldBlockDefinition(
new ParanoidFieldBlockDefinition(
'',
new DummyWidgetDefinition('The widget'),
{