mirror of
https://github.com/apache/superset.git
synced 2026-05-12 19:35:17 +00:00
fix: Clear database form errors (#36854)
This commit is contained in:
committed by
GitHub
parent
d4ba44fce2
commit
85e830de46
@@ -1585,6 +1585,87 @@ describe('DatabaseModal', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('handleChangeWithValidation function clears validation errors when called', () => {
|
||||
const mockSetValidationErrors = jest.fn();
|
||||
const mockSetHasValidated = jest.fn();
|
||||
const mockClearError = jest.fn();
|
||||
const mockOnChange = jest.fn();
|
||||
|
||||
// Test the handleClearValidationErrors function directly
|
||||
const handleClearValidationErrors = jest.fn(() => {
|
||||
mockSetValidationErrors(null);
|
||||
mockSetHasValidated(false);
|
||||
mockClearError();
|
||||
});
|
||||
|
||||
// Test the handleChangeWithValidation function behavior
|
||||
const handleChangeWithValidation = (actionType: any, payload: any) => {
|
||||
mockOnChange(actionType, payload);
|
||||
handleClearValidationErrors();
|
||||
};
|
||||
|
||||
// Simulate calling handleChangeWithValidation as would happen in form changes
|
||||
handleChangeWithValidation('TextChange', {
|
||||
name: 'database_name',
|
||||
value: 'test',
|
||||
});
|
||||
|
||||
expect(mockOnChange).toHaveBeenCalledWith('TextChange', {
|
||||
name: 'database_name',
|
||||
value: 'test',
|
||||
});
|
||||
expect(handleClearValidationErrors).toHaveBeenCalled();
|
||||
expect(mockSetValidationErrors).toHaveBeenCalledWith(null);
|
||||
expect(mockSetHasValidated).toHaveBeenCalledWith(false);
|
||||
expect(mockClearError).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('validates fix by testing all form field types clear validation errors', () => {
|
||||
// This test validates that all the different types of form fields changed in the fix
|
||||
// (TextChange, ExtraInputChange, ExtraEditorChange, InputChange, ParametersChange, etc.)
|
||||
// properly call the validation clearing functions
|
||||
const mockSetValidationErrors = jest.fn();
|
||||
const mockSetHasValidated = jest.fn();
|
||||
const mockClearError = jest.fn();
|
||||
|
||||
const handleClearValidationErrors = () => {
|
||||
mockSetValidationErrors(null);
|
||||
mockSetHasValidated(false);
|
||||
mockClearError();
|
||||
};
|
||||
|
||||
const handleChangeWithValidation = (actionType: any, payload: any) => {
|
||||
handleClearValidationErrors();
|
||||
};
|
||||
|
||||
// Test all the action types that were modified in the fix to use handleChangeWithValidation
|
||||
const actionTypesToTest = [
|
||||
'TextChange',
|
||||
'ExtraInputChange',
|
||||
'ExtraEditorChange',
|
||||
'InputChange',
|
||||
'ParametersChange',
|
||||
'QueryChange',
|
||||
'EncryptedExtraInputChange',
|
||||
'EditorChange',
|
||||
];
|
||||
|
||||
actionTypesToTest.forEach((actionType, index) => {
|
||||
handleChangeWithValidation(actionType, { name: 'test', value: 'test' });
|
||||
|
||||
// Verify each call cleared validation errors
|
||||
expect(mockSetValidationErrors).toHaveBeenNthCalledWith(index + 1, null);
|
||||
expect(mockSetHasValidated).toHaveBeenNthCalledWith(index + 1, false);
|
||||
expect(mockClearError).toHaveBeenCalledTimes(index + 1);
|
||||
});
|
||||
|
||||
expect(mockSetValidationErrors).toHaveBeenCalledTimes(
|
||||
actionTypesToTest.length,
|
||||
);
|
||||
expect(mockSetHasValidated).toHaveBeenCalledTimes(actionTypesToTest.length);
|
||||
expect(mockClearError).toHaveBeenCalledTimes(actionTypesToTest.length);
|
||||
});
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals -- TODO: Migrate from describe blocks
|
||||
describe('dbReducer', () => {
|
||||
test('it will reset state to null', () => {
|
||||
|
||||
@@ -776,7 +776,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
||||
setValidationErrors(null);
|
||||
setHasValidated(false);
|
||||
clearError();
|
||||
}, [setValidationErrors, setHasValidated]);
|
||||
}, [setValidationErrors, setHasValidated, clearError]);
|
||||
|
||||
const handleParametersChange = useCallback(
|
||||
({ target }: { target: HTMLInputElement }) => {
|
||||
@@ -790,6 +790,17 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
||||
[onChange],
|
||||
);
|
||||
|
||||
const handleChangeWithValidation = useCallback(
|
||||
(
|
||||
actionType: ActionType,
|
||||
payload: CustomTextType | DBReducerPayloadType,
|
||||
) => {
|
||||
onChange(actionType, payload);
|
||||
handleClearValidationErrors();
|
||||
},
|
||||
[onChange, handleClearValidationErrors],
|
||||
);
|
||||
|
||||
const onClose = () => {
|
||||
setDB({ type: ActionType.Reset });
|
||||
setHasConnectedDb(false);
|
||||
@@ -1757,13 +1768,13 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
||||
setDB({ type: ActionType.AddTableCatalogSheet });
|
||||
}}
|
||||
onQueryChange={({ target }: { target: HTMLInputElement }) =>
|
||||
onChange(ActionType.QueryChange, {
|
||||
handleChangeWithValidation(ActionType.QueryChange, {
|
||||
name: target.name,
|
||||
value: target.value,
|
||||
})
|
||||
}
|
||||
onExtraInputChange={({ target }: { target: HTMLInputElement }) =>
|
||||
onChange(ActionType.ExtraInputChange, {
|
||||
handleChangeWithValidation(ActionType.ExtraInputChange, {
|
||||
name: target.name,
|
||||
value: target.value,
|
||||
})
|
||||
@@ -1773,7 +1784,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
||||
}: {
|
||||
target: HTMLInputElement;
|
||||
}) =>
|
||||
onChange(ActionType.EncryptedExtraInputChange, {
|
||||
handleChangeWithValidation(ActionType.EncryptedExtraInputChange, {
|
||||
name: target.name,
|
||||
value: target.value,
|
||||
})
|
||||
@@ -1786,7 +1797,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
||||
}}
|
||||
onParametersChange={handleParametersChange}
|
||||
onChange={({ target }: { target: HTMLInputElement }) =>
|
||||
onChange(ActionType.TextChange, {
|
||||
handleChangeWithValidation(ActionType.TextChange, {
|
||||
name: target.name,
|
||||
value: target.value,
|
||||
})
|
||||
@@ -1812,7 +1823,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
||||
e: CheckboxChangeEvent | React.ChangeEvent<HTMLInputElement>,
|
||||
) => {
|
||||
const { target } = e;
|
||||
onChange(ActionType.InputChange, {
|
||||
handleChangeWithValidation(ActionType.InputChange, {
|
||||
type: target.type,
|
||||
name: target.name,
|
||||
checked: 'checked' in target ? target.checked : false,
|
||||
@@ -1820,19 +1831,19 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
||||
});
|
||||
}}
|
||||
onTextChange={({ target }: { target: HTMLTextAreaElement }) =>
|
||||
onChange(ActionType.TextChange, {
|
||||
handleChangeWithValidation(ActionType.TextChange, {
|
||||
name: target.name,
|
||||
value: target.value,
|
||||
})
|
||||
}
|
||||
onEditorChange={(payload: { name: string; json: any }) =>
|
||||
onChange(ActionType.EditorChange, payload)
|
||||
handleChangeWithValidation(ActionType.EditorChange, payload)
|
||||
}
|
||||
onExtraInputChange={(
|
||||
e: CheckboxChangeEvent | React.ChangeEvent<HTMLInputElement>,
|
||||
) => {
|
||||
const { target } = e;
|
||||
onChange(ActionType.ExtraInputChange, {
|
||||
handleChangeWithValidation(ActionType.ExtraInputChange, {
|
||||
type: target.type,
|
||||
name: target.name,
|
||||
checked: 'checked' in target ? target.checked : false,
|
||||
@@ -1840,7 +1851,7 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
||||
});
|
||||
}}
|
||||
onExtraEditorChange={(payload: { name: string; json: any }) =>
|
||||
onChange(ActionType.ExtraEditorChange, payload)
|
||||
handleChangeWithValidation(ActionType.ExtraEditorChange, payload)
|
||||
}
|
||||
/>
|
||||
);
|
||||
@@ -2059,36 +2070,39 @@ const DatabaseModal: FunctionComponent<DatabaseModalProps> = ({
|
||||
db={db as DatabaseObject}
|
||||
onInputChange={(e: CheckboxChangeEvent) => {
|
||||
const { target } = e;
|
||||
onChange(ActionType.InputChange, {
|
||||
handleChangeWithValidation(ActionType.InputChange, {
|
||||
type: target.type,
|
||||
name: target.name,
|
||||
checked: target.checked,
|
||||
value: target.value,
|
||||
});
|
||||
}}
|
||||
onTextChange={({ target }: { target: HTMLTextAreaElement }) => {
|
||||
onChange(ActionType.TextChange, {
|
||||
onTextChange={({ target }: { target: HTMLTextAreaElement }) =>
|
||||
handleChangeWithValidation(ActionType.TextChange, {
|
||||
name: target.name,
|
||||
value: target.value,
|
||||
});
|
||||
}}
|
||||
onEditorChange={(payload: { name: string; json: any }) => {
|
||||
onChange(ActionType.EditorChange, payload);
|
||||
}}
|
||||
})
|
||||
}
|
||||
onEditorChange={(payload: { name: string; json: any }) =>
|
||||
handleChangeWithValidation(ActionType.EditorChange, payload)
|
||||
}
|
||||
onExtraInputChange={(
|
||||
e: React.ChangeEvent<HTMLInputElement> | CheckboxChangeEvent,
|
||||
) => {
|
||||
const { target } = e;
|
||||
onChange(ActionType.ExtraInputChange, {
|
||||
handleChangeWithValidation(ActionType.ExtraInputChange, {
|
||||
type: target.type,
|
||||
name: target.name,
|
||||
checked: target.checked,
|
||||
value: target.value,
|
||||
});
|
||||
}}
|
||||
onExtraEditorChange={(payload: { name: string; json: any }) => {
|
||||
onChange(ActionType.ExtraEditorChange, payload);
|
||||
}}
|
||||
onExtraEditorChange={(payload: { name: string; json: any }) =>
|
||||
handleChangeWithValidation(
|
||||
ActionType.ExtraEditorChange,
|
||||
payload,
|
||||
)
|
||||
}
|
||||
/>
|
||||
),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user