Skip to content

Commit b1c6d23

Browse files
authored
feat(flagd): add flag metadata (open-feature#1151)
Signed-off-by: Michael Beemer <[email protected]>
1 parent 5b2ac49 commit b1c6d23

22 files changed

+152
-369
lines changed

libs/providers/flagd-web/project.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@
5959
]
6060
},
6161
"e2e": {
62-
"executor": "nx:run-commands",
62+
"executor": "@nx/jest:jest",
63+
"outputs": [
64+
"{workspaceRoot}/coverage/libs/providers/flagd-web"
65+
],
6366
"options": {
64-
"commands": [
65-
"npx jest"
66-
],
67-
"cwd": "libs/providers/flagd-web/src/e2e",
67+
"jestConfig": "libs/providers/flagd-web/src/e2e/jest.config.ts",
6868
"parallel": false
6969
},
7070
"dependsOn": [
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getGherkinTestPath } from '@openfeature/flagd-core';
22

3-
export const FLAGD_NAME = 'flagd-web';
3+
export const FLAGD_NAME = 'flagd';
44

55
export const GHERKIN_EVALUATION_FEATURE = getGherkinTestPath('flagd.feature');
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
export default {
1+
import type { Config } from 'jest';
2+
3+
const config: Config = {
24
displayName: 'providers-flagd-web-e2e',
3-
transform: {
4-
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: './tsconfig.lib.json' }],
5-
},
5+
clearMocks: true,
6+
preset: 'ts-jest',
67
moduleNameMapper: {
78
'@openfeature/flagd-core': ['<rootDir>/../../../../shared/flagd-core/src'],
8-
'^(.*)\\.js$': ['$1.js', '$1.ts', '$1'],
9+
'(.+)\\.js$': '$1',
910
},
10-
testEnvironment: 'node',
11-
preset: 'ts-jest',
12-
clearMocks: true,
13-
setupFiles: [],
1411
verbose: true,
15-
silent: false,
1612
};
13+
14+
export default config;

libs/providers/flagd-web/src/e2e/step-definitions/flag.ts

+30-37
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { StepDefinitions } from 'jest-cucumber';
22
import {
3-
EvaluationContext,
43
EvaluationDetails,
54
FlagValue,
65
JsonObject,
@@ -13,10 +12,8 @@ import { E2E_CLIENT_NAME } from '@openfeature/flagd-core';
1312
export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then }) => {
1413
let flagKey: string;
1514
let value: FlagValue;
16-
let context: EvaluationContext = {};
1715
let details: EvaluationDetails<FlagValue>;
1816
let fallback: FlagValue;
19-
let flagsChanged: string[];
2017

2118
const client = OpenFeature.getClient(E2E_CLIENT_NAME);
2219

@@ -26,19 +23,15 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
2623
});
2724
});
2825

29-
beforeEach(() => {
30-
context = {};
31-
});
32-
3326
given('a provider is registered', () => undefined);
3427
given('a flagd provider is set', () => undefined);
3528

3629
when(
3730
/^a boolean flag with key "(.*)" is evaluated with default value "(.*)"$/,
38-
async (key: string, defaultValue: string) => {
31+
(key: string, defaultValue: string) => {
3932
flagKey = key;
4033
fallback = defaultValue;
41-
value = await client.getBooleanValue(key, defaultValue === 'true');
34+
value = client.getBooleanValue(key, defaultValue === 'true');
4235
},
4336
);
4437

@@ -48,10 +41,10 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
4841

4942
when(
5043
/^a string flag with key "(.*)" is evaluated with default value "(.*)"$/,
51-
async (key: string, defaultValue: string) => {
44+
(key: string, defaultValue: string) => {
5245
flagKey = key;
5346
fallback = defaultValue;
54-
value = await client.getStringValue(key, defaultValue);
47+
value = client.getStringValue(key, defaultValue);
5548
},
5649
);
5750

@@ -64,7 +57,7 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
6457
async (key: string, defaultValue: string) => {
6558
flagKey = key;
6659
fallback = Number(defaultValue);
67-
value = await client.getNumberValue(key, Number.parseInt(defaultValue));
60+
value = client.getNumberValue(key, Number.parseInt(defaultValue));
6861
},
6962
);
7063

@@ -77,7 +70,7 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
7770
async (key: string, defaultValue: string) => {
7871
flagKey = key;
7972
fallback = Number(defaultValue);
80-
value = await client.getNumberValue(key, Number.parseFloat(defaultValue));
73+
value = client.getNumberValue(key, Number.parseFloat(defaultValue));
8174
},
8275
);
8376

