mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: support custom validation errors for number-typed parameters (#12224)
This commit is contained in:
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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) || "",
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user