my-usage-date-range-dst.test.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { describe, expect, it, vi } from "vitest";
  2. import { fromZonedTime } from "date-fns-tz";
  3. const mocks = vi.hoisted(() => ({
  4. getSession: vi.fn(),
  5. getSystemSettings: vi.fn(),
  6. findUsageLogsWithDetails: vi.fn(),
  7. getEnvConfig: vi.fn(),
  8. }));
  9. vi.mock("@/lib/auth", () => ({
  10. getSession: mocks.getSession,
  11. }));
  12. vi.mock("@/repository/system-config", () => ({
  13. getSystemSettings: mocks.getSystemSettings,
  14. }));
  15. vi.mock("@/repository/usage-logs", async (importOriginal) => {
  16. const actual = await importOriginal<typeof import("@/repository/usage-logs")>();
  17. return {
  18. ...actual,
  19. findUsageLogsWithDetails: mocks.findUsageLogsWithDetails,
  20. };
  21. });
  22. vi.mock("@/lib/config", () => ({
  23. getEnvConfig: mocks.getEnvConfig,
  24. }));
  25. describe("my-usage date range parsing", () => {
  26. it("computes exclusive endTime as next local midnight across DST start", async () => {
  27. const tz = "America/Los_Angeles";
  28. mocks.getEnvConfig.mockReturnValue({ TZ: tz });
  29. mocks.getSession.mockResolvedValue({
  30. key: { id: 1, key: "k" },
  31. user: { id: 1 },
  32. });
  33. mocks.getSystemSettings.mockResolvedValue({
  34. currencyDisplay: "USD",
  35. billingModelSource: "original",
  36. });
  37. mocks.findUsageLogsWithDetails.mockResolvedValue({ logs: [], total: 0 });
  38. const { getMyUsageLogs } = await import("@/actions/my-usage");
  39. const res = await getMyUsageLogs({ startDate: "2024-03-10", endDate: "2024-03-10" });
  40. expect(res.ok).toBe(true);
  41. expect(mocks.findUsageLogsWithDetails).toHaveBeenCalledTimes(1);
  42. const args = mocks.findUsageLogsWithDetails.mock.calls[0]?.[0];
  43. expect(args.startTime).toBe(fromZonedTime("2024-03-10T00:00:00", tz).getTime());
  44. expect(args.endTime).toBe(fromZonedTime("2024-03-11T00:00:00", tz).getTime());
  45. expect(args.endTime - args.startTime).toBe(23 * 60 * 60 * 1000);
  46. });
  47. it("computes exclusive endTime as next local midnight across DST end", async () => {
  48. const tz = "America/Los_Angeles";
  49. mocks.getEnvConfig.mockReturnValue({ TZ: tz });
  50. mocks.getSession.mockResolvedValue({
  51. key: { id: 1, key: "k" },
  52. user: { id: 1 },
  53. });
  54. mocks.getSystemSettings.mockResolvedValue({
  55. currencyDisplay: "USD",
  56. billingModelSource: "original",
  57. });
  58. mocks.findUsageLogsWithDetails.mockResolvedValue({ logs: [], total: 0 });
  59. const { getMyUsageLogs } = await import("@/actions/my-usage");
  60. const res = await getMyUsageLogs({ startDate: "2024-11-03", endDate: "2024-11-03" });
  61. expect(res.ok).toBe(true);
  62. expect(mocks.findUsageLogsWithDetails).toHaveBeenCalledTimes(1);
  63. const args = mocks.findUsageLogsWithDetails.mock.calls[0]?.[0];
  64. expect(args.startTime).toBe(fromZonedTime("2024-11-03T00:00:00", tz).getTime());
  65. expect(args.endTime).toBe(fromZonedTime("2024-11-04T00:00:00", tz).getTime());
  66. expect(args.endTime - args.startTime).toBe(25 * 60 * 60 * 1000);
  67. });
  68. });