useCompleteOnboarding.spec.js
1 month ago
useDateRangePicker.spec.js
2 months ago
useEmail.spec.js
2 months ago
useEngagementChartData.spec.js
2 months ago
useLicenseSettings.spec.js
2 months ago
useLink.spec.js
2 months ago
useMediaDetail.spec.js
2 months ago
useMediaLibrary.spec.js
2 months ago
useMediaList.spec.js
1 month ago
usePerformanceSettings.spec.js
2 months ago
useRegisterActivePage.spec.js
2 months ago
useSettingOption.spec.js
2 months ago
useSimpleSettingsPage.spec.js
2 months ago
useTopPerforming.spec.js
2 months ago
useTopVideosPaginated.spec.js
2 months ago
useUpgradeCTA.spec.js
2 months ago
useUserDetail.spec.js
2 months ago
useSettingOption.spec.js
128 lines
| 1 | import { renderHook, act } from "@testing-library/react-hooks"; |
| 2 | |
| 3 | const mockUseSettingsData = jest.fn(); |
| 4 | |
| 5 | jest.mock("../../pages/settings/shared/SettingsDataProvider", () => ({ |
| 6 | useSettingsData: () => mockUseSettingsData(), |
| 7 | })); |
| 8 | |
| 9 | import useSettingOption from "../useSettingOption"; |
| 10 | |
| 11 | const stubData = (overrides = {}) => ({ |
| 12 | settings: {}, |
| 13 | lastSaved: {}, |
| 14 | isLoading: false, |
| 15 | savingKeys: new Set(), |
| 16 | updateLocal: jest.fn(), |
| 17 | resetKey: jest.fn(), |
| 18 | saveSlice: jest.fn(), |
| 19 | ...overrides, |
| 20 | }); |
| 21 | |
| 22 | beforeEach(() => { |
| 23 | mockUseSettingsData.mockReset(); |
| 24 | }); |
| 25 | |
| 26 | describe("useSettingOption", () => { |
| 27 | it("returns the stored value when present", () => { |
| 28 | mockUseSettingsData.mockReturnValue( |
| 29 | stubData({ |
| 30 | settings: { presto_branding: { logo: "x.png" } }, |
| 31 | lastSaved: { presto_branding: { logo: "x.png" } }, |
| 32 | }) |
| 33 | ); |
| 34 | |
| 35 | const { result } = renderHook(() => |
| 36 | useSettingOption("presto_branding", { logo: "" }) |
| 37 | ); |
| 38 | expect(result.current.data).toEqual({ logo: "x.png" }); |
| 39 | expect(result.current.isDirty).toBe(false); |
| 40 | }); |
| 41 | |
| 42 | it("falls back to defaultValue when the stored option is undefined", () => { |
| 43 | mockUseSettingsData.mockReturnValue(stubData()); |
| 44 | const { result } = renderHook(() => |
| 45 | useSettingOption("missing_key", { fallback: true }) |
| 46 | ); |
| 47 | expect(result.current.data).toEqual({ fallback: true }); |
| 48 | }); |
| 49 | |
| 50 | it("falls back to defaultValue when the stored option is null (WP schema-rejected)", () => { |
| 51 | mockUseSettingsData.mockReturnValue( |
| 52 | stubData({ settings: { foo: null } }) |
| 53 | ); |
| 54 | const { result } = renderHook(() => useSettingOption("foo", "default")); |
| 55 | expect(result.current.data).toBe("default"); |
| 56 | }); |
| 57 | |
| 58 | it("treats null in lastSaved as defaultValue when computing isDirty", () => { |
| 59 | mockUseSettingsData.mockReturnValue( |
| 60 | stubData({ |
| 61 | settings: { foo: "default" }, |
| 62 | lastSaved: { foo: null }, |
| 63 | }) |
| 64 | ); |
| 65 | const { result } = renderHook(() => useSettingOption("foo", "default")); |
| 66 | // data === defaultValue ("default") and effectiveSaved === defaultValue |
| 67 | // → not dirty. |
| 68 | expect(result.current.isDirty).toBe(false); |
| 69 | }); |
| 70 | |
| 71 | it("flags isDirty=true when local data differs from lastSaved", () => { |
| 72 | mockUseSettingsData.mockReturnValue( |
| 73 | stubData({ |
| 74 | settings: { foo: { a: 1 } }, |
| 75 | lastSaved: { foo: { a: 2 } }, |
| 76 | }) |
| 77 | ); |
| 78 | const { result } = renderHook(() => useSettingOption("foo", {})); |
| 79 | expect(result.current.isDirty).toBe(true); |
| 80 | }); |
| 81 | |
| 82 | it("uses deep equality so identical-shape objects are not dirty", () => { |
| 83 | mockUseSettingsData.mockReturnValue( |
| 84 | stubData({ |
| 85 | settings: { foo: { a: 1, b: { c: 2 } } }, |
| 86 | lastSaved: { foo: { a: 1, b: { c: 2 } } }, |
| 87 | }) |
| 88 | ); |
| 89 | const { result } = renderHook(() => useSettingOption("foo", {})); |
| 90 | expect(result.current.isDirty).toBe(false); |
| 91 | }); |
| 92 | |
| 93 | it("flags isSaving=true when the option key is in savingKeys", () => { |
| 94 | mockUseSettingsData.mockReturnValue( |
| 95 | stubData({ |
| 96 | settings: { foo: "x" }, |
| 97 | lastSaved: { foo: "x" }, |
| 98 | savingKeys: new Set(["foo"]), |
| 99 | }) |
| 100 | ); |
| 101 | const { result } = renderHook(() => useSettingOption("foo", "")); |
| 102 | expect(result.current.isSaving).toBe(true); |
| 103 | }); |
| 104 | |
| 105 | it("setData delegates to updateLocal(optionKey, next)", () => { |
| 106 | const updateLocal = jest.fn(); |
| 107 | mockUseSettingsData.mockReturnValue(stubData({ updateLocal })); |
| 108 | |
| 109 | const { result } = renderHook(() => useSettingOption("foo", "")); |
| 110 | act(() => { |
| 111 | result.current.setData("new-value"); |
| 112 | }); |
| 113 | expect(updateLocal).toHaveBeenCalledWith("foo", "new-value"); |
| 114 | }); |
| 115 | |
| 116 | it("save delegates to saveSlice([optionKey])", () => { |
| 117 | const saveSlice = jest.fn(); |
| 118 | mockUseSettingsData.mockReturnValue(stubData({ saveSlice })); |
| 119 | |
| 120 | const { result } = renderHook(() => useSettingOption("foo", "")); |
| 121 | act(() => { |
| 122 | result.current.save(); |
| 123 | }); |
| 124 | expect(saveSlice).toHaveBeenCalledWith(["foo"]); |
| 125 | }); |
| 126 | |
| 127 | }); |
| 128 |