dateRange.test.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /* @vitest-environment node */
  2. import { describe, it, expect } from "vitest";
  3. import {
  4. isValidIsoDateYmd,
  5. normalizeIsoDateYmdOrNull,
  6. compareIsoDatesYmd,
  7. isInvalidIsoDateRange,
  8. formatIsoDateDe,
  9. formatIsoDateRangeLabelDe,
  10. toIsoDateYmdFromDate,
  11. toDateFromIsoDateYmd,
  12. } from "./dateRange.js";
  13. describe("lib/frontend/search/dateRange", () => {
  14. describe("isValidIsoDateYmd", () => {
  15. it("accepts strict YYYY-MM-DD", () => {
  16. expect(isValidIsoDateYmd("2025-12-01")).toBe(true);
  17. expect(isValidIsoDateYmd("2025-01-31")).toBe(true);
  18. });
  19. it("rejects invalid formats and obvious invalid ranges", () => {
  20. expect(isValidIsoDateYmd("2025/12/01")).toBe(false);
  21. expect(isValidIsoDateYmd("2025-1-01")).toBe(false);
  22. expect(isValidIsoDateYmd("2025-01-1")).toBe(false);
  23. expect(isValidIsoDateYmd("2025-13-01")).toBe(false);
  24. expect(isValidIsoDateYmd("2025-00-01")).toBe(false);
  25. expect(isValidIsoDateYmd("2025-12-00")).toBe(false);
  26. expect(isValidIsoDateYmd("2025-12-32")).toBe(false);
  27. });
  28. });
  29. describe("normalizeIsoDateYmdOrNull", () => {
  30. it("trims and returns null for invalid values", () => {
  31. expect(normalizeIsoDateYmdOrNull(" 2025-12-01 ")).toBe("2025-12-01");
  32. expect(normalizeIsoDateYmdOrNull("")).toBe(null);
  33. expect(normalizeIsoDateYmdOrNull("2025/12/01")).toBe(null);
  34. expect(normalizeIsoDateYmdOrNull(null)).toBe(null);
  35. });
  36. });
  37. describe("compareIsoDatesYmd", () => {
  38. it("compares lexicographically", () => {
  39. expect(compareIsoDatesYmd("2025-01-01", "2025-01-01")).toBe(0);
  40. expect(compareIsoDatesYmd("2025-01-01", "2025-01-02")).toBe(-1);
  41. expect(compareIsoDatesYmd("2025-12-31", "2025-01-01")).toBe(1);
  42. });
  43. });
  44. describe("isInvalidIsoDateRange", () => {
  45. it("is false for open ranges and equal dates", () => {
  46. expect(isInvalidIsoDateRange("2025-12-01", null)).toBe(false);
  47. expect(isInvalidIsoDateRange(null, "2025-12-31")).toBe(false);
  48. expect(isInvalidIsoDateRange("2025-12-01", "2025-12-01")).toBe(false);
  49. });
  50. it("is true when from > to", () => {
  51. expect(isInvalidIsoDateRange("2025-12-31", "2025-12-01")).toBe(true);
  52. });
  53. });
  54. describe("formatIsoDateDe / formatIsoDateRangeLabelDe", () => {
  55. it("formats single dates as DD.MM.YYYY", () => {
  56. expect(formatIsoDateDe("2025-12-01")).toBe("01.12.2025");
  57. expect(formatIsoDateDe("invalid")).toBe(null);
  58. });
  59. it("formats date range labels", () => {
  60. expect(
  61. formatIsoDateRangeLabelDe({ from: "2025-12-01", to: "2025-12-31" })
  62. ).toBe("01.12.2025 – 31.12.2025");
  63. expect(
  64. formatIsoDateRangeLabelDe({ from: "2025-12-01", to: "2025-12-01" })
  65. ).toBe("01.12.2025");
  66. expect(formatIsoDateRangeLabelDe({ from: "2025-12-01", to: null })).toBe(
  67. "ab 01.12.2025"
  68. );
  69. expect(formatIsoDateRangeLabelDe({ from: null, to: "2025-12-31" })).toBe(
  70. "bis 31.12.2025"
  71. );
  72. expect(formatIsoDateRangeLabelDe({ from: null, to: null })).toBe(null);
  73. });
  74. });
  75. describe("toIsoDateYmdFromDate / toDateFromIsoDateYmd", () => {
  76. it("converts dates without timezone drift", () => {
  77. const d = new Date(2026, 0, 14); // 14 Jan 2026 (local)
  78. expect(toIsoDateYmdFromDate(d)).toBe("2026-01-14");
  79. const back = toDateFromIsoDateYmd("2026-01-14");
  80. expect(back).not.toBe(null);
  81. expect(back.getFullYear()).toBe(2026);
  82. expect(back.getMonth()).toBe(0);
  83. expect(back.getDate()).toBe(14);
  84. });
  85. });
  86. });