Skip to content

Commit

Permalink
refactor use useManagedStorageState instead of readManagedStorageByKey
Browse files Browse the repository at this point in the history
  • Loading branch information
mnholtz committed Oct 3, 2024
1 parent 4cba229 commit 1370d6a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 31 deletions.
59 changes: 32 additions & 27 deletions src/hooks/useTheme.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ import { initialTheme } from "@/themes/themeStore";
import { type AsyncState } from "@/types/sliceTypes";
import { themeStorage } from "@/themes/themeUtils";
import { activateTheme } from "@/background/messenger/api";
import { readManagedStorageByKey } from "@/store/enterprise/managedStorage";
import useManagedStorageState from "@/store/enterprise/useManagedStorageState";

afterEach(() => {
jest.clearAllMocks();
});

jest.mock("@/hooks/useAsyncExternalStore");
jest.mock("@/background/messenger/api");
jest.mock("@/store/enterprise/managedStorage");
jest.mock("@/store/enterprise/useManagedStorageState");

const customTheme = {
themeName: "custom",
Expand All @@ -49,16 +49,14 @@ describe("useTheme", () => {
jest
.mocked(useAsyncExternalStore)
.mockReturnValue({ data: initialTheme, isLoading: false } as AsyncState);
// eslint-disable-next-line no-restricted-syntax -- this func requires a parameter
jest.mocked(readManagedStorageByKey).mockResolvedValue(undefined);
jest.mocked(useManagedStorageState).mockReturnValue({
data: {},
isLoading: false,
});
});

test("calls useAsyncExternalStore and gets current theme state", async () => {
const { result: themeResult, waitForNextUpdate } = renderHook(() =>
useTheme(),
);

await waitForNextUpdate();
const { result: themeResult } = renderHook(() => useTheme());

expect(useAsyncExternalStore).toHaveBeenNthCalledWith(
1,
Expand All @@ -79,22 +77,22 @@ describe("useTheme", () => {
});
});

it("calls activateTheme after loading is done and it hasn't been called recently", async () => {
it("calls activateTheme after loading is done and it hasn't been called recently", () => {
jest.useFakeTimers();

jest.mocked(useAsyncExternalStore).mockReturnValue({
data: { ...initialTheme, lastFetched: Date.now() },
isLoading: false,
} as AsyncState);

let result = renderHook(() => useTheme());
await result.waitForNextUpdate();
renderHook(() => useTheme());

expect(activateTheme).not.toHaveBeenCalled();

jest.advanceTimersByTime(125_000);

result = renderHook(() => useTheme());
await result.waitForNextUpdate();
renderHook(() => useTheme());

expect(activateTheme).toHaveBeenCalledOnce();
});

Expand All @@ -105,11 +103,12 @@ describe("useTheme", () => {
data: { ...customTheme, showSidebarLogo: !policyValue },
isLoading: false,
} as AsyncState);
jest.mocked(readManagedStorageByKey).mockResolvedValue(policyValue);

const { result, waitForNextUpdate } = renderHook(() => useTheme());
jest.mocked(useManagedStorageState).mockReturnValue({
data: { showSidebarLogo: policyValue },
isLoading: false,
});

await waitForNextUpdate();
const { result } = renderHook(() => useTheme());

expect(result.current.activeTheme).toMatchObject({
...customTheme,
Expand All @@ -119,28 +118,34 @@ describe("useTheme", () => {
);

it.each([
{ scenario: "showSidebarLogo is undefined", mockPolicyValue: undefined },
{
scenario: "showSidebarLogo is undefined",
mockManagedStorageResult: undefined,
},
{
scenario: "error occurs",
mockPolicyValue: new Error("Managed storage error"),
mockManagedStorageResult: new Error("Managed storage error"),
},
])(
"uses activeTheme when $scenario in managed storage",
async ({ mockPolicyValue }) => {
async ({ mockManagedStorageResult }) => {
jest.mocked(useAsyncExternalStore).mockReturnValue({
data: customTheme,
isLoading: false,
} as AsyncState);

if (mockPolicyValue instanceof Error) {
jest.mocked(readManagedStorageByKey).mockRejectedValue(mockPolicyValue);
if (mockManagedStorageResult instanceof Error) {
jest.mocked(useManagedStorageState).mockImplementation(() => {
throw mockManagedStorageResult;
});
} else {
jest.mocked(readManagedStorageByKey).mockResolvedValue(mockPolicyValue);
jest.mocked(useManagedStorageState).mockReturnValue({
data: mockManagedStorageResult,
isLoading: false,
});
}

const { result, waitForNextUpdate } = renderHook(() => useTheme());

await waitForNextUpdate();
const { result } = renderHook(() => useTheme());

expect(result.current.activeTheme.showSidebarLogo).toBe(
customTheme.showSidebarLogo,
Expand Down
9 changes: 5 additions & 4 deletions src/hooks/useTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ import {
import { initialTheme } from "@/themes/themeStore";
import useAsyncExternalStore from "@/hooks/useAsyncExternalStore";
import { activateTheme } from "@/background/messenger/api";
import useAsyncState from "@/hooks/useAsyncState";
import { readManagedStorageByKey } from "@/store/enterprise/managedStorage";
import useManagedStorageState from "@/store/enterprise/useManagedStorageState";

const themeStorageSubscribe = (callback: () => void) => {
const abortController = new AbortController();
Expand All @@ -47,8 +46,10 @@ function useTheme(): { activeTheme: ThemeAssets; isLoading: boolean } {
const { data: cachedTheme, isLoading: isCachedThemeLoading } =
useAsyncExternalStore(themeStorageSubscribe, themeStorage.get);

const { data: showSidebarLogoOverride, isLoading: isManagedStorageLoading } =
useAsyncState(async () => readManagedStorageByKey("showSidebarLogo"), []);
const { data: managedStorageState, isLoading: isManagedStorageLoading } =
useManagedStorageState();

const showSidebarLogoOverride = managedStorageState?.showSidebarLogo;

const isLoading = isManagedStorageLoading || isCachedThemeLoading;

Expand Down

0 comments on commit 1370d6a

Please sign in to comment.