feat(#415): theme fix, AuthDivider, SessionExpiryWarning components
- AUTH-014: Fix theme storage key (jarvis-theme -> mosaic-theme) - AUTH-016: Create AuthDivider component with customizable text - AUTH-019: Create SessionExpiryWarning floating banner (PDA-friendly, blue) - Fix lint errors in LoginForm, OAuthButton from parallel agents - Sync pnpm-lock.yaml for recharts dependency Refs #415 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
89
apps/web/src/components/auth/OAuthButton.test.tsx
Normal file
89
apps/web/src/components/auth/OAuthButton.test.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { OAuthButton } from "./OAuthButton";
|
||||
|
||||
describe("OAuthButton", (): void => {
|
||||
const defaultProps = {
|
||||
providerName: "Authentik",
|
||||
providerId: "authentik",
|
||||
onClick: vi.fn(),
|
||||
};
|
||||
|
||||
it("should render with provider name", (): void => {
|
||||
render(<OAuthButton {...defaultProps} />);
|
||||
expect(screen.getByText("Continue with Authentik")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should have full width styling", (): void => {
|
||||
render(<OAuthButton {...defaultProps} />);
|
||||
const button = screen.getByRole("button");
|
||||
expect(button.className).toContain("w-full");
|
||||
});
|
||||
|
||||
it("should call onClick when clicked", async (): Promise<void> => {
|
||||
const user = userEvent.setup();
|
||||
const onClick = vi.fn();
|
||||
render(<OAuthButton {...defaultProps} onClick={onClick} />);
|
||||
|
||||
const button = screen.getByRole("button");
|
||||
await user.click(button);
|
||||
|
||||
expect(onClick).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should show loading state with spinner and Connecting text", (): void => {
|
||||
render(<OAuthButton {...defaultProps} isLoading={true} />);
|
||||
expect(screen.getByText("Connecting...")).toBeInTheDocument();
|
||||
expect(screen.queryByText("Continue with Authentik")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should be disabled when isLoading is true", (): void => {
|
||||
render(<OAuthButton {...defaultProps} isLoading={true} />);
|
||||
const button = screen.getByRole("button");
|
||||
expect(button).toBeDisabled();
|
||||
});
|
||||
|
||||
it("should be disabled when disabled prop is true", (): void => {
|
||||
render(<OAuthButton {...defaultProps} disabled={true} />);
|
||||
const button = screen.getByRole("button");
|
||||
expect(button).toBeDisabled();
|
||||
});
|
||||
|
||||
it("should have reduced opacity when disabled", (): void => {
|
||||
render(<OAuthButton {...defaultProps} disabled={true} />);
|
||||
const button = screen.getByRole("button");
|
||||
expect(button.className).toContain("opacity-50");
|
||||
expect(button.className).toContain("pointer-events-none");
|
||||
});
|
||||
|
||||
it("should have aria-label with provider name", (): void => {
|
||||
render(<OAuthButton {...defaultProps} />);
|
||||
const button = screen.getByRole("button");
|
||||
expect(button).toHaveAttribute("aria-label", "Continue with Authentik");
|
||||
});
|
||||
|
||||
it("should have aria-label Connecting when loading", (): void => {
|
||||
render(<OAuthButton {...defaultProps} isLoading={true} />);
|
||||
const button = screen.getByRole("button");
|
||||
expect(button).toHaveAttribute("aria-label", "Connecting");
|
||||
});
|
||||
|
||||
it("should render a spinner SVG when loading", (): void => {
|
||||
const { container } = render(<OAuthButton {...defaultProps} isLoading={true} />);
|
||||
const spinner = container.querySelector("svg");
|
||||
expect(spinner).toBeInTheDocument();
|
||||
expect(spinner?.getAttribute("class")).toContain("animate-spin");
|
||||
});
|
||||
|
||||
it("should not call onClick when disabled", async (): Promise<void> => {
|
||||
const user = userEvent.setup();
|
||||
const onClick = vi.fn();
|
||||
render(<OAuthButton {...defaultProps} onClick={onClick} disabled={true} />);
|
||||
|
||||
const button = screen.getByRole("button");
|
||||
await user.click(button);
|
||||
|
||||
expect(onClick).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user