128 lines
3.7 KiB
TypeScript
128 lines
3.7 KiB
TypeScript
import { render, screen } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
// Mock the hook so we can control its return values
|
|
const mockPromptInstall = vi.fn();
|
|
const mockDismiss = vi.fn();
|
|
|
|
vi.mock("../hooks/useInstallPrompt", () => ({
|
|
useInstallPrompt: vi.fn(() => ({
|
|
canInstall: false,
|
|
isStandalone: false,
|
|
isIOS: false,
|
|
isDismissed: false,
|
|
promptInstall: mockPromptInstall,
|
|
dismiss: mockDismiss,
|
|
})),
|
|
}));
|
|
|
|
import { useInstallPrompt } from "../hooks/useInstallPrompt";
|
|
import { InstallBanner } from "./InstallBanner";
|
|
|
|
const mockUseInstallPrompt = vi.mocked(useInstallPrompt);
|
|
|
|
describe("InstallBanner", () => {
|
|
beforeEach(() => {
|
|
mockPromptInstall.mockClear();
|
|
mockDismiss.mockClear();
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it("renders nothing when canInstall is false and not iOS", () => {
|
|
mockUseInstallPrompt.mockReturnValue({
|
|
canInstall: false,
|
|
isStandalone: false,
|
|
isIOS: false,
|
|
isDismissed: false,
|
|
promptInstall: mockPromptInstall,
|
|
dismiss: mockDismiss,
|
|
});
|
|
const { container } = render(<InstallBanner />);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
it("renders nothing when already in standalone mode", () => {
|
|
mockUseInstallPrompt.mockReturnValue({
|
|
canInstall: true,
|
|
isStandalone: true,
|
|
isIOS: false,
|
|
isDismissed: false,
|
|
promptInstall: mockPromptInstall,
|
|
dismiss: mockDismiss,
|
|
});
|
|
const { container } = render(<InstallBanner />);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
it("renders nothing when dismissed", () => {
|
|
mockUseInstallPrompt.mockReturnValue({
|
|
canInstall: true,
|
|
isStandalone: false,
|
|
isIOS: false,
|
|
isDismissed: true,
|
|
promptInstall: mockPromptInstall,
|
|
dismiss: mockDismiss,
|
|
});
|
|
const { container } = render(<InstallBanner />);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
|
|
it("renders install banner when canInstall is true", () => {
|
|
mockUseInstallPrompt.mockReturnValue({
|
|
canInstall: true,
|
|
isStandalone: false,
|
|
isIOS: false,
|
|
isDismissed: false,
|
|
promptInstall: mockPromptInstall,
|
|
dismiss: mockDismiss,
|
|
});
|
|
render(<InstallBanner />);
|
|
expect(screen.getByText(/install/i)).toBeInTheDocument();
|
|
});
|
|
|
|
it("calls promptInstall when install button is clicked", async () => {
|
|
mockUseInstallPrompt.mockReturnValue({
|
|
canInstall: true,
|
|
isStandalone: false,
|
|
isIOS: false,
|
|
isDismissed: false,
|
|
promptInstall: mockPromptInstall,
|
|
dismiss: mockDismiss,
|
|
});
|
|
render(<InstallBanner />);
|
|
await userEvent.click(screen.getByRole("button", { name: /install/i }));
|
|
expect(mockPromptInstall).toHaveBeenCalledOnce();
|
|
});
|
|
|
|
it("calls dismiss when close button is clicked", async () => {
|
|
mockUseInstallPrompt.mockReturnValue({
|
|
canInstall: true,
|
|
isStandalone: false,
|
|
isIOS: false,
|
|
isDismissed: false,
|
|
promptInstall: mockPromptInstall,
|
|
dismiss: mockDismiss,
|
|
});
|
|
render(<InstallBanner />);
|
|
await userEvent.click(screen.getByRole("button", { name: /dismiss|close/i }));
|
|
expect(mockDismiss).toHaveBeenCalledOnce();
|
|
});
|
|
|
|
it("renders iOS instructions when isIOS is true and not dismissed", () => {
|
|
mockUseInstallPrompt.mockReturnValue({
|
|
canInstall: false,
|
|
isStandalone: false,
|
|
isIOS: true,
|
|
isDismissed: false,
|
|
promptInstall: mockPromptInstall,
|
|
dismiss: mockDismiss,
|
|
});
|
|
render(<InstallBanner />);
|
|
expect(screen.getByText(/share/i)).toBeInTheDocument();
|
|
expect(screen.getByText(/add to home screen/i)).toBeInTheDocument();
|
|
});
|
|
});
|