feat: sonarqube + coderabbit

This commit is contained in:
Harsh Bhat
2026-03-11 11:25:18 +05:30
parent 9ec19adaba
commit 8f9daaaa43
9 changed files with 94 additions and 67 deletions
@@ -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: {
+9 -7
View File
@@ -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",
});
}
+64 -47
View File
@@ -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();
});
});
});
+10 -7
View File
@@ -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;
}
+1
View File
@@ -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 {