mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-16 00:51:52 +00:00
80c5363649
Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
266 lines
7.8 KiB
TypeScript
266 lines
7.8 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
import {
|
|
assertGatedIntegrations,
|
|
readGatedEnv,
|
|
warnGatedIntegrationsMisconfig,
|
|
} from "./integrations";
|
|
|
|
// Every env var any gated integration reads. Cleared before each test so the
|
|
// assertions never depend on ambient shell/CI env.
|
|
const GATED_ENV_VARS = [
|
|
"UI_SENTRY_ENABLED",
|
|
"UI_SENTRY_DSN",
|
|
"NEXT_PUBLIC_SENTRY_DSN",
|
|
"UI_SENTRY_ENVIRONMENT",
|
|
"NEXT_PUBLIC_SENTRY_ENVIRONMENT",
|
|
"UI_GOOGLE_TAG_MANAGER_ENABLED",
|
|
"UI_GOOGLE_TAG_MANAGER_ID",
|
|
"NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID",
|
|
"UI_POSTHOG_ENABLED",
|
|
"UI_POSTHOG_KEY",
|
|
"POSTHOG_KEY",
|
|
"UI_POSTHOG_HOST",
|
|
"POSTHOG_HOST",
|
|
] as const;
|
|
|
|
beforeEach(() => {
|
|
for (const key of GATED_ENV_VARS) {
|
|
vi.stubEnv(key, undefined);
|
|
}
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllEnvs();
|
|
});
|
|
|
|
describe("readGatedEnv", () => {
|
|
it("returns the primary value when the integration is enabled", () => {
|
|
// Given
|
|
vi.stubEnv("UI_SENTRY_ENABLED", "true");
|
|
vi.stubEnv("UI_SENTRY_DSN", "https://dsn.example");
|
|
|
|
// When / Then
|
|
expect(
|
|
readGatedEnv(
|
|
"UI_SENTRY_ENABLED",
|
|
"UI_SENTRY_DSN",
|
|
"NEXT_PUBLIC_SENTRY_DSN",
|
|
),
|
|
).toBe("https://dsn.example");
|
|
});
|
|
|
|
it("falls back to the legacy value when enabled and the primary is unset", () => {
|
|
// Given
|
|
vi.stubEnv("UI_SENTRY_ENABLED", "true");
|
|
vi.stubEnv("NEXT_PUBLIC_SENTRY_DSN", "https://legacy.example");
|
|
|
|
// When / Then
|
|
expect(
|
|
readGatedEnv(
|
|
"UI_SENTRY_ENABLED",
|
|
"UI_SENTRY_DSN",
|
|
"NEXT_PUBLIC_SENTRY_DSN",
|
|
),
|
|
).toBe("https://legacy.example");
|
|
});
|
|
|
|
it("ignores the primary (new) value when disabled and no legacy is set", () => {
|
|
// Given - the new UI_* name only counts when the enable flag is "true"
|
|
vi.stubEnv("UI_SENTRY_ENABLED", "false");
|
|
vi.stubEnv("UI_SENTRY_DSN", "https://dsn.example");
|
|
|
|
// When / Then
|
|
expect(
|
|
readGatedEnv(
|
|
"UI_SENTRY_ENABLED",
|
|
"UI_SENTRY_DSN",
|
|
"NEXT_PUBLIC_SENTRY_DSN",
|
|
),
|
|
).toBeNull();
|
|
});
|
|
|
|
it("returns the legacy value when disabled (legacy ignores the enable flag)", () => {
|
|
// Given - legacy names stay backward compatible: they work without the flag
|
|
vi.stubEnv("UI_SENTRY_ENABLED", "false");
|
|
vi.stubEnv("NEXT_PUBLIC_SENTRY_DSN", "https://legacy.example");
|
|
|
|
// When / Then
|
|
expect(
|
|
readGatedEnv(
|
|
"UI_SENTRY_ENABLED",
|
|
"UI_SENTRY_DSN",
|
|
"NEXT_PUBLIC_SENTRY_DSN",
|
|
),
|
|
).toBe("https://legacy.example");
|
|
});
|
|
|
|
it("returns the legacy value when disabled even if the new value is also set", () => {
|
|
// Given - new value is ignored without the flag; legacy still activates
|
|
vi.stubEnv("UI_SENTRY_ENABLED", "false");
|
|
vi.stubEnv("UI_SENTRY_DSN", "https://dsn.example");
|
|
vi.stubEnv("NEXT_PUBLIC_SENTRY_DSN", "https://legacy.example");
|
|
|
|
// When / Then
|
|
expect(
|
|
readGatedEnv(
|
|
"UI_SENTRY_ENABLED",
|
|
"UI_SENTRY_DSN",
|
|
"NEXT_PUBLIC_SENTRY_DSN",
|
|
),
|
|
).toBe("https://legacy.example");
|
|
});
|
|
|
|
it("returns null when the enable flag is unset and only the new name is set", () => {
|
|
// Given
|
|
vi.stubEnv("UI_SENTRY_DSN", "https://dsn.example");
|
|
|
|
// When / Then
|
|
expect(readGatedEnv("UI_SENTRY_ENABLED", "UI_SENTRY_DSN")).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("assertGatedIntegrations", () => {
|
|
it("does not throw when every integration is disabled (the default)", () => {
|
|
expect(() => assertGatedIntegrations()).not.toThrow();
|
|
});
|
|
|
|
it("throws when Sentry is enabled but the DSN is unset", () => {
|
|
// Given
|
|
vi.stubEnv("UI_SENTRY_ENABLED", "true");
|
|
|
|
// When / Then
|
|
expect(() => assertGatedIntegrations()).toThrow("UI_SENTRY_DSN");
|
|
});
|
|
|
|
it("does not throw when Sentry is enabled and the DSN is present", () => {
|
|
// Given
|
|
vi.stubEnv("UI_SENTRY_ENABLED", "true");
|
|
vi.stubEnv("UI_SENTRY_DSN", "https://dsn.example");
|
|
|
|
// When / Then
|
|
expect(() => assertGatedIntegrations()).not.toThrow();
|
|
});
|
|
|
|
it("accepts the legacy DSN name when Sentry is enabled", () => {
|
|
// Given
|
|
vi.stubEnv("UI_SENTRY_ENABLED", "true");
|
|
vi.stubEnv("NEXT_PUBLIC_SENTRY_DSN", "https://legacy.example");
|
|
|
|
// When / Then
|
|
expect(() => assertGatedIntegrations()).not.toThrow();
|
|
});
|
|
|
|
it("does not require the optional Sentry environment when enabled", () => {
|
|
// Given - DSN present, UI_SENTRY_ENVIRONMENT intentionally unset
|
|
vi.stubEnv("UI_SENTRY_ENABLED", "true");
|
|
vi.stubEnv("UI_SENTRY_DSN", "https://dsn.example");
|
|
|
|
// When / Then
|
|
expect(() => assertGatedIntegrations()).not.toThrow();
|
|
});
|
|
|
|
it("throws when GTM is enabled without an id", () => {
|
|
// Given
|
|
vi.stubEnv("UI_GOOGLE_TAG_MANAGER_ENABLED", "true");
|
|
|
|
// When / Then
|
|
expect(() => assertGatedIntegrations()).toThrow("UI_GOOGLE_TAG_MANAGER_ID");
|
|
});
|
|
|
|
it("requires BOTH UI_POSTHOG_KEY and UI_POSTHOG_HOST when PostHog is enabled", () => {
|
|
// Given - key set, host missing
|
|
vi.stubEnv("UI_POSTHOG_ENABLED", "true");
|
|
vi.stubEnv("UI_POSTHOG_KEY", "phc_key");
|
|
|
|
// When / Then
|
|
expect(() => assertGatedIntegrations()).toThrow("UI_POSTHOG_HOST");
|
|
});
|
|
|
|
it("does not throw when PostHog is enabled with both key and host", () => {
|
|
// Given
|
|
vi.stubEnv("UI_POSTHOG_ENABLED", "true");
|
|
vi.stubEnv("UI_POSTHOG_KEY", "phc_key");
|
|
vi.stubEnv("UI_POSTHOG_HOST", "https://eu.i.posthog.com");
|
|
|
|
// When / Then
|
|
expect(() => assertGatedIntegrations()).not.toThrow();
|
|
});
|
|
|
|
it("accepts the legacy Sentry DSN without the enable flag", () => {
|
|
// Given - backward compat: legacy presence activates without the flag
|
|
vi.stubEnv("NEXT_PUBLIC_SENTRY_DSN", "https://legacy.example");
|
|
|
|
// When / Then
|
|
expect(() => assertGatedIntegrations()).not.toThrow();
|
|
});
|
|
|
|
it("accepts the legacy PostHog names without the enable flag", () => {
|
|
// Given - both legacy names present, no UI_POSTHOG_ENABLED
|
|
vi.stubEnv("POSTHOG_KEY", "phc_key");
|
|
vi.stubEnv("POSTHOG_HOST", "https://eu.i.posthog.com");
|
|
|
|
// When / Then
|
|
expect(() => assertGatedIntegrations()).not.toThrow();
|
|
});
|
|
|
|
it("throws when a partial legacy PostHog config is set without the enable flag", () => {
|
|
// Given - one legacy name present; the full legacy set is then required
|
|
vi.stubEnv("POSTHOG_KEY", "phc_key");
|
|
|
|
// When / Then
|
|
expect(() => assertGatedIntegrations()).toThrow("POSTHOG_HOST");
|
|
});
|
|
});
|
|
|
|
describe("warnGatedIntegrationsMisconfig", () => {
|
|
it("warns when a config value is set but its enable flag is not 'true'", () => {
|
|
// Given
|
|
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
vi.stubEnv("UI_SENTRY_DSN", "https://dsn.example");
|
|
|
|
// When
|
|
warnGatedIntegrationsMisconfig();
|
|
|
|
// Then
|
|
expect(warn).toHaveBeenCalledTimes(1);
|
|
expect(warn.mock.calls[0][0]).toContain("UI_SENTRY_ENABLED");
|
|
});
|
|
|
|
it("does not warn when the integration is enabled", () => {
|
|
// Given
|
|
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
vi.stubEnv("UI_SENTRY_ENABLED", "true");
|
|
vi.stubEnv("UI_SENTRY_DSN", "https://dsn.example");
|
|
|
|
// When
|
|
warnGatedIntegrationsMisconfig();
|
|
|
|
// Then
|
|
expect(warn).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("does not warn when nothing is configured", () => {
|
|
// Given
|
|
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
|
|
// When
|
|
warnGatedIntegrationsMisconfig();
|
|
|
|
// Then
|
|
expect(warn).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("does not warn when only a legacy name is set without the enable flag", () => {
|
|
// Given - legacy stays backward compatible, so it loads and is not a misconfig
|
|
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
|
|
vi.stubEnv("NEXT_PUBLIC_SENTRY_DSN", "https://legacy.example");
|
|
|
|
// When
|
|
warnGatedIntegrationsMisconfig();
|
|
|
|
// Then
|
|
expect(warn).not.toHaveBeenCalled();
|
|
});
|
|
});
|