123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- import {OrganizationFixture} from 'sentry-fixture/organization';
- import {ProjectFixture} from 'sentry-fixture/project';
- import type {Organization} from 'sentry/types/organization';
- import type {Project} from 'sentry/types/project';
- import FeatureObserver from 'sentry/utils/featureObserver';
- describe('FeatureObserver', () => {
- let organization: Organization;
- let project: Project;
- beforeEach(() => {
- organization = OrganizationFixture({
- features: ['enable-issues', 'enable-profiling', 'enable-replay'],
- });
- project = ProjectFixture({
- features: ['enable-proj-flag', 'enable-performance'],
- });
- });
- describe('observeOrganizationFlags', () => {
- it('should add recently evaluated org flags to the flag queue', () => {
- const inst = new FeatureObserver({bufferSize: 3});
- expect(organization.features).toEqual([
- 'enable-issues',
- 'enable-profiling',
- 'enable-replay',
- ]);
- inst.observeOrganizationFlags({organization});
- expect(inst.getFeatureFlags().values).toEqual([]);
- organization.features.includes('enable-issues');
- organization.features.includes('replay-mobile-ui');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.organizations:enable-issues', result: true},
- {flag: 'feature.organizations:replay-mobile-ui', result: false},
- ]);
- // do more evaluations to fill up and overflow the buffer
- organization.features.includes('enable-replay');
- organization.features.includes('autofix-ui');
- organization.features.includes('new-issue-details');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.organizations:enable-replay', result: true},
- {flag: 'feature.organizations:autofix-ui', result: false},
- {flag: 'feature.organizations:new-issue-details', result: false},
- ]);
- });
- it('should remove duplicate flags with a full queue', () => {
- const inst = new FeatureObserver({bufferSize: 3});
- inst.observeOrganizationFlags({organization});
- expect(inst.getFeatureFlags().values).toEqual([]);
- organization.features.includes('enable-issues');
- organization.features.includes('replay-mobile-ui');
- organization.features.includes('enable-discover');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.organizations:enable-issues', result: true},
- {flag: 'feature.organizations:replay-mobile-ui', result: false},
- {flag: 'feature.organizations:enable-discover', result: false},
- ]);
- // this is already in the queue; it should be removed and
- // added back to the end of the queue
- organization.features.includes('enable-issues');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.organizations:replay-mobile-ui', result: false},
- {flag: 'feature.organizations:enable-discover', result: false},
- {flag: 'feature.organizations:enable-issues', result: true},
- ]);
- organization.features.includes('spam-ingest');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.organizations:enable-discover', result: false},
- {flag: 'feature.organizations:enable-issues', result: true},
- {flag: 'feature.organizations:spam-ingest', result: false},
- ]);
- // this is already in the queue but in the back
- // the queue should not change
- organization.features.includes('spam-ingest');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.organizations:enable-discover', result: false},
- {flag: 'feature.organizations:enable-issues', result: true},
- {flag: 'feature.organizations:spam-ingest', result: false},
- ]);
- });
- it('should remove duplicate flags with an unfilled queue', () => {
- const inst = new FeatureObserver({bufferSize: 3});
- inst.observeOrganizationFlags({organization});
- expect(inst.getFeatureFlags().values).toEqual([]);
- organization.features.includes('enable-issues');
- organization.features.includes('replay-mobile-ui');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.organizations:enable-issues', result: true},
- {flag: 'feature.organizations:replay-mobile-ui', result: false},
- ]);
- // this is already in the queue; it should be removed and
- // added back to the end of the queue
- organization.features.includes('enable-issues');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.organizations:replay-mobile-ui', result: false},
- {flag: 'feature.organizations:enable-issues', result: true},
- ]);
- // this is already in the queue but in the back
- // the queue should not change
- organization.features.includes('enable-issues');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.organizations:replay-mobile-ui', result: false},
- {flag: 'feature.organizations:enable-issues', result: true},
- ]);
- });
- it('should not change the functionality of `includes`', () => {
- const inst = new FeatureObserver({bufferSize: 3});
- inst.observeOrganizationFlags({organization});
- expect(inst.getFeatureFlags().values).toEqual([]);
- organization.features.includes('enable-issues');
- organization.features.includes('replay-mobile-ui');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.organizations:enable-issues', result: true},
- {flag: 'feature.organizations:replay-mobile-ui', result: false},
- ]);
- expect(organization.features.includes('enable-issues')).toBe(true);
- expect(organization.features.includes('replay-mobile-ui')).toBe(false);
- });
- });
- describe('observeProjectFlags', () => {
- it('should add recently evaluated proj flags to the flag queue', () => {
- const inst = new FeatureObserver({bufferSize: 3});
- expect(project.features).toEqual(['enable-proj-flag', 'enable-performance']);
- inst.observeProjectFlags({project});
- expect(inst.getFeatureFlags().values).toEqual([]);
- project.features.includes('enable-proj-flag');
- project.features.includes('replay-mobile-ui');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.projects:enable-proj-flag', result: true},
- {flag: 'feature.projects:replay-mobile-ui', result: false},
- ]);
- // do more evaluations to fill up and overflow the buffer
- project.features.includes('enable-performance');
- project.features.includes('autofix-ui');
- project.features.includes('new-issue-details');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.projects:enable-performance', result: true},
- {flag: 'feature.projects:autofix-ui', result: false},
- {flag: 'feature.projects:new-issue-details', result: false},
- ]);
- });
- it('should not change the functionality of `includes`', () => {
- const inst = new FeatureObserver({bufferSize: 3});
- inst.observeProjectFlags({project});
- expect(inst.getFeatureFlags().values).toEqual([]);
- project.features.includes('enable-proj-flag');
- project.features.includes('replay-mobile-ui');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.projects:enable-proj-flag', result: true},
- {flag: 'feature.projects:replay-mobile-ui', result: false},
- ]);
- expect(project.features.includes('enable-proj-flag')).toBe(true);
- expect(project.features.includes('replay-mobile-ui')).toBe(false);
- });
- });
- describe('observeProjectFlags and observeOrganizationFlags', () => {
- it('should add recently evaluated org and proj flags to the flag queue', () => {
- const inst = new FeatureObserver({bufferSize: 3});
- expect(project.features).toEqual(['enable-proj-flag', 'enable-performance']);
- expect(organization.features).toEqual([
- 'enable-issues',
- 'enable-profiling',
- 'enable-replay',
- ]);
- inst.observeProjectFlags({project});
- inst.observeOrganizationFlags({organization});
- expect(inst.getFeatureFlags().values).toEqual([]);
- project.features.includes('enable-proj-flag');
- project.features.includes('enable-replay');
- organization.features.includes('enable-issues');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.projects:enable-proj-flag', result: true},
- {flag: 'feature.projects:enable-replay', result: false},
- {flag: 'feature.organizations:enable-issues', result: true},
- ]);
- organization.features.includes('enable-replay');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.projects:enable-replay', result: false},
- {flag: 'feature.organizations:enable-issues', result: true},
- {flag: 'feature.organizations:enable-replay', result: true},
- ]);
- });
- it('should keep the same queue if the project changes', () => {
- const inst = new FeatureObserver({bufferSize: 3});
- expect(project.features).toEqual(['enable-proj-flag', 'enable-performance']);
- expect(organization.features).toEqual([
- 'enable-issues',
- 'enable-profiling',
- 'enable-replay',
- ]);
- inst.observeProjectFlags({project});
- inst.observeOrganizationFlags({organization});
- expect(inst.getFeatureFlags().values).toEqual([]);
- project.features.includes('enable-proj-flag');
- project.features.includes('enable-replay');
- organization.features.includes('enable-issues');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.projects:enable-proj-flag', result: true},
- {flag: 'feature.projects:enable-replay', result: false},
- {flag: 'feature.organizations:enable-issues', result: true},
- ]);
- project = ProjectFixture({
- features: ['enable-new-flag'],
- });
- inst.observeProjectFlags({project});
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.projects:enable-proj-flag', result: true},
- {flag: 'feature.projects:enable-replay', result: false},
- {flag: 'feature.organizations:enable-issues', result: true},
- ]);
- project.features.includes('enable-new-flag');
- expect(inst.getFeatureFlags().values).toEqual([
- {flag: 'feature.projects:enable-replay', result: false},
- {flag: 'feature.organizations:enable-issues', result: true},
- {flag: 'feature.projects:enable-new-flag', result: true},
- ]);
- });
- });
- });
|