flagsmith-nodejs 6.0.1 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/.github/workflows/publish.yml +17 -17
  2. package/.github/workflows/pull_request.yaml +33 -33
  3. package/.husky/pre-commit +0 -0
  4. package/.prettierignore +2 -1
  5. package/README.md +2 -1
  6. package/build/cjs/flagsmith-engine/features/util.js +3 -3
  7. package/build/cjs/flagsmith-engine/index.d.ts +1 -1
  8. package/build/cjs/flagsmith-engine/index.js +2 -1
  9. package/build/cjs/flagsmith-engine/segments/models.js +7 -7
  10. package/build/cjs/flagsmith-engine/utils/hashing/index.js +1 -1
  11. package/build/cjs/index.d.ts +4 -4
  12. package/build/cjs/index.js +3 -1
  13. package/build/cjs/sdk/analytics.d.ts +1 -1
  14. package/build/cjs/sdk/index.d.ts +5 -5
  15. package/build/cjs/sdk/index.js +7 -5
  16. package/build/cjs/sdk/models.d.ts +25 -0
  17. package/build/cjs/sdk/models.js +25 -0
  18. package/build/cjs/sdk/types.d.ts +14 -4
  19. package/build/cjs/sdk/utils.d.ts +4 -4
  20. package/build/cjs/sdk/utils.js +2 -2
  21. package/build/esm/flagsmith-engine/features/models.js +1 -1
  22. package/build/esm/flagsmith-engine/features/util.js +3 -3
  23. package/build/esm/flagsmith-engine/index.d.ts +1 -1
  24. package/build/esm/flagsmith-engine/index.js +1 -1
  25. package/build/esm/flagsmith-engine/segments/models.js +7 -7
  26. package/build/esm/flagsmith-engine/utils/hashing/index.js +2 -2
  27. package/build/esm/flagsmith-engine/utils/index.js +1 -1
  28. package/build/esm/index.d.ts +4 -4
  29. package/build/esm/index.js +3 -3
  30. package/build/esm/sdk/analytics.d.ts +1 -1
  31. package/build/esm/sdk/index.d.ts +5 -5
  32. package/build/esm/sdk/index.js +6 -5
  33. package/build/esm/sdk/models.d.ts +25 -0
  34. package/build/esm/sdk/models.js +25 -0
  35. package/build/esm/sdk/types.d.ts +14 -4
  36. package/build/esm/sdk/utils.d.ts +4 -4
  37. package/build/esm/sdk/utils.js +2 -2
  38. package/flagsmith-engine/environments/util.ts +2 -2
  39. package/flagsmith-engine/features/models.ts +1 -1
  40. package/flagsmith-engine/features/util.ts +14 -14
  41. package/flagsmith-engine/identities/models.ts +1 -1
  42. package/flagsmith-engine/index.ts +1 -1
  43. package/flagsmith-engine/segments/evaluators.ts +2 -3
  44. package/flagsmith-engine/segments/models.ts +25 -15
  45. package/flagsmith-engine/utils/hashing/index.ts +3 -3
  46. package/flagsmith-engine/utils/index.ts +4 -2
  47. package/index.ts +19 -22
  48. package/package.json +1 -1
  49. package/sdk/analytics.ts +7 -5
  50. package/sdk/index.ts +38 -21
  51. package/sdk/models.ts +25 -0
  52. package/sdk/offline_handlers.ts +1 -1
  53. package/sdk/types.ts +17 -8
  54. package/sdk/utils.ts +8 -8
  55. package/tests/engine/e2e/engine.test.ts +2 -4
  56. package/tests/engine/unit/engine.test.ts +1 -5
  57. package/tests/engine/unit/features/models.test.ts +2 -2
  58. package/tests/engine/unit/identities/identities_builders.test.ts +1 -1
  59. package/tests/engine/unit/segments/segment_evaluators.test.ts +52 -23
  60. package/tests/engine/unit/segments/segments_model.test.ts +35 -37
  61. package/tests/engine/unit/utils/utils.test.ts +28 -30
  62. package/tests/sdk/analytics.test.ts +25 -26
  63. package/tests/sdk/flagsmith-cache.test.ts +84 -76
  64. package/tests/sdk/flagsmith-environment-flags.test.ts +93 -93
  65. package/tests/sdk/flagsmith-identity-flags.test.ts +146 -149
  66. package/tests/sdk/flagsmith.test.ts +40 -42
  67. package/tests/sdk/offline-handlers.test.ts +32 -32
  68. package/tests/sdk/polling.test.ts +0 -1
  69. package/tests/sdk/utils.ts +26 -18
  70. package/vitest.config.ts +10 -15
