Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default feature flags as an object #5810

Merged
merged 10 commits into from
Nov 22, 2024
26 changes: 22 additions & 4 deletions frontend/src/lib/constants/environment.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,36 @@ export interface FeatureFlags<T> {
TEST_FLAG_EDITABLE: T;
TEST_FLAG_NOT_EDITABLE: T;
}
export const defaultFeatureFlagValues: FeatureFlags<boolean> = {
ENABLE_CKTESTBTC: false,
DISABLE_IMPORT_TOKEN_VALIDATION_FOR_TESTING: false,
ENABLE_PERIODIC_FOLLOWING_CONFIRMATION: false,
ENABLE_EXPORT_NEURONS_REPORT: false,
TEST_FLAG_EDITABLE: false,
TEST_FLAG_NOT_EDITABLE: false,
};

export type FeatureKey = keyof FeatureFlags<boolean>;

const getFeatureFlagsFromEnv = (): FeatureFlags<boolean> => {
let featureFlags = {};
try {
mstrasinskis marked this conversation as resolved.
Show resolved Hide resolved
featureFlags = JSON.parse(envVars?.featureFlags);
} catch (e) {
console.error("Error parsing featureFlags", e);
}
// Complement the default flags with the ones from the environment to avoid missing flags.
return { ...defaultFeatureFlagValues, ...featureFlags };
};

/**
* DO NOT USE DIRECTLY
*
* @see feature-flags.store.ts to use feature flags
*/
export const FEATURE_FLAG_ENVIRONMENT: FeatureFlags<boolean> = JSON.parse(
envVars?.featureFlags ??
'{"ENABLE_CKTESTBTC": false, "ENABLE_SNS_TYPES_FILTER": false, "ENABLE_EXPORT_NEURONS_REPORT": false}'
);

export const FEATURE_FLAG_ENVIRONMENT: FeatureFlags<boolean> =
getFeatureFlagsFromEnv();

export const IS_TESTNET: boolean =
DFX_NETWORK !== "mainnet" &&
Expand Down
1 change: 1 addition & 0 deletions frontend/src/tests/lib/api/canisters.api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ describe("canisters-api", () => {
});

it("should not notify if transfer fails", async () => {
vi.spyOn(console, "error").mockImplementation(() => undefined);
mockLedgerCanister.transfer.mockRejectedValue(new Error());

const call = () =>
Expand Down
53 changes: 53 additions & 0 deletions frontend/src/tests/lib/constants/environment.constants.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { defaultFeatureFlagValues } from "$lib/constants/environment.constants";
import * as envVarsUtils from "$lib/utils/env-vars.utils";

describe("FEATURE_FLAG_ENVIRONMENT", () => {
const environmentVars = envVarsUtils.getEnvVars();

beforeEach(() => {
// The FEATURE_FLAG_ENVIRONMENT is a constant that is set once when the module
// `environment.constants` is imported. To test different states of it,
// we need to reset the imported modules and reimport `environment.constants` for each test.
vi.resetModules();
mstrasinskis marked this conversation as resolved.
Show resolved Hide resolved
});

it("should equal the environment values", async () => {
const { FEATURE_FLAG_ENVIRONMENT } = await import(
"$lib/constants/environment.constants"
);
const expectedFlags = JSON.parse(environmentVars.featureFlags);
expect(FEATURE_FLAG_ENVIRONMENT).toEqual(expectedFlags);
});

it("should contain missing entries substituted with default values", async () => {
vi.spyOn(envVarsUtils, "getEnvVars").mockReturnValue({
...environmentVars,
featureFlags: JSON.stringify({}),
});

const { FEATURE_FLAG_ENVIRONMENT } = await import(
"$lib/constants/environment.constants"
);
expect(FEATURE_FLAG_ENVIRONMENT).toEqual(defaultFeatureFlagValues);
});

it("should fallback to default on error", async () => {
const spyConsoleError = vi
.spyOn(console, "error")
.mockImplementation(() => undefined);
vi.spyOn(envVarsUtils, "getEnvVars").mockReturnValue({
...environmentVars,
featureFlags: `{"TEST_FLAG_NOT_EDITABLE": TRUE}`,
});

const { FEATURE_FLAG_ENVIRONMENT } = await import(
"$lib/constants/environment.constants"
);
expect(FEATURE_FLAG_ENVIRONMENT).toEqual(defaultFeatureFlagValues);
expect(spyConsoleError).toBeCalledTimes(1);
mstrasinskis marked this conversation as resolved.
Show resolved Hide resolved
expect(spyConsoleError).toBeCalledWith(
"Error parsing featureFlags",
new SyntaxError("Unexpected token T in JSON at position 27")
);
});
});