-
Notifications
You must be signed in to change notification settings - Fork 4
support feature flags #65
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
Changes from 1 commit
c035f89
6730571
e269596
2d0c820
708f759
7f62f14
3cd5f59
923c124
8e2de54
1182638
99f2c29
dc4f553
c29d834
6411a30
4ec140a
453dad3
e4eedc9
87316f3
1499cbf
0c8a4f2
a3f068e
fb56a0f
b1cf809
3c12654
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT license. | ||
|
|
||
| import { FeatureFlagRefreshOptions } from "../RefreshOptions"; | ||
| import { SettingSelector } from "../types"; | ||
|
|
||
| /** | ||
| * Options used to configure feature flags. | ||
| */ | ||
| export interface FeatureFlagOptions { | ||
| /** | ||
| * Specifies whether feature flag support is enabled. | ||
Eskibear marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| */ | ||
| enabled: boolean; | ||
|
|
||
| /** | ||
| * Specifies the selectors used to filter feature flags. | ||
| * | ||
| * @remarks | ||
| * keyFilter of selector will be prefixed with "appconfig.featureflag/" when request is sent. | ||
| * If no selectors are specified then no feature flags will be retrieved. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If no selectors are specified, shouldn't we load all Feature Flags with null label? That's what we do for key-values too.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per discussion, for feature flags we expect customers to explicitly specify selectors.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we throw an error if
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, as it makes no sense to enable feature flags but load nothing. Throwing an error is better than silently loading nothing.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| */ | ||
| selectors?: SettingSelector[]; | ||
|
|
||
| /** | ||
| * Specifies how feature flag refresh is configured. All selected feature flags will be watched for changes. | ||
| */ | ||
| refresh?: FeatureFlagRefreshOptions; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT license. | ||
|
|
||
| export const featureManagementKeyName = "feature_management"; | ||
| export const featureFlagsKeyName = "feature_flags"; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| // Copyright (c) Microsoft Corporation. | ||
| // Licensed under the MIT license. | ||
|
|
||
| import * as chai from "chai"; | ||
| import * as chaiAsPromised from "chai-as-promised"; | ||
| import { load } from "./exportedApi"; | ||
| import { createMockedConnectionString, createMockedFeatureFlag, createMockedKeyValue, mockAppConfigurationClientListConfigurationSettings, restoreMocks } from "./utils/testHelper"; | ||
| chai.use(chaiAsPromised); | ||
| const expect = chai.expect; | ||
|
|
||
| const mockedKVs = [{ | ||
| key: "app.settings.fontColor", | ||
| value: "red", | ||
| }].map(createMockedKeyValue).concat([ | ||
| createMockedFeatureFlag("Beta", true), | ||
| createMockedFeatureFlag("Alpha_1", true), | ||
| createMockedFeatureFlag("Alpha2", false), | ||
| ]); | ||
|
|
||
| describe("feature flags", function () { | ||
| this.timeout(10000); | ||
|
|
||
| before(() => { | ||
| mockAppConfigurationClientListConfigurationSettings(mockedKVs); | ||
| }); | ||
|
|
||
| after(() => { | ||
| restoreMocks(); | ||
| }) | ||
| it("should load feature flags if enabled", async () => { | ||
| const connectionString = createMockedConnectionString(); | ||
| const settings = await load(connectionString, { | ||
| featureFlagOptions: { | ||
| enabled: true | ||
| } | ||
| }); | ||
| expect(settings).not.undefined; | ||
| expect(settings.get("feature_management")).not.undefined; | ||
| expect(settings.get<any>("feature_management").feature_flags).not.undefined; | ||
| }); | ||
|
|
||
| it("should not load feature flags if disabled", async () => { | ||
| const connectionString = createMockedConnectionString(); | ||
| const settings = await load(connectionString, { | ||
| featureFlagOptions: { | ||
| enabled: false | ||
| } | ||
| }); | ||
| expect(settings).not.undefined; | ||
| expect(settings.get("feature_management")).undefined; | ||
| }); | ||
|
|
||
| it("should not load feature flags if not specified", async () => { | ||
| const connectionString = createMockedConnectionString(); | ||
| const settings = await load(connectionString); | ||
| expect(settings).not.undefined; | ||
| expect(settings.get("feature_management")).undefined; | ||
| }); | ||
|
|
||
| it("should load feature flags with custom selector", async () => { | ||
| const connectionString = createMockedConnectionString(); | ||
| const settings = await load(connectionString, { | ||
| featureFlagOptions: { | ||
| enabled: true, | ||
| selectors: [{ | ||
| keyFilter: "Alpha*" | ||
| }] | ||
| } | ||
| }); | ||
| expect(settings).not.undefined; | ||
| expect(settings.get("feature_management")).not.undefined; | ||
| const featureFlags = settings.get<any>("feature_management").feature_flags; | ||
| expect(featureFlags).not.undefined; | ||
| expect((featureFlags as []).length).equals(2); | ||
| }); | ||
|
|
||
| }); |
Uh oh!
There was an error while loading. Please reload this page.