Files
silo-server/web/src/components/profiles/ProfileEditorDialog.test.tsx
T

126 lines
3.4 KiB
TypeScript

// @vitest-environment jsdom
import { act } from "react";
import { createRoot, type Root } from "react-dom/client";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { Profile } from "@/api/types";
const mocks = vi.hoisted(() => ({
useCreateProfile: vi.fn(),
useUpdateProfile: vi.fn(),
useUploadProfileAvatar: vi.fn(),
useDeleteProfileAvatar: vi.fn(),
}));
vi.mock("@/hooks/queries/profiles", () => ({
useCreateProfile: () => mocks.useCreateProfile(),
useUpdateProfile: () => mocks.useUpdateProfile(),
useUploadProfileAvatar: () => mocks.useUploadProfileAvatar(),
useDeleteProfileAvatar: () => mocks.useDeleteProfileAvatar(),
}));
import { ProfileEditorDialog } from "./ProfileEditorDialog";
function makeProfile(overrides: Partial<Profile> = {}): Profile {
return {
id: "profile-1",
name: "Main",
avatar: "",
has_pin: false,
is_child: false,
is_primary: false,
max_content_rating: "",
quality_preference: "auto",
language: "en",
subtitle_language: "",
subtitle_mode: "auto",
show_forced_subtitles: true,
auto_skip_intro: false,
auto_skip_credits: false,
library_restrictions_enabled: false,
allowed_library_ids: null,
max_playback_quality: "",
created_at: "2026-04-06T00:00:00Z",
updated_at: "2026-04-06T00:00:00Z",
...overrides,
};
}
describe("ProfileEditorDialog", () => {
let container: HTMLDivElement;
let root: Root;
let originalResizeObserver: typeof globalThis.ResizeObserver | undefined;
beforeEach(() => {
(
globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean }
).IS_REACT_ACT_ENVIRONMENT = true;
container = document.createElement("div");
document.body.appendChild(container);
root = createRoot(container);
mocks.useCreateProfile.mockReset();
mocks.useUpdateProfile.mockReset();
mocks.useUploadProfileAvatar.mockReset();
mocks.useDeleteProfileAvatar.mockReset();
mocks.useCreateProfile.mockReturnValue({
isPending: false,
mutate: vi.fn(),
});
mocks.useUpdateProfile.mockReturnValue({
isPending: false,
mutate: vi.fn(),
});
mocks.useUploadProfileAvatar.mockReturnValue({
isPending: false,
mutate: vi.fn(),
mutateAsync: vi.fn(),
});
mocks.useDeleteProfileAvatar.mockReturnValue({
isPending: false,
mutate: vi.fn(),
mutateAsync: vi.fn(),
});
originalResizeObserver = globalThis.ResizeObserver;
globalThis.ResizeObserver = class ResizeObserver {
observe() {}
unobserve() {}
disconnect() {}
};
});
afterEach(async () => {
await act(async () => {
root.unmount();
});
container.remove();
if (originalResizeObserver) {
globalThis.ResizeObserver = originalResizeObserver;
} else {
Reflect.deleteProperty(globalThis, "ResizeObserver");
}
});
it("renders an unrestricted profile without throwing", async () => {
await act(async () => {
root.render(
<ProfileEditorDialog
open
profile={makeProfile({
max_content_rating: "",
max_playback_quality: "",
})}
libraries={[]}
onOpenChange={() => {}}
/>,
);
});
expect(document.body.textContent).toContain("Edit profile");
expect(document.body.textContent).toContain("Any content");
});
});