@@ -89,7 +82,7 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
8982
const defaultValue = {};
9083
flagKey = key;
9184
fallback = '';
92-
value = await client.getObjectValue(key, defaultValue);
85+
value = client.getObjectValue(key, defaultValue);
9386
});
9487

9588
then(
@@ -107,7 +100,7 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
107100
async (key: string, defaultValue: string) => {
108101
flagKey = key;
109102
fallback = defaultValue;
110-
details = await client.getBooleanDetails(key, defaultValue === 'true');
103+
details = client.getBooleanDetails(key, defaultValue === 'true');
111104
},
112105
);
113106

@@ -123,10 +116,10 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
123116

124117
when(
125118
/^a string flag with key "(.*)" is evaluated with details and default value "(.*)"$/,
126-
async (key: string, defaultValue: string) => {
119+
(key: string, defaultValue: string) => {
127120
flagKey = key;
128121
fallback = defaultValue;
129-
details = await client.getStringDetails(key, defaultValue);
122+
details = client.getStringDetails(key, defaultValue);
130123
},
131124
);
132125

@@ -142,10 +135,10 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
142135

143136
when(
144137
/^an integer flag with key "(.*)" is evaluated with details and default value (\d+)$/,
145-
async (key: string, defaultValue: string) => {
138+
(key: string, defaultValue: string) => {
146139
flagKey = key;
147140
fallback = defaultValue;
148-
details = await client.getNumberDetails(key, Number.parseInt(defaultValue));
141+
details = client.getNumberDetails(key, Number.parseInt(defaultValue));
149142
},
150143
);
151144

@@ -161,10 +154,10 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
161154

162155
when(
163156
/^a float flag with key "(.*)" is evaluated with details and default value (\d+\.?\d*)$/,
164-
async (key: string, defaultValue: string) => {
157+
(key: string, defaultValue: string) => {
165158
flagKey = key;
166159
fallback = defaultValue;
167-
details = await client.getNumberDetails(key, Number.parseFloat(defaultValue));
160+
details = client.getNumberDetails(key, Number.parseFloat(defaultValue));
168161
},
169162
);
170163

@@ -178,10 +171,10 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
178171
},
179172
);
180173

181-
when(/^an object flag with key "(.*)" is evaluated with details and a null default value$/, async (key: string) => {
174+
when(/^an object flag with key "(.*)" is evaluated with details and a null default value$/, (key: string) => {
182175
flagKey = key;
183176
fallback = {};
184-
details = await client.getObjectDetails(key, {});
177+
details = client.getObjectDetails(key, {});
185178
});
186179

187180
then(
@@ -211,10 +204,10 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
211204

212205
when(
213206
/^a non-existent string flag with key "(.*)" is evaluated with details and a default value "(.*)"$/,
214-
async (key: string, defaultValue: string) => {
207+
(key: string, defaultValue: string) => {
215208
flagKey = key;
216209
fallback = defaultValue;
217-
details = await client.getStringDetails(flagKey, defaultValue);
210+
details = client.getStringDetails(flagKey, defaultValue);
218211
},
219212
);
220213

@@ -234,10 +227,10 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
234227

235228
when(
236229
/^a string flag with key "(.*)" is evaluated as an integer, with details and a default value (\d+)$/,
237-
async (key: string, defaultValue: string) => {
230+
(key: string, defaultValue: string) => {
238231
flagKey = key;
239232
fallback = Number.parseInt(defaultValue);
240-
details = await client.getNumberDetails(flagKey, Number.parseInt(defaultValue));
233+
details = client.getNumberDetails(flagKey, Number.parseInt(defaultValue));
241234
},
242235
);
243236

@@ -266,7 +259,7 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
266259
});
267260

268261
when('a PROVIDER_CONFIGURATION_CHANGED handler is added', () => {
269-
client.addHandler(ProviderEvents.ConfigurationChanged, async (details) => {
262+
client.addHandler(ProviderEvents.ConfigurationChanged, async () => {
270263
// file writes are not atomic, so we get a few events in quick succession from the testbed
271264
// some will not contain changes, this tolerates that; at least 1 should have our change
272265

@@ -290,7 +283,7 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
290283
expect(ran).toBeTruthy();
291284
});
292285

293-
and(/^the event details must indicate "(.*)" was altered$/, (flagName) => {
286+
and(/^the event details must indicate "(.*)" was altered$/, () => {
294287
// TODO: enable this for testing of issue
295288
//expect(flagsChanged).toContain(flagName);
296289
});
@@ -303,9 +296,9 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
303296
},
304297
);
305298

306-
then(/^the resolved boolean zero-value should be "(.*)"$/, async (expectedVal: string) => {
299+
then(/^the resolved boolean zero-value should be "(.*)"$/, (expectedVal: string) => {
307300
const expectedValue = expectedVal === 'true';
308-
const value = await client.getBooleanValue(flagKey, fallback as boolean);
301+
const value = client.getBooleanValue(flagKey, fallback as boolean);
309302
expect(value).toEqual(expectedValue);
310303
});
311304

@@ -314,8 +307,8 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
314307
fallback = defaultVal;
315308
});
316309

317-
then('the resolved string zero-value should be ""', async () => {
318-
const value = await client.getStringValue(flagKey, fallback as string);
310+
then('the resolved string zero-value should be ""', () => {
311+
const value = client.getStringValue(flagKey, fallback as string);
319312
expect(value).toEqual('');
320313
});
321314

@@ -324,9 +317,9 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
324317
fallback = defaultVal;
325318
});
326319

327-
then(/^the resolved integer zero-value should be (\d+)$/, async (expectedValueString) => {
320+
then(/^the resolved integer zero-value should be (\d+)$/, (expectedValueString) => {
328321
const expectedValue = Number.parseInt(expectedValueString);
329-
const value = await client.getNumberValue(flagKey, fallback as number);
322+
const value = client.getNumberValue(flagKey, fallback as number);
330323
expect(value).toEqual(expectedValue);
331324
});
332325

@@ -338,9 +331,9 @@ export const flagStepDefinitions: StepDefinitions = ({ given, and, when, then })
338331
},
339332
);
340333

341-
then(/^the resolved float zero-value should be (\d+\.\d+)$/, async (expectedValueString) => {
334+
then(/^the resolved float zero-value should be (\d+\.\d+)$/, (expectedValueString) => {
342335
const expectedValue = Number.parseFloat(expectedValueString);
343-
const value = await client.getNumberValue(flagKey, fallback as number);
336+
const value = client.getNumberValue(flagKey, fallback as number);
344337
expect(value).toEqual(expectedValue);
345338
});
346339

libs/providers/flagd-web/src/e2e/tsconfig.lib.json

-12
This file was deleted.

libs/providers/flagd-web/src/lib/flagd-web-provider.spec.ts

+3-21
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
JsonValue,
77
OpenFeature,
88
ProviderEvents,
9-
ProviderStatus,
109
StandardResolutionReasons,
1110
} from '@openfeature/web-sdk';
1211
import fetchMock from 'jest-fetch-mock';
@@ -193,21 +192,12 @@ describe(FlagdWebProvider.name, () => {
193192

194193
describe(ProviderEvents.Ready, () => {
195194
it('should fire as soon as client subscribes, if ready', (done) => {
196-
try {
197-
// should start NOT_READY
198-
expect(provider.status).toEqual(ProviderStatus.NOT_READY);
199-
done();
200-
} catch (err) {
201-
done(err);
202-
}
203-
204195
mockCallbackClient.mockMessage({
205196
type: EVENT_PROVIDER_READY,
206197
});
207198

208199
client.addHandler(ProviderEvents.Ready, () => {
209200
try {
210-
expect(provider.status).toEqual(ProviderStatus.READY);
211201
done();
212202
} catch (err) {
213203
done(err);
@@ -216,22 +206,14 @@ describe(FlagdWebProvider.name, () => {
216206
});
217207

218208
it('should fire and be ready if message received', (done) => {
219-
try {
220-
// should start NOT_READY
221-
expect(provider.status).toEqual(ProviderStatus.NOT_READY);
222-
done();
223-
} catch (err) {
224-
done(err);
225-
}
226-
227209
client.addHandler(ProviderEvents.Ready, () => {
228210
try {
229-
expect(provider.status).toEqual(ProviderStatus.READY);
230211
done();
231212
} catch (err) {
232213
done(err);
233214
}
234215
});
216+
235217
mockCallbackClient.mockMessage({
236218
type: EVENT_PROVIDER_READY,
237219
});
@@ -269,9 +251,9 @@ describe(FlagdWebProvider.name, () => {
269251

270252
describe(ProviderEvents.Error, () => {
271253
it('should fire if message received', (done) => {
272-
client.addHandler(ProviderEvents.Error, () => {
254+
client.addHandler(ProviderEvents.Error, (event) => {
273255
try {
274-
expect(provider.status).toEqual(ProviderStatus.ERROR);
256+
expect(event?.providerName).toBe('flagd');
275257
done();
276258
} catch (err) {
277259
done(err);

0 commit comments

Comments
 (0)