🐛(frontend) analytic feature flags problem
When multiple analytics are registered, if one analytic has the flag at true, the feature was activated, even if another analytic had it at false. We change the logic to require all analytics to have the flag at true for the feature to be activated.
This commit is contained in:
@@ -15,6 +15,10 @@ and this project adheres to
|
||||
- 📝(docs) improve README and add documentation hub #1870
|
||||
- ♿️(frontend) restore focus to triggers after closing menus and modals #1863
|
||||
|
||||
### Fixed
|
||||
|
||||
- 🐛(frontend) analytic feature flags problem #1953
|
||||
|
||||
## [v4.6.0] - 2026-03-03
|
||||
|
||||
### Added
|
||||
|
||||
@@ -56,16 +56,18 @@ export class Analytics {
|
||||
/**
|
||||
* Check if a feature flag is activated
|
||||
*
|
||||
* Feature flags are activated if at least one analytic is activated
|
||||
* because we don't want to hide feature if the user does not
|
||||
* use analytics (AB testing, etc)
|
||||
* A feature flag is considered active only if ALL analytics agree it is.
|
||||
* This ensures that if one analytic explicitly disables a flag,
|
||||
* it takes precedence over analytics that do not manage flags.
|
||||
* If no analytics are registered, default to true so features are not hidden
|
||||
* when analytics are not configured.
|
||||
*/
|
||||
public static isFeatureFlagActivated(flagName: string): boolean {
|
||||
if (!Analytics.analytics.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Analytics.analytics.some((analytic) =>
|
||||
return Analytics.analytics.every((analytic) =>
|
||||
analytic.isFeatureFlagActivated(flagName),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
import { AbstractAnalytic, Analytics, useAnalytics } from '@/libs';
|
||||
import { AppWrapper } from '@/tests/utils';
|
||||
|
||||
class TestAnalytic1 extends AbstractAnalytic {
|
||||
public constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Provider() {
|
||||
return <Fragment />;
|
||||
}
|
||||
|
||||
public trackEvent() {}
|
||||
|
||||
public isFeatureFlagActivated(flagName: string): boolean {
|
||||
if (flagName === 'test-flag') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flagName === 'test-flag2') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class TestAnalytic2 extends AbstractAnalytic {
|
||||
public constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Provider() {
|
||||
return <Fragment />;
|
||||
}
|
||||
|
||||
public trackEvent() {}
|
||||
|
||||
public isFeatureFlagActivated(): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const TestComponent = ({ flag }: { flag: string }) => {
|
||||
const { isFeatureFlagActivated } = useAnalytics();
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isFeatureFlagActivated(flag) ? (
|
||||
<span>Feature is enabled</span>
|
||||
) : (
|
||||
<span>Feature is not enabled</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
describe('Analytics feature flag', () => {
|
||||
beforeEach(() => {
|
||||
Analytics.clearAnalytics();
|
||||
});
|
||||
|
||||
test('renders feature when feature flag is not existing', async () => {
|
||||
new TestAnalytic1();
|
||||
new TestAnalytic2();
|
||||
|
||||
render(<TestComponent flag="unexisting-flag" />, {
|
||||
wrapper: AppWrapper,
|
||||
});
|
||||
expect(await screen.findByText('Feature is enabled')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders feature when feature flag is not enabled', async () => {
|
||||
new TestAnalytic1();
|
||||
new TestAnalytic2();
|
||||
|
||||
render(<TestComponent flag="test-flag" />, {
|
||||
wrapper: AppWrapper,
|
||||
});
|
||||
expect(screen.getByText('Feature is not enabled')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders feature when feature flag is enabled', async () => {
|
||||
new TestAnalytic1();
|
||||
new TestAnalytic2();
|
||||
|
||||
render(<TestComponent flag="test-flag2" />, {
|
||||
wrapper: AppWrapper,
|
||||
});
|
||||
expect(screen.getByText('Feature is enabled')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user