From 848732a2851582f532fd0371c98a6c85a31a9a84 Mon Sep 17 00:00:00 2001 From: Presley Pizzo Date: Mon, 8 Aug 2022 22:51:23 +0000 Subject: [PATCH] Fix validation for falsey values --- .../WorkspaceScheduleForm.test.ts | 28 ++++++------- .../WorkspaceScheduleForm.tsx | 42 +++++++++---------- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts index 0b08446f0f..c3b2cf1f40 100644 --- a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts +++ b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts @@ -1,7 +1,7 @@ import { Language, ttlShutdownAt, - validationSchema, + getValidationSchema, WorkspaceScheduleFormValues, } from "./WorkspaceScheduleForm" import { zones } from "./zones" @@ -35,7 +35,7 @@ describe("validationSchema", () => { timezone: "", ttl: 0, } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).not.toThrow() }) @@ -44,7 +44,7 @@ describe("validationSchema", () => { ...valid, ttl: -1, } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).toThrow() }) @@ -59,7 +59,7 @@ describe("validationSchema", () => { friday: false, saturday: false, } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).toThrowError(Language.errorNoDayOfWeek) }) @@ -75,7 +75,7 @@ describe("validationSchema", () => { saturday: false, startTime: "", } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).toThrowError(Language.errorNoTime) }) @@ -84,7 +84,7 @@ describe("validationSchema", () => { ...valid, startTime: "16:20", } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).not.toThrow() }) @@ -93,7 +93,7 @@ describe("validationSchema", () => { ...valid, startTime: "9:30", } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).toThrowError(Language.errorTime) }) @@ -102,7 +102,7 @@ describe("validationSchema", () => { ...valid, startTime: "09:5", } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).toThrowError(Language.errorTime) }) @@ -111,7 +111,7 @@ describe("validationSchema", () => { ...valid, startTime: "24:01", } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).toThrowError(Language.errorTime) }) @@ -120,7 +120,7 @@ describe("validationSchema", () => { ...valid, startTime: "09:60", } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).toThrowError(Language.errorTime) }) @@ -129,7 +129,7 @@ describe("validationSchema", () => { ...valid, timezone: "Canada/North", } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).toThrowError(Language.errorTimezone) }) @@ -138,7 +138,7 @@ describe("validationSchema", () => { ...valid, timezone: zone, } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).not.toThrow() }) @@ -147,7 +147,7 @@ describe("validationSchema", () => { ...valid, ttl: 24 * 7, } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).not.toThrowError() }) @@ -156,7 +156,7 @@ describe("validationSchema", () => { ...valid, ttl: 24 * 7 + 1, } - const validate = () => validationSchema.validateSync(values) + const validate = () => getValidationSchema(true, true).validateSync(values) expect(validate).toThrowError("ttl must be less than or equal to 168") }) }) diff --git a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx index 583ef04cef..8fb8f4cf7c 100644 --- a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx +++ b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx @@ -21,6 +21,7 @@ import { AutoStart } from "pages/WorkspaceSchedulePage/schedule" import { AutoStop } from "pages/WorkspaceSchedulePage/ttl" import { FC } from "react" import * as Yup from "yup" +import { OptionalObjectSchema } from "yup/lib/object" import { getFormHelpersWithError } from "../../util/formUtils" import { FormFooter } from "../FormFooter/FormFooter" import { FullPageForm } from "../FullPageForm/FullPageForm" @@ -36,10 +37,11 @@ dayjs.extend(relativeTime) dayjs.extend(timezone) export const Language = { - errorNoDayOfWeek: "Must set at least one day of week if start time is set", - errorNoTime: "Start time is required when days of the week are selected", + errorNoDayOfWeek: "Must set at least one day of week if auto-start is enabled", + errorNoTime: "Start time is required when auto-start is enabled", errorTime: "Time must be in HH:mm format (24 hours)", errorTimezone: "Invalid timezone", + errorNoStop: "Time until shutdown must be greater than zero when auto-stop is enabled", daysOfWeekLabel: "Days of Week", daySundayLabel: "Sunday", dayMondayLabel: "Monday", @@ -89,12 +91,13 @@ export interface WorkspaceScheduleFormValues { ttl: number } -export const validationSchema = Yup.object({ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export const getValidationSchema = (autoStartEnabled: boolean, autoStopEnabled: boolean) => (Yup.object({ sunday: Yup.boolean(), monday: Yup.boolean().test("at-least-one-day", Language.errorNoDayOfWeek, function (value) { const parent = this.parent as WorkspaceScheduleFormValues - if (!parent.startTime) { + if (!autoStartEnabled) { return true } else { return ![ @@ -116,20 +119,8 @@ export const validationSchema = Yup.object({ startTime: Yup.string() .ensure() - .test("required-if-day-selected", Language.errorNoTime, function (value) { - const parent = this.parent as WorkspaceScheduleFormValues - - const isDaySelected = [ - parent.sunday, - parent.monday, - parent.tuesday, - parent.wednesday, - parent.thursday, - parent.friday, - parent.saturday, - ].some((day) => day) - - if (isDaySelected) { + .test("required-if-auto-start", Language.errorNoTime, function (value) { + if (autoStartEnabled) { return value !== "" } else { return true @@ -168,9 +159,16 @@ export const validationSchema = Yup.object({ }), ttl: Yup.number() .integer() - .min(1) - .max(24 * 7 /* 7 days */), -}) + .min(0) + .max(24 * 7 /* 7 days */) + .test("positive-if-auto-stop", Language.errorNoStop, (value) => { + if (autoStopEnabled) { + return !!value + } else { + return true + } + }), +})) export const WorkspaceScheduleForm: FC = ({ submitScheduleError, @@ -190,7 +188,7 @@ export const WorkspaceScheduleForm: FC = ({ initialValues, enableReinitialize: true, onSubmit, - validationSchema, + validationSchema: () => getValidationSchema(autoStart.enabled, autoStop.enabled), initialTouched, }) const formHelpers = getFormHelpersWithError(