@@ -2,60 +2,58 @@ import { randomUUID as uuidv4 } from 'node:crypto';
2
2
  import { getHashedPercentateForObjIds } from '../../../../flagsmith-engine/utils/hashing/index.js';
3
3
 
4
4
  describe('getHashedPercentageForObjIds', () => {
5
- it.each([
6
- [[12, 93]],
7
- [[uuidv4(), 99]],
8
- [[99, uuidv4()]],
9
- [[uuidv4(), uuidv4()]]
10
- ])('returns x where 0 <= x < 100', (objIds: (string|number)[]) => {
11
- let result = getHashedPercentateForObjIds(objIds);
12
- expect(result).toBeLessThan(100);
13
- expect(result).toBeGreaterThanOrEqual(0);
14
- });
15
-
16
- it.each([
17
- [[12, 93]],
18
- [[uuidv4(), 99]],
19
- [[99, uuidv4()]],
20
- [[uuidv4(), uuidv4()]]
21
- ])('returns the same value each time', (objIds: (string|number)[]) => {
22
- let resultOne = getHashedPercentateForObjIds(objIds);
23
- let resultTwo = getHashedPercentateForObjIds(objIds);
24
- expect(resultOne).toEqual(resultTwo);
25
- })
5
+ it.each([[[12, 93]], [[uuidv4(), 99]], [[99, uuidv4()]], [[uuidv4(), uuidv4()]]])(
6
+ 'returns x where 0 <= x < 100',
7
+ (objIds: (string | number)[]) => {
8
+ let result = getHashedPercentateForObjIds(objIds);
9
+ expect(result).toBeLessThan(100);
10
+ expect(result).toBeGreaterThanOrEqual(0);
11
+ }
12
+ );
13
+
14
+ it.each([[[12, 93]], [[uuidv4(), 99]], [[99, uuidv4()]], [[uuidv4(), uuidv4()]]])(
15
+ 'returns the same value each time',
16
+ (objIds: (string | number)[]) => {
17
+ let resultOne = getHashedPercentateForObjIds(objIds);
18
+ let resultTwo = getHashedPercentateForObjIds(objIds);
19
+ expect(resultOne).toEqual(resultTwo);
20
+ }
21
+ );
26
22
 
27
23
  it('is unique for different object ids', () => {
28
24
  let resultOne = getHashedPercentateForObjIds([14, 106]);
29
25
  let resultTwo = getHashedPercentateForObjIds([53, 200]);
30
26
  expect(resultOne).not.toEqual(resultTwo);
31
- })
27
+ });
32
28
 
33
29
  it('is evenly distributed', () => {
34
30
  // copied from python test here:
35
31
  // https://github.com/Flagsmith/flagsmith-engine/blob/main/tests/unit/utils/test_utils_hashing.py#L56
36
32
  const testSample = 500;
37
33
  const numTestBuckets = 50;
38
- const testBucketSize = Math.floor(testSample / numTestBuckets)
39
- const errorFactor = 0.1
34
+ const testBucketSize = Math.floor(testSample / numTestBuckets);
35
+ const errorFactor = 0.1;
40
36
 
41
37
  // Given
42
- let objectIdPairs = Array.from(Array(testSample).keys()).flatMap(d => Array.from(Array(testSample).keys()).map(e => [d, e].flat()))
38
+ let objectIdPairs = Array.from(Array(testSample).keys()).flatMap(d =>
39
+ Array.from(Array(testSample).keys()).map(e => [d, e].flat())
40
+ );
43
41
 
44
42
  // When
45
- let values = objectIdPairs.map((objIds) => getHashedPercentateForObjIds(objIds));
43
+ let values = objectIdPairs.map(objIds => getHashedPercentateForObjIds(objIds));
46
44
 
47
45
  // Then
48
46
  for (let i = 0; i++; i < numTestBuckets) {
49
47
  let bucketStart = i * testBucketSize;
50
48
  let bucketEnd = (i + 1) * testBucketSize;
51
49
  let bucketValueLimit = Math.min(
52
- (i + 1) / numTestBuckets + errorFactor + ((i + 1) / numTestBuckets),
50
+ (i + 1) / numTestBuckets + errorFactor + (i + 1) / numTestBuckets,
53
51
  1
54
- )
52
+ );
55
53
 
56
54
  for (let i = bucketStart; i++; i < bucketEnd) {
57
55
  expect(values[i]).toBeLessThanOrEqual(bucketValueLimit);
58
56
  }
59
57
  }
60
- })
61
- })
58
+ });
59
+ });
@@ -1,40 +1,43 @@
1
- import {analyticsProcessor, fetch} from './utils.js';
1
+ import { analyticsProcessor, fetch } from './utils.js';
2
2
 
