mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-23 13:48:58 -05:00
feat: sonarqube + coderabbit
This commit is contained in:
@@ -177,7 +177,7 @@ export const POST = async (request: Request, context: Context): Promise<Response
|
||||
|
||||
try {
|
||||
const posthogServer = getPostHogClient();
|
||||
posthogServer.capture({
|
||||
posthogServer?.capture({
|
||||
distinctId: environmentId,
|
||||
event: "survey_response_finished",
|
||||
properties: {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import posthog from "posthog-js";
|
||||
|
||||
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
|
||||
api_host: "/ingest",
|
||||
ui_host: "https://eu.posthog.com",
|
||||
defaults: "2026-01-30",
|
||||
capture_exceptions: true,
|
||||
debug: process.env.NODE_ENV === "development",
|
||||
});
|
||||
if (process.env.NEXT_PUBLIC_POSTHOG_KEY) {
|
||||
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
|
||||
api_host: "/ingest",
|
||||
ui_host: "https://eu.posthog.com",
|
||||
defaults: "2026-01-30",
|
||||
capture_exceptions: true,
|
||||
debug: process.env.NODE_ENV === "development",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ class MockPostHog {
|
||||
capture = mockCapture;
|
||||
}
|
||||
|
||||
vi.mock("server-only", () => ({}));
|
||||
|
||||
vi.mock("posthog-node", () => ({
|
||||
PostHog: MockPostHog,
|
||||
}));
|
||||
@@ -20,8 +22,6 @@ describe("posthog-server", () => {
|
||||
beforeEach(() => {
|
||||
vi.resetModules();
|
||||
vi.clearAllMocks();
|
||||
process.env.NEXT_PUBLIC_POSTHOG_KEY = "phc_test_key";
|
||||
process.env.NEXT_PUBLIC_POSTHOG_HOST = "https://eu.i.posthog.com";
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -29,58 +29,75 @@ describe("posthog-server", () => {
|
||||
delete process.env.NEXT_PUBLIC_POSTHOG_HOST;
|
||||
});
|
||||
|
||||
test("getPostHogClient returns a PostHog instance", async () => {
|
||||
const { getPostHogClient } = await import("./posthog-server");
|
||||
const client = getPostHogClient();
|
||||
expect(client).toBeDefined();
|
||||
expect(client.capture).toBeDefined();
|
||||
expect(client.shutdown).toBeDefined();
|
||||
});
|
||||
describe("when NEXT_PUBLIC_POSTHOG_KEY is set", () => {
|
||||
beforeEach(() => {
|
||||
process.env.NEXT_PUBLIC_POSTHOG_KEY = "phc_test_key";
|
||||
process.env.NEXT_PUBLIC_POSTHOG_HOST = "https://eu.i.posthog.com";
|
||||
});
|
||||
|
||||
test("getPostHogClient returns the same instance on subsequent calls (singleton)", async () => {
|
||||
const { getPostHogClient } = await import("./posthog-server");
|
||||
const client1 = getPostHogClient();
|
||||
const client2 = getPostHogClient();
|
||||
expect(client1).toBe(client2);
|
||||
});
|
||||
test("getPostHogClient returns a PostHog instance", async () => {
|
||||
const { getPostHogClient } = await import("./posthog-server");
|
||||
const client = getPostHogClient();
|
||||
expect(client).not.toBeNull();
|
||||
expect(client!.capture).toBeDefined();
|
||||
expect(client!.shutdown).toBeDefined();
|
||||
});
|
||||
|
||||
test("getPostHogClient creates PostHog with correct config", async () => {
|
||||
const { getPostHogClient } = await import("./posthog-server");
|
||||
const client = getPostHogClient() as unknown as MockPostHog;
|
||||
test("getPostHogClient returns the same instance on subsequent calls (singleton)", async () => {
|
||||
const { getPostHogClient } = await import("./posthog-server");
|
||||
const client1 = getPostHogClient();
|
||||
const client2 = getPostHogClient();
|
||||
expect(client1).toBe(client2);
|
||||
});
|
||||
|
||||
expect(client.apiKey).toBe("phc_test_key");
|
||||
expect(client.options).toEqual({
|
||||
host: "https://eu.i.posthog.com",
|
||||
flushAt: 1,
|
||||
flushInterval: 0,
|
||||
test("getPostHogClient creates PostHog with correct config", async () => {
|
||||
const { getPostHogClient } = await import("./posthog-server");
|
||||
const client = getPostHogClient() as unknown as MockPostHog;
|
||||
|
||||
expect(client.apiKey).toBe("phc_test_key");
|
||||
expect(client.options).toEqual({
|
||||
host: "https://eu.i.posthog.com",
|
||||
flushAt: 1,
|
||||
flushInterval: 0,
|
||||
});
|
||||
});
|
||||
|
||||
test("shutdownPostHog calls shutdown on the client", async () => {
|
||||
const { getPostHogClient, shutdownPostHog } = await import("./posthog-server");
|
||||
getPostHogClient();
|
||||
await shutdownPostHog();
|
||||
expect(mockShutdown).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
test("capture can be called on the client", async () => {
|
||||
const { getPostHogClient } = await import("./posthog-server");
|
||||
const client = getPostHogClient();
|
||||
client!.capture({
|
||||
distinctId: "env-123",
|
||||
event: "survey_response_finished",
|
||||
properties: { survey_id: "survey-1" },
|
||||
});
|
||||
expect(mockCapture).toHaveBeenCalledWith({
|
||||
distinctId: "env-123",
|
||||
event: "survey_response_finished",
|
||||
properties: { survey_id: "survey-1" },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("shutdownPostHog calls shutdown on the client", async () => {
|
||||
const { getPostHogClient, shutdownPostHog } = await import("./posthog-server");
|
||||
getPostHogClient();
|
||||
await shutdownPostHog();
|
||||
expect(mockShutdown).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
test("shutdownPostHog does nothing when no client exists", async () => {
|
||||
const { shutdownPostHog } = await import("./posthog-server");
|
||||
await shutdownPostHog();
|
||||
expect(mockShutdown).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("capture can be called on the client", async () => {
|
||||
const { getPostHogClient } = await import("./posthog-server");
|
||||
const client = getPostHogClient();
|
||||
client.capture({
|
||||
distinctId: "env-123",
|
||||
event: "survey_response_finished",
|
||||
properties: { survey_id: "survey-1" },
|
||||
describe("when NEXT_PUBLIC_POSTHOG_KEY is not set", () => {
|
||||
test("getPostHogClient returns null", async () => {
|
||||
delete process.env.NEXT_PUBLIC_POSTHOG_KEY;
|
||||
const { getPostHogClient } = await import("./posthog-server");
|
||||
const client = getPostHogClient();
|
||||
expect(client).toBeNull();
|
||||
});
|
||||
expect(mockCapture).toHaveBeenCalledWith({
|
||||
distinctId: "env-123",
|
||||
event: "survey_response_finished",
|
||||
properties: { survey_id: "survey-1" },
|
||||
|
||||
test("shutdownPostHog does nothing when no client exists", async () => {
|
||||
delete process.env.NEXT_PUBLIC_POSTHOG_KEY;
|
||||
const { shutdownPostHog } = await import("./posthog-server");
|
||||
await shutdownPostHog();
|
||||
expect(mockShutdown).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import "server-only";
|
||||
import { PostHog } from "posthog-node";
|
||||
|
||||
let posthogClient: PostHog | null = null;
|
||||
|
||||
export function getPostHogClient(): PostHog {
|
||||
if (!posthogClient) {
|
||||
posthogClient = new PostHog(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
|
||||
host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
|
||||
flushAt: 1,
|
||||
flushInterval: 0,
|
||||
});
|
||||
export function getPostHogClient(): PostHog | null {
|
||||
if (!process.env.NEXT_PUBLIC_POSTHOG_KEY) {
|
||||
return null;
|
||||
}
|
||||
|
||||
posthogClient ??= new PostHog(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
|
||||
host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
|
||||
flushAt: 1,
|
||||
flushInterval: 0,
|
||||
});
|
||||
return posthogClient;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
"enter_your_backup_code": "Enter your backup code",
|
||||
"enter_your_two_factor_authentication_code": "Enter your two-factor authentication code",
|
||||
"forgot_your_password": "Forgot your password?",
|
||||
"login_failed": "Login failed. Please try again.",
|
||||
"login_to_your_account": "Login to your account",
|
||||
"login_with_email": "Login with Email",
|
||||
"lost_access": "Lost Access?",
|
||||
|
||||
@@ -128,8 +128,9 @@ export const LoginForm = ({
|
||||
router.push(searchParams?.get("callbackUrl") ?? "/");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
posthog.captureException(error);
|
||||
toast.error(error.toString());
|
||||
toast.error(t("auth.login.login_failed"));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -129,10 +129,11 @@ export const SignupForm = ({
|
||||
: `/auth/verification-requested?token=${token}`;
|
||||
|
||||
if (createUserResponse?.data) {
|
||||
posthog.identify(data.email, { name: data.name, email: data.email });
|
||||
const normalizedEmail = data.email.trim().toLowerCase();
|
||||
posthog.identify(normalizedEmail, { name: data.name, email: normalizedEmail });
|
||||
posthog.capture("user_signed_up", {
|
||||
name: data.name,
|
||||
email: data.email,
|
||||
email: normalizedEmail,
|
||||
is_formbricks_cloud: isFormbricksCloud,
|
||||
has_invite_token: !!inviteToken,
|
||||
email_verification_disabled: emailVerificationDisabled,
|
||||
|
||||
@@ -157,7 +157,8 @@ export const AddWebhookModal = ({ environmentId, surveys, open, setOpen }: AddWe
|
||||
posthog.capture("webhook_created", {
|
||||
environment_id: environmentId,
|
||||
webhook_triggers: selectedTriggers,
|
||||
survey_count: selectedAllSurveys ? "all" : selectedSurveys.length,
|
||||
survey_count: selectedSurveys.length,
|
||||
all_surveys_selected: selectedAllSurveys,
|
||||
});
|
||||
router.refresh();
|
||||
setCreatedWebhook(createWebhookActionResult.data);
|
||||
|
||||
@@ -83,7 +83,8 @@ export const EditAPIKeys = ({ organizationId, apiKeys, locale, isReadOnly, proje
|
||||
setIsLoading(false);
|
||||
posthog.capture("api_key_created", {
|
||||
organization_id: organizationId,
|
||||
api_key_label: data.label,
|
||||
has_label: Boolean(data.label),
|
||||
label_length: data.label?.length ?? 0,
|
||||
});
|
||||
toast.success(t("environments.workspace.api_keys.api_key_created"));
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user