A rejected submitKey dispatched the same ERROR action as a failed boot load, so the CWE-703 retry backoff armed on it and the auto refresh (LOAD_START) cleared the "invalid key" message ~1s after submit — LicenseCard has no local error state, the context is the only source. Split the state: load lifecycle (status/error, retried) vs validation (validating/validationError, never retried). VALIDATE_ERROR leaves status untouched, so a ready license stays ready on a typo'd key (no `ready` regression for gating consumers) and a boot-error retry loop keeps running through a failed validation. Reducer + initial state exported for tests, covered by LicenseContext.test.ts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
58 lines
1.5 KiB
TypeScript
58 lines
1.5 KiB
TypeScript
import { describe, it, expect, vi } from "vitest";
|
|
import { useIsPremium } from "./useIsPremium";
|
|
|
|
// useIsPremium now reads LicenseContext (was: useLicense). Mock the context hook.
|
|
vi.mock("../contexts/LicenseContext", () => ({
|
|
useLicenseContext: vi.fn(),
|
|
}));
|
|
|
|
import { useLicenseContext } from "../contexts/LicenseContext";
|
|
|
|
const mockUseLicenseContext = vi.mocked(useLicenseContext);
|
|
|
|
describe("useIsPremium", () => {
|
|
it('returns true when edition is "premium"', () => {
|
|
mockUseLicenseContext.mockReturnValue({
|
|
status: "ready",
|
|
edition: "premium",
|
|
features: [],
|
|
info: null,
|
|
error: null,
|
|
validating: false,
|
|
validationError: null,
|
|
refresh: vi.fn(),
|
|
submitKey: vi.fn(),
|
|
});
|
|
expect(useIsPremium()).toBe(true);
|
|
});
|
|
|
|
it('returns false when edition is "base"', () => {
|
|
mockUseLicenseContext.mockReturnValue({
|
|
status: "ready",
|
|
edition: "base",
|
|
features: [],
|
|
info: null,
|
|
error: null,
|
|
validating: false,
|
|
validationError: null,
|
|
refresh: vi.fn(),
|
|
submitKey: vi.fn(),
|
|
});
|
|
expect(useIsPremium()).toBe(false);
|
|
});
|
|
|
|
it('returns false when edition is "free"', () => {
|
|
mockUseLicenseContext.mockReturnValue({
|
|
status: "ready",
|
|
edition: "free",
|
|
features: [],
|
|
info: null,
|
|
error: null,
|
|
validating: false,
|
|
validationError: null,
|
|
refresh: vi.fn(),
|
|
submitKey: vi.fn(),
|
|
});
|
|
expect(useIsPremium()).toBe(false);
|
|
});
|
|
});
|