From 2d519469d46b03c959cfa3c0b6fe6ee69c9f1c7f Mon Sep 17 00:00:00 2001 From: Jaanus Sellin Date: Thu, 23 May 2024 08:36:58 +0300 Subject: [PATCH] chore: rename feature toggle to feature flag #5 (#7115) --- .../frontend-api/frontend-api-controller.ts | 6 +- .../client-metrics-store-v2.e2e.test.ts | 8 +- .../metrics/client-metrics/client-metrics.ts | 2 +- src/lib/features/metrics/instance/metrics.ts | 2 +- .../tests/last-seen-service.e2e.test.ts | 4 +- .../project/project-service.e2e.test.ts | 268 ++++++++---------- src/lib/features/project/project-service.ts | 26 +- .../segment/admin-segment.e2e.test.ts | 130 ++++----- .../features/tag-type/tag-types.e2e.test.ts | 2 +- src/test/e2e/helpers/app.utils.ts | 2 +- 10 files changed, 215 insertions(+), 235 deletions(-) diff --git a/src/lib/features/frontend-api/frontend-api-controller.ts b/src/lib/features/frontend-api/frontend-api-controller.ts index cea0fb0f98..de06727315 100644 --- a/src/lib/features/frontend-api/frontend-api-controller.ts +++ b/src/lib/features/frontend-api/frontend-api-controller.ts @@ -73,9 +73,9 @@ export default class FrontendAPIController extends Controller { ...getStandardResponses(401, 404), }, summary: - 'Retrieve enabled feature toggles for the provided context.', + 'Retrieve enabled feature flags for the provided context.', description: - 'This endpoint returns the list of feature toggles that the frontend API evaluates to enabled for the given context. Context values are provided as query parameters. If the Frontend API is disabled 404 is returned.', + 'This endpoint returns the list of feature flags that the frontend API evaluates to enabled for the given context. Context values are provided as query parameters. If the Frontend API is disabled 404 is returned.', }), ], }); @@ -103,7 +103,7 @@ export default class FrontendAPIController extends Controller { this.services.openApiService.validPath({ tags: ['Frontend API'], summary: 'Register client usage metrics', - description: `Registers usage metrics. Stores information about how many times each toggle was evaluated to enabled and disabled within a time frame. If provided, this operation will also store data on how many times each feature toggle's variants were displayed to the end user. If the Frontend API is disabled 404 is returned.`, + description: `Registers usage metrics. Stores information about how many times each flag was evaluated to enabled and disabled within a time frame. If provided, this operation will also store data on how many times each feature flag's variants were displayed to the end user. If the Frontend API is disabled 404 is returned.`, operationId: 'registerFrontendMetrics', requestBody: createRequestSchema('clientMetricsSchema'), responses: { diff --git a/src/lib/features/metrics/client-metrics/client-metrics-store-v2.e2e.test.ts b/src/lib/features/metrics/client-metrics/client-metrics-store-v2.e2e.test.ts index 824b729ac5..986cf420d8 100644 --- a/src/lib/features/metrics/client-metrics/client-metrics-store-v2.e2e.test.ts +++ b/src/lib/features/metrics/client-metrics/client-metrics-store-v2.e2e.test.ts @@ -149,7 +149,7 @@ test('Should insert individual rows for different apps', async () => { expect(savedMetrics[0].no).toBe(2); }); -test('Should insert individual rows for different toggles', async () => { +test('Should insert individual rows for different flags', async () => { const metrics: IClientMetricsEnv[] = []; const date = new Date(); @@ -173,7 +173,7 @@ test('Should insert individual rows for different toggles', async () => { expect(savedMetrics[0].no).toBe(2); }); -test('Should get toggle metrics', async () => { +test('Should get flag metrics', async () => { const metrics: IClientMetricsEnv[] = []; const date = new Date(); @@ -198,7 +198,7 @@ test('Should get toggle metrics', async () => { expect(savedMetrics[0].no).toBe(5050); }); -test('Should insert 1500 feature toggle metrics', async () => { +test('Should insert 1500 feature flag metrics', async () => { const metrics: IClientMetricsEnv[] = []; const date = new Date(); @@ -220,7 +220,7 @@ test('Should insert 1500 feature toggle metrics', async () => { expect(savedMetrics).toHaveLength(1500); }); -test('Should return seen applications using a feature toggle', async () => { +test('Should return seen applications using a feature flag', async () => { const metrics: IClientMetricsEnv[] = [ { featureName: 'demo', diff --git a/src/lib/features/metrics/client-metrics/client-metrics.ts b/src/lib/features/metrics/client-metrics/client-metrics.ts index 1e77e60fac..0714eac66b 100644 --- a/src/lib/features/metrics/client-metrics/client-metrics.ts +++ b/src/lib/features/metrics/client-metrics/client-metrics.ts @@ -84,7 +84,7 @@ class ClientMetricsController extends Controller { openApiService.validPath({ operationId: 'getFeatureUsageSummary', tags: ['Metrics'], - summary: `Last hour of usage and a list of applications that have reported seeing this feature toggle`, + summary: `Last hour of usage and a list of applications that have reported seeing this feature flag`, description: 'Separate counts for yes (enabled), no (disabled), as well as how many times each variant was selected during the last hour', responses: { diff --git a/src/lib/features/metrics/instance/metrics.ts b/src/lib/features/metrics/instance/metrics.ts index 29b77ad394..c7f1681793 100644 --- a/src/lib/features/metrics/instance/metrics.ts +++ b/src/lib/features/metrics/instance/metrics.ts @@ -64,7 +64,7 @@ export default class ClientMetricsController extends Controller { openApiService.validPath({ tags: ['Client'], summary: 'Register client usage metrics', - description: `Registers usage metrics. Stores information about how many times each toggle was evaluated to enabled and disabled within a time frame. If provided, this operation will also store data on how many times each feature toggle's variants were displayed to the end user.`, + description: `Registers usage metrics. Stores information about how many times each flag was evaluated to enabled and disabled within a time frame. If provided, this operation will also store data on how many times each feature flag's variants were displayed to the end user.`, operationId: 'registerClientMetrics', requestBody: createRequestSchema('clientMetricsSchema'), responses: { diff --git a/src/lib/features/metrics/last-seen/tests/last-seen-service.e2e.test.ts b/src/lib/features/metrics/last-seen/tests/last-seen-service.e2e.test.ts index c96da37f54..366055374d 100644 --- a/src/lib/features/metrics/last-seen/tests/last-seen-service.e2e.test.ts +++ b/src/lib/features/metrics/last-seen/tests/last-seen-service.e2e.test.ts @@ -35,7 +35,7 @@ afterAll(async () => { await db.destroy(); }); -test('should clean unknown feature toggle names from last seen store', async () => { +test('should clean unknown feature flag names from last seen store', async () => { const { lastSeenService, featureToggleService } = app.services; const clean = ['clean1', 'clean2', 'clean3', 'clean4']; @@ -86,7 +86,7 @@ test('should clean unknown feature toggle names from last seen store', async () expect(notInDirty.length).toBe(4); }); -test('should clean unknown feature toggle environments from last seen store', async () => { +test('should clean unknown feature flag environments from last seen store', async () => { const { lastSeenService, featureToggleService } = app.services; const clean = [ diff --git a/src/lib/features/project/project-service.e2e.test.ts b/src/lib/features/project/project-service.e2e.test.ts index a5a4f298d8..88b4ed461b 100644 --- a/src/lib/features/project/project-service.e2e.test.ts +++ b/src/lib/features/project/project-service.e2e.test.ts @@ -188,9 +188,9 @@ test('should delete project', async () => { } }); -test('should not be able to delete project with toggles', async () => { +test('should not be able to delete project with flags', async () => { const project = { - id: 'test-delete-with-toggles', + id: 'test-delete-with-flags', name: 'New project', description: 'Blah', mode: 'open' as const, @@ -206,7 +206,7 @@ test('should not be able to delete project with toggles', async () => { await projectService.deleteProject(project.id, user, auditUser); } catch (err) { expect(err.message).toBe( - 'You can not delete a project with active feature toggles', + 'You can not delete a project with active feature flags', ); } }); @@ -842,7 +842,7 @@ test('should remove user from the project', async () => { expect(memberUsers).toHaveLength(0); }); -test('should not change project if feature toggle project does not match current project id', async () => { +test('should not change project if feature flag project does not match current project id', async () => { const project = { id: 'test-change-project', name: 'New project', @@ -851,19 +851,15 @@ test('should not change project if feature toggle project does not match current defaultStickiness: 'clientId', }; - const toggle = { name: 'test-toggle' }; + const flag = { name: 'test-flag' }; await projectService.createProject(project, user, auditUser); - await featureToggleService.createFeatureToggle( - project.id, - toggle, - auditUser, - ); + await featureToggleService.createFeatureToggle(project.id, flag, auditUser); try { await projectService.changeProject( 'newProject', - toggle.name, + flag.name, user, 'wrong-project-id', auditUser, @@ -883,19 +879,15 @@ test('should return 404 if no project is found with the project id', async () => defaultStickiness: 'clientId', }; - const toggle = { name: 'test-toggle-2' }; + const flag = { name: 'test-flag-2' }; await projectService.createProject(project, user, auditUser); - await featureToggleService.createFeatureToggle( - project.id, - toggle, - auditUser, - ); + await featureToggleService.createFeatureToggle(project.id, flag, auditUser); try { await projectService.changeProject( 'newProject', - toggle.name, + flag.name, user, project.id, auditUser, @@ -922,7 +914,7 @@ test('should fail if user is not authorized', async () => { defaultStickiness: 'clientId', }; - const toggle = { name: 'test-toggle-3' }; + const flag = { name: 'test-flag-3' }; const projectAdmin1 = await stores.userStore.insert({ name: 'test-change-project-creator', email: 'admin-change-project@getunleash.io', @@ -934,16 +926,12 @@ test('should fail if user is not authorized', async () => { projectAdmin1, auditUser, ); - await featureToggleService.createFeatureToggle( - project.id, - toggle, - auditUser, - ); + await featureToggleService.createFeatureToggle(project.id, flag, auditUser); try { await projectService.changeProject( projectDestination.id, - toggle.name, + flag.name, user, project.id, auditUser, @@ -967,25 +955,25 @@ test('should change project when checks pass', async () => { mode: 'open' as const, defaultStickiness: 'clientId', }; - const toggle = { name: randomId() }; + const flag = { name: randomId() }; await projectService.createProject(projectA, user, auditUser); await projectService.createProject(projectB, user, auditUser); await featureToggleService.createFeatureToggle( projectA.id, - toggle, + flag, auditUser, ); await projectService.changeProject( projectB.id, - toggle.name, + flag.name, user, projectA.id, auditUser, ); const updatedFeature = await featureToggleService.getFeature({ - featureName: toggle.name, + featureName: flag.name, }); expect(updatedFeature.project).toBe(projectB.id); }); @@ -1003,18 +991,18 @@ test('changing project should emit event even if user does not have a username s mode: 'open' as const, defaultStickiness: 'clientId', }; - const toggle = { name: randomId() }; + const flag = { name: randomId() }; await projectService.createProject(projectA, user, auditUser); await projectService.createProject(projectB, user, auditUser); await featureToggleService.createFeatureToggle( projectA.id, - toggle, + flag, auditUser, ); const eventsBeforeChange = await stores.eventStore.getEvents(); await projectService.changeProject( projectB.id, - toggle.name, + flag.name, user, projectA.id, auditUser, @@ -1037,13 +1025,13 @@ test('should require equal project environments to move features', async () => { defaultStickiness: 'clientId', }; const environment = { name: randomId(), type: 'production' }; - const toggle = { name: randomId() }; + const flag = { name: randomId() }; await projectService.createProject(projectA, user, auditUser); await projectService.createProject(projectB, user, auditUser); await featureToggleService.createFeatureToggle( projectA.id, - toggle, + flag, auditUser, ); await stores.environmentStore.create(environment); @@ -1056,7 +1044,7 @@ test('should require equal project environments to move features', async () => { await expect(() => projectService.changeProject( projectB.id, - toggle.name, + flag.name, user, projectA.id, auditUser, @@ -1816,7 +1804,7 @@ test('Should allow permutations of roles, groups and users when adding a new acc expect(groups[0].roles).toStrictEqual([role1.id, role2.id]); }); -test('should only count active feature toggles for project', async () => { +test('should only count active feature flags for project', async () => { const project = { id: 'only-active', name: 'New project', @@ -1855,15 +1843,11 @@ test('should list projects with all features archived', async () => { await projectService.createProject(project, user, auditUser); await stores.featureToggleStore.create(project.id, { - name: 'archived-toggle', + name: 'archived-flag', createdByUserId: 9999, }); - await featureToggleService.archiveToggle( - 'archived-toggle', - user, - auditUser, - ); + await featureToggleService.archiveToggle('archived-flag', user, auditUser); const projects = await projectService.getProjects(); const theProject = projects.find((p) => p.id === project.id); @@ -1894,7 +1878,7 @@ test('should calculate average time to production', async () => { await projectService.createProject(project, user, auditUser); - const toggles = [ + const flags = [ { name: 'average-prod-time' }, { name: 'average-prod-time-2' }, { name: 'average-prod-time-3' }, @@ -1902,23 +1886,23 @@ test('should calculate average time to production', async () => { { name: 'average-prod-time-5' }, ]; - const featureToggles = await Promise.all( - toggles.map((toggle) => { + const featureFlags = await Promise.all( + flags.map((flag) => { return featureToggleService.createFeatureToggle( project.id, - toggle, + flag, auditUser, ); }), ); await Promise.all( - featureToggles.map((toggle) => { + featureFlags.map((flag) => { return eventService.storeEvent( new FeatureEnvironmentEvent({ enabled: true, project: project.id, - featureName: toggle.name, + featureName: flag.name, environment: 'default', auditUser, }), @@ -1929,8 +1913,8 @@ test('should calculate average time to production', async () => { await updateEventCreatedAt(subDays(new Date(), 31), 'average-prod-time-5'); await Promise.all( - featureToggles.map((toggle) => - updateFeature(toggle.name, { created_at: subDays(new Date(), 15) }), + featureFlags.map((flag) => + updateFeature(flag.name, { created_at: subDays(new Date(), 15) }), ), ); @@ -1969,74 +1953,70 @@ test('should calculate average time to production ignoring some items', async () SYSTEM_USER_AUDIT, ); - // actual toggle we take for calculations - const toggle = { name: 'main-toggle' }; - await featureToggleService.createFeatureToggle( - project.id, - toggle, - auditUser, - ); - await updateFeature(toggle.name, { + // actual flag we take for calculations + const flag = { name: 'main-flag' }; + await featureToggleService.createFeatureToggle(project.id, flag, auditUser); + await updateFeature(flag.name, { created_at: subDays(new Date(), 20), }); await eventService.storeEvent( - new FeatureEnvironmentEvent(makeEvent(toggle.name)), + new FeatureEnvironmentEvent(makeEvent(flag.name)), ); // ignore events added after first enabled - await updateEventCreatedAt(addDays(new Date(), 1), toggle.name); + await updateEventCreatedAt(addDays(new Date(), 1), flag.name); await eventService.storeEvent( - new FeatureEnvironmentEvent(makeEvent(toggle.name)), + new FeatureEnvironmentEvent(makeEvent(flag.name)), ); - // ignore toggles enabled in non-prod envs - const devToggle = { name: 'dev-toggle' }; + // ignore flags enabled in non-prod envs + const devFlag = { name: 'dev-flag' }; await featureToggleService.createFeatureToggle( project.id, - devToggle, + devFlag, auditUser, ); await eventService.storeEvent( new FeatureEnvironmentEvent({ - ...makeEvent(devToggle.name), + ...makeEvent(devFlag.name), environment: 'customEnv', }), ); - // ignore toggles from other projects - const otherProjectToggle = { name: 'other-project' }; + // ignore flags from other projects + const otherProjectFlag = { name: 'other-project' }; await featureToggleService.createFeatureToggle( 'default', - otherProjectToggle, + otherProjectFlag, auditUser, ); await eventService.storeEvent( - new FeatureEnvironmentEvent(makeEvent(otherProjectToggle.name)), + new FeatureEnvironmentEvent(makeEvent(otherProjectFlag.name)), ); - // ignore non-release toggles - const nonReleaseToggle = { name: 'permission-toggle', type: 'permission' }; + // ignore non-release flags + const nonReleaseFlag = { name: 'permission-flag', type: 'permission' }; await featureToggleService.createFeatureToggle( project.id, - nonReleaseToggle, + nonReleaseFlag, auditUser, ); await eventService.storeEvent( - new FeatureEnvironmentEvent(makeEvent(nonReleaseToggle.name)), + new FeatureEnvironmentEvent(makeEvent(nonReleaseFlag.name)), ); - // ignore toggles with events before toggle creation time - const previouslyDeleteToggle = { name: 'previously-deleted' }; + // ignore flags with events before flag creation time + const previouslyDeleteFlag = { name: 'previously-deleted' }; await featureToggleService.createFeatureToggle( project.id, - previouslyDeleteToggle, + previouslyDeleteFlag, auditUser, ); await eventService.storeEvent( - new FeatureEnvironmentEvent(makeEvent(previouslyDeleteToggle.name)), + new FeatureEnvironmentEvent(makeEvent(previouslyDeleteFlag.name)), ); await updateEventCreatedAt( subDays(new Date(), 30), - previouslyDeleteToggle.name, + previouslyDeleteFlag.name, ); const result = await projectService.getStatusUpdates(project.id); @@ -2053,7 +2033,7 @@ test('should get correct amount of features created in current and past window', await projectService.createProject(project, user, auditUser); - const toggles = [ + const flags = [ { name: 'features-created' }, { name: 'features-created-2' }, { name: 'features-created-3' }, @@ -2061,18 +2041,18 @@ test('should get correct amount of features created in current and past window', ]; await Promise.all( - toggles.map((toggle) => { + flags.map((flag) => { return featureToggleService.createFeatureToggle( project.id, - toggle, + flag, auditUser, ); }), ); await Promise.all([ - updateFeature(toggles[2].name, { created_at: subDays(new Date(), 31) }), - updateFeature(toggles[3].name, { created_at: subDays(new Date(), 31) }), + updateFeature(flags[2].name, { created_at: subDays(new Date(), 31) }), + updateFeature(flags[3].name, { created_at: subDays(new Date(), 31) }), ]); const result = await projectService.getStatusUpdates(project.id); @@ -2090,7 +2070,7 @@ test('should get correct amount of features archived in current and past window' await projectService.createProject(project, user, auditUser); - const toggles = [ + const flags = [ { name: 'features-archived' }, { name: 'features-archived-2' }, { name: 'features-archived-3' }, @@ -2098,26 +2078,26 @@ test('should get correct amount of features archived in current and past window' ]; await Promise.all( - toggles.map((toggle) => { + flags.map((flag) => { return featureToggleService.createFeatureToggle( project.id, - toggle, + flag, auditUser, ); }), ); await Promise.all([ - updateFeature(toggles[0].name, { + updateFeature(flags[0].name, { archived_at: new Date(), }), - updateFeature(toggles[1].name, { + updateFeature(flags[1].name, { archived_at: new Date(), }), - updateFeature(toggles[2].name, { + updateFeature(flags[2].name, { archived_at: subDays(new Date(), 31), }), - updateFeature(toggles[3].name, { + updateFeature(flags[3].name, { archived_at: subDays(new Date(), 31), }), ]); @@ -2167,17 +2147,17 @@ test('should get correct amount of project members for current and past window', expect(result.updates.projectActivityPastWindow).toBe(0); }); -test('should return average time to production per toggle', async () => { +test('should return average time to production per flag', async () => { const project = { - id: 'average-time-to-prod-per-toggle', - name: 'average-time-to-prod-per-toggle', + id: 'average-time-to-prod-per-flag', + name: 'average-time-to-prod-per-flag', mode: 'open' as const, defaultStickiness: 'clientId', }; await projectService.createProject(project, user, auditUser); - const toggles = [ + const flags = [ { name: 'average-prod-time-pt', subdays: 7 }, { name: 'average-prod-time-pt-2', subdays: 14 }, { name: 'average-prod-time-pt-3', subdays: 40 }, @@ -2185,23 +2165,23 @@ test('should return average time to production per toggle', async () => { { name: 'average-prod-time-pt-5', subdays: 2 }, ]; - const featureToggles = await Promise.all( - toggles.map((toggle) => { + const featureFlags = await Promise.all( + flags.map((flag) => { return featureToggleService.createFeatureToggle( project.id, - toggle, + flag, auditUser, ); }), ); await Promise.all( - featureToggles.map((toggle) => { + featureFlags.map((flag) => { return eventService.storeEvent( new FeatureEnvironmentEvent({ enabled: true, project: project.id, - featureName: toggle.name, + featureName: flag.name, environment: 'default', auditUser, }), @@ -2210,9 +2190,9 @@ test('should return average time to production per toggle', async () => { ); await Promise.all( - toggles.map((toggle) => - updateFeature(toggle.name, { - created_at: subDays(new Date(), toggle.subdays), + flags.map((flag) => + updateFeature(flag.name, { + created_at: subDays(new Date(), flag.subdays), }), ), ); @@ -2224,16 +2204,16 @@ test('should return average time to production per toggle', async () => { expect(result.projectAverage).toBeTruthy(); }); -test('should return average time to production per toggle for a specific project', async () => { +test('should return average time to production per flag for a specific project', async () => { const project1 = { - id: 'average-time-to-prod-per-toggle-1', + id: 'average-time-to-prod-per-flag-1', name: 'Project 1', mode: 'open' as const, defaultStickiness: 'clientId', }; const project2 = { - id: 'average-time-to-prod-per-toggle-2', + id: 'average-time-to-prod-per-flag-2', name: 'Project 2', mode: 'open' as const, defaultStickiness: 'clientId', @@ -2242,44 +2222,44 @@ test('should return average time to production per toggle for a specific project await projectService.createProject(project1, user, auditUser); await projectService.createProject(project2, user, auditUser); - const togglesProject1 = [ + const flagsProject1 = [ { name: 'average-prod-time-pt-10', subdays: 7 }, { name: 'average-prod-time-pt-11', subdays: 14 }, { name: 'average-prod-time-pt-12', subdays: 40 }, ]; - const togglesProject2 = [ + const flagsProject2 = [ { name: 'average-prod-time-pt-13', subdays: 15 }, { name: 'average-prod-time-pt-14', subdays: 2 }, ]; - const featureTogglesProject1 = await Promise.all( - togglesProject1.map((toggle) => { + const featureFlagsProject1 = await Promise.all( + flagsProject1.map((flag) => { return featureToggleService.createFeatureToggle( project1.id, - toggle, + flag, auditUser, ); }), ); - const featureTogglesProject2 = await Promise.all( - togglesProject2.map((toggle) => { + const featureFlagsProject2 = await Promise.all( + flagsProject2.map((flag) => { return featureToggleService.createFeatureToggle( project2.id, - toggle, + flag, auditUser, ); }), ); await Promise.all( - featureTogglesProject1.map((toggle) => { + featureFlagsProject1.map((flag) => { return eventService.storeEvent( new FeatureEnvironmentEvent({ enabled: true, project: project1.id, - featureName: toggle.name, + featureName: flag.name, environment: 'default', auditUser, }), @@ -2288,12 +2268,12 @@ test('should return average time to production per toggle for a specific project ); await Promise.all( - featureTogglesProject2.map((toggle) => { + featureFlagsProject2.map((flag) => { return eventService.storeEvent( new FeatureEnvironmentEvent({ enabled: true, project: project2.id, - featureName: toggle.name, + featureName: flag.name, environment: 'default', auditUser, }), @@ -2302,17 +2282,17 @@ test('should return average time to production per toggle for a specific project ); await Promise.all( - togglesProject1.map((toggle) => - updateFeature(toggle.name, { - created_at: subDays(new Date(), toggle.subdays), + flagsProject1.map((flag) => + updateFeature(flag.name, { + created_at: subDays(new Date(), flag.subdays), }), ), ); await Promise.all( - togglesProject2.map((toggle) => - updateFeature(toggle.name, { - created_at: subDays(new Date(), toggle.subdays), + flagsProject2.map((flag) => + updateFeature(flag.name, { + created_at: subDays(new Date(), flag.subdays), }), ), ); @@ -2324,9 +2304,9 @@ test('should return average time to production per toggle for a specific project expect(resultProject2.features).toHaveLength(2); }); -test('should return average time to production per toggle and include archived toggles', async () => { +test('should return average time to production per flag and include archived flags', async () => { const project1 = { - id: 'average-time-to-prod-per-toggle-12', + id: 'average-time-to-prod-per-flag-12', name: 'Project 1', mode: 'open' as const, defaultStickiness: 'clientId', @@ -2334,29 +2314,29 @@ test('should return average time to production per toggle and include archived t await projectService.createProject(project1, user, auditUser); - const togglesProject1 = [ + const flagsProject1 = [ { name: 'average-prod-time-pta-10', subdays: 7 }, { name: 'average-prod-time-pta-11', subdays: 14 }, { name: 'average-prod-time-pta-12', subdays: 40 }, ]; - const featureTogglesProject1 = await Promise.all( - togglesProject1.map((toggle) => { + const featureFlagsProject1 = await Promise.all( + flagsProject1.map((flag) => { return featureToggleService.createFeatureToggle( project1.id, - toggle, + flag, auditUser, ); }), ); await Promise.all( - featureTogglesProject1.map((toggle) => { + featureFlagsProject1.map((flag) => { return eventService.storeEvent( new FeatureEnvironmentEvent({ enabled: true, project: project1.id, - featureName: toggle.name, + featureName: flag.name, environment: 'default', auditUser, }), @@ -2365,9 +2345,9 @@ test('should return average time to production per toggle and include archived t ); await Promise.all( - togglesProject1.map((toggle) => - updateFeature(toggle.name, { - created_at: subDays(new Date(), toggle.subdays), + flagsProject1.map((flag) => + updateFeature(flag.name, { + created_at: subDays(new Date(), flag.subdays), }), ), ); @@ -2436,36 +2416,36 @@ describe('feature flag naming patterns', () => { }); }); -test('deleting a project with archived toggles should result in any remaining archived toggles being deleted', async () => { +test('deleting a project with archived flags should result in any remaining archived flags being deleted', async () => { const project = { - id: 'project-with-archived-toggles', - name: 'project-with-archived-toggles', + id: 'project-with-archived-flags', + name: 'project-with-archived-flags', }; - const toggleName = 'archived-and-deleted'; + const flagName = 'archived-and-deleted'; await projectService.createProject(project, user, auditUser); await stores.featureToggleStore.create(project.id, { - name: toggleName, + name: flagName, createdByUserId: 9999, }); - await stores.featureToggleStore.archive(toggleName); + await stores.featureToggleStore.archive(flagName); await projectService.deleteProject(project.id, user, auditUser); - // bring the project back again, previously this would allow those archived toggles to be resurrected + // bring the project back again, previously this would allow those archived flags to be resurrected // we now expect them to be deleted correctly await projectService.createProject(project, user, auditUser); - const toggles = await stores.featureToggleStore.getAll({ + const flags = await stores.featureToggleStore.getAll({ project: project.id, archived: true, }); - expect(toggles.find((t) => t.name === toggleName)).toBeUndefined(); + expect(flags.find((t) => t.name === flagName)).toBeUndefined(); }); -test('deleting a project with no archived toggles should not result in an error', async () => { +test('deleting a project with no archived flags should not result in an error', async () => { const project = { id: 'project-with-nothing', name: 'project-with-nothing', diff --git a/src/lib/features/project/project-service.ts b/src/lib/features/project/project-service.ts index 5dfdcddfb1..efb06a0e11 100644 --- a/src/lib/features/project/project-service.ts +++ b/src/lib/features/project/project-service.ts @@ -521,24 +521,24 @@ export default class ProjectService { ); } - const toggles = await this.featureToggleStore.getAll({ + const flags = await this.featureToggleStore.getAll({ project: id, archived: false, }); - if (toggles.length > 0) { + if (flags.length > 0) { throw new InvalidOperationError( - 'You can not delete a project with active feature toggles', + 'You can not delete a project with active feature flags', ); } - const archivedToggles = await this.featureToggleStore.getAll({ + const archivedFlags = await this.featureToggleStore.getAll({ project: id, archived: true, }); this.featureToggleService.deleteFeatures( - archivedToggles.map((toggle) => toggle.name), + archivedFlags.map((flag) => flag.name), id, auditUser, ); @@ -1041,34 +1041,34 @@ export default class ProjectService { /** @deprecated use projectInsightsService instead */ async getDoraMetrics(projectId: string): Promise { - const activeFeatureToggles = ( + const activeFeatureFlags = ( await this.featureToggleStore.getAll({ project: projectId }) ).map((feature) => feature.name); - const archivedFeatureToggles = ( + const archivedFeatureFlags = ( await this.featureToggleStore.getAll({ project: projectId, archived: true, }) ).map((feature) => feature.name); - const featureToggleNames = [ - ...activeFeatureToggles, - ...archivedFeatureToggles, + const featureFlagNames = [ + ...activeFeatureFlags, + ...archivedFeatureFlags, ]; const projectAverage = calculateAverageTimeToProd( await this.projectStatsStore.getTimeToProdDates(projectId), ); - const toggleAverage = + const flagAverage = await this.projectStatsStore.getTimeToProdDatesForFeatureToggles( projectId, - featureToggleNames, + featureFlagNames, ); return { - features: toggleAverage, + features: flagAverage, projectAverage: projectAverage, }; } diff --git a/src/lib/features/segment/admin-segment.e2e.test.ts b/src/lib/features/segment/admin-segment.e2e.test.ts index 46010d7b7f..08096246e8 100644 --- a/src/lib/features/segment/admin-segment.e2e.test.ts +++ b/src/lib/features/segment/admin-segment.e2e.test.ts @@ -5,7 +5,7 @@ import dbInit, { type ITestDb } from '../../../test/e2e/helpers/database-init'; import getLogger from '../../../test/fixtures/no-logger'; import { addStrategyToFeatureEnv, - createFeatureToggle, + createFeatureFlag, } from '../../../test/e2e/helpers/app.utils'; import { type IUnleashTest, @@ -80,7 +80,7 @@ const addSegmentsToStrategy = ( }) .expect(expectStatusCode); -const mockFeatureToggle = () => ({ +const mockFeatureFlag = () => ({ name: randomId(), strategies: [ { @@ -277,15 +277,15 @@ test('should not delete segments used by strategies', async () => { name: 'a', constraints: [], }); - const toggle = mockFeatureToggle(); - await createFeatureToggle(app, toggle); + const flag = mockFeatureFlag(); + await createFeatureFlag(app, flag); const [segment] = await fetchSegments(); await addStrategyToFeatureEnv( app, - { ...toggle.strategies[0] }, + { ...flag.strategies[0] }, 'default', - toggle.name, + flag.name, ); const [feature] = await fetchFeatures(); //@ts-ignore @@ -300,20 +300,20 @@ test('should not delete segments used by strategies', async () => { expect((await fetchSegments()).length).toEqual(1); }); -test('should delete segments used by strategies in archived feature toggles', async () => { +test('should delete segments used by strategies in archived feature flags', async () => { await app.createSegment({ name: 'a', constraints: [], }); - const toggle = mockFeatureToggle(); - await createFeatureToggle(app, toggle); + const flag = mockFeatureFlag(); + await createFeatureFlag(app, flag); const [segment] = await fetchSegments(); await addStrategyToFeatureEnv( app, - { ...toggle.strategies[0] }, + { ...flag.strategies[0] }, 'default', - toggle.name, + flag.name, ); const [feature] = await fetchFeatures(); //@ts-ignore @@ -343,30 +343,30 @@ test('should list strategies by segment', async () => { name: 'S3', constraints: [], }); - const toggle1 = mockFeatureToggle(); - const toggle2 = mockFeatureToggle(); - const toggle3 = mockFeatureToggle(); - await createFeatureToggle(app, toggle1); - await createFeatureToggle(app, toggle2); - await createFeatureToggle(app, toggle3); + const flag1 = mockFeatureFlag(); + const flag2 = mockFeatureFlag(); + const flag3 = mockFeatureFlag(); + await createFeatureFlag(app, flag1); + await createFeatureFlag(app, flag2); + await createFeatureFlag(app, flag3); await addStrategyToFeatureEnv( app, - { ...toggle1.strategies[0] }, + { ...flag1.strategies[0] }, 'default', - toggle1.name, + flag1.name, ); await addStrategyToFeatureEnv( app, - { ...toggle1.strategies[0] }, + { ...flag1.strategies[0] }, 'default', - toggle2.name, + flag2.name, ); await addStrategyToFeatureEnv( app, - { ...toggle3.strategies[0] }, + { ...flag3.strategies[0] }, 'default', - toggle3.name, + flag3.name, ); const [feature1, feature2, feature3] = await fetchFeatures(); @@ -419,30 +419,30 @@ test('should list segments by strategy', async () => { name: 'S3', constraints: [], }); - const toggle1 = mockFeatureToggle(); - const toggle2 = mockFeatureToggle(); - const toggle3 = mockFeatureToggle(); - await createFeatureToggle(app, toggle1); - await createFeatureToggle(app, toggle2); - await createFeatureToggle(app, toggle3); + const flag1 = mockFeatureFlag(); + const flag2 = mockFeatureFlag(); + const flag3 = mockFeatureFlag(); + await createFeatureFlag(app, flag1); + await createFeatureFlag(app, flag2); + await createFeatureFlag(app, flag3); await addStrategyToFeatureEnv( app, - { ...toggle1.strategies[0] }, + { ...flag1.strategies[0] }, 'default', - toggle1.name, + flag1.name, ); await addStrategyToFeatureEnv( app, - { ...toggle1.strategies[0] }, + { ...flag1.strategies[0] }, 'default', - toggle2.name, + flag2.name, ); await addStrategyToFeatureEnv( app, - { ...toggle3.strategies[0] }, + { ...flag3.strategies[0] }, 'default', - toggle3.name, + flag3.name, ); const [feature1, feature2, feature3] = await fetchFeatures(); @@ -571,14 +571,14 @@ test('Should show usage in features and projects', async () => { name: 'a', constraints: [], }); - const toggle = mockFeatureToggle(); - await createFeatureToggle(app, toggle); + const flag = mockFeatureFlag(); + await createFeatureFlag(app, flag); const [segment] = await fetchSegments(); await addStrategyToFeatureEnv( app, - { ...toggle.strategies[0] }, + { ...flag.strategies[0] }, 'default', - toggle.name, + flag.name, ); const [feature] = await fetchFeatures(); //@ts-ignore @@ -662,12 +662,12 @@ describe('detect strategy usage in change requests', () => { name: 'a', constraints: [], }); - const toggle = mockFeatureToggle(); - await createFeatureToggle(enterpriseApp, toggle); + const flag = mockFeatureFlag(); + await createFeatureFlag(enterpriseApp, flag); const [segment] = await enterpriseFetchSegments(); await db.rawDatabase.table('change_request_events').insert({ - feature: toggle.name, + feature: flag.name, action: 'addStrategy', payload: { name: 'flexibleRollout', @@ -676,7 +676,7 @@ describe('detect strategy usage in change requests', () => { segments: [segment.id], variants: [], parameters: { - groupId: toggle.name, + groupId: flag.name, rollout: '100', stickiness: 'default', }, @@ -706,12 +706,12 @@ describe('detect strategy usage in change requests', () => { name: 'a', constraints: [], }); - const toggle = mockFeatureToggle(); - await createFeatureToggle(enterpriseApp, toggle); + const flag = mockFeatureFlag(); + await createFeatureFlag(enterpriseApp, flag); const [segment] = await enterpriseFetchSegments(); await db.rawDatabase.table('change_request_events').insert({ - feature: toggle.name, + feature: flag.name, action: 'addStrategy', payload: { name: 'flexibleRollout', @@ -720,7 +720,7 @@ describe('detect strategy usage in change requests', () => { segments: [segment.id], variants: [], parameters: { - groupId: toggle.name, + groupId: flag.name, rollout: '100', stickiness: 'default', }, @@ -737,7 +737,7 @@ describe('detect strategy usage in change requests', () => { expect(changeRequestStrategies).toMatchObject([ { environment: 'default', - featureName: toggle.name, + featureName: flag.name, projectId: 'default', strategyName: 'flexibleRollout', changeRequest: { id: CR_ID, title: CR_TITLE }, @@ -756,15 +756,15 @@ describe('detect strategy usage in change requests', () => { name: 'a', constraints: [], }); - const toggle = mockFeatureToggle(); - await createFeatureToggle(enterpriseApp, toggle); + const flag = mockFeatureFlag(); + await createFeatureFlag(enterpriseApp, flag); const [segment] = await enterpriseFetchSegments(); await addStrategyToFeatureEnv( enterpriseApp, - { ...toggle.strategies[0] }, + { ...flag.strategies[0] }, 'default', - toggle.name, + flag.name, ); const [feature] = await fetchFeatures(); @@ -772,7 +772,7 @@ describe('detect strategy usage in change requests', () => { const strategyId = feature.strategies[0].id; await db.rawDatabase.table('change_request_events').insert({ - feature: toggle.name, + feature: flag.name, action: 'updateStrategy', payload: { id: strategyId, @@ -782,7 +782,7 @@ describe('detect strategy usage in change requests', () => { segments: [segment.id], variants: [], parameters: { - groupId: toggle.name, + groupId: flag.name, rollout: '100', stickiness: 'default', }, @@ -815,15 +815,15 @@ describe('detect strategy usage in change requests', () => { name: 'a', constraints: [], }); - const toggle = mockFeatureToggle(); - await createFeatureToggle(enterpriseApp, toggle); + const flag = mockFeatureFlag(); + await createFeatureFlag(enterpriseApp, flag); const [segment] = await enterpriseFetchSegments(); await addStrategyToFeatureEnv( enterpriseApp, - { ...toggle.strategies[0] }, + { ...flag.strategies[0] }, 'default', - toggle.name, + flag.name, ); const [feature] = await fetchFeatures(); @@ -832,7 +832,7 @@ describe('detect strategy usage in change requests', () => { await addSegmentsToStrategy([segment.id], strategyId!); await db.rawDatabase.table('change_request_events').insert({ - feature: toggle.name, + feature: flag.name, action: 'updateStrategy', payload: { id: strategyId, @@ -842,7 +842,7 @@ describe('detect strategy usage in change requests', () => { segments: [segment.id], variants: [], parameters: { - groupId: toggle.name, + groupId: flag.name, rollout: '100', stickiness: 'default', }, @@ -868,17 +868,17 @@ describe('detect strategy usage in change requests', () => { test('Should show usage in features and projects in CRs', async () => { // because they use the same db, we can use the regular app - // (through `createSegment` and `createFeatureToggle`) to + // (through `createSegment` and `createFeatureFlag`) to // create the segment and the flag await app.createSegment({ name: 'a', constraints: [] }); - const toggle = mockFeatureToggle(); - await createFeatureToggle(app, toggle); + const flag = mockFeatureFlag(); + await createFeatureFlag(app, flag); const [segment] = await enterpriseFetchSegments(); expect(segment).toMatchObject({ usedInFeatures: 0, usedInProjects: 0 }); await db.rawDatabase.table('change_request_events').insert({ - feature: toggle.name, + feature: flag.name, action: 'addStrategy', payload: { name: 'flexibleRollout', @@ -887,7 +887,7 @@ describe('detect strategy usage in change requests', () => { segments: [segment.id], variants: [], parameters: { - groupId: toggle.name, + groupId: flag.name, rollout: '100', stickiness: 'default', }, diff --git a/src/lib/features/tag-type/tag-types.e2e.test.ts b/src/lib/features/tag-type/tag-types.e2e.test.ts index 06eb83ffa3..bef86e1876 100644 --- a/src/lib/features/tag-type/tag-types.e2e.test.ts +++ b/src/lib/features/tag-type/tag-types.e2e.test.ts @@ -64,7 +64,7 @@ test('Can create a new tag type', async () => { .send({ name: 'slack', description: - 'Tag your feature toggles with slack channel to post updates for toggle to', + 'Tag your feature flags with slack channel to post updates for flag to', icon: 'http://icons.iconarchive.com/icons/papirus-team/papirus-apps/32/slack-icon.png', }) .expect(201); diff --git a/src/test/e2e/helpers/app.utils.ts b/src/test/e2e/helpers/app.utils.ts index d065bc0d79..cb5e7e7e8b 100644 --- a/src/test/e2e/helpers/app.utils.ts +++ b/src/test/e2e/helpers/app.utils.ts @@ -4,7 +4,7 @@ import type { IUnleashTest } from './test-helper'; export const FEATURES_BASE_PATH = '/api/admin/projects/default/features'; export const ADMIN_BASE_PATH = '/api/admin'; -export const createFeatureToggle = ( +export const createFeatureFlag = ( app: IUnleashTest, postData: object, expectStatusCode = 201,