diff --git a/frontend/__tests__/root/config-metadata.spec.ts b/frontend/__tests__/root/config-metadata.spec.ts new file mode 100644 index 000000000..04f98b93e --- /dev/null +++ b/frontend/__tests__/root/config-metadata.spec.ts @@ -0,0 +1,278 @@ +import { configMetadata } from "../../src/ts/config-metadata"; +import * as Config from "../../src/ts/config"; +import { ConfigKey, Config as ConfigType } from "@monkeytype/schemas/configs"; + +const { replaceConfig, getConfig } = Config.__testing; + +type TestsByConfig = Partial<{ + [K in keyof ConfigType]: (T & { value: ConfigType[K] })[]; +}>; + +describe("ConfigMeta", () => { + afterAll(() => { + replaceConfig({}); + vi.resetModules(); + }); + it("should have changeRequiresRestart defined", () => { + const configsRequiringRestarts = Object.entries(configMetadata) + .filter(([_key, value]) => value.changeRequiresRestart === true) + .map(([key]) => key) + .sort(); + + expect(configsRequiringRestarts).toEqual( + [ + "punctuation", + "numbers", + "words", + "time", + "mode", + "quoteLength", + "language", + "difficulty", + "minWpmCustomSpeed", + "minWpm", + "minAcc", + "minAccCustom", + "minBurst", + "minBurstCustomSpeed", + "britishEnglish", + "funbox", + "customLayoutfluid", + "strictSpace", + "stopOnError", + "lazyMode", + "layout", + "codeUnindentOnBackspace", + ].sort() + ); + }); + + it("should have triggerResize defined", () => { + const configsWithTriggeResize = Object.entries(configMetadata) + .filter(([_key, value]) => value.triggerResize === true) + .map(([key]) => key) + .sort(); + + expect(configsWithTriggeResize).toEqual( + ["fontSize", "keymapSize", "maxLineWidth", "tapeMode"].sort() + ); + }); + describe("overrideValue", () => { + const testCases: TestsByConfig<{ + given?: Partial; + expected: Partial; + }> = { + punctuation: [ + { value: true, expected: { punctuation: true } }, + { + value: true, + given: { mode: "quote" }, + expected: { punctuation: false }, + }, + ], + numbers: [ + { value: true, expected: { numbers: true } }, + { + value: true, + given: { mode: "quote" }, + expected: { numbers: false }, + }, + ], + customLayoutfluid: [ + { + value: ["qwerty", "qwerty", "qwertz"], + expected: { customLayoutfluid: ["qwerty", "qwertz"] }, + }, + ], + customPolyglot: [ + { + value: ["english", "polish", "english"], + expected: { customPolyglot: ["english", "polish"] }, + }, + ], + keymapSize: [ + { value: 1, expected: { keymapSize: 1 } }, + { value: 1.234, expected: { keymapSize: 1.2 } }, + { value: 0.4, expected: { keymapSize: 0.5 } }, + { value: 3.6, expected: { keymapSize: 3.5 } }, + ], + customBackground: [ + { + value: " https://example.com/test.jpg ", + expected: { customBackground: "https://example.com/test.jpg" }, + }, + ], + accountChart: [ + { + value: ["on", "off", "off", "off"], + expected: { accountChart: ["on", "off", "off", "off"] }, + }, + { + value: ["off", "off", "off", "off"], + given: { accountChart: ["on", "off", "off", "off"] }, + expected: { accountChart: ["off", "on", "off", "off"] }, + }, + { + value: ["off", "off", "on", "on"], + given: { accountChart: ["off", "on", "off", "off"] }, + expected: { accountChart: ["on", "off", "on", "on"] }, + }, + ], + }; + + it.for( + Object.entries(testCases).flatMap(([key, value]) => + value.flatMap((it) => ({ key: key as ConfigKey, ...it })) + ) + )( + `$key value=$value given=$given expect=$expected`, + ({ key, value, given, expected }) => { + //GIVEN + replaceConfig(given ?? {}); + + //WHEN + Config.genericSet(key, value as any); + + //THEN + expect(getConfig()).toMatchObject(expected); + } + ); + }); + describe("isBlocked", () => { + const testCases: TestsByConfig<{ + given?: Partial; + fail?: true; + }> = { + funbox: [ + { + value: "gibberish" as any, + given: { mode: "quote" }, + fail: true, + }, + ], + showAllLines: [ + { value: true, given: { tapeMode: "off" } }, + { value: false, given: { tapeMode: "word" } }, + { value: true, given: { tapeMode: "word" }, fail: true }, + ], + }; + + it.for( + Object.entries(testCases).flatMap(([key, value]) => + value.flatMap((it) => ({ key: key as ConfigKey, ...it })) + ) + )( + `$key value=$value given=$given fail=$fail`, + ({ key, value, given, fail }) => { + //GIVEN + replaceConfig(given ?? {}); + + //WHEN + const applied = Config.genericSet(key, value as any); + + //THEN + expect(applied).toEqual(!fail); + } + ); + }); + + describe("overrideConfig", () => { + const testCases: TestsByConfig<{ + given: Partial; + expected?: Partial; + }> = { + mode: [ + { value: "time", given: { numbers: true, punctuation: true } }, + { + value: "custom", + given: { numbers: true, punctuation: true }, + expected: { numbers: false, punctuation: false }, + }, + { + value: "quote", + given: { numbers: true, punctuation: true }, + expected: { numbers: false, punctuation: false }, + }, + { + value: "zen", + given: { numbers: true, punctuation: true }, + expected: { numbers: false, punctuation: false }, + }, + ], + numbers: [{ value: false, given: { mode: "quote" } }], + freedomMode: [ + { + value: false, + given: { confidenceMode: "on" }, + expected: { confidenceMode: "on" }, + }, + { + value: true, + given: { confidenceMode: "on" }, + expected: { confidenceMode: "off" }, + }, + ], + stopOnError: [ + { + value: "off", + given: { confidenceMode: "on" }, + expected: { confidenceMode: "on" }, + }, + { + value: "word", + given: { confidenceMode: "on" }, + expected: { confidenceMode: "off" }, + }, + ], + confidenceMode: [ + { + value: "off", + given: { freedomMode: true, stopOnError: "word" }, + expected: { freedomMode: true, stopOnError: "word" }, + }, + { + value: "on", + given: { freedomMode: true, stopOnError: "word" }, + expected: { freedomMode: false, stopOnError: "off" }, + }, + ], + tapeMode: [ + { + value: "off", + given: { showAllLines: true }, + expected: { showAllLines: true }, + }, + { + value: "letter", + given: { showAllLines: true }, + expected: { showAllLines: false }, + }, + ], + theme: [ + { + value: "8008", + given: { customTheme: true }, + expected: { customTheme: false }, + }, + ], + }; + + it.for( + Object.entries(testCases).flatMap(([key, value]) => + value.flatMap((it) => ({ key: key as ConfigKey, ...it })) + ) + )( + `$key value=$value given=$given expected=$expected`, + ({ key, value, given, expected }) => { + //GIVEN + replaceConfig(given); + + //WHEN + Config.genericSet(key, value as any); + + //THEN + expect(getConfig()).toMatchObject(expected ?? {}); + } + ); + }); +}); diff --git a/frontend/__tests__/root/config.spec.ts b/frontend/__tests__/root/config.spec.ts index 2fd5860a2..03143a852 100644 --- a/frontend/__tests__/root/config.spec.ts +++ b/frontend/__tests__/root/config.spec.ts @@ -4,7 +4,7 @@ import { CustomThemeColors, FunboxName, ConfigKey, - Config as ConfigType, + CaretStyleSchema, } from "@monkeytype/schemas/configs"; import { randomBytes } from "crypto"; import { vi } from "vitest"; @@ -15,66 +15,60 @@ import * as DB from "../../src/ts/db"; import * as AccountButton from "../../src/ts/elements/account-button"; import * as Notifications from "../../src/ts/elements/notifications"; -type TestsByConfig = Partial<{ - [K in keyof ConfigType]: (T & { value: ConfigType[K] })[]; -}>; - -const { configMetadata, replaceConfig, getConfig } = Config.__testing; +const { replaceConfig, getConfig } = Config.__testing; describe("Config", () => { - const isDevEnvironmentMock = vi.spyOn(Misc, "isDevEnvironment"); - beforeEach(() => isDevEnvironmentMock.mockReset()); + describe("test with mocks", () => { + const isDevEnvironmentMock = vi.spyOn(Misc, "isDevEnvironment"); + + const canSetConfigWithCurrentFunboxesMock = vi.spyOn( + FunboxValidation, + "canSetConfigWithCurrentFunboxes" + ); + const isConfigValueValidMock = vi.spyOn( + ConfigValidation, + "isConfigValueValid" + ); + const dispatchConfigEventMock = vi.spyOn(ConfigEvent, "dispatch"); + const dbSaveConfigMock = vi.spyOn(DB, "saveConfig"); + const accountButtonLoadingMock = vi.spyOn(AccountButton, "loading"); + const notificationAddMock = vi.spyOn(Notifications, "add"); + const miscReloadAfterMock = vi.spyOn(Misc, "reloadAfter"); + const miscTriggerResizeMock = vi.spyOn(Misc, "triggerResize"); + + const mocks = [ + canSetConfigWithCurrentFunboxesMock, + isConfigValueValidMock, + dispatchConfigEventMock, + dbSaveConfigMock, + accountButtonLoadingMock, + notificationAddMock, + miscReloadAfterMock, + miscTriggerResizeMock, + ]; + + beforeEach(async () => { + vi.useFakeTimers(); + mocks.forEach((it) => it.mockReset()); + + vi.mock("../../src/ts/test/test-state", () => ({ + isActive: true, + })); + + isConfigValueValidMock.mockReturnValue(true); + canSetConfigWithCurrentFunboxesMock.mockReturnValue(true); + dbSaveConfigMock.mockResolvedValue(); - describe("configMeta", () => { - afterAll(() => { replaceConfig({}); - vi.resetModules(); - }); - it("should have changeRequiresRestart defined", () => { - const configsRequiringRestarts = Object.entries(configMetadata) - .filter(([_key, value]) => value.changeRequiresRestart === true) - .map(([key]) => key) - .sort(); - - expect(configsRequiringRestarts).toEqual( - [ - "punctuation", - "numbers", - "words", - "time", - "mode", - "quoteLength", - "language", - "difficulty", - "minWpmCustomSpeed", - "minWpm", - "minAcc", - "minAccCustom", - "minBurst", - "minBurstCustomSpeed", - "britishEnglish", - "funbox", - "customLayoutfluid", - "strictSpace", - "stopOnError", - "lazyMode", - "layout", - "codeUnindentOnBackspace", - ].sort() - ); }); - it("should have triggerResize defined", () => { - const configsWithTriggeResize = Object.entries(configMetadata) - .filter(([_key, value]) => value.triggerResize === true) - .map(([key]) => key) - .sort(); - - expect(configsWithTriggeResize).toEqual( - ["fontSize", "keymapSize", "maxLineWidth", "tapeMode"].sort() - ); + afterAll(() => { + mocks.forEach((it) => it.mockRestore()); + vi.useRealTimers(); }); + beforeEach(() => isDevEnvironmentMock.mockReset()); + it("should throw if config key in not found in metadata", () => { expect(() => { Config.genericSet("nonExistentKey" as ConfigKey, true); @@ -83,417 +77,198 @@ describe("Config", () => { ); }); - describe("overrideValue", () => { - const testCases: TestsByConfig<{ - given?: Partial; - expected: Partial; - }> = { - punctuation: [ - { value: true, expected: { punctuation: true } }, - { - value: true, - given: { mode: "quote" }, - expected: { punctuation: false }, - }, - ], - numbers: [ - { value: true, expected: { numbers: true } }, - { - value: true, - given: { mode: "quote" }, - expected: { numbers: false }, - }, - ], - customLayoutfluid: [ - { - value: ["qwerty", "qwerty", "qwertz"], - expected: { customLayoutfluid: ["qwerty", "qwertz"] }, - }, - ], - customPolyglot: [ - { - value: ["english", "polish", "english"], - expected: { customPolyglot: ["english", "polish"] }, - }, - ], - keymapSize: [ - { value: 1, expected: { keymapSize: 1 } }, - { value: 1.234, expected: { keymapSize: 1.2 } }, - { value: 0.4, expected: { keymapSize: 0.5 } }, - { value: 3.6, expected: { keymapSize: 3.5 } }, - ], - customBackground: [ - { - value: " https://example.com/test.jpg ", - expected: { customBackground: "https://example.com/test.jpg" }, - }, - ], - accountChart: [ - { - value: ["on", "off", "off", "off"], - expected: { accountChart: ["on", "off", "off", "off"] }, - }, - { - value: ["off", "off", "off", "off"], - given: { accountChart: ["on", "off", "off", "off"] }, - expected: { accountChart: ["off", "on", "off", "off"] }, - }, - { - value: ["off", "off", "on", "on"], - given: { accountChart: ["off", "on", "off", "off"] }, - expected: { accountChart: ["on", "off", "on", "on"] }, - }, - ], - }; + it("fails if test is active and funbox no_quit", () => { + //GIVEN + replaceConfig({ funbox: ["no_quit"], numbers: false }); - it.for( - Object.entries(testCases).flatMap(([key, value]) => - value.flatMap((it) => ({ key: key as ConfigKey, ...it })) - ) - )( - `$key value=$value given=$given expect=$expected`, - ({ key, value, given, expected }) => { - //GIVEN - replaceConfig(given ?? {}); + //WHEN + expect(Config.genericSet("numbers", true, true)).toBe(false); - //WHEN - Config.genericSet(key, value as any); - - //THEN - expect(getConfig()).toMatchObject(expected); + //THEN + expect(notificationAddMock).toHaveBeenCalledWith( + "No quit funbox is active. Please finish the test.", + 0, + { + important: true, } ); }); - describe("isBlocked", () => { - const testCases: TestsByConfig<{ - given?: Partial; - fail?: true; - }> = { - funbox: [ - { - value: "gibberish" as any, - given: { mode: "quote" }, - fail: true, - }, - ], - showAllLines: [ - { value: true, given: { tapeMode: "off" } }, - { value: false, given: { tapeMode: "word" } }, - { value: true, given: { tapeMode: "word" }, fail: true }, - ], - }; + //TODO isBlocked + it("should fail if config is blocked", () => { + //GIVEN + replaceConfig({ tapeMode: "letter" }); - it.for( - Object.entries(testCases).flatMap(([key, value]) => - value.flatMap((it) => ({ key: key as ConfigKey, ...it })) - ) - )( - `$key value=$value given=$given fail=$fail`, - ({ key, value, given, fail }) => { - //GIVEN - replaceConfig(given ?? {}); + //WHEN / THEN + expect(Config.genericSet("showAllLines", true)).toBe(false); + }); - //WHEN - const applied = Config.genericSet(key, value as any); + it("should use overrideValue", () => { + //WHEN + Config.genericSet("customLayoutfluid", ["3l", "ABNT2", "3l"]); - //THEN - expect(applied).toEqual(!fail); - } + //THEN + expect(getConfig().customLayoutfluid).toEqual(["3l", "ABNT2"]); + }); + + it("fails if config is invalid", () => { + //GIVEN + isConfigValueValidMock.mockReturnValue(false); + + //WHEN / THEN + expect(Config.genericSet("caretStyle", "banana" as any)).toBe(false); + expect(isConfigValueValidMock).toHaveBeenCalledWith( + "caret style", + "banana", + CaretStyleSchema ); }); - describe("overrideConfig", () => { - const testCases: TestsByConfig<{ - given: Partial; - expected?: Partial; - }> = { - mode: [ - { value: "time", given: { numbers: true, punctuation: true } }, - { - value: "custom", - given: { numbers: true, punctuation: true }, - expected: { numbers: false, punctuation: false }, - }, - { - value: "quote", - given: { numbers: true, punctuation: true }, - expected: { numbers: false, punctuation: false }, - }, - { - value: "zen", - given: { numbers: true, punctuation: true }, - expected: { numbers: false, punctuation: false }, - }, - ], - numbers: [{ value: false, given: { mode: "quote" } }], - freedomMode: [ - { - value: false, - given: { confidenceMode: "on" }, - expected: { confidenceMode: "on" }, - }, - { - value: true, - given: { confidenceMode: "on" }, - expected: { confidenceMode: "off" }, - }, - ], - stopOnError: [ - { - value: "off", - given: { confidenceMode: "on" }, - expected: { confidenceMode: "on" }, - }, - { - value: "word", - given: { confidenceMode: "on" }, - expected: { confidenceMode: "off" }, - }, - ], - confidenceMode: [ - { - value: "off", - given: { freedomMode: true, stopOnError: "word" }, - expected: { freedomMode: true, stopOnError: "word" }, - }, - { - value: "on", - given: { freedomMode: true, stopOnError: "word" }, - expected: { freedomMode: false, stopOnError: "off" }, - }, - ], - tapeMode: [ - { - value: "off", - given: { showAllLines: true }, - expected: { showAllLines: true }, - }, - { - value: "letter", - given: { showAllLines: true }, - expected: { showAllLines: false }, - }, - ], - theme: [ - { - value: "8008", - given: { customTheme: true }, - expected: { customTheme: false }, - }, - ], - }; + it("cannot set if funbox disallows", () => { + //GIVEN + canSetConfigWithCurrentFunboxesMock.mockReturnValue(false); - it.for( - Object.entries(testCases).flatMap(([key, value]) => - value.flatMap((it) => ({ key: key as ConfigKey, ...it })) - ) - )( - `$key value=$value given=$given expected=$expected`, - ({ key, value, given, expected }) => { - //GIVEN - replaceConfig(given); + //WHEN / THEN + expect(Config.genericSet("numbers", true)).toBe(false); + }); - //WHEN - Config.genericSet(key, value as any); + it("sets overrideConfigs", () => { + //GIVEN + replaceConfig({ + confidenceMode: "off", + freedomMode: false, //already set correctly + stopOnError: "letter", //should get updated + }); - //THEN - expect(getConfig()).toMatchObject(expected ?? {}); - } + //WHEN + Config.genericSet("confidenceMode", "max"); + + //THEN + expect(dispatchConfigEventMock).not.toHaveBeenCalledWith( + "freedomMode", + false, + true, + true + ); + + expect(dispatchConfigEventMock).toHaveBeenCalledWith( + "stopOnError", + "off", + true, + "letter" + ); + + expect(dispatchConfigEventMock).toHaveBeenCalledWith( + "confidenceMode", + "max", + false, + "off" ); }); - describe("test with mocks", () => { - const canSetConfigWithCurrentFunboxesMock = vi.spyOn( - FunboxValidation, - "canSetConfigWithCurrentFunboxes" + it("saves to localstorage if nosave=false", async () => { + //GIVEN + replaceConfig({ numbers: false }); + + //WHEN + Config.genericSet("numbers", true); + + //THEN + //wait for debounce + await vi.advanceTimersByTimeAsync(2500); + + //show loading + expect(accountButtonLoadingMock).toHaveBeenNthCalledWith(1, true); + + //save + expect(dbSaveConfigMock).toHaveBeenCalledWith({ numbers: true }); + + //hide loading + expect(accountButtonLoadingMock).toHaveBeenNthCalledWith(2, false); + + //send event + expect(dispatchConfigEventMock).toHaveBeenCalledWith( + "saveToLocalStorage", + expect.stringContaining("numbers") ); - const isConfigValueValidMock = vi.spyOn( - ConfigValidation, - "isConfigValueValid" + }); + it("does not save to localstorage if nosave=true", async () => { + //GIVEN + + replaceConfig({ numbers: false }); + + //WHEN + Config.genericSet("numbers", true, true); + + //THEN + //wait for debounce + await vi.advanceTimersByTimeAsync(2500); + + expect(accountButtonLoadingMock).not.toHaveBeenCalled(); + expect(dbSaveConfigMock).not.toHaveBeenCalled(); + + expect(dispatchConfigEventMock).not.toHaveBeenCalledWith( + "saveToLocalStorage", + expect.any(String) ); - const dispatchConfigEventMock = vi.spyOn(ConfigEvent, "dispatch"); - const dbSaveConfigMock = vi.spyOn(DB, "saveConfig"); - const accountButtonLoadingMock = vi.spyOn(AccountButton, "loading"); - const notificationAddMock = vi.spyOn(Notifications, "add"); - const miscReloadAfterMock = vi.spyOn(Misc, "reloadAfter"); + }); - const mocks = [ - canSetConfigWithCurrentFunboxesMock, - isConfigValueValidMock, - dispatchConfigEventMock, - dbSaveConfigMock, - accountButtonLoadingMock, - notificationAddMock, - miscReloadAfterMock, - ]; + it("dispatches event on set", () => { + //GIVEN + replaceConfig({ numbers: false }); - beforeEach(async () => { - vi.useFakeTimers(); - mocks.forEach((it) => it.mockReset()); + //WHEN + Config.genericSet("numbers", true, true); - vi.mock("../../src/ts/test/test-state", () => ({ - isActive: true, - })); + //THEN - isConfigValueValidMock.mockReturnValue(true); - canSetConfigWithCurrentFunboxesMock.mockReturnValue(true); - dbSaveConfigMock.mockResolvedValue(); - }); + expect(dispatchConfigEventMock).toHaveBeenCalledWith( + "numbers", + true, + true, + false + ); + }); - afterAll(() => { - mocks.forEach((it) => it.mockRestore()); - vi.useRealTimers(); - }); + it("triggers resize if property is set", () => { + ///WHEN + Config.genericSet("maxLineWidth", 50, false); - it("cannot set if funbox disallows", () => { - //GIVEN - canSetConfigWithCurrentFunboxesMock.mockReturnValue(false); + expect(miscTriggerResizeMock).toHaveBeenCalled(); + }); - //WHEN / THEN - expect(Config.genericSet("numbers", true)).toBe(false); - }); + it("does not triggers resize if property is not set", () => { + ///WHEN + Config.genericSet("startGraphsAtZero", true, false); - it("fails if config is invalid", () => { - //GIVEN - isConfigValueValidMock.mockReturnValue(false); + expect(miscTriggerResizeMock).not.toHaveBeenCalled(); + }); - //WHEN / THEN - expect(Config.genericSet("numbers", "off" as any)).toBe(false); - }); + it("does not triggers resize if property on nosave", () => { + ///WHEN + Config.genericSet("maxLineWidth", 50, true); - it("dispatches event on set", () => { - //GIVEN - replaceConfig({ numbers: false }); + expect(miscTriggerResizeMock).not.toHaveBeenCalled(); + }); - //WHEN - Config.genericSet("numbers", true, true); + it("calls afterSet", () => { + //GIVEN + isDevEnvironmentMock.mockReturnValue(false); + replaceConfig({ ads: "off" }); - //THEN + //WHEN + Config.genericSet("ads", "sellout"); - expect(dispatchConfigEventMock).toHaveBeenCalledWith( - "numbers", - true, - true, - false - ); - }); - - it("saves to localstorage if nosave=false", async () => { - //GIVEN - replaceConfig({ numbers: false }); - - //WHEN - Config.genericSet("numbers", true); - - //THEN - //wait for debounce - await vi.advanceTimersByTimeAsync(2500); - - //show loading - expect(accountButtonLoadingMock).toHaveBeenNthCalledWith(1, true); - - //save - expect(dbSaveConfigMock).toHaveBeenCalledWith({ numbers: true }); - - //hide loading - expect(accountButtonLoadingMock).toHaveBeenNthCalledWith(2, false); - - //send event - expect(dispatchConfigEventMock).toHaveBeenCalledWith( - "saveToLocalStorage", - expect.stringContaining("numbers") - ); - }); - it("does not save to localstorage if nosave=true", async () => { - //GIVEN - - replaceConfig({ numbers: false }); - - //WHEN - Config.genericSet("numbers", true, true); - - //THEN - //wait for debounce - await vi.advanceTimersByTimeAsync(2500); - - expect(accountButtonLoadingMock).not.toHaveBeenCalled(); - expect(dbSaveConfigMock).not.toHaveBeenCalled(); - - expect(dispatchConfigEventMock).not.toHaveBeenCalledWith( - "saveToLocalStorage", - expect.any(String) - ); - }); - it("calls afterSet", () => { - //GIVEN - isDevEnvironmentMock.mockReturnValue(false); - replaceConfig({ ads: "off" }); - - //WHEN - Config.genericSet("ads", "sellout"); - - //THEN - expect(notificationAddMock).toHaveBeenCalledWith( - "Ad settings changed. Refreshing...", - 0 - ); - expect(miscReloadAfterMock).toHaveBeenCalledWith(3); - }); - - it("fails if test is active and funbox no_quit", () => { - //GIVEN - replaceConfig({ funbox: ["no_quit"], numbers: false }); - - //WHEN - expect(Config.genericSet("numbers", true, true)).toBe(false); - - //THEN - expect(notificationAddMock).toHaveBeenCalledWith( - "No quit funbox is active. Please finish the test.", - 0, - { - important: true, - } - ); - }); - - it("sends configEvents for overrideConfigs", () => { - //GIVEN - replaceConfig({ - confidenceMode: "off", - freedomMode: true, - stopOnError: "letter", - }); - - //WHEN - Config.genericSet("confidenceMode", "max"); - - //THEN - expect(dispatchConfigEventMock).toHaveBeenCalledWith( - "freedomMode", - false, - true, - true - ); - - expect(dispatchConfigEventMock).toHaveBeenCalledWith( - "stopOnError", - "off", - true, - "letter" - ); - - expect(dispatchConfigEventMock).toHaveBeenCalledWith( - "confidenceMode", - "max", - false, - "off" - ); - }); + //THEN + expect(notificationAddMock).toHaveBeenCalledWith( + "Ad settings changed. Refreshing...", + 0 + ); + expect(miscReloadAfterMock).toHaveBeenCalledWith(3); }); }); + //TODO move the rest to schema/tests or remove after removing the setX functions from Config it("setMode", () => { expect(Config.setMode("zen")).toBe(true); expect(Config.setMode("invalid" as any)).toBe(false); diff --git a/frontend/src/ts/config.ts b/frontend/src/ts/config.ts index 7cef16028..da06fd463 100644 --- a/frontend/src/ts/config.ts +++ b/frontend/src/ts/config.ts @@ -12,6 +12,7 @@ import { createErrorMessage, isObject, promiseWithResolvers, + triggerResize, typedKeys, } from "./utils/misc"; import * as ConfigSchemas from "@monkeytype/schemas/configs"; @@ -200,7 +201,7 @@ export function genericSet( ConfigEvent.dispatch(key, value, nosave, previousValue); if (metadata.triggerResize && !nosave) { - $(window).trigger("resize"); + triggerResize(); } metadata.afterSet?.({ nosave: nosave || false, currentConfig: config }); diff --git a/frontend/src/ts/utils/misc.ts b/frontend/src/ts/utils/misc.ts index debae3866..62bdaea32 100644 --- a/frontend/src/ts/utils/misc.ts +++ b/frontend/src/ts/utils/misc.ts @@ -760,4 +760,7 @@ export function sanitize( ) as z.infer; } +export function triggerResize(): void { + $(window).trigger("resize"); +} // DO NOT ALTER GLOBAL OBJECTSONSTRUCTOR, IT WILL BREAK RESULT HASHES