5c09f97cb3
- Export DashboardPage helper functions for testability - Add new test files: App, SharedSchedule, AppContext, UnsavedChangesContext, useUnsavedChangesWarning - Expand existing test coverage for Auth, MedDetailModal, MobileEditModal, DashboardPage, MedicationsPage, PlannerPage, and more - Add edge case and error handling tests across components, hooks, and pages
131 lines
3.9 KiB
TypeScript
131 lines
3.9 KiB
TypeScript
import { act, fireEvent, render, screen } from "@testing-library/react";
|
||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||
import AboutModal from "../../components/AboutModal";
|
||
|
||
// Mock App module for constants
|
||
vi.mock("../../App", () => ({
|
||
FRONTEND_VERSION: "1.0.0",
|
||
GITHUB_URL: "https://github.com/test/repo",
|
||
}));
|
||
|
||
describe("AboutModal", () => {
|
||
const defaultProps = {
|
||
isOpen: true,
|
||
onClose: vi.fn(),
|
||
};
|
||
|
||
beforeEach(() => {
|
||
vi.clearAllMocks();
|
||
});
|
||
|
||
it("returns null when not open", () => {
|
||
const { container } = render(<AboutModal {...defaultProps} isOpen={false} />);
|
||
expect(container.firstChild).toBeNull();
|
||
});
|
||
|
||
it("renders when open", () => {
|
||
render(<AboutModal {...defaultProps} />);
|
||
expect(screen.getByText(/about\.appName/i)).toBeInTheDocument();
|
||
});
|
||
|
||
it("displays version number", () => {
|
||
render(<AboutModal {...defaultProps} />);
|
||
expect(screen.getByText(/1\.0\.0/)).toBeInTheDocument();
|
||
});
|
||
|
||
it("calls onClose when close button is clicked", () => {
|
||
render(<AboutModal {...defaultProps} />);
|
||
fireEvent.click(screen.getByText("×"));
|
||
expect(defaultProps.onClose).toHaveBeenCalled();
|
||
});
|
||
|
||
it("calls onClose when overlay is clicked", () => {
|
||
const { container } = render(<AboutModal {...defaultProps} />);
|
||
const overlay = container.querySelector(".modal-overlay");
|
||
fireEvent.click(overlay!);
|
||
expect(defaultProps.onClose).toHaveBeenCalled();
|
||
});
|
||
|
||
it("does not call onClose when modal content is clicked", () => {
|
||
const { container } = render(<AboutModal {...defaultProps} />);
|
||
const content = container.querySelector(".about-modal");
|
||
if (content) {
|
||
fireEvent.click(content);
|
||
expect(defaultProps.onClose).not.toHaveBeenCalled();
|
||
}
|
||
});
|
||
|
||
it("renders GitHub link", () => {
|
||
render(<AboutModal {...defaultProps} />);
|
||
const links = screen.getAllByRole("link");
|
||
expect(links.length).toBeGreaterThan(0);
|
||
});
|
||
|
||
it("renders version as link to GitHub release", () => {
|
||
render(<AboutModal {...defaultProps} />);
|
||
const versionLink = screen.getByText("1.0.0").closest("a");
|
||
expect(versionLink).toHaveAttribute("href", "https://github.com/test/repo/releases/tag/v1.0.0");
|
||
expect(versionLink).toHaveAttribute("target", "_blank");
|
||
});
|
||
|
||
it("shows up-to-date result after successful version check", async () => {
|
||
vi.useFakeTimers();
|
||
(global.fetch as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
|
||
ok: true,
|
||
json: () => Promise.resolve({ tag_name: "v1.0.0" }),
|
||
});
|
||
|
||
render(<AboutModal {...defaultProps} />);
|
||
|
||
await act(async () => {
|
||
fireEvent.click(screen.getByRole("button", { name: /about\.checkForUpdates/i }));
|
||
await vi.advanceTimersByTimeAsync(1000);
|
||
});
|
||
|
||
expect(screen.getByText(/about\.upToDate/i)).toBeInTheDocument();
|
||
|
||
vi.useRealTimers();
|
||
});
|
||
|
||
it("shows update available result with download link", async () => {
|
||
vi.useFakeTimers();
|
||
(global.fetch as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
|
||
ok: true,
|
||
json: () => Promise.resolve({ tag_name: "v1.2.0" }),
|
||
});
|
||
|
||
render(<AboutModal {...defaultProps} />);
|
||
|
||
await act(async () => {
|
||
fireEvent.click(screen.getByRole("button", { name: /about\.checkForUpdates/i }));
|
||
await vi.advanceTimersByTimeAsync(1000);
|
||
});
|
||
|
||
expect(screen.getByText(/about\.updateAvailable/i)).toBeInTheDocument();
|
||
|
||
const downloadLink = screen.getByRole("link", { name: /about\.downloadUpdate/i });
|
||
expect(downloadLink).toHaveAttribute("href", "https://github.com/test/repo/releases/latest");
|
||
|
||
vi.useRealTimers();
|
||
});
|
||
|
||
it("shows error result when update check fails", async () => {
|
||
vi.useFakeTimers();
|
||
(global.fetch as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
|
||
ok: false,
|
||
json: () => Promise.resolve({}),
|
||
});
|
||
|
||
render(<AboutModal {...defaultProps} />);
|
||
|
||
await act(async () => {
|
||
fireEvent.click(screen.getByRole("button", { name: /about\.checkForUpdates/i }));
|
||
await vi.advanceTimersByTimeAsync(1000);
|
||
});
|
||
|
||
expect(screen.getByText(/about\.checkFailed/i)).toBeInTheDocument();
|
||
|
||
vi.useRealTimers();
|
||
});
|
||
});
|