Allow range crossing midnight

This commit is contained in:
Adria Navarro 2024-05-23 14:47:54 +02:00
parent 5b80e4fb6e
commit d1ef9067dc
2 changed files with 45 additions and 10 deletions

View File

@ -183,6 +183,26 @@ describe("validate", () => {
time: ["must be no later than 15:00"], time: ["must be no later than 15:00"],
}) })
}) })
describe("range crossing midnight", () => {
const table = getTable()
table.schema.time.constraints = {
presence: true,
datetime: {
earliest: "15:00",
latest: "10:00",
},
}
it.each(["10:00", "15:00", `9:${minute()}`, "16:34"])(
"should accept values in range (%s)",
async time => {
const row = { time }
const output = await validate({ table, tableId: table._id!, row })
expect(output.valid).toBe(true)
}
)
})
}) })
}) })

View File

@ -227,31 +227,46 @@ function validateTimeOnlyField(
res = [`"${fieldName}" is not a valid time`] res = [`"${fieldName}" is not a valid time`]
} else if (constraints) { } else if (constraints) {
let castedValue = value let castedValue = value
const stringTimeToDateISOString = (value: string) => { const stringTimeToDate = (value: string) => {
const [hour, minute, second] = value.split(":").map((x: string) => +x) const [hour, minute, second] = value.split(":").map((x: string) => +x)
let date = dayjs("2000-01-01T00:00:00.000Z").hour(hour).minute(minute) let date = dayjs("2000-01-01T00:00:00.000Z").hour(hour).minute(minute)
if (!isNaN(second)) { if (!isNaN(second)) {
date = date.second(second) date = date.second(second)
} }
return date.toISOString() return date
} }
if (castedValue) { if (castedValue) {
castedValue = stringTimeToDateISOString(castedValue) castedValue = stringTimeToDate(castedValue)
} }
let castedConstraints = cloneDeep(constraints) let castedConstraints = cloneDeep(constraints)
let earliest, latest
if (castedConstraints.datetime?.earliest) { if (castedConstraints.datetime?.earliest) {
castedConstraints.datetime.earliest = stringTimeToDateISOString( earliest = stringTimeToDate(castedConstraints.datetime?.earliest)
castedConstraints.datetime?.earliest
)
} }
if (castedConstraints.datetime?.latest) { if (castedConstraints.datetime?.latest) {
castedConstraints.datetime.latest = stringTimeToDateISOString( latest = stringTimeToDate(castedConstraints.datetime?.latest)
castedConstraints.datetime?.latest
)
} }
let jsValidation = validateJs.single(castedValue, castedConstraints) if (earliest && latest && earliest.isAfter(latest)) {
latest = latest.add(1, "day")
if (earliest.isAfter(castedValue)) {
castedValue = castedValue.add(1, "day")
}
}
if (earliest || latest) {
castedConstraints.datetime = {
earliest: earliest?.toISOString() || "",
latest: latest?.toISOString() || "",
}
}
let jsValidation = validateJs.single(
castedValue?.toISOString(),
castedConstraints
)
jsValidation = jsValidation?.map((m: string) => jsValidation = jsValidation?.map((m: string) =>
m m
?.replace( ?.replace(