103 lines
3.2 KiB
TypeScript
103 lines
3.2 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
|
|
import {
|
|
getWidgetConnectionStatus,
|
|
resolveMatchingIntegrationsAsync,
|
|
tryLockSelection,
|
|
unlockSelection,
|
|
} from "./item-select-data";
|
|
|
|
describe("getWidgetConnectionStatus", () => {
|
|
const availableKinds = new Set(["sonarr" as const]);
|
|
|
|
it("reports widgets with a configured compatible integration as ready", () => {
|
|
expect(
|
|
getWidgetConnectionStatus({
|
|
supportedIntegrations: ["sonarr", "radarr"],
|
|
availableKinds,
|
|
connectionOptional: false,
|
|
}),
|
|
).toBe("ready");
|
|
});
|
|
|
|
it("reports required integrations that are not configured as needing setup", () => {
|
|
expect(
|
|
getWidgetConnectionStatus({
|
|
supportedIntegrations: ["radarr"],
|
|
availableKinds,
|
|
connectionOptional: false,
|
|
}),
|
|
).toBe("needsSetup");
|
|
});
|
|
|
|
it.each([
|
|
{ supportedIntegrations: [], connectionOptional: false },
|
|
{ supportedIntegrations: ["radarr" as const], connectionOptional: true },
|
|
])("reports a widget without a required connection", ({ supportedIntegrations, connectionOptional }) => {
|
|
expect(getWidgetConnectionStatus({ supportedIntegrations, availableKinds, connectionOptional })).toBe(
|
|
"noConnectionRequired",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("widget selection lock", () => {
|
|
it("rejects repeated selection synchronously until the active selection finishes", () => {
|
|
const lock = { current: false };
|
|
|
|
expect(tryLockSelection(lock)).toBe(true);
|
|
expect(tryLockSelection(lock)).toBe(false);
|
|
|
|
unlockSelection(lock);
|
|
expect(tryLockSelection(lock)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("resolveMatchingIntegrationsAsync", () => {
|
|
it("waits for the shared integration query before a cold integration-backed selection", async () => {
|
|
const ensureDataAsync = vi.fn(async () => [
|
|
{ id: "matching", kind: "sonarr" as const },
|
|
{ id: "other", kind: "radarr" as const },
|
|
]);
|
|
|
|
await expect(
|
|
resolveMatchingIntegrationsAsync({
|
|
hasIntegrationSupport: true,
|
|
supportedIntegrations: ["sonarr"],
|
|
currentData: undefined,
|
|
ensureDataAsync,
|
|
}),
|
|
).resolves.toEqual([{ id: "matching", kind: "sonarr" }]);
|
|
expect(ensureDataAsync).toHaveBeenCalledOnce();
|
|
});
|
|
|
|
it("does not wait for integrations when the widget has no integration support", async () => {
|
|
const ensureDataAsync = vi.fn(async () => [{ id: "unused", kind: "sonarr" as const }]);
|
|
|
|
await expect(
|
|
resolveMatchingIntegrationsAsync({
|
|
hasIntegrationSupport: false,
|
|
supportedIntegrations: [],
|
|
currentData: undefined,
|
|
ensureDataAsync,
|
|
}),
|
|
).resolves.toEqual([]);
|
|
expect(ensureDataAsync).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("excludes matching integrations the user cannot use", async () => {
|
|
const currentData = [
|
|
{ id: "allowed", kind: "sonarr" as const, permissions: { hasUseAccess: true } },
|
|
{ id: "blocked", kind: "sonarr" as const, permissions: { hasUseAccess: false } },
|
|
];
|
|
|
|
await expect(
|
|
resolveMatchingIntegrationsAsync({
|
|
hasIntegrationSupport: true,
|
|
supportedIntegrations: ["sonarr"],
|
|
currentData,
|
|
ensureDataAsync: vi.fn(),
|
|
}),
|
|
).resolves.toEqual([currentData[0]]);
|
|
});
|
|
});
|