mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-30 18:30:32 -06:00
fix: renames init to setup (#4714)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useSyncExternalStore } from "react";
|
||||
import { SurveyWebView } from "@/components/survey-web-view";
|
||||
import { init } from "@/lib/common/initialize";
|
||||
import { Logger } from "@/lib/common/logger";
|
||||
import { setup } from "@/lib/common/setup";
|
||||
import { SurveyStore } from "@/lib/survey/store";
|
||||
|
||||
interface FormbricksProps {
|
||||
@@ -15,9 +15,9 @@ const logger = Logger.getInstance();
|
||||
export function Formbricks({ appUrl, environmentId }: FormbricksProps): React.JSX.Element | null {
|
||||
// initializes sdk
|
||||
useEffect(() => {
|
||||
const initialize = async (): Promise<void> => {
|
||||
const setupFormbricks = async (): Promise<void> => {
|
||||
try {
|
||||
await init({
|
||||
await setup({
|
||||
environmentId,
|
||||
appUrl,
|
||||
});
|
||||
@@ -26,7 +26,7 @@ export function Formbricks({ appUrl, environmentId }: FormbricksProps): React.JS
|
||||
}
|
||||
};
|
||||
|
||||
initialize().catch(() => {
|
||||
setupFormbricks().catch(() => {
|
||||
logger.debug("Initialization error");
|
||||
});
|
||||
}, [environmentId, appUrl]);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/* eslint-disable no-console -- we need to log global errors */
|
||||
import { checkInitialized } from "@/lib/common/initialize";
|
||||
import { checkSetup } from "@/lib/common/setup";
|
||||
import { wrapThrowsAsync } from "@/lib/common/utils";
|
||||
import type { Result } from "@/types/error";
|
||||
|
||||
export class CommandQueue {
|
||||
private queue: {
|
||||
command: (...args: any[]) => Promise<Result<void, unknown>> | Result<void, unknown> | Promise<void>;
|
||||
checkInitialized: boolean;
|
||||
checkSetup: boolean;
|
||||
commandArgs: any[];
|
||||
}[] = [];
|
||||
private running = false;
|
||||
@@ -15,10 +15,10 @@ export class CommandQueue {
|
||||
|
||||
public add<A>(
|
||||
command: (...args: A[]) => Promise<Result<void, unknown>> | Result<void, unknown> | Promise<void>,
|
||||
shouldCheckInitialized = true,
|
||||
shouldCheckSetup = true,
|
||||
...args: A[]
|
||||
): void {
|
||||
this.queue.push({ command, checkInitialized: shouldCheckInitialized, commandArgs: args });
|
||||
this.queue.push({ command, checkSetup: shouldCheckSetup, commandArgs: args });
|
||||
|
||||
if (!this.running) {
|
||||
this.commandPromise = new Promise((resolve) => {
|
||||
@@ -41,12 +41,12 @@ export class CommandQueue {
|
||||
|
||||
if (!currentItem) continue;
|
||||
|
||||
// make sure formbricks is initialized
|
||||
if (currentItem.checkInitialized) {
|
||||
// make sure formbricks is setup
|
||||
if (currentItem.checkSetup) {
|
||||
// call different function based on package type
|
||||
const initResult = checkInitialized();
|
||||
const setupResult = checkSetup();
|
||||
|
||||
if (!initResult.ok) {
|
||||
if (!setupResult.ok) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,26 +15,26 @@ import {
|
||||
type MissingFieldError,
|
||||
type MissingPersonError,
|
||||
type NetworkError,
|
||||
type NotInitializedError,
|
||||
type NotSetupError,
|
||||
type Result,
|
||||
err,
|
||||
okVoid,
|
||||
} from "@/types/error";
|
||||
|
||||
let isInitialized = false;
|
||||
let isSetup = false;
|
||||
|
||||
export const setIsInitialize = (state: boolean): void => {
|
||||
isInitialized = state;
|
||||
export const setIsSetup = (state: boolean): void => {
|
||||
isSetup = state;
|
||||
};
|
||||
|
||||
export const init = async (
|
||||
export const setup = async (
|
||||
configInput: TConfigInput
|
||||
): Promise<Result<void, MissingFieldError | NetworkError | MissingPersonError>> => {
|
||||
const appConfig = RNConfig.getInstance();
|
||||
const logger = Logger.getInstance();
|
||||
|
||||
if (isInitialized) {
|
||||
logger.debug("Already initialized, skipping initialization.");
|
||||
if (isSetup) {
|
||||
logger.debug("Already set up, skipping setup.");
|
||||
return okVoid();
|
||||
}
|
||||
|
||||
@@ -46,20 +46,20 @@ export const init = async (
|
||||
logger.debug("No existing configuration found.");
|
||||
}
|
||||
|
||||
// formbricks is in error state, skip initialization
|
||||
// formbricks is in error state, skip setup
|
||||
if (existingConfig?.status.value === "error") {
|
||||
logger.debug("Formbricks was set to an error state.");
|
||||
|
||||
const expiresAt = existingConfig.status.expiresAt;
|
||||
|
||||
if (expiresAt && isNowExpired(expiresAt)) {
|
||||
logger.debug("Error state is not expired, skipping initialization");
|
||||
logger.debug("Error state is not expired, skipping setup");
|
||||
return okVoid();
|
||||
}
|
||||
logger.debug("Error state is expired. Continue with initialization.");
|
||||
logger.debug("Error state is expired. Continue with setup.");
|
||||
}
|
||||
|
||||
logger.debug("Start initialize");
|
||||
logger.debug("Start setup");
|
||||
|
||||
if (!configInput.environmentId) {
|
||||
logger.debug("No environmentId provided");
|
||||
@@ -83,7 +83,7 @@ export const init = async (
|
||||
existingConfig.environmentId === configInput.environmentId &&
|
||||
existingConfig.appUrl === configInput.appUrl
|
||||
) {
|
||||
logger.debug("Configuration fits init parameters.");
|
||||
logger.debug("Configuration fits setup parameters.");
|
||||
let isEnvironmentStateExpired = false;
|
||||
let isUserStateExpired = false;
|
||||
|
||||
@@ -179,7 +179,7 @@ export const init = async (
|
||||
void appConfig.resetConfig();
|
||||
logger.debug("Syncing.");
|
||||
|
||||
// During init, if we don't have a valid config, we need to fetch the environment state
|
||||
// During setup, if we don't have a valid config, we need to fetch the environment state
|
||||
// but not the person state, we can set it to the default value.
|
||||
// The person state will be fetched when the `setUserId` method is called.
|
||||
|
||||
@@ -207,7 +207,7 @@ export const init = async (
|
||||
filteredSurveys,
|
||||
});
|
||||
} catch (e) {
|
||||
await handleErrorOnFirstInit(e as { code: string; responseMessage: string });
|
||||
await handleErrorOnFirstSetup(e as { code: string; responseMessage: string });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,21 +215,21 @@ export const init = async (
|
||||
addEventListeners();
|
||||
addCleanupEventListeners();
|
||||
|
||||
setIsInitialize(true);
|
||||
logger.debug("Initialized");
|
||||
setIsSetup(true);
|
||||
logger.debug("Set up complete");
|
||||
|
||||
// check page url if initialized after page load
|
||||
// check page url if set up after page load
|
||||
return okVoid();
|
||||
};
|
||||
|
||||
export const checkInitialized = (): Result<void, NotInitializedError> => {
|
||||
export const checkSetup = (): Result<void, NotSetupError> => {
|
||||
const logger = Logger.getInstance();
|
||||
logger.debug("Check if initialized");
|
||||
logger.debug("Check if set up");
|
||||
|
||||
if (!isInitialized) {
|
||||
if (!isSetup) {
|
||||
return err({
|
||||
code: "not_initialized",
|
||||
message: "Formbricks not initialized. Call initialize() first.",
|
||||
code: "not_setup",
|
||||
message: "Formbricks is not set up. Call setup() first.",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -237,21 +237,22 @@ export const checkInitialized = (): Result<void, NotInitializedError> => {
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await -- disabled for now
|
||||
export const deinitalize = async (): Promise<void> => {
|
||||
export const tearDown = async (): Promise<void> => {
|
||||
const logger = Logger.getInstance();
|
||||
const appConfig = RNConfig.getInstance();
|
||||
|
||||
logger.debug("Setting person state to default");
|
||||
logger.debug("Setting user state to default");
|
||||
// clear the user state and set it to the default value
|
||||
appConfig.update({
|
||||
...appConfig.get(),
|
||||
user: DEFAULT_USER_STATE_NO_USER_ID,
|
||||
});
|
||||
setIsInitialize(false);
|
||||
|
||||
setIsSetup(false);
|
||||
removeAllEventListeners();
|
||||
};
|
||||
|
||||
export const handleErrorOnFirstInit = async (e: {
|
||||
export const handleErrorOnFirstSetup = async (e: {
|
||||
code: string;
|
||||
responseMessage: string;
|
||||
}): Promise<never> => {
|
||||
@@ -260,9 +261,7 @@ export const handleErrorOnFirstInit = async (e: {
|
||||
if (e.code === "forbidden") {
|
||||
logger.error(`Authorization error: ${e.responseMessage}`);
|
||||
} else {
|
||||
logger.error(
|
||||
`Error during first initialization: ${e.code} - ${e.responseMessage}. Please try again later.`
|
||||
);
|
||||
logger.error(`Error during first setup: ${e.code} - ${e.responseMessage}. Please try again later.`);
|
||||
}
|
||||
|
||||
// put formbricks in error state (by creating a new config) and throw error
|
||||
@@ -277,5 +276,5 @@ export const handleErrorOnFirstInit = async (e: {
|
||||
await AsyncStorage.setItem(RN_ASYNC_STORAGE_KEY, JSON.stringify(initialErrorConfig));
|
||||
})();
|
||||
|
||||
throw new Error("Could not initialize formbricks");
|
||||
throw new Error("Could not set up formbricks");
|
||||
};
|
||||
@@ -1,11 +1,11 @@
|
||||
import { beforeEach, describe, expect, test, vi } from "vitest";
|
||||
import { CommandQueue } from "@/lib/common/command-queue";
|
||||
import { checkInitialized } from "@/lib/common/initialize";
|
||||
import { checkSetup } from "@/lib/common/setup";
|
||||
import { type Result } from "@/types/error";
|
||||
|
||||
// Mock the initialize module so we can control checkInitialized()
|
||||
vi.mock("@/lib/common/initialize", () => ({
|
||||
checkInitialized: vi.fn(),
|
||||
// Mock the setup module so we can control checkSetup()
|
||||
vi.mock("@/lib/common/setup", () => ({
|
||||
checkSetup: vi.fn(),
|
||||
}));
|
||||
|
||||
describe("CommandQueue", () => {
|
||||
@@ -47,8 +47,8 @@ describe("CommandQueue", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// We'll assume checkInitialized always ok for this test
|
||||
vi.mocked(checkInitialized).mockReturnValue({ ok: true, data: undefined });
|
||||
// We'll assume checkSetup always ok for this test
|
||||
vi.mocked(checkSetup).mockReturnValue({ ok: true, data: undefined });
|
||||
|
||||
// Enqueue commands
|
||||
queue.add(cmdA, true);
|
||||
@@ -61,7 +61,7 @@ describe("CommandQueue", () => {
|
||||
expect(executionOrder).toEqual(["A", "B", "C"]);
|
||||
});
|
||||
|
||||
test("skips execution if checkInitialized() fails", async () => {
|
||||
test("skips execution if checkSetup() fails", async () => {
|
||||
const cmd = vi.fn(async (): Promise<void> => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
@@ -70,12 +70,12 @@ describe("CommandQueue", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// Force checkInitialized to fail
|
||||
vi.mocked(checkInitialized).mockReturnValue({
|
||||
// Force checkSetup to fail
|
||||
vi.mocked(checkSetup).mockReturnValue({
|
||||
ok: false,
|
||||
error: {
|
||||
code: "not_initialized",
|
||||
message: "Not initialized",
|
||||
code: "not_setup",
|
||||
message: "Not setup",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -86,7 +86,7 @@ describe("CommandQueue", () => {
|
||||
expect(cmd).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("executes command if checkInitialized is false (no check)", async () => {
|
||||
test("executes command if checkSetup is false (no check)", async () => {
|
||||
const cmd = vi.fn(async (): Promise<Result<void, unknown>> => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
@@ -95,8 +95,8 @@ describe("CommandQueue", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// checkInitialized is irrelevant in this scenario, but let's mock it anyway
|
||||
vi.mocked(checkInitialized).mockReturnValue({ ok: true, data: undefined });
|
||||
// checkSetup is irrelevant in this scenario, but let's mock it anyway
|
||||
vi.mocked(checkSetup).mockReturnValue({ ok: true, data: undefined });
|
||||
|
||||
// Here we pass 'false' for the second argument, so no check is performed
|
||||
queue.add(cmd, false);
|
||||
@@ -114,8 +114,8 @@ describe("CommandQueue", () => {
|
||||
};
|
||||
});
|
||||
|
||||
// Force checkInitialized to succeed
|
||||
vi.mocked(checkInitialized).mockReturnValue({ ok: true, data: undefined });
|
||||
// Force checkSetup to succeed
|
||||
vi.mocked(checkSetup).mockReturnValue({ ok: true, data: undefined });
|
||||
|
||||
// Mock command that fails
|
||||
const failingCmd = vi.fn(async () => {
|
||||
@@ -151,7 +151,7 @@ describe("CommandQueue", () => {
|
||||
});
|
||||
});
|
||||
|
||||
vi.mocked(checkInitialized).mockReturnValue({ ok: true, data: undefined });
|
||||
vi.mocked(checkSetup).mockReturnValue({ ok: true, data: undefined });
|
||||
|
||||
queue.add(cmd1, true);
|
||||
queue.add(cmd2, true);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// initialize.test.ts
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { type Mock, type MockInstance, afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
||||
import { RNConfig, RN_ASYNC_STORAGE_KEY } from "@/lib/common/config";
|
||||
@@ -7,14 +6,8 @@ import {
|
||||
addEventListeners,
|
||||
removeAllEventListeners,
|
||||
} from "@/lib/common/event-listeners";
|
||||
import {
|
||||
checkInitialized,
|
||||
deinitalize,
|
||||
handleErrorOnFirstInit,
|
||||
init,
|
||||
setIsInitialize,
|
||||
} from "@/lib/common/initialize";
|
||||
import { Logger } from "@/lib/common/logger";
|
||||
import { checkSetup, handleErrorOnFirstSetup, setIsSetup, setup, tearDown } from "@/lib/common/setup";
|
||||
import { filterSurveys, isNowExpired } from "@/lib/common/utils";
|
||||
import { fetchEnvironmentState } from "@/lib/environment/state";
|
||||
import { DEFAULT_USER_STATE_NO_USER_ID } from "@/lib/user/state";
|
||||
@@ -77,7 +70,7 @@ vi.mock("@/lib/user/update", () => ({
|
||||
sendUpdatesToBackend: vi.fn(),
|
||||
}));
|
||||
|
||||
describe("initialize.ts", () => {
|
||||
describe("setup.ts", () => {
|
||||
let getInstanceConfigMock: MockInstance<() => RNConfig>;
|
||||
let getInstanceLoggerMock: MockInstance<() => Logger>;
|
||||
|
||||
@@ -88,8 +81,8 @@ describe("initialize.ts", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
// By default, set isInitialize to false so we can test init logic from scratch
|
||||
setIsInitialize(false);
|
||||
// By default, set isSetup to false so we can test setup logic from scratch
|
||||
setIsSetup(false);
|
||||
|
||||
getInstanceConfigMock = vi.spyOn(RNConfig, "getInstance");
|
||||
getInstanceLoggerMock = vi.spyOn(Logger, "getInstance").mockReturnValue(mockLogger as unknown as Logger);
|
||||
@@ -99,17 +92,17 @@ describe("initialize.ts", () => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("init()", () => {
|
||||
test("returns ok if already initialized", async () => {
|
||||
describe("setup()", () => {
|
||||
test("returns ok if already setup", async () => {
|
||||
getInstanceLoggerMock.mockReturnValue(mockLogger as unknown as Logger);
|
||||
setIsInitialize(true);
|
||||
const result = await init({ environmentId: "env_id", appUrl: "https://my.url" });
|
||||
setIsSetup(true);
|
||||
const result = await setup({ environmentId: "env_id", appUrl: "https://my.url" });
|
||||
expect(result.ok).toBe(true);
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith("Already initialized, skipping initialization.");
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith("Already set up, skipping setup.");
|
||||
});
|
||||
|
||||
test("fails if no environmentId is provided", async () => {
|
||||
const result = await init({ environmentId: "", appUrl: "https://my.url" });
|
||||
const result = await setup({ environmentId: "", appUrl: "https://my.url" });
|
||||
expect(result.ok).toBe(false);
|
||||
if (!result.ok) {
|
||||
expect(result.error.code).toBe("missing_field");
|
||||
@@ -117,14 +110,14 @@ describe("initialize.ts", () => {
|
||||
});
|
||||
|
||||
test("fails if no appUrl is provided", async () => {
|
||||
const result = await init({ environmentId: "env_123", appUrl: "" });
|
||||
const result = await setup({ environmentId: "env_123", appUrl: "" });
|
||||
expect(result.ok).toBe(false);
|
||||
if (!result.ok) {
|
||||
expect(result.error.code).toBe("missing_field");
|
||||
}
|
||||
});
|
||||
|
||||
test("skips init if existing config is in error state and not expired", async () => {
|
||||
test("skips setup if existing config is in error state and not expired", async () => {
|
||||
const mockConfig = {
|
||||
get: vi.fn().mockReturnValue({
|
||||
environmentId: "env_123",
|
||||
@@ -139,10 +132,10 @@ describe("initialize.ts", () => {
|
||||
|
||||
(isNowExpired as unknown as Mock).mockReturnValue(true);
|
||||
|
||||
const result = await init({ environmentId: "env_123", appUrl: "https://my.url" });
|
||||
const result = await setup({ environmentId: "env_123", appUrl: "https://my.url" });
|
||||
expect(result.ok).toBe(true);
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith("Formbricks was set to an error state.");
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith("Error state is not expired, skipping initialization");
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith("Error state is not expired, skipping setup");
|
||||
});
|
||||
|
||||
test("proceeds if error state is expired", async () => {
|
||||
@@ -158,10 +151,10 @@ describe("initialize.ts", () => {
|
||||
|
||||
getInstanceConfigMock.mockReturnValue(mockConfig as unknown as RNConfig);
|
||||
|
||||
const result = await init({ environmentId: "env_123", appUrl: "https://my.url" });
|
||||
const result = await setup({ environmentId: "env_123", appUrl: "https://my.url" });
|
||||
expect(result.ok).toBe(true);
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith("Formbricks was set to an error state.");
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith("Error state is expired. Continue with initialization.");
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith("Error state is expired. Continue with setup.");
|
||||
});
|
||||
|
||||
test("uses existing config if environmentId/appUrl match, checks for expiration sync", async () => {
|
||||
@@ -202,7 +195,7 @@ describe("initialize.ts", () => {
|
||||
|
||||
(filterSurveys as unknown as Mock).mockReturnValueOnce([{ name: "S1" }, { name: "S2" }]);
|
||||
|
||||
const result = await init({ environmentId: "env_123", appUrl: "https://my.url" });
|
||||
const result = await setup({ environmentId: "env_123", appUrl: "https://my.url" });
|
||||
expect(result.ok).toBe(true);
|
||||
|
||||
// environmentState was fetched
|
||||
@@ -246,7 +239,7 @@ describe("initialize.ts", () => {
|
||||
|
||||
(filterSurveys as unknown as Mock).mockReturnValueOnce([{ name: "SurveyA" }]);
|
||||
|
||||
const result = await init({ environmentId: "envX", appUrl: "https://urlX" });
|
||||
const result = await setup({ environmentId: "envX", appUrl: "https://urlX" });
|
||||
expect(result.ok).toBe(true);
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith("No existing configuration found.");
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith(
|
||||
@@ -269,7 +262,7 @@ describe("initialize.ts", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("calls handleErrorOnFirstInit if environment fetch fails initially", async () => {
|
||||
test("calls handleErrorOnFirstSetup if environment fetch fails initially", async () => {
|
||||
const mockConfig = {
|
||||
get: vi.fn().mockReturnValue(undefined),
|
||||
update: vi.fn(),
|
||||
@@ -283,12 +276,12 @@ describe("initialize.ts", () => {
|
||||
error: { code: "forbidden", responseMessage: "No access" },
|
||||
});
|
||||
|
||||
await expect(init({ environmentId: "envX", appUrl: "https://urlX" })).rejects.toThrow(
|
||||
"Could not initialize formbricks"
|
||||
await expect(setup({ environmentId: "envX", appUrl: "https://urlX" })).rejects.toThrow(
|
||||
"Could not set up formbricks"
|
||||
);
|
||||
});
|
||||
|
||||
test("adds event listeners and sets isInitialized", async () => {
|
||||
test("adds event listeners and sets isSetup", async () => {
|
||||
const mockConfig = {
|
||||
get: vi.fn().mockReturnValue({
|
||||
environmentId: "env_abc",
|
||||
@@ -302,30 +295,30 @@ describe("initialize.ts", () => {
|
||||
|
||||
getInstanceConfigMock.mockReturnValueOnce(mockConfig as unknown as RNConfig);
|
||||
|
||||
const result = await init({ environmentId: "env_abc", appUrl: "https://test.app" });
|
||||
const result = await setup({ environmentId: "env_abc", appUrl: "https://test.app" });
|
||||
expect(result.ok).toBe(true);
|
||||
expect(addEventListeners).toHaveBeenCalled();
|
||||
expect(addCleanupEventListeners).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("checkInitialized()", () => {
|
||||
test("returns err if not initialized", () => {
|
||||
const res = checkInitialized();
|
||||
describe("checkSetup()", () => {
|
||||
test("returns err if not setup", () => {
|
||||
const res = checkSetup();
|
||||
expect(res.ok).toBe(false);
|
||||
if (!res.ok) {
|
||||
expect(res.error.code).toBe("not_initialized");
|
||||
expect(res.error.code).toBe("not_setup");
|
||||
}
|
||||
});
|
||||
|
||||
test("returns ok if initialized", () => {
|
||||
setIsInitialize(true);
|
||||
const res = checkInitialized();
|
||||
test("returns ok if setup", () => {
|
||||
setIsSetup(true);
|
||||
const res = checkSetup();
|
||||
expect(res.ok).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("deinitalize()", () => {
|
||||
describe("tearDown()", () => {
|
||||
test("resets user state to default and removes event listeners", async () => {
|
||||
const mockConfig = {
|
||||
get: vi.fn().mockReturnValue({
|
||||
@@ -336,7 +329,7 @@ describe("initialize.ts", () => {
|
||||
|
||||
getInstanceConfigMock.mockReturnValueOnce(mockConfig as unknown as RNConfig);
|
||||
|
||||
await deinitalize();
|
||||
await tearDown();
|
||||
|
||||
expect(mockConfig.update).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
@@ -347,14 +340,14 @@ describe("initialize.ts", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("handleErrorOnFirstInit()", () => {
|
||||
describe("handleErrorOnFirstSetup()", () => {
|
||||
test("stores error state in AsyncStorage, throws error", async () => {
|
||||
// We import the function directly
|
||||
const errorObj = { code: "forbidden", responseMessage: "No access" };
|
||||
|
||||
await expect(async () => {
|
||||
await handleErrorOnFirstInit(errorObj);
|
||||
}).rejects.toThrow("Could not initialize formbricks");
|
||||
await handleErrorOnFirstSetup(errorObj);
|
||||
}).rejects.toThrow("Could not set up formbricks");
|
||||
|
||||
// AsyncStorage setItem should be called with the error config
|
||||
expect(AsyncStorage.setItem).toHaveBeenCalledWith(
|
||||
@@ -1,9 +1,9 @@
|
||||
import { type Mock, type MockInstance, beforeEach, describe, expect, test, vi } from "vitest";
|
||||
import { RNConfig } from "@/lib/common/config";
|
||||
import { deinitalize, init } from "@/lib/common/initialize";
|
||||
import { Logger } from "@/lib/common/logger";
|
||||
import { setup, tearDown } from "@/lib/common/setup";
|
||||
import { UpdateQueue } from "@/lib/user/update-queue";
|
||||
import { logout, logoutUser, setUserId } from "@/lib/user/user";
|
||||
import { logout, setUserId } from "@/lib/user/user";
|
||||
|
||||
// Mock dependencies
|
||||
vi.mock("@/lib/common/config", () => ({
|
||||
@@ -32,9 +32,9 @@ vi.mock("@/lib/user/update-queue", () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("@/lib/common/initialize", () => ({
|
||||
deinitalize: vi.fn(),
|
||||
init: vi.fn(),
|
||||
vi.mock("@/lib/common/setup", () => ({
|
||||
tearDown: vi.fn(),
|
||||
setup: vi.fn(),
|
||||
}));
|
||||
|
||||
describe("user.ts", () => {
|
||||
@@ -115,15 +115,8 @@ describe("user.ts", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("logoutUser", () => {
|
||||
test("calls deinitalize", async () => {
|
||||
await logoutUser();
|
||||
expect(deinitalize).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("logout", () => {
|
||||
test("successfully reinitializes after logout", async () => {
|
||||
test("successfully sets up formbricks after logout", async () => {
|
||||
const mockConfig = {
|
||||
get: vi.fn().mockReturnValue({
|
||||
environmentId: mockEnvironmentId,
|
||||
@@ -134,19 +127,19 @@ describe("user.ts", () => {
|
||||
|
||||
getInstanceConfigMock.mockReturnValue(mockConfig as unknown as RNConfig);
|
||||
|
||||
(init as Mock).mockResolvedValue(undefined);
|
||||
(setup as Mock).mockResolvedValue(undefined);
|
||||
|
||||
const result = await logout();
|
||||
|
||||
expect(deinitalize).toHaveBeenCalled();
|
||||
expect(init).toHaveBeenCalledWith({
|
||||
expect(tearDown).toHaveBeenCalled();
|
||||
expect(setup).toHaveBeenCalledWith({
|
||||
environmentId: mockEnvironmentId,
|
||||
appUrl: mockAppUrl,
|
||||
});
|
||||
expect(result.ok).toBe(true);
|
||||
});
|
||||
|
||||
test("returns error if initialization fails", async () => {
|
||||
test("returns error if setup fails", async () => {
|
||||
const mockConfig = {
|
||||
get: vi.fn().mockReturnValue({
|
||||
environmentId: mockEnvironmentId,
|
||||
@@ -158,12 +151,12 @@ describe("user.ts", () => {
|
||||
getInstanceConfigMock.mockReturnValue(mockConfig as unknown as RNConfig);
|
||||
|
||||
const mockError = { code: "network_error", message: "Failed to connect" };
|
||||
(init as Mock).mockRejectedValue(mockError);
|
||||
(setup as Mock).mockRejectedValue(mockError);
|
||||
|
||||
const result = await logout();
|
||||
|
||||
expect(deinitalize).toHaveBeenCalled();
|
||||
expect(init).toHaveBeenCalledWith({
|
||||
expect(tearDown).toHaveBeenCalled();
|
||||
expect(setup).toHaveBeenCalledWith({
|
||||
environmentId: mockEnvironmentId,
|
||||
appUrl: mockAppUrl,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { RNConfig } from "@/lib/common/config";
|
||||
import { deinitalize, init } from "@/lib/common/initialize";
|
||||
import { Logger } from "@/lib/common/logger";
|
||||
import { setup, tearDown } from "@/lib/common/setup";
|
||||
import { UpdateQueue } from "@/lib/user/update-queue";
|
||||
import { type ApiErrorResponse, type NetworkError, type Result, err, okVoid } from "@/types/error";
|
||||
|
||||
@@ -31,10 +31,6 @@ export const setUserId = async (userId: string): Promise<Result<void, ApiErrorRe
|
||||
return okVoid();
|
||||
};
|
||||
|
||||
export const logoutUser = async (): Promise<void> => {
|
||||
await deinitalize();
|
||||
};
|
||||
|
||||
export const logout = async (): Promise<Result<void, NetworkError>> => {
|
||||
const logger = Logger.getInstance();
|
||||
const appConfig = RNConfig.getInstance();
|
||||
@@ -52,10 +48,11 @@ export const logout = async (): Promise<Result<void, NetworkError>> => {
|
||||
appUrl: appConfig.get().appUrl,
|
||||
};
|
||||
|
||||
void logoutUser();
|
||||
// logout the user, remove user state and setup formbricks again
|
||||
await tearDown();
|
||||
|
||||
try {
|
||||
await init(initParams);
|
||||
await setup(initParams);
|
||||
return okVoid();
|
||||
} catch (e) {
|
||||
return err(e as NetworkError);
|
||||
|
||||
@@ -54,8 +54,8 @@ export interface NetworkError {
|
||||
url: URL;
|
||||
responseMessage: string;
|
||||
}
|
||||
export interface NotInitializedError {
|
||||
code: "not_initialized";
|
||||
export interface NotSetupError {
|
||||
code: "not_setup";
|
||||
message: string;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user