diff --git a/apps/web/test/lib/getTimezone.test.ts b/apps/web/test/lib/getTimezone.test.ts index 5055eed8fe..ff2be79b49 100644 --- a/apps/web/test/lib/getTimezone.test.ts +++ b/apps/web/test/lib/getTimezone.test.ts @@ -1,4 +1,4 @@ -import { expect, it } from "vitest"; +import { expect, beforeEach, afterEach, it, vi, describe } from "vitest"; import { filterByCities, addCitiesToDropdown, handleOptionLabel } from "@calcom/lib/timezone"; @@ -33,12 +33,22 @@ const option = { altName: "Pacific Standard Time", }; -it("should return empty array for an empty string", () => { - expect(filterByCities("", cityData)).toMatchInlineSnapshot(`[]`); -}); +describe("getTimezone", () => { + beforeEach(() => { + vi.useFakeTimers().setSystemTime(new Date("2020-01-01")); + }); -it("should filter cities for a valid city name", () => { - expect(filterByCities("San Francisco", cityData)).toMatchInlineSnapshot(` + afterEach(() => { + vi.runOnlyPendingTimers(); + vi.useRealTimers(); + }); + + it("should return empty array for an empty string", () => { + expect(filterByCities("", cityData)).toMatchInlineSnapshot(`[]`); + }); + + it("should filter cities for a valid city name", () => { + expect(filterByCities("San Francisco", cityData)).toMatchInlineSnapshot(` [ { "city": "San Francisco", @@ -58,10 +68,10 @@ it("should filter cities for a valid city name", () => { }, ] `); -}); + }); -it("should return appropriate timezone(s) for a given city name array", () => { - expect(addCitiesToDropdown(cityData)).toMatchInlineSnapshot(` + it("should return appropriate timezone(s) for a given city name array", () => { + expect(addCitiesToDropdown(cityData)).toMatchInlineSnapshot(` { "America/Argentina/Cordoba": "San Francisco", "America/El_Salvador": "San Francisco Gotera", @@ -70,12 +80,17 @@ it("should return appropriate timezone(s) for a given city name array", () => { "America/Sao_Paulo": "Sao Francisco do Sul", } `); -}); + }); -it("should render city name as option label if cityData is not empty", () => { - expect(handleOptionLabel(option, cityData)).toMatchInlineSnapshot(`"San Francisco GMT -8:00"`); -}); + it("should render city name as option label if cityData is not empty", () => { + expect(handleOptionLabel(option, cityData)).toMatchInlineSnapshot(`"San Francisco GMT -8:00"`); + vi.setSystemTime(new Date("2020-06-01")); + expect(handleOptionLabel(option, cityData)).toMatchInlineSnapshot(`"San Francisco GMT -7:00"`); + }); -it("should return timezone as option label if cityData is empty", () => { - expect(handleOptionLabel(option, [])).toMatchInlineSnapshot(`"America/Los Angeles GMT -8:00"`); + it("should return timezone as option label if cityData is empty", () => { + expect(handleOptionLabel(option, [])).toMatchInlineSnapshot(`"America/Los Angeles GMT -8:00"`); + vi.setSystemTime(new Date("2020-06-01")); + expect(handleOptionLabel(option, [])).toMatchInlineSnapshot(`"America/Los Angeles GMT -7:00"`); + }); }); diff --git a/packages/lib/timezone.ts b/packages/lib/timezone.ts index f9159e00ed..d4820943b0 100644 --- a/packages/lib/timezone.ts +++ b/packages/lib/timezone.ts @@ -1,5 +1,6 @@ import type { ITimezoneOption } from "react-timezone-select"; +import dayjs from "@calcom/dayjs"; import type { ICity } from "@calcom/ui/components/form/timezone-select"; import isProblematicTimezone from "./isProblematicTimezone"; @@ -32,9 +33,15 @@ export const addCitiesToDropdown = (cities: ICity[]) => { return cityTimezones || {}; }; +const formatOffset = (offset: string) => + offset.replace(/^([-+])(0)(\d):00$/, (_, sign, _zero, hour) => `${sign}${hour}:00`); + export const handleOptionLabel = (option: ITimezoneOption, cities: ICity[]) => { - const timezoneValue = option.label.split(")")[0].replace("(", " ").replace("T", "T "); + const offsetUnit = option.label.split("-")[0].substring(1); const cityName = option.label.split(") ")[1]; - const refactoredOption = option.value.replace(/_/g, " "); - return cities.length > 0 ? `${cityName}${timezoneValue}` : `${refactoredOption}${timezoneValue}`; + + const timezoneValue = ` ${offsetUnit} ${formatOffset(dayjs.tz(undefined, option.value).format("Z"))}`; + return cities.length > 0 + ? `${cityName}${timezoneValue}` + : `${option.value.replace(/_/g, " ")}${timezoneValue}`; }; diff --git a/packages/ui/components/form/timezone-select/timezone-select.test.tsx b/packages/ui/components/form/timezone-select/timezone-select.test.tsx index 953c391666..f24a9cf6c6 100644 --- a/packages/ui/components/form/timezone-select/timezone-select.test.tsx +++ b/packages/ui/components/form/timezone-select/timezone-select.test.tsx @@ -107,12 +107,9 @@ describe("Test TimezoneSelect", () => { expect(menuListEl).toHaveClass(classNames.menuList()); expect(menuEl).toHaveClass(classNames.menu()); - expect(screen.getByText(optionMockValues[1])).toBeInTheDocument(); - - // TODO America/Juneau and America/Toronto failing - // for (const mockText of optionMockValues) { - // expect(screen.getByText(mockText)).toBeInTheDocument(); - // } + for (const mockText of optionMockValues) { + expect(screen.getByText(mockText)).toBeInTheDocument(); + } }); test("Should render with the correct CSS when provided with className prop", async () => { @@ -142,13 +139,12 @@ describe("Test TimezoneSelect", () => { const element = screen.getByLabelText("Test"); element.focus(); fireEvent.keyDown(element, { key: "ArrowDown", code: "ArrowDown" }); - // TODO: optionMockValues[3] was failing - screen.getByText(optionMockValues[1]); + screen.getByText(optionMockValues[3]); const inputEl = screen.getByRole("combobox", { hidden: true }).parentElement; const menuIsOpenEl = inputEl?.parentElement?.nextSibling; expect(menuIsOpenEl).toHaveClass("rotate-180 transition-transform "); - const opt = screen.getByText(optionMockValues[1]); + const opt = screen.getByText(optionMockValues[3]); fireEvent.click(opt); fireEvent.keyDown(element, { key: "ArrowDown", code: "ArrowDown" }); });