* fix: use hidden input for UTC date value in add-game form The onSubmit handler was setting the datetime-local input's value to an ISO UTC string (e.g. "2026-03-11T17:00:00.000Z"). datetime-local inputs only accept the format "YYYY-MM-DDTHH:MM" — values with a 'Z' timezone suffix are invalid and the browser silently clears the field to "". This caused the form to submit an empty scheduledAt, which the server treated as null, so games were always saved without a date. Fix by keeping the datetime-local input for user interaction (renamed scheduledAtLocal, not submitted) and writing the converted UTC ISO string into a separate hidden input named scheduledAt in the onSubmit handler. Also adds app/lib/date-utils.ts with a localDateTimeToUtcIso helper and matching tests to document and verify the datetime-local ↔ ISO conversion behaviour. https://claude.ai/code/session_0148fgZiXpyvGX8ZX3BFRGCs * refactor: use localDateTimeToUtcIso in component and clean up tests - Import and call localDateTimeToUtcIso in the add-game onSubmit handler instead of duplicating the conversion inline; also applies the null/ invalid-date safety from the utility to the component - Remove the redundant "incompatible with datetime-local" test case (its intent is better expressed as a code comment than a test assertion) - Move the datetime-local incompatibility explanation into a NOTE comment on the utility function's JSDoc https://claude.ai/code/session_0148fgZiXpyvGX8ZX3BFRGCs --------- Co-authored-by: Claude <noreply@anthropic.com>
44 lines
1.5 KiB
TypeScript
44 lines
1.5 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { localDateTimeToUtcIso } from "../date-utils";
|
|
|
|
describe("localDateTimeToUtcIso", () => {
|
|
it("returns null for empty string", () => {
|
|
expect(localDateTimeToUtcIso("")).toBeNull();
|
|
});
|
|
|
|
it("returns null for null", () => {
|
|
expect(localDateTimeToUtcIso(null)).toBeNull();
|
|
});
|
|
|
|
it("returns null for undefined", () => {
|
|
expect(localDateTimeToUtcIso(undefined)).toBeNull();
|
|
});
|
|
|
|
it("returns null for an invalid date string", () => {
|
|
expect(localDateTimeToUtcIso("not-a-date")).toBeNull();
|
|
});
|
|
|
|
it("converts a valid datetime-local value and round-trips correctly", () => {
|
|
// The input matches the datetime-local format "YYYY-MM-DDTHH:MM".
|
|
// Regardless of timezone, the resulting ISO string should parse back
|
|
// to the same moment in time.
|
|
const input = "2026-03-11T17:00";
|
|
const result = localDateTimeToUtcIso(input);
|
|
expect(result).not.toBeNull();
|
|
expect(new Date(result!).getTime()).toBe(new Date(input).getTime());
|
|
});
|
|
|
|
it("returns a string ending with 'Z' (UTC designator)", () => {
|
|
const result = localDateTimeToUtcIso("2026-03-11T10:00");
|
|
expect(result).not.toBeNull();
|
|
expect(result!.endsWith("Z")).toBe(true);
|
|
});
|
|
|
|
it("returns a full ISO-8601 string with milliseconds", () => {
|
|
const result = localDateTimeToUtcIso("2026-06-15T08:30");
|
|
expect(result).not.toBeNull();
|
|
// toISOString() always produces "YYYY-MM-DDTHH:MM:SS.mmmZ"
|
|
expect(result).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/);
|
|
});
|
|
|
|
});
|