Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions packages/web/src/components/dashboard/date-range-picker.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* @vitest-environment jsdom
*/
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { useRouter, useSearchParams } from "next/navigation";
import { DateRangePicker } from "./date-range-picker";
import { cleanup } from "@testing-library/react";

// Mock next/navigation
vi.mock("next/navigation", () => {
return {
useRouter: vi.fn(),
useSearchParams: vi.fn(),
};
});

describe("DateRangePicker", () => {
let mockPush: ReturnType<typeof vi.fn>;

beforeEach(() => {
mockPush = vi.fn();
vi.mocked(useRouter).mockReturnValue({
push: mockPush,
replace: vi.fn(),
prefetch: vi.fn(),
back: vi.fn(),
forward: vi.fn(),
refresh: vi.fn(),
} as unknown as ReturnType<typeof useRouter>);

// Default search params
const mockSearchParams = new URLSearchParams();
vi.mocked(useSearchParams).mockReturnValue(
mockSearchParams as unknown as ReturnType<typeof useSearchParams>,
);
});

afterEach(() => {
cleanup();
});

it("renders presets", () => {
render(<DateRangePicker />);

expect(screen.getByRole("button", { name: "7d" })).toBeDefined();
expect(screen.getByRole("button", { name: "30d" })).toBeDefined();
expect(screen.getByRole("button", { name: "90d" })).toBeDefined();
expect(screen.getByRole("button", { name: "ALL" })).toBeDefined();
});

it("updates URL when a preset is clicked", () => {
render(<DateRangePicker />);

const button30d = screen.getByRole("button", { name: "30d" });
fireEvent.click(button30d);

expect(mockPush).toHaveBeenCalledTimes(1);

// Check if the URL contains from and to parameters
const calledUrl = mockPush.mock.calls[0][0];
expect(calledUrl).toContain("from=");
expect(calledUrl).toContain("to=");
});

it("has aria-pressed set correctly based on active state", () => {
render(<DateRangePicker />);

const button7d = screen.getByRole("button", { name: "7d" });
expect(button7d.hasAttribute("aria-pressed")).toBe(true);
});
});
4 changes: 3 additions & 1 deletion packages/web/src/components/dashboard/date-range-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { useSearchParams, useRouter } from 'next/navigation'
import { subDays, format, differenceInDays } from 'date-fns'
import { Suspense } from 'react'
import React, { Suspense } from 'react'
import { cn } from '@/lib/utils'

const PRESETS = [
Expand Down Expand Up @@ -62,9 +62,11 @@ function DateRangePickerContent() {
<button
key={preset.days}
type="button"
aria-pressed={activePreset === preset.days}
onClick={() => handlePreset(preset.days)}
className={cn(
'px-3 py-1 text-xs font-medium rounded-md transition-colors',
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
activePreset === preset.days
? 'bg-primary text-primary-foreground'
: 'text-muted-foreground hover:text-foreground hover:bg-muted',
Expand Down
Loading