feat: support custom validation errors for number-typed parameters (#12224)

This commit is contained in:
Marcin Tojek
2024-02-20 16:32:03 +01:00
committed by GitHub
parent 6414b7aade
commit 57bf997369
7 changed files with 156 additions and 9 deletions
@@ -25,7 +25,6 @@ import { rest } from "msw";
const nameLabelText = "Workspace Name";
const createWorkspaceText = "Create Workspace";
const validationNumberNotInRangeText = "Value must be between 1 and 3.";
const validationPatternNotMatched = `${MockTemplateVersionParameter3.validation_error} (value does not match the pattern ^[a-z]{3}$)`;
const renderCreateWorkspacePage = () => {
return renderWithAuth(<CreateWorkspacePage />, {
@@ -152,7 +151,36 @@ describe("CreateWorkspacePage", () => {
fireEvent.submit(thirdParameterField);
const validationError = await screen.findByText(
validationPatternNotMatched,
MockTemplateVersionParameter3.validation_error as string,
);
expect(validationError).toBeInTheDocument();
});
it("rich parameter: number validation fails with custom error", async () => {
jest.spyOn(API, "getTemplateVersionRichParameters").mockResolvedValueOnce([
MockTemplateVersionParameter1,
{
...MockTemplateVersionParameter2,
validation_error: "These are values: {min}, {max}, and {value}.",
validation_monotonic: undefined, // only needs min-max rules
},
]);
renderCreateWorkspacePage();
await waitForLoaderToBeRemoved();
const secondParameterField = await screen.findByLabelText(
MockTemplateVersionParameter2.name,
{ exact: false },
);
expect(secondParameterField).toBeDefined();
fireEvent.change(secondParameterField, {
target: { value: "4" },
});
fireEvent.submit(secondParameterField);
const validationError = await screen.findByText(
"These are values: 1, 3, and 4.",
);
expect(validationError).toBeInTheDocument();
});
+39 -4
View File
@@ -79,7 +79,9 @@ export const useValidationSchemaForRichParameters = (
if (Number(val) < templateParameter.validation_min) {
return ctx.createError({
path: ctx.path,
message: `Value must be greater than ${templateParameter.validation_min}.`,
message:
parameterError(templateParameter, val) ??
`Value must be greater than ${templateParameter.validation_min}.`,
});
}
} else if (
@@ -89,7 +91,9 @@ export const useValidationSchemaForRichParameters = (
if (templateParameter.validation_max < Number(val)) {
return ctx.createError({
path: ctx.path,
message: `Value must be less than ${templateParameter.validation_max}.`,
message:
parameterError(templateParameter, val) ??
`Value must be less than ${templateParameter.validation_max}.`,
});
}
} else if (
@@ -102,7 +106,9 @@ export const useValidationSchemaForRichParameters = (
) {
return ctx.createError({
path: ctx.path,
message: `Value must be between ${templateParameter.validation_min} and ${templateParameter.validation_max}.`,
message:
parameterError(templateParameter, val) ??
`Value must be between ${templateParameter.validation_min} and ${templateParameter.validation_max}.`,
});
}
}
@@ -149,7 +155,7 @@ export const useValidationSchemaForRichParameters = (
if (val && !regex.test(val)) {
return ctx.createError({
path: ctx.path,
message: `${templateParameter.validation_error} (value does not match the pattern ${templateParameter.validation_regex})`,
message: parameterError(templateParameter, val),
});
}
}
@@ -162,3 +168,32 @@ export const useValidationSchemaForRichParameters = (
)
.required();
};
const parameterError = (
parameter: TemplateVersionParameter,
value?: string,
): string | undefined => {
if (!parameter.validation_error || !value) {
return;
}
const r = new Map<string, string>([
[
"{min}",
parameter.validation_min !== undefined
? parameter.validation_min.toString()
: "",
],
[
"{max}",
parameter.validation_max !== undefined
? parameter.validation_max.toString()
: "",
],
["{value}", value],
]);
return parameter.validation_error.replace(
/{min}|{max}|{value}/g,
(match) => r.get(match) || "",
);
};