Path: blob/master/src/packages/frontend/app/dayjs-antd-plugins.test.ts
16567 views
/*1* This file is part of CoCalc: Copyright © 2026 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45/*6Regression test for the antd DatePicker "weekday is not a function" crash.78antd's pickers (via rc-picker) call dayjs plugin methods such as9`.weekday()` and `.localeData()` on the dayjs objects we hand them. Those10methods only exist if the corresponding plugins were registered via11`dayjs.extend(...)` on *our* dayjs instance. When they aren't, the store's12license start/end date picker throws:1314TypeError: t.weekday is not a function15at Object.getWeekDay ...1617See ./dayjs-antd-plugins.ts for the full explanation.18*/1920import { readFileSync } from "fs";21import { join } from "path";2223import dayjs from "dayjs";2425// Importing the setup module for its side effects is exactly what the app26// entry points do. After this, our dayjs instance must have all the plugins.27import "./dayjs-antd-plugins";2829describe("antd dayjs plugin registration", () => {30it("exposes the plugin methods rc-picker needs on a dayjs object", () => {31const d = dayjs();32expect(typeof d.weekday).toBe("function");33expect(typeof d.localeData).toBe("function");34expect(typeof d.week).toBe("function"); // weekOfYear35expect(typeof d.weekYear).toBe("function");36});3738it("reproduces rc-picker's getWeekDay() without throwing", () => {39// This mirrors rc-picker/es/generate/dayjs.js getWeekDay(), the exact40// call site that threw "t.weekday is not a function" in production.41const getWeekDay = (date: dayjs.Dayjs): number => {42const clone = date.locale("en");43return clone.weekday() + clone.localeData().firstDayOfWeek();44};45expect(() => getWeekDay(dayjs("2026-06-08"))).not.toThrow();46expect(typeof getWeekDay(dayjs("2026-06-08"))).toBe("number");47});4849it("supports advancedFormat tokens (Q, Do, k, ...)", () => {50// advancedFormat adds tokens like Q (quarter) and Do (ordinal day).51expect(dayjs("2026-06-08").format("Q")).toBe("2");52expect(dayjs("2026-06-08").format("Do")).toBe("8th");53});5455it("supports customParseFormat parsing", () => {56const d = dayjs("08-06-2026", "DD-MM-YYYY");57expect(d.isValid()).toBe(true);58expect(d.year()).toBe(2026);59expect(d.month()).toBe(5); // June (0-indexed)60expect(d.date()).toBe(8);61});62});6364describe("antd dayjs plugins are wired into the app entry points", () => {65// Guard against silently dropping the side-effect import that activates the66// fix. If these break, the production picker crash will come back.67const setupImport = "app/dayjs-antd-plugins";6869it("frontend entry-point.ts imports the dayjs plugin setup", () => {70const src = readFileSync(join(__dirname, "..", "entry-point.ts"), "utf8");71expect(src).toContain(setupImport);72});7374it("next _app.tsx imports the dayjs plugin setup", () => {75const appPath = join(76__dirname,77"..",78"..",79"next",80"pages",81"_app.tsx",82);83const src = readFileSync(appPath, "utf8");84expect(src).toContain(setupImport);85});86});878889