3
3
  test('test_analytics_processor_track_feature_updates_analytics_data', () => {
4
4
  const aP = analyticsProcessor();
5
- aP.trackFeature("myFeature");
6
- expect(aP.analyticsData["myFeature"]).toBe(1);
5
+ aP.trackFeature('myFeature');
6
+ expect(aP.analyticsData['myFeature']).toBe(1);
7
7
 
8
- aP.trackFeature("myFeature");
9
- expect(aP.analyticsData["myFeature"]).toBe(2);
8
+ aP.trackFeature('myFeature');
9
+ expect(aP.analyticsData['myFeature']).toBe(2);
10
10
  });
11
11
 
12
12
  test('test_analytics_processor_flush_clears_analytics_data', async () => {
13
13
  const aP = analyticsProcessor();
14
- aP.trackFeature("myFeature");
14
+ aP.trackFeature('myFeature');
15
15
  await aP.flush();
16
16
  expect(aP.analyticsData).toStrictEqual({});
17
17
  });
18
18
 
19
19
  test('test_analytics_processor_flush_post_request_data_match_ananlytics_data', async () => {
20
20
  const aP = analyticsProcessor();
21
- aP.trackFeature("myFeature1");
22
- aP.trackFeature("myFeature2");
21
+ aP.trackFeature('myFeature1');
22
+ aP.trackFeature('myFeature2');
23
23
  await aP.flush();
24
24
  expect(fetch).toHaveBeenCalledTimes(1);
25
- expect(fetch).toHaveBeenCalledWith('http://testUrl/analytics/flags/', expect.objectContaining({
26
- body: '{"myFeature1":1,"myFeature2":1}',
27
- headers: { 'Content-Type': 'application/json', 'X-Environment-Key': 'test-key' },
28
- method: 'POST',
29
- }));
25
+ expect(fetch).toHaveBeenCalledWith(
26
+ 'http://testUrl/analytics/flags/',
27
+ expect.objectContaining({
28
+ body: '{"myFeature1":1,"myFeature2":1}',
29
+ headers: { 'Content-Type': 'application/json', 'X-Environment-Key': 'test-key' },
30
+ method: 'POST'
31
+ })
32
+ );
30
33
  });
31
34
 
32
- vi.useFakeTimers()
35
+ vi.useFakeTimers();
33
36
  test('test_analytics_processor_flush_post_request_data_match_ananlytics_data_test', async () => {
34
37
  const aP = analyticsProcessor();
35
- aP.trackFeature("myFeature1");
38
+ aP.trackFeature('myFeature1');
36
39
  setTimeout(() => {
37
- aP.trackFeature("myFeature2");
40
+ aP.trackFeature('myFeature2');
38
41
  expect(fetch).toHaveBeenCalledTimes(1);
39
42
  }, 15000);
40
43
  vi.runOnlyPendingTimers();
@@ -46,7 +49,6 @@ test('test_analytics_processor_flush_early_exit_if_analytics_data_is_empty', asy
46
49
  expect(fetch).not.toHaveBeenCalled();
47
50
  });
48
51
 
49
-
50
52
  test('errors in fetch sending analytics data are swallowed', async () => {
51
53
  // Given
52
54
  // we mock the fetch function to throw and error to mimick a network failure
@@ -63,21 +65,18 @@ test('errors in fetch sending analytics data are swallowed', async () => {
63
65
  // Then
64
66
  // we expect that fetch was called but the exception was handled
65
67
  expect(fetch).toHaveBeenCalled();
66
- })
68
+ });
67
69
 
68
70
  test('analytics is only flushed once even if requested concurrently', async () => {
69
71
  const processor = analyticsProcessor();
70
72
  processor.trackFeature('myFeature');
71
73
  fetch.mockImplementation(() => {
72
74
  return new Promise((resolve, _) => {
73
- setTimeout(resolve, 1000)
74
- })
75
+ setTimeout(resolve, 1000);
76
+ });
75
77
  });
76
- const flushes = Promise.all([
77
- processor.flush(),
78
- processor.flush(),
79
- ])
78
+ const flushes = Promise.all([processor.flush(), processor.flush()]);
80
79
  vi.runOnlyPendingTimers();
81
80
  await flushes;
82
- expect(fetch).toHaveBeenCalledTimes(1)
83
- })
81
+ expect(fetch).toHaveBeenCalledTimes(1);
82
+ });
@@ -1,113 +1,121 @@
1
- import { fetch, environmentJSON, environmentModel, flagsJSON, flagsmith, identitiesJSON, TestCache } from './utils.js';
1
+ import {
2
+ fetch,
3
+ environmentJSON,
4
+ environmentModel,
5
+ flagsJSON,
6
+ flagsmith,
7
+ identitiesJSON,
8
+ TestCache
9
+ } from './utils.js';
2
10
 
3
11
  test('test_empty_cache_not_read_but_populated', async () => {
4
- const cache = new TestCache();
5
- const set = vi.spyOn(cache, 'set');
12
+ const cache = new TestCache();
13
+ const set = vi.spyOn(cache, 'set');
6
14
 
7
- const flg = flagsmith({ cache });
8
- const allFlags = (await flg.getEnvironmentFlags()).allFlags();
15
+ const flg = flagsmith({ cache });
16
+ const allFlags = (await flg.getEnvironmentFlags()).allFlags();
9
17
 
10
- expect(set).toBeCalled();
11
- expect(await cache.get('flags')).toBeTruthy();
18
+ expect(set).toBeCalled();
19
+ expect(await cache.get('flags')).toBeTruthy();
12
20
 
13
- expect(fetch).toBeCalledTimes(1);
14
- expect(allFlags[0].enabled).toBe(true);
15
- expect(allFlags[0].value).toBe('some-value');
16
- expect(allFlags[0].featureName).toBe('some_feature');
21
+ expect(fetch).toBeCalledTimes(1);
22
+ expect(allFlags[0].enabled).toBe(true);
23
+ expect(allFlags[0].value).toBe('some-value');
24
+ expect(allFlags[0].featureName).toBe('some_feature');
17
25
  });
18
26
 
19
27
  test('test_api_not_called_when_cache_present', async () => {
20
- const cache = new TestCache();
21
- const set = vi.spyOn(cache, 'set');
28
+ const cache = new TestCache();
29
+ const set = vi.spyOn(cache, 'set');
22
30
 
23
- const flg = flagsmith({ cache });
24
- await (await flg.getEnvironmentFlags()).allFlags();
25
- const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
31
+ const flg = flagsmith({ cache });
32
+ await (await flg.getEnvironmentFlags()).allFlags();
33
+ const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
26
34
 
27
- expect(set).toBeCalled();
28
- expect(await cache.get('flags')).toBeTruthy();
35
+ expect(set).toBeCalled();
36
+ expect(await cache.get('flags')).toBeTruthy();
29
37
 
30
- expect(fetch).toBeCalledTimes(1);
31
- expect(allFlags[0].enabled).toBe(true);
32
- expect(allFlags[0].value).toBe('some-value');
33
- expect(allFlags[0].featureName).toBe('some_feature');
38
+ expect(fetch).toBeCalledTimes(1);
39
+ expect(allFlags[0].enabled).toBe(true);
40
+ expect(allFlags[0].value).toBe('some-value');
41
+ expect(allFlags[0].featureName).toBe('some_feature');
34
42
  });
35
43
 
36
44
  test('test_api_called_twice_when_no_cache', async () => {
37
- fetch.mockImplementation(() => Promise.resolve(new Response(flagsJSON)));
45
+ fetch.mockImplementation(() => Promise.resolve(new Response(flagsJSON)));
38
46
 
39
- const flg = flagsmith();
40
- await (await flg.getEnvironmentFlags()).allFlags();
47
+ const flg = flagsmith();
48
+ await (await flg.getEnvironmentFlags()).allFlags();
41
49
 
42
- const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
50
+ const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
43
51
 
44
- expect(fetch).toBeCalledTimes(2);
45
- expect(allFlags[0].enabled).toBe(true);
46
- expect(allFlags[0].value).toBe('some-value');
47
- expect(allFlags[0].featureName).toBe('some_feature');
52
+ expect(fetch).toBeCalledTimes(2);
53
+ expect(allFlags[0].enabled).toBe(true);
54
+ expect(allFlags[0].value).toBe('some-value');
55
+ expect(allFlags[0].featureName).toBe('some_feature');
48
56
  });
49
57
 
50
58
  test('test_get_environment_flags_uses_local_environment_when_available', async () => {
51
- const cache = new TestCache();
52
- const set = vi.spyOn(cache, 'set');
53
-
54
- const flg = flagsmith({ cache, environmentKey: 'ser.key', enableLocalEvaluation: true });
55
- const model = environmentModel(JSON.parse(environmentJSON));
56
- const getEnvironment = vi.spyOn(flg, 'getEnvironment')
57
- getEnvironment.mockResolvedValue(model)
58
-
59
- const allFlags = (await flg.getEnvironmentFlags()).allFlags();
60
-
61
- expect(set).toBeCalled();
62
- expect(fetch).toBeCalledTimes(0);
63
- expect(getEnvironment).toBeCalledTimes(1);
64
- expect(allFlags[0].enabled).toBe(model.featureStates[0].enabled);
65
- expect(allFlags[0].value).toBe(model.featureStates[0].getValue());
66
- expect(allFlags[0].featureName).toBe(model.featureStates[0].feature.name);
59
+ const cache = new TestCache();
60
+ const set = vi.spyOn(cache, 'set');
61
+
62
+ const flg = flagsmith({ cache, environmentKey: 'ser.key', enableLocalEvaluation: true });
63
+ const model = environmentModel(JSON.parse(environmentJSON));
64
+ const getEnvironment = vi.spyOn(flg, 'getEnvironment');
65
+ getEnvironment.mockResolvedValue(model);
66
+
67
+ const allFlags = (await flg.getEnvironmentFlags()).allFlags();
68
+
69
+ expect(set).toBeCalled();
70
+ expect(fetch).toBeCalledTimes(0);
71
+ expect(getEnvironment).toBeCalledTimes(1);
72
+ expect(allFlags[0].enabled).toBe(model.featureStates[0].enabled);
73
+ expect(allFlags[0].value).toBe(model.featureStates[0].getValue());
74
+ expect(allFlags[0].featureName).toBe(model.featureStates[0].feature.name);
67
75
  });
68
76
 
69
77
  test('test_cache_used_for_identity_flags', async () => {
70
- const cache = new TestCache();
71
- const set = vi.spyOn(cache, 'set');
78
+ const cache = new TestCache();
79
+ const set = vi.spyOn(cache, 'set');
72
80
 
73
- const identifier = 'identifier';
74
- const traits = { some_trait: 'some_value' };
75
- const flg = flagsmith({ cache });
81
+ const identifier = 'identifier';
82
+ const traits = { some_trait: 'some_value' };
83
+ const flg = flagsmith({ cache });
76
84
 
77
- (await flg.getIdentityFlags(identifier, traits)).allFlags();
78
- const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
85
+ (await flg.getIdentityFlags(identifier, traits)).allFlags();
86
+ const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
79
87
 
80
- expect(set).toBeCalled();
81
- expect(await cache.get('flags-identifier')).toBeTruthy();
88
+ expect(set).toBeCalled();
89
+ expect(await cache.get('flags-identifier')).toBeTruthy();
82
90
 
83
- expect(fetch).toBeCalledTimes(1);
91
+ expect(fetch).toBeCalledTimes(1);
84
92
 
85
- expect(identityFlags[0].enabled).toBe(true);
86
- expect(identityFlags[0].value).toBe('some-value');
87
- expect(identityFlags[0].featureName).toBe('some_feature');
93
+ expect(identityFlags[0].enabled).toBe(true);
94
+ expect(identityFlags[0].value).toBe('some-value');
95
+ expect(identityFlags[0].featureName).toBe('some_feature');
88
96
  });
89
97
 
90
98
  test('test_cache_used_for_identity_flags_local_evaluation', async () => {
91
- const cache = new TestCache();
92
- const set = vi.spyOn(cache, 'set');
99
+ const cache = new TestCache();
100
+ const set = vi.spyOn(cache, 'set');
93
101
 
94
- const identifier = 'identifier';
95
- const traits = { some_trait: 'some_value' };
96
- const flg = flagsmith({
97
- cache,
98
- environmentKey: 'ser.key',
99
- enableLocalEvaluation: true,
100
- });
102
+ const identifier = 'identifier';
103
+ const traits = { some_trait: 'some_value' };
104
+ const flg = flagsmith({
105
+ cache,
106
+ environmentKey: 'ser.key',
107
+ enableLocalEvaluation: true
108
+ });
101
109
 
102
- (await flg.getIdentityFlags(identifier, traits)).allFlags();
103
- const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
110
+ (await flg.getIdentityFlags(identifier, traits)).allFlags();
111
+ const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
104
112
 
105
- expect(set).toBeCalled();
106
- expect(await cache.get('flags-identifier')).toBeTruthy();
113
+ expect(set).toBeCalled();
114
+ expect(await cache.get('flags-identifier')).toBeTruthy();
107
115
 
108
- expect(fetch).toBeCalledTimes(1);
116
+ expect(fetch).toBeCalledTimes(1);
109
117
 
110
- expect(identityFlags[0].enabled).toBe(true);
111
- expect(identityFlags[0].value).toBe('some-value');
112
- expect(identityFlags[0].featureName).toBe('some_feature');
118
+ expect(identityFlags[0].enabled).toBe(true);
119
+ expect(identityFlags[0].value).toBe('some-value');
120
+ expect(identityFlags[0].featureName).toBe('some_feature');
113
121
  });
@@ -5,150 +5,150 @@ import { DefaultFlag } from '../../sdk/models.js';
5
5
  vi.mock('../../sdk/polling_manager');
6
6
 
7
7
  test('test_get_environment_flags_calls_api_when_no_local_environment', async () => {
8
- const flg = flagsmith();
9
- const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
8
+ const flg = flagsmith();
9
+ const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
10
10
 
11
- expect(fetch).toBeCalledTimes(1);
12
- expect(allFlags[0].enabled).toBe(true);
13
- expect(allFlags[0].value).toBe('some-value');
14
- expect(allFlags[0].featureName).toBe('some_feature');
11
+ expect(fetch).toBeCalledTimes(1);
12
+ expect(allFlags[0].enabled).toBe(true);
13
+ expect(allFlags[0].value).toBe('some-value');
14
+ expect(allFlags[0].featureName).toBe('some_feature');
15
15
  });
16
16
 
17
17
  test('test_default_flag_is_used_when_no_environment_flags_returned', async () => {
18
- fetch.mockResolvedValue(new Response(JSON.stringify([])));
18
+ fetch.mockResolvedValue(new Response(JSON.stringify([])));
19
19
 
20
- const defaultFlag = new DefaultFlag('some-default-value', true);
20
+ const defaultFlag = new DefaultFlag('some-default-value', true);
21
21
 
22
- const defaultFlagHandler = (featureName: string) => defaultFlag;
22
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
23
23
 
24
- const flg = new Flagsmith({
25
- environmentKey: 'key',
26
- defaultFlagHandler: defaultFlagHandler,
27
- customHeaders: {
28
- 'X-Test-Header': '1',
29
- }
30
- });
24
+ const flg = new Flagsmith({
25
+ environmentKey: 'key',
26
+ defaultFlagHandler: defaultFlagHandler,
27
+ customHeaders: {
28
+ 'X-Test-Header': '1'
29
+ }
30
+ });
31
31
 
32
- const flags = await flg.getEnvironmentFlags();
33
- const flag = flags.getFlag('some_feature');
34
- expect(flag.isDefault).toBe(true);
35
- expect(flag.enabled).toBe(defaultFlag.enabled);
36
- expect(flag.value).toBe(defaultFlag.value);
32
+ const flags = await flg.getEnvironmentFlags();
33
+ const flag = flags.getFlag('some_feature');
34
+ expect(flag.isDefault).toBe(true);
35
+ expect(flag.enabled).toBe(defaultFlag.enabled);
36
+ expect(flag.value).toBe(defaultFlag.value);
37
37
  });
38
38
 
39
39
  test('test_analytics_processor_tracks_flags', async () => {
40
- const defaultFlag = new DefaultFlag('some-default-value', true);
40
+ const defaultFlag = new DefaultFlag('some-default-value', true);
41
41
 
42
- const defaultFlagHandler = (featureName: string) => defaultFlag;
42
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
43
43
 
44
- const flg = flagsmith({
45
- environmentKey: 'key',
46
- defaultFlagHandler: defaultFlagHandler,
47
- enableAnalytics: true,
48
- });
44
+ const flg = flagsmith({
45
+ environmentKey: 'key',
46
+ defaultFlagHandler: defaultFlagHandler,
47
+ enableAnalytics: true
48
+ });
49
49
 
50
- const flags = await flg.getEnvironmentFlags();
51
- const flag = flags.getFlag('some_feature');
50
+ const flags = await flg.getEnvironmentFlags();
51
+ const flag = flags.getFlag('some_feature');
52
52
 
53
- expect(flag.isDefault).toBe(false);
54
- expect(flag.enabled).toBe(true);
55
- expect(flag.value).toBe('some-value');
53
+ expect(flag.isDefault).toBe(false);
54
+ expect(flag.enabled).toBe(true);
55
+ expect(flag.value).toBe('some-value');
56
56
  });
57
57
 
58
58
  test('test_getFeatureValue', async () => {
59
- const defaultFlag = new DefaultFlag('some-default-value', true);
59
+ const defaultFlag = new DefaultFlag('some-default-value', true);
60
60
 
61
- const defaultFlagHandler = (featureName: string) => defaultFlag;
61
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
62
62
 
63
- const flg = flagsmith({
64
- environmentKey: 'key',
65
- defaultFlagHandler: defaultFlagHandler,
66
- enableAnalytics: true,
67
- });
63
+ const flg = flagsmith({
64
+ environmentKey: 'key',
65
+ defaultFlagHandler: defaultFlagHandler,
66
+ enableAnalytics: true
67
+ });
68
68
 
69
- const flags = await flg.getEnvironmentFlags();
70
- const featureValue = flags.getFeatureValue('some_feature');
69
+ const flags = await flg.getEnvironmentFlags();
70
+ const featureValue = flags.getFeatureValue('some_feature');
71
71
 
72
- expect(featureValue).toBe('some-value');
72
+ expect(featureValue).toBe('some-value');
73
73
  });
74
74
 
75
75
  test('test_throws_when_no_default_flag_handler_after_multiple_API_errors', async () => {
76
- fetch.mockRejectedValue('Error during fetching the API response');
76
+ fetch.mockRejectedValue('Error during fetching the API response');
77
77
 
78
- const flg = flagsmith({
79
- environmentKey: 'key',
80
- });
78
+ const flg = flagsmith({
79
+ environmentKey: 'key'
80
+ });
81
81
 
82
- await expect(async () => {
83
- const flags = await flg.getEnvironmentFlags();
84
- const flag = flags.getFlag('some_feature');
85
- }).rejects.toThrow('getEnvironmentFlags failed and no default flag handler was provided');
82
+ await expect(async () => {
83
+ const flags = await flg.getEnvironmentFlags();
84
+ const flag = flags.getFlag('some_feature');
85
+ }).rejects.toThrow('getEnvironmentFlags failed and no default flag handler was provided');
86
86
  });
87
87
 
88
88
  test('test_non_200_response_raises_flagsmith_api_error', async () => {
89
- const errorResponse403 = new Response('403 Forbidden', {
90
- status: 403
91
- });
92
- fetch.mockResolvedValue(errorResponse403);
89
+ const errorResponse403 = new Response('403 Forbidden', {
90
+ status: 403
91
+ });
92
+ fetch.mockResolvedValue(errorResponse403);
93
93
 
94
- const flg = new Flagsmith({
95
- environmentKey: 'some'
96
- });
94
+ const flg = new Flagsmith({
95
+ environmentKey: 'some'
96
+ });
97
97
 
98
- await expect(flg.getEnvironmentFlags()).rejects.toThrow();
98
+ await expect(flg.getEnvironmentFlags()).rejects.toThrow();
99
99
  });
100
100
  test('test_default_flag_is_not_used_when_environment_flags_returned', async () => {
101
- const defaultFlag = new DefaultFlag('some-default-value', true);
101
+ const defaultFlag = new DefaultFlag('some-default-value', true);
102
102
 
103
- const defaultFlagHandler = (featureName: string) => defaultFlag;
103
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
104
104
 
105
- const flg = flagsmith({
106
- environmentKey: 'key',
107
- defaultFlagHandler: defaultFlagHandler
108
- });
105
+ const flg = flagsmith({
106
+ environmentKey: 'key',
107
+ defaultFlagHandler: defaultFlagHandler
108
+ });
109
109
 
110
- const flags = await flg.getEnvironmentFlags();
111
- const flag = flags.getFlag('some_feature');
110
+ const flags = await flg.getEnvironmentFlags();
111
+ const flag = flags.getFlag('some_feature');
112
112
 
113
- expect(flag.isDefault).toBe(false);
114
- expect(flag.value).not.toBe(defaultFlag.value);
115
- expect(flag.value).toBe('some-value');
113
+ expect(flag.isDefault).toBe(false);
114
+ expect(flag.value).not.toBe(defaultFlag.value);
115
+ expect(flag.value).toBe('some-value');
116
116
  });
117
117
 
118
118
  test('test_default_flag_is_used_when_bad_api_response_happens', async () => {
119
- fetch.mockResolvedValue(new Response('bad-data'));
119
+ fetch.mockResolvedValue(new Response('bad-data'));
120
120
 
121
- const defaultFlag = new DefaultFlag('some-default-value', true);
121
+ const defaultFlag = new DefaultFlag('some-default-value', true);
122
122
 
123
- const defaultFlagHandler = (featureName: string) => defaultFlag;
123
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
124
124
 
125
- const flg = new Flagsmith({
126
- environmentKey: 'key',
127
- defaultFlagHandler: defaultFlagHandler
128
- });
125
+ const flg = new Flagsmith({
126
+ environmentKey: 'key',
127
+ defaultFlagHandler: defaultFlagHandler
128
+ });
129
129
 
130
- const flags = await flg.getEnvironmentFlags();
131
- const flag = flags.getFlag('some_feature');
130
+ const flags = await flg.getEnvironmentFlags();
131
+ const flag = flags.getFlag('some_feature');
132
132
 
133
- expect(flag.isDefault).toBe(true);
134
- expect(flag.value).toBe(defaultFlag.value);
133
+ expect(flag.isDefault).toBe(true);
134
+ expect(flag.value).toBe(defaultFlag.value);
135
135
  });
136
136
 
137
137
  test('test_local_evaluation', async () => {
138
- const defaultFlag = new DefaultFlag('some-default-value', true);
138
+ const defaultFlag = new DefaultFlag('some-default-value', true);
139
139
 
140
- const defaultFlagHandler = (featureName: string) => defaultFlag;
140
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
141
141
 
142
- const flg = flagsmith({
143
- environmentKey: 'ser.key',
144
- enableLocalEvaluation: true,
145
- defaultFlagHandler: defaultFlagHandler
146
- });
142
+ const flg = flagsmith({
143
+ environmentKey: 'ser.key',
144
+ enableLocalEvaluation: true,
145
+ defaultFlagHandler: defaultFlagHandler
146
+ });
147
147
 
148
- const flags = await flg.getEnvironmentFlags();
149
- const flag = flags.getFlag('some_feature');
148
+ const flags = await flg.getEnvironmentFlags();
149
+ const flag = flags.getFlag('some_feature');
150
150
 
151
- expect(flag.isDefault).toBe(false);
152
- expect(flag.value).not.toBe(defaultFlag.value);
153
- expect(flag.value).toBe('some-value');
151
+ expect(flag.isDefault).toBe(false);
152
+ expect(flag.value).not.toBe(defaultFlag.value);
153
+ expect(flag.value).toBe('some-value');
154
154
  });