flagsmith-nodejs 2.0.0-beta.4 → 2.0.0-beta.7

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 (96) hide show
  1. package/.github/workflows/pull_request.yaml +37 -29
  2. package/.idea/flagsmith-nodejs-client.iml +12 -0
  3. package/.idea/modules.xml +8 -0
  4. package/.idea/vcs.xml +6 -0
  5. package/README.md +7 -0
  6. package/build/flagsmith-engine/environments/integrations/models.d.ts +4 -0
  7. package/build/flagsmith-engine/environments/integrations/models.js +11 -0
  8. package/build/flagsmith-engine/environments/models.d.ts +25 -0
  9. package/build/flagsmith-engine/environments/models.js +29 -0
  10. package/build/flagsmith-engine/environments/util.d.ts +3 -0
  11. package/build/flagsmith-engine/environments/util.js +21 -0
  12. package/build/flagsmith-engine/features/constants.d.ts +4 -0
  13. package/build/flagsmith-engine/features/constants.js +7 -0
  14. package/build/flagsmith-engine/features/models.d.ts +31 -0
  15. package/build/flagsmith-engine/features/models.js +99 -0
  16. package/build/flagsmith-engine/features/util.d.ts +3 -0
  17. package/build/flagsmith-engine/features/util.js +20 -0
  18. package/build/flagsmith-engine/identities/models.d.ts +15 -0
  19. package/build/flagsmith-engine/identities/models.js +112 -0
  20. package/build/flagsmith-engine/identities/traits/models.d.ts +5 -0
  21. package/build/flagsmith-engine/identities/traits/models.js +11 -0
  22. package/build/flagsmith-engine/identities/util.d.ts +4 -0
  23. package/build/flagsmith-engine/identities/util.js +46 -0
  24. package/build/flagsmith-engine/index.d.ts +8 -0
  25. package/build/flagsmith-engine/index.js +113 -0
  26. package/build/flagsmith-engine/organisations/models.d.ts +9 -0
  27. package/build/flagsmith-engine/organisations/models.js +21 -0
  28. package/build/flagsmith-engine/organisations/util.d.ts +2 -0
  29. package/build/flagsmith-engine/organisations/util.js +8 -0
  30. package/build/flagsmith-engine/projects/models.d.ts +10 -0
  31. package/build/flagsmith-engine/projects/models.js +14 -0
  32. package/build/flagsmith-engine/projects/util.d.ts +2 -0
  33. package/build/flagsmith-engine/projects/util.js +15 -0
  34. package/build/flagsmith-engine/segments/constants.d.ts +26 -0
  35. package/build/flagsmith-engine/segments/constants.js +31 -0
  36. package/build/flagsmith-engine/segments/evaluators.d.ts +6 -0
  37. package/build/flagsmith-engine/segments/evaluators.js +37 -0
  38. package/build/flagsmith-engine/segments/models.d.ts +31 -0
  39. package/build/flagsmith-engine/segments/models.js +89 -0
  40. package/build/flagsmith-engine/segments/util.d.ts +4 -0
  41. package/build/flagsmith-engine/segments/util.js +25 -0
  42. package/build/flagsmith-engine/utils/collections.d.ts +3 -0
  43. package/build/flagsmith-engine/utils/collections.js +26 -0
  44. package/build/flagsmith-engine/utils/errors.d.ts +2 -0
  45. package/build/flagsmith-engine/utils/errors.js +26 -0
  46. package/build/flagsmith-engine/utils/hashing/index.d.ts +9 -0
  47. package/build/flagsmith-engine/utils/hashing/index.js +60 -0
  48. package/build/flagsmith-engine/utils/index.d.ts +1 -0
  49. package/build/flagsmith-engine/utils/index.js +14 -0
  50. package/build/index.d.ts +1 -0
  51. package/build/index.js +11 -0
  52. package/build/sdk/analytics.d.ts +28 -0
  53. package/build/sdk/analytics.js +102 -0
  54. package/build/sdk/errors.d.ts +4 -0
  55. package/build/sdk/errors.js +34 -0
  56. package/build/sdk/index.d.ts +123 -0
  57. package/build/sdk/index.js +484 -0
  58. package/build/sdk/models.d.ts +55 -0
  59. package/build/sdk/models.js +149 -0
  60. package/build/sdk/polling_manager.d.ts +9 -0
  61. package/build/sdk/polling_manager.js +72 -0
  62. package/build/sdk/types.d.ts +7 -0
  63. package/build/sdk/types.js +2 -0
  64. package/build/sdk/utils.d.ts +12 -0
  65. package/build/sdk/utils.js +94 -0
  66. package/example/package-lock.json +1 -996
  67. package/flagsmith-engine/features/models.ts +0 -4
  68. package/flagsmith-engine/identities/models.ts +1 -1
  69. package/flagsmith-engine/index.ts +1 -1
  70. package/flagsmith-engine/organisations/models.ts +1 -1
  71. package/flagsmith-engine/segments/models.ts +0 -2
  72. package/flagsmith-engine/utils/collections.ts +1 -12
  73. package/flagsmith-engine/utils/hashing/index.ts +5 -2
  74. package/package.json +3 -2
  75. package/sdk/analytics.ts +0 -2
  76. package/sdk/index.ts +83 -26
  77. package/sdk/polling_manager.ts +0 -1
  78. package/sdk/types.ts +8 -0
  79. package/tests/engine/unit/{egine.test.ts → engine.test.ts} +20 -0
  80. package/tests/engine/unit/features/models.test.ts +7 -3
  81. package/tests/engine/unit/identities/identities_builders.test.ts +13 -0
  82. package/tests/engine/unit/identities/identities_models.test.ts +3 -14
  83. package/tests/engine/unit/organization/models.test.ts +1 -1
  84. package/tests/engine/unit/segments/segments_model.test.ts +2 -1
  85. package/tests/engine/unit/utils.ts +1 -1
  86. package/tests/sdk/analytics.test.ts +11 -0
  87. package/tests/sdk/flagsmith-cache.test.ts +150 -0
  88. package/tests/sdk/flagsmith-environment-flags.test.ts +197 -0
  89. package/tests/sdk/flagsmith-identity-flags.test.ts +140 -0
  90. package/tests/sdk/flagsmith.test.ts +100 -85
  91. package/tests/sdk/polling.test.ts +25 -0
  92. package/tests/sdk/utils.ts +21 -2
  93. package/tsconfig.json +2 -1
  94. package/.tool-versions +0 -1
  95. package/tests/engine/engine-tests/engine-test-data/data/environment_n9fbf9h3v4fFgH3U3ngWhb.json +0 -12393
  96. package/tests/engine/engine-tests/engine-test-data/readme.md +0 -30
@@ -0,0 +1,150 @@
1
+ import fetch, { Headers } from 'node-fetch';
2
+ import { environmentJSON, environmentModel, flagsJSON, flagsmith, identitiesJSON, TestCache } from './utils';
3
+
4
+ jest.mock('node-fetch');
5
+ jest.mock('../../sdk/polling_manager');
6
+
7
+ const { Response } = jest.requireActual('node-fetch');
8
+
9
+ beforeEach(() => {
10
+ // @ts-ignore
11
+ jest.clearAllMocks();
12
+ });
13
+
14
+ test('test_wrong_cache_interface_throws_an_error', async () => {
15
+ const cache = {
16
+ set: () => { },
17
+ get: () => { },
18
+ };
19
+
20
+ expect(() => { const flg = flagsmith({ cache }); }).toThrow();
21
+ });
22
+
23
+ test('test_empty_cache_not_read_but_populated', async () => {
24
+ // @ts-ignore
25
+ fetch.mockReturnValue(Promise.resolve(new Response(flagsJSON())));
26
+
27
+ const cache = new TestCache();
28
+ const set = jest.spyOn(cache, 'set');
29
+
30
+ const flg = flagsmith({ cache });
31
+ const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
32
+
33
+ expect(set).toBeCalled();
34
+ expect(await cache.has('flags')).toBe(true);
35
+
36
+ expect(fetch).toBeCalledTimes(1);
37
+ expect(allFlags[0].enabled).toBe(true);
38
+ expect(allFlags[0].value).toBe('some-value');
39
+ expect(allFlags[0].featureName).toBe('some_feature');
40
+ });
41
+
42
+ test('test_api_not_called_when_cache_present', async () => {
43
+ // @ts-ignore
44
+ fetch.mockReturnValue(Promise.resolve(new Response(flagsJSON())));
45
+
46
+ const cache = new TestCache();
47
+ const set = jest.spyOn(cache, 'set');
48
+
49
+ const flg = flagsmith({ cache });
50
+ await (await flg.getEnvironmentFlags()).allFlags();
51
+ const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
52
+
53
+ expect(set).toBeCalled();
54
+ expect(await cache.has('flags')).toBe(true);
55
+
56
+ expect(fetch).toBeCalledTimes(1);
57
+ expect(allFlags[0].enabled).toBe(true);
58
+ expect(allFlags[0].value).toBe('some-value');
59
+ expect(allFlags[0].featureName).toBe('some_feature');
60
+ });
61
+
62
+ test('test_api_called_twice_when_no_cache', async () => {
63
+ // @ts-ignore
64
+ fetch.mockReturnValue(Promise.resolve(new Response(flagsJSON())));
65
+
66
+ const flg = flagsmith();
67
+ await (await flg.getEnvironmentFlags()).allFlags();
68
+ // @ts-ignore
69
+ fetch.mockReturnValue(Promise.resolve(new Response(flagsJSON())));
70
+ const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
71
+
72
+ expect(fetch).toBeCalledTimes(2);
73
+ expect(allFlags[0].enabled).toBe(true);
74
+ expect(allFlags[0].value).toBe('some-value');
75
+ expect(allFlags[0].featureName).toBe('some_feature');
76
+ });
77
+
78
+ test('test_get_environment_flags_uses_local_environment_when_available', async () => {
79
+ // @ts-ignore
80
+ fetch.mockReturnValue(Promise.resolve(new Response(flagsJSON())));
81
+
82
+ const cache = new TestCache();
83
+ const set = jest.spyOn(cache, 'set');
84
+
85
+ const flg = flagsmith({ cache });
86
+ const model = environmentModel(JSON.parse(environmentJSON()));
87
+ flg.environment = model;
88
+
89
+ const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
90
+
91
+ expect(set).toBeCalled();
92
+ expect(fetch).toBeCalledTimes(0);
93
+ expect(allFlags[0].enabled).toBe(model.featureStates[0].enabled);
94
+ expect(allFlags[0].value).toBe(model.featureStates[0].getValue());
95
+ expect(allFlags[0].featureName).toBe(model.featureStates[0].feature.name);
96
+ });
97
+
98
+ test('test_cache_used_for_identity_flags', async () => {
99
+ // @ts-ignore
100
+ fetch.mockReturnValue(Promise.resolve(new Response(identitiesJSON())));
101
+
102
+ const cache = new TestCache();
103
+ const set = jest.spyOn(cache, 'set');
104
+
105
+ const identifier = 'identifier';
106
+ const traits = { some_trait: 'some_value' };
107
+ const flg = flagsmith({ cache });
108
+
109
+ (await flg.getIdentityFlags(identifier, traits)).allFlags();
110
+ const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
111
+
112
+ expect(set).toBeCalled();
113
+ expect(await cache.has('flags-identifier')).toBe(true);
114
+
115
+ expect(fetch).toBeCalledTimes(1);
116
+
117
+ expect(identityFlags[0].enabled).toBe(true);
118
+ expect(identityFlags[0].value).toBe('some-value');
119
+ expect(identityFlags[0].featureName).toBe('some_feature');
120
+ });
121
+
122
+ test('test_cache_used_for_identity_flags_local_evaluation', async () => {
123
+ // @ts-ignore
124
+ fetch.mockReturnValue(Promise.resolve(new Response(environmentJSON())));
125
+
126
+ const cache = new TestCache();
127
+ const set = jest.spyOn(cache, 'set');
128
+
129
+ const identifier = 'identifier';
130
+ const traits = { some_trait: 'some_value' };
131
+ const flg = flagsmith({
132
+ cache,
133
+ environmentKey: 'ser.key',
134
+ enableLocalEvaluation: true,
135
+ });
136
+
137
+ (await flg.getIdentityFlags(identifier, traits)).allFlags();
138
+ const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
139
+
140
+ expect(set).toBeCalled();
141
+ expect(await cache.has('flags-identifier')).toBe(true);
142
+
143
+ expect(fetch).toBeCalledTimes(1);
144
+
145
+ expect(identityFlags[0].enabled).toBe(true);
146
+ expect(identityFlags[0].value).toBe('some-value');
147
+ expect(identityFlags[0].featureName).toBe('some_feature');
148
+ });
149
+
150
+ test('test_cache_used_for_all_flags', async () => { });
@@ -0,0 +1,197 @@
1
+ import Flagsmith from '../../sdk';
2
+ import fetch from 'node-fetch';
3
+ import { environmentJSON, environmentModel, flagsJSON, flagsmith, identitiesJSON } from './utils';
4
+ import { DefaultFlag } from '../../sdk/models';
5
+
6
+ jest.mock('node-fetch');
7
+ jest.mock('../../sdk/polling_manager');
8
+ const { Response } = jest.requireActual('node-fetch');
9
+
10
+ beforeEach(() => {
11
+ // @ts-ignore
12
+ jest.clearAllMocks();
13
+ });
14
+
15
+ test('test_get_environment_flags_calls_api_when_no_local_environment', async () => {
16
+ // @ts-ignore
17
+ fetch.mockReturnValue(Promise.resolve(new Response(flagsJSON())));
18
+
19
+ const flg = flagsmith();
20
+ const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
21
+
22
+ expect(fetch).toBeCalledTimes(1);
23
+ expect(allFlags[0].enabled).toBe(true);
24
+ expect(allFlags[0].value).toBe('some-value');
25
+ expect(allFlags[0].featureName).toBe('some_feature');
26
+ });
27
+
28
+ test('test_get_environment_flags_uses_local_environment_when_available', async () => {
29
+ // @ts-ignore
30
+ fetch.mockReturnValue(Promise.resolve(new Response(flagsJSON())));
31
+
32
+ const flg = flagsmith();
33
+ const model = environmentModel(JSON.parse(environmentJSON()));
34
+ flg.environment = model;
35
+
36
+ const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
37
+ expect(fetch).toBeCalledTimes(0);
38
+ expect(allFlags[0].enabled).toBe(model.featureStates[0].enabled);
39
+ expect(allFlags[0].value).toBe(model.featureStates[0].getValue());
40
+ expect(allFlags[0].featureName).toBe(model.featureStates[0].feature.name);
41
+ });
42
+
43
+ test('test_default_flag_is_used_when_no_environment_flags_returned', async () => {
44
+ // @ts-ignore
45
+ fetch.mockReturnValue(Promise.resolve(new Response(JSON.stringify([]))));
46
+
47
+ const defaultFlag = new DefaultFlag('some-default-value', true);
48
+
49
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
50
+
51
+ const flg = new Flagsmith({
52
+ environmentKey: 'key',
53
+ defaultFlagHandler: defaultFlagHandler,
54
+ customHeaders: {
55
+ 'X-Test-Header': '1',
56
+ }
57
+ });
58
+
59
+ const flags = await flg.getEnvironmentFlags();
60
+ const flag = flags.getFlag('some_feature');
61
+ expect(flag.isDefault).toBe(true);
62
+ expect(flag.enabled).toBe(defaultFlag.enabled);
63
+ expect(flag.value).toBe(defaultFlag.value);
64
+ });
65
+
66
+ test('test_analytics_processor_tracks_flags', async () => {
67
+ // @ts-ignore
68
+ fetch.mockReturnValue(Promise.resolve(new Response(flagsJSON())));
69
+
70
+ const defaultFlag = new DefaultFlag('some-default-value', true);
71
+
72
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
73
+
74
+ const flg = new Flagsmith({
75
+ environmentKey: 'key',
76
+ defaultFlagHandler: defaultFlagHandler,
77
+ enableAnalytics: true,
78
+ });
79
+
80
+ const flags = await flg.getEnvironmentFlags();
81
+ const flag = flags.getFlag('some_feature');
82
+
83
+ expect(flag.isDefault).toBe(false);
84
+ expect(flag.enabled).toBe(true);
85
+ expect(flag.value).toBe('some-value');
86
+ });
87
+
88
+ test('test_getFeatureValue', async () => {
89
+ // @ts-ignore
90
+ fetch.mockReturnValue(Promise.resolve(new Response(flagsJSON())));
91
+
92
+ const defaultFlag = new DefaultFlag('some-default-value', true);
93
+
94
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
95
+
96
+ const flg = new Flagsmith({
97
+ environmentKey: 'key',
98
+ defaultFlagHandler: defaultFlagHandler,
99
+ enableAnalytics: true,
100
+ });
101
+
102
+ const flags = await flg.getEnvironmentFlags();
103
+ const featureValue = flags.getFeatureValue('some_feature');
104
+
105
+ expect(featureValue).toBe('some-value');
106
+ });
107
+
108
+ test('test_throws_when_no_default_flag_handler_after_multiple_API_errors', async () => {
109
+ fetch
110
+ // @ts-ignore
111
+ .mockRejectedValue(new Error('Error during fetching the API response'));
112
+
113
+ const flg = new Flagsmith({
114
+ environmentKey: 'key',
115
+ });
116
+
117
+ await expect(async () => {
118
+ const flags = await flg.getEnvironmentFlags();
119
+ const flag = flags.getFlag('some_feature');
120
+ }).rejects.toThrow('Error during fetching the API response');
121
+ });
122
+
123
+ test('test_non_200_response_raises_flagsmith_api_error', async () => {
124
+ const errorResponse403 = new Response('403 Forbidden', {
125
+ status: 403
126
+ });
127
+ // @ts-ignore
128
+ fetch.mockReturnValue(Promise.resolve(errorResponse403));
129
+
130
+ const flg = new Flagsmith({
131
+ environmentKey: 'some'
132
+ });
133
+
134
+ await expect(flg.getEnvironmentFlags()).rejects.toThrow();
135
+ });
136
+ test('test_default_flag_is_not_used_when_environment_flags_returned', async () => {
137
+ // @ts-ignore
138
+ fetch.mockReturnValue(Promise.resolve(new Response(flagsJSON())));
139
+
140
+ const defaultFlag = new DefaultFlag('some-default-value', true);
141
+
142
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
143
+
144
+ const flg = new Flagsmith({
145
+ environmentKey: 'key',
146
+ defaultFlagHandler: defaultFlagHandler
147
+ });
148
+
149
+ const flags = await flg.getEnvironmentFlags();
150
+ const flag = flags.getFlag('some_feature');
151
+
152
+ expect(flag.isDefault).toBe(false);
153
+ expect(flag.value).not.toBe(defaultFlag.value);
154
+ expect(flag.value).toBe('some-value');
155
+ });
156
+
157
+ test('test_default_flag_is_used_when_bad_api_response_happens', async () => {
158
+ // @ts-ignore
159
+ fetch.mockReturnValue(Promise.resolve(new Response('bad-data')));
160
+
161
+ const defaultFlag = new DefaultFlag('some-default-value', true);
162
+
163
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
164
+
165
+ const flg = new Flagsmith({
166
+ environmentKey: 'key',
167
+ defaultFlagHandler: defaultFlagHandler
168
+ });
169
+
170
+ const flags = await flg.getEnvironmentFlags();
171
+ const flag = flags.getFlag('some_feature');
172
+
173
+ expect(flag.isDefault).toBe(true);
174
+ expect(flag.value).toBe(defaultFlag.value);
175
+ });
176
+
177
+ test('test_local_evaluation', async () => {
178
+ // @ts-ignore
179
+ fetch.mockReturnValue(Promise.resolve(new Response(environmentJSON())));
180
+
181
+ const defaultFlag = new DefaultFlag('some-default-value', true);
182
+
183
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
184
+
185
+ const flg = new Flagsmith({
186
+ environmentKey: 'ser.key',
187
+ enableLocalEvaluation: true,
188
+ defaultFlagHandler: defaultFlagHandler
189
+ });
190
+
191
+ const flags = await flg.getEnvironmentFlags();
192
+ const flag = flags.getFlag('some_feature');
193
+
194
+ expect(flag.isDefault).toBe(false);
195
+ expect(flag.value).not.toBe(defaultFlag.value);
196
+ expect(flag.value).toBe('some-value');
197
+ });
@@ -0,0 +1,140 @@
1
+ import Flagsmith from '../../sdk';
2
+ import fetch from 'node-fetch';
3
+ import { environmentJSON, flagsmith, identitiesJSON } from './utils';
4
+ import { DefaultFlag } from '../../sdk/models';
5
+
6
+ jest.mock('node-fetch');
7
+ jest.mock('../../sdk/polling_manager');
8
+ const { Response } = jest.requireActual('node-fetch');
9
+
10
+ beforeEach(() => {
11
+ // @ts-ignore
12
+ jest.clearAllMocks();
13
+ });
14
+
15
+
16
+ test('test_get_identity_flags_calls_api_when_no_local_environment_no_traits', async () => {
17
+ // @ts-ignore
18
+ fetch.mockReturnValue(Promise.resolve(new Response(identitiesJSON())));
19
+ const identifier = 'identifier';
20
+
21
+ const flg = flagsmith();
22
+
23
+ const identityFlags = (await flg.getIdentityFlags(identifier)).allFlags();
24
+
25
+ expect(identityFlags[0].enabled).toBe(true);
26
+ expect(identityFlags[0].value).toBe('some-value');
27
+ expect(identityFlags[0].featureName).toBe('some_feature');
28
+ });
29
+
30
+ test('test_get_identity_flags_calls_api_when_local_environment_no_traits', async () => {
31
+ // @ts-ignore
32
+ fetch.mockReturnValue(Promise.resolve(new Response(environmentJSON())));
33
+ const identifier = 'identifier';
34
+
35
+ const flg = flagsmith({
36
+ environmentKey: 'ser.key',
37
+ enableLocalEvaluation: true,
38
+
39
+ });
40
+
41
+
42
+ const identityFlags = (await flg.getIdentityFlags(identifier)).allFlags();
43
+
44
+ expect(identityFlags[0].enabled).toBe(true);
45
+ expect(identityFlags[0].value).toBe('some-value');
46
+ expect(identityFlags[0].featureName).toBe('some_feature');
47
+ });
48
+
49
+ test('test_get_identity_flags_calls_api_when_no_local_environment_with_traits', async () => {
50
+ // @ts-ignore
51
+ fetch.mockReturnValue(Promise.resolve(new Response(identitiesJSON())));
52
+ const identifier = 'identifier';
53
+ const traits = { some_trait: 'some_value' };
54
+ const flg = flagsmith();
55
+
56
+ const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
57
+
58
+ expect(identityFlags[0].enabled).toBe(true);
59
+ expect(identityFlags[0].value).toBe('some-value');
60
+ expect(identityFlags[0].featureName).toBe('some_feature');
61
+ });
62
+
63
+ test('test_default_flag_is_not_used_when_identity_flags_returned', async () => {
64
+ // @ts-ignore
65
+ fetch.mockReturnValue(Promise.resolve(new Response(identitiesJSON())));
66
+
67
+ const defaultFlag = new DefaultFlag('some-default-value', true);
68
+
69
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
70
+
71
+ const flg = new Flagsmith({
72
+ environmentKey: 'key',
73
+ defaultFlagHandler: defaultFlagHandler
74
+ });
75
+
76
+ const flags = await flg.getIdentityFlags('identifier');
77
+ const flag = flags.getFlag('some_feature');
78
+
79
+ expect(flag.isDefault).toBe(false);
80
+ expect(flag.value).not.toBe(defaultFlag.value);
81
+ expect(flag.value).toBe('some-value');
82
+ });
83
+
84
+ test('test_default_flag_is_used_when_no_identity_flags_returned', async () => {
85
+ // @ts-ignore
86
+ fetch.mockReturnValue(Promise.resolve(new Response(JSON.stringify({ flags: [], traits: [] }))));
87
+
88
+ const defaultFlag = new DefaultFlag('some-default-value', true);
89
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
90
+
91
+ const flg = new Flagsmith({
92
+ environmentKey: 'key',
93
+ defaultFlagHandler: defaultFlagHandler
94
+ });
95
+
96
+ const flags = await flg.getIdentityFlags('identifier');
97
+ const flag = flags.getFlag('some_feature');
98
+
99
+ expect(flag.isDefault).toBe(true);
100
+ expect(flag.value).toBe(defaultFlag.value);
101
+ expect(flag.enabled).toBe(defaultFlag.enabled);
102
+ });
103
+
104
+ test('test_default_flag_is_used_when_no_identity_flags_returned_due_to_error', async () => {
105
+ // @ts-ignore
106
+ fetch.mockReturnValue(Promise.resolve(new Response('bad data')));
107
+
108
+ const defaultFlag = new DefaultFlag('some-default-value', true);
109
+ const defaultFlagHandler = (featureName: string) => defaultFlag;
110
+
111
+ const flg = new Flagsmith({
112
+ environmentKey: 'key',
113
+ defaultFlagHandler: defaultFlagHandler
114
+ });
115
+
116
+ const flags = await flg.getIdentityFlags('identifier');
117
+ const flag = flags.getFlag('some_feature');
118
+
119
+ expect(flag.isDefault).toBe(true);
120
+ expect(flag.value).toBe(defaultFlag.value);
121
+ expect(flag.enabled).toBe(defaultFlag.enabled);
122
+ });
123
+
124
+ test('test_default_flag_is_used_when_no_identity_flags_returned_and_no_custom_default_flag_handler', async () => {
125
+ // @ts-ignore
126
+ fetch.mockReturnValue(Promise.resolve(new Response(JSON.stringify({ flags: [], traits: [] }))));
127
+
128
+
129
+ const flg = new Flagsmith({
130
+ environmentKey: 'key',
131
+ });
132
+
133
+ const flags = await flg.getIdentityFlags('identifier');
134
+ const flag = flags.getFlag('some_feature');
135
+
136
+ expect(flag.isDefault).toBe(true);
137
+ expect(flag.value).toBe(undefined);
138
+ expect(flag.enabled).toBe(false);
139
+ });
140
+