Skip to content

Commit 5956b72

Browse files
load all feature flag with no label by default (#158)
1 parent ed1d35e commit 5956b72

File tree

4 files changed

+20
-22
lines changed

4 files changed

+20
-22
lines changed

src/AzureAppConfigurationImpl.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -898,8 +898,8 @@ function getValidKeyValueSelectors(selectors?: SettingSelector[]): SettingSelect
898898

899899
function getValidFeatureFlagSelectors(selectors?: SettingSelector[]): SettingSelector[] {
900900
if (selectors === undefined || selectors.length === 0) {
901-
// selectors must be explicitly provided.
902-
throw new Error("Feature flag selectors must be provided.");
901+
// Default selector: key: *, label: \0
902+
return [{ keyFilter: `${featureFlagPrefix}${KeyFilter.Any}`, labelFilter: LabelFilter.Null }];
903903
} else {
904904
selectors.forEach(selector => {
905905
selector.keyFilter = `${featureFlagPrefix}${selector.keyFilter}`;

src/featureManagement/FeatureFlagOptions.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ import { SettingSelector } from "../types.js";
1010
export interface FeatureFlagOptions {
1111
/**
1212
* Specifies whether feature flags will be loaded from Azure App Configuration.
13-
1413
*/
1514
enabled: boolean;
1615

1716
/**
18-
* Specifies the selectors used to filter feature flags.
17+
* Specifies what feature flags to include in the configuration provider.
1918
*
2019
* @remarks
2120
* keyFilter of selector will be prefixed with "appconfig.featureflag/" when request is sent.
22-
* If no selectors are specified then no feature flags will be retrieved.
21+
* If no selectors are specified then all feature flags with no label will be included.
2322
*/
2423
selectors?: SettingSelector[];
2524

test/featureFlag.test.ts

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import * as chai from "chai";
55
import * as chaiAsPromised from "chai-as-promised";
6+
import { featureFlagContentType } from "@azure/app-configuration";
67
import { load } from "./exportedApi.js";
78
import { MAX_TIME_OUT, createMockedConnectionString, createMockedEndpoint, createMockedFeatureFlag, createMockedKeyValue, mockAppConfigurationClientListConfigurationSettings, restoreMocks } from "./utils/testHelper.js";
89
chai.use(chaiAsPromised);
@@ -49,9 +50,9 @@ const mockedKVs = [{
4950
}, {
5051
key: ".appconfig.featureflag/variant",
5152
value: sampleVariantValue,
52-
contentType: "application/vnd.microsoft.appconfig.ff+json;charset=utf-8",
53+
contentType: featureFlagContentType,
5354
}].map(createMockedKeyValue).concat([
54-
createMockedFeatureFlag("Beta", { enabled: true }),
55+
createMockedFeatureFlag("FlagWithTestLabel", { enabled: true }, {label: "Test"}),
5556
createMockedFeatureFlag("Alpha_1", { enabled: true }),
5657
createMockedFeatureFlag("Alpha_2", { enabled: false }),
5758
createMockedFeatureFlag("Telemetry_1", { enabled: true, telemetry: { enabled: true } }, { etag: "ETag"}),
@@ -213,15 +214,22 @@ describe("feature flags", function () {
213214
const connectionString = createMockedConnectionString();
214215
const settings = await load(connectionString, {
215216
featureFlagOptions: {
216-
enabled: true,
217-
selectors: [{
218-
keyFilter: "*"
219-
}]
217+
enabled: true
220218
}
221219
});
222220
expect(settings).not.undefined;
223221
expect(settings.get("feature_management")).not.undefined;
224222
expect(settings.get<any>("feature_management").feature_flags).not.undefined;
223+
// it should only load feature flags with no label by default
224+
expect((settings.get<any>("feature_management").feature_flags as any[]).find(ff => ff.id === "FlagWithTestLabel")).to.be.undefined;
225+
226+
const settings2 = await load(connectionString, {
227+
featureFlagOptions: {
228+
enabled: true,
229+
selectors: [ { keyFilter: "*", labelFilter: "Test" } ]
230+
}
231+
});
232+
expect((settings2.get<any>("feature_management").feature_flags as any[]).find(ff => ff.id === "FlagWithTestLabel")).not.undefined;
225233
});
226234

227235
it("should not load feature flags if disabled", async () => {
@@ -242,15 +250,6 @@ describe("feature flags", function () {
242250
expect(settings.get("feature_management")).undefined;
243251
});
244252

245-
it("should throw error if selectors not specified", async () => {
246-
const connectionString = createMockedConnectionString();
247-
return expect(load(connectionString, {
248-
featureFlagOptions: {
249-
enabled: true
250-
}
251-
})).eventually.rejectedWith("Feature flag selectors must be provided.");
252-
});
253-
254253
it("should load feature flags with custom selector", async () => {
255254
const connectionString = createMockedConnectionString();
256255
const settings = await load(connectionString, {

test/utils/testHelper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the MIT license.
33

44
import * as sinon from "sinon";
5-
import { AppConfigurationClient, ConfigurationSetting } from "@azure/app-configuration";
5+
import { AppConfigurationClient, ConfigurationSetting, featureFlagContentType } from "@azure/app-configuration";
66
import { ClientSecretCredential } from "@azure/identity";
77
import { KeyVaultSecret, SecretClient } from "@azure/keyvault-secrets";
88
import * as uuid from "uuid";
@@ -240,7 +240,7 @@ const createMockedFeatureFlag = (name: string, flagProps?: any, props?: any) =>
240240
"client_filters": []
241241
}
242242
}, flagProps)),
243-
contentType: "application/vnd.microsoft.appconfig.ff+json;charset=utf-8",
243+
contentType: featureFlagContentType,
244244
lastModified: new Date(),
245245
tags: {},
246246
etag: uuid.v4(),

0 commit comments

Comments
 (0)