flagsmith-nodejs 6.0.0 → 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.
- package/.github/workflows/publish.yml +17 -17
- package/.github/workflows/pull_request.yaml +33 -33
- package/.husky/pre-commit +0 -0
- package/.prettierignore +2 -1
- package/README.md +2 -1
- package/build/cjs/flagsmith-engine/features/util.js +3 -3
- package/build/cjs/flagsmith-engine/index.d.ts +1 -1
- package/build/cjs/flagsmith-engine/index.js +2 -1
- package/build/cjs/flagsmith-engine/segments/models.js +7 -7
- package/build/cjs/flagsmith-engine/utils/hashing/index.js +1 -1
- package/build/cjs/index.d.ts +4 -4
- package/build/cjs/index.js +3 -1
- package/build/cjs/sdk/analytics.d.ts +1 -1
- package/build/cjs/sdk/index.d.ts +5 -5
- package/build/cjs/sdk/index.js +7 -5
- package/build/cjs/sdk/models.d.ts +32 -5
- package/build/cjs/sdk/models.js +25 -0
- package/build/cjs/sdk/types.d.ts +14 -4
- package/build/cjs/sdk/utils.d.ts +4 -4
- package/build/cjs/sdk/utils.js +2 -2
- package/build/esm/flagsmith-engine/features/models.js +1 -1
- package/build/esm/flagsmith-engine/features/util.js +3 -3
- package/build/esm/flagsmith-engine/index.d.ts +1 -1
- package/build/esm/flagsmith-engine/index.js +1 -1
- package/build/esm/flagsmith-engine/segments/models.js +7 -7
- package/build/esm/flagsmith-engine/utils/hashing/index.js +2 -2
- package/build/esm/flagsmith-engine/utils/index.js +1 -1
- package/build/esm/index.d.ts +4 -4
- package/build/esm/index.js +3 -3
- package/build/esm/sdk/analytics.d.ts +1 -1
- package/build/esm/sdk/index.d.ts +5 -5
- package/build/esm/sdk/index.js +6 -5
- package/build/esm/sdk/models.d.ts +32 -5
- package/build/esm/sdk/models.js +25 -0
- package/build/esm/sdk/types.d.ts +14 -4
- package/build/esm/sdk/utils.d.ts +4 -4
- package/build/esm/sdk/utils.js +2 -2
- package/flagsmith-engine/environments/util.ts +2 -2
- package/flagsmith-engine/features/models.ts +1 -1
- package/flagsmith-engine/features/util.ts +14 -14
- package/flagsmith-engine/identities/models.ts +1 -1
- package/flagsmith-engine/index.ts +1 -1
- package/flagsmith-engine/segments/evaluators.ts +2 -3
- package/flagsmith-engine/segments/models.ts +25 -15
- package/flagsmith-engine/utils/hashing/index.ts +3 -3
- package/flagsmith-engine/utils/index.ts +4 -2
- package/index.ts +19 -22
- package/package.json +2 -2
- package/sdk/analytics.ts +7 -5
- package/sdk/index.ts +38 -21
- package/sdk/models.ts +34 -12
- package/sdk/offline_handlers.ts +1 -1
- package/sdk/types.ts +17 -8
- package/sdk/utils.ts +8 -8
- package/tests/engine/e2e/engine.test.ts +2 -4
- package/tests/engine/unit/engine.test.ts +1 -5
- package/tests/engine/unit/features/models.test.ts +2 -2
- package/tests/engine/unit/identities/identities_builders.test.ts +1 -1
- package/tests/engine/unit/segments/segment_evaluators.test.ts +52 -23
- package/tests/engine/unit/segments/segments_model.test.ts +35 -37
- package/tests/engine/unit/utils/utils.test.ts +28 -30
- package/tests/sdk/analytics.test.ts +25 -26
- package/tests/sdk/flagsmith-cache.test.ts +84 -76
- package/tests/sdk/flagsmith-environment-flags.test.ts +93 -93
- package/tests/sdk/flagsmith-identity-flags.test.ts +146 -149
- package/tests/sdk/flagsmith.test.ts +40 -42
- package/tests/sdk/offline-handlers.test.ts +32 -32
- package/tests/sdk/polling.test.ts +0 -1
- package/tests/sdk/utils.ts +26 -18
- package/vitest.config.ts +10 -15
|
@@ -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
|
-
|
|
9
|
-
|
|
8
|
+
const flg = flagsmith();
|
|
9
|
+
const allFlags = await (await flg.getEnvironmentFlags()).allFlags();
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
18
|
+
fetch.mockResolvedValue(new Response(JSON.stringify([])));
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
const defaultFlag = new DefaultFlag('some-default-value', true);
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
const defaultFlagHandler = (featureName: string) => defaultFlag;
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
40
|
+
const defaultFlag = new DefaultFlag('some-default-value', true);
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
const defaultFlagHandler = (featureName: string) => defaultFlag;
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
const flg = flagsmith({
|
|
45
|
+
environmentKey: 'key',
|
|
46
|
+
defaultFlagHandler: defaultFlagHandler,
|
|
47
|
+
enableAnalytics: true
|
|
48
|
+
});
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
const flags = await flg.getEnvironmentFlags();
|
|
51
|
+
const flag = flags.getFlag('some_feature');
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
59
|
+
const defaultFlag = new DefaultFlag('some-default-value', true);
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
const defaultFlagHandler = (featureName: string) => defaultFlag;
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
const flg = flagsmith({
|
|
64
|
+
environmentKey: 'key',
|
|
65
|
+
defaultFlagHandler: defaultFlagHandler,
|
|
66
|
+
enableAnalytics: true
|
|
67
|
+
});
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
const flags = await flg.getEnvironmentFlags();
|
|
70
|
+
const featureValue = flags.getFeatureValue('some_feature');
|
|
71
71
|
|
|
72
|
-
|
|
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
|
-
|
|
76
|
+
fetch.mockRejectedValue('Error during fetching the API response');
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
const flg = flagsmith({
|
|
79
|
+
environmentKey: 'key'
|
|
80
|
+
});
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
const errorResponse403 = new Response('403 Forbidden', {
|
|
90
|
+
status: 403
|
|
91
|
+
});
|
|
92
|
+
fetch.mockResolvedValue(errorResponse403);
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
const flg = new Flagsmith({
|
|
95
|
+
environmentKey: 'some'
|
|
96
|
+
});
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
await expect(flg.getEnvironmentFlags()).rejects.toThrow();
|
|
99
99
|
});
|
|
100
100
|
test('test_default_flag_is_not_used_when_environment_flags_returned', async () => {
|
|
101
|
-
|
|
101
|
+
const defaultFlag = new DefaultFlag('some-default-value', true);
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
const defaultFlagHandler = (featureName: string) => defaultFlag;
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
const flg = flagsmith({
|
|
106
|
+
environmentKey: 'key',
|
|
107
|
+
defaultFlagHandler: defaultFlagHandler
|
|
108
|
+
});
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
const flags = await flg.getEnvironmentFlags();
|
|
111
|
+
const flag = flags.getFlag('some_feature');
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
119
|
+
fetch.mockResolvedValue(new Response('bad-data'));
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
const defaultFlag = new DefaultFlag('some-default-value', true);
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
const defaultFlagHandler = (featureName: string) => defaultFlag;
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
const flg = new Flagsmith({
|
|
126
|
+
environmentKey: 'key',
|
|
127
|
+
defaultFlagHandler: defaultFlagHandler
|
|
128
|
+
});
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
const flags = await flg.getEnvironmentFlags();
|
|
131
|
+
const flag = flags.getFlag('some_feature');
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
138
|
+
const defaultFlag = new DefaultFlag('some-default-value', true);
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
const defaultFlagHandler = (featureName: string) => defaultFlag;
|
|
141
141
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
const flg = flagsmith({
|
|
143
|
+
environmentKey: 'ser.key',
|
|
144
|
+
enableLocalEvaluation: true,
|
|
145
|
+
defaultFlagHandler: defaultFlagHandler
|
|
146
|
+
});
|
|
147
147
|
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
const flags = await flg.getEnvironmentFlags();
|
|
149
|
+
const flag = flags.getFlag('some_feature');
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
expect(flag.isDefault).toBe(false);
|
|
152
|
+
expect(flag.value).not.toBe(defaultFlag.value);
|
|
153
|
+
expect(flag.value).toBe('some-value');
|
|
154
154
|
});
|
|
@@ -1,213 +1,210 @@
|
|
|
1
1
|
import Flagsmith from '../../sdk/index.js';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
fetch,
|
|
4
|
+
environmentJSON,
|
|
5
|
+
flagsmith,
|
|
6
|
+
identitiesJSON,
|
|
7
|
+
identityWithTransientTraitsJSON,
|
|
8
|
+
transientIdentityJSON,
|
|
9
|
+
badFetch
|
|
10
10
|
} from './utils.js';
|
|
11
11
|
import { DefaultFlag } from '../../sdk/models.js';
|
|
12
12
|
|
|
13
13
|
vi.mock('../../sdk/polling_manager');
|
|
14
14
|
|
|
15
15
|
test('test_get_identity_flags_calls_api_when_no_local_environment_no_traits', async () => {
|
|
16
|
-
|
|
16
|
+
const identifier = 'identifier';
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
const flg = flagsmith();
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
const identityFlags = (await flg.getIdentityFlags(identifier)).allFlags();
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
expect(identityFlags[0].enabled).toBe(true);
|
|
23
|
+
expect(identityFlags[0].value).toBe('some-value');
|
|
24
|
+
expect(identityFlags[0].featureName).toBe('some_feature');
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
test('test_get_identity_flags_uses_environment_when_local_environment_no_traits', async () => {
|
|
28
|
-
|
|
28
|
+
const identifier = 'identifier';
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
const flg = flagsmith({
|
|
31
|
+
environmentKey: 'ser.key',
|
|
32
|
+
enableLocalEvaluation: true
|
|
33
|
+
});
|
|
34
34
|
|
|
35
|
+
const identityFlags = (await flg.getIdentityFlags(identifier)).allFlags();
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
expect(identityFlags[0].value).toBe('some-value');
|
|
40
|
-
expect(identityFlags[0].featureName).toBe('some_feature');
|
|
37
|
+
expect(identityFlags[0].enabled).toBe(true);
|
|
38
|
+
expect(identityFlags[0].value).toBe('some-value');
|
|
39
|
+
expect(identityFlags[0].featureName).toBe('some_feature');
|
|
41
40
|
});
|
|
42
41
|
|
|
43
42
|
test('test_get_identity_flags_calls_api_when_no_local_environment_with_traits', async () => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
const identifier = 'identifier';
|
|
44
|
+
const traits = { some_trait: 'some_value' };
|
|
45
|
+
const flg = flagsmith();
|
|
47
46
|
|
|
48
|
-
|
|
47
|
+
const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
expect(identityFlags[0].enabled).toBe(true);
|
|
50
|
+
expect(identityFlags[0].value).toBe('some-value');
|
|
51
|
+
expect(identityFlags[0].featureName).toBe('some_feature');
|
|
53
52
|
});
|
|
54
53
|
|
|
55
54
|
test('test_default_flag_is_not_used_when_identity_flags_returned', async () => {
|
|
56
|
-
|
|
55
|
+
const defaultFlag = new DefaultFlag('some-default-value', true);
|
|
57
56
|
|
|
58
|
-
|
|
57
|
+
const defaultFlagHandler = (featureName: string) => defaultFlag;
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
const flg = flagsmith({
|
|
60
|
+
environmentKey: 'key',
|
|
61
|
+
defaultFlagHandler: defaultFlagHandler
|
|
62
|
+
});
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
const flags = await flg.getIdentityFlags('identifier');
|
|
65
|
+
const flag = flags.getFlag('some_feature');
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
expect(flag.isDefault).toBe(false);
|
|
68
|
+
expect(flag.value).not.toBe(defaultFlag.value);
|
|
69
|
+
expect(flag.value).toBe('some-value');
|
|
71
70
|
});
|
|
72
71
|
|
|
73
72
|
test('test_default_flag_is_used_when_no_identity_flags_returned', async () => {
|
|
74
|
-
|
|
73
|
+
fetch.mockResolvedValue(new Response(JSON.stringify({ flags: [], traits: [] })));
|
|
75
74
|
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
const defaultFlag = new DefaultFlag('some-default-value', true);
|
|
76
|
+
const defaultFlagHandler = (featureName: string) => defaultFlag;
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
const flg = new Flagsmith({
|
|
79
|
+
environmentKey: 'key',
|
|
80
|
+
defaultFlagHandler: defaultFlagHandler
|
|
81
|
+
});
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
const flags = await flg.getIdentityFlags('identifier');
|
|
84
|
+
const flag = flags.getFlag('some_feature');
|
|
86
85
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
expect(flag.isDefault).toBe(true);
|
|
87
|
+
expect(flag.value).toBe(defaultFlag.value);
|
|
88
|
+
expect(flag.enabled).toBe(defaultFlag.enabled);
|
|
90
89
|
});
|
|
91
90
|
|
|
92
91
|
test('test_default_flag_is_used_when_no_identity_flags_returned_due_to_error', async () => {
|
|
93
|
-
|
|
92
|
+
fetch.mockResolvedValue(new Response('bad data'));
|
|
94
93
|
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
const defaultFlag = new DefaultFlag('some-default-value', true);
|
|
95
|
+
const defaultFlagHandler = (featureName: string) => defaultFlag;
|
|
97
96
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
const flg = new Flagsmith({
|
|
98
|
+
environmentKey: 'key',
|
|
99
|
+
defaultFlagHandler: defaultFlagHandler
|
|
100
|
+
});
|
|
102
101
|
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
const flags = await flg.getIdentityFlags('identifier');
|
|
103
|
+
const flag = flags.getFlag('some_feature');
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
expect(flag.isDefault).toBe(true);
|
|
106
|
+
expect(flag.value).toBe(defaultFlag.value);
|
|
107
|
+
expect(flag.enabled).toBe(defaultFlag.enabled);
|
|
109
108
|
});
|
|
110
109
|
|
|
111
110
|
test('test_default_flag_is_used_when_no_identity_flags_returned_and_no_custom_default_flag_handler', async () => {
|
|
112
|
-
|
|
111
|
+
fetch.mockResolvedValue(new Response(JSON.stringify({ flags: [], traits: [] })));
|
|
113
112
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
const flg = flagsmith({
|
|
114
|
+
environmentKey: 'key'
|
|
115
|
+
});
|
|
117
116
|
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
const flags = await flg.getIdentityFlags('identifier');
|
|
118
|
+
const flag = flags.getFlag('some_feature');
|
|
120
119
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
120
|
+
expect(flag.isDefault).toBe(true);
|
|
121
|
+
expect(flag.value).toBe(undefined);
|
|
122
|
+
expect(flag.enabled).toBe(false);
|
|
124
123
|
});
|
|
125
124
|
|
|
126
125
|
test('test_get_identity_flags_multivariate_value_with_local_evaluation_enabled', async () => {
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
fetch.mockResolvedValue(new Response(environmentJSON));
|
|
127
|
+
const identifier = 'identifier';
|
|
129
128
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
const flg = flagsmith({
|
|
130
|
+
environmentKey: 'ser.key',
|
|
131
|
+
enableLocalEvaluation: true
|
|
132
|
+
});
|
|
134
133
|
|
|
135
|
-
|
|
134
|
+
const identityFlags = await flg.getIdentityFlags(identifier);
|
|
136
135
|
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
expect(identityFlags.getFeatureValue('mv_feature')).toBe('bar');
|
|
137
|
+
expect(identityFlags.isFeatureEnabled('mv_feature')).toBe(false);
|
|
139
138
|
});
|
|
140
139
|
|
|
141
|
-
|
|
142
140
|
test('test_transient_identity', async () => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
141
|
+
fetch.mockResolvedValue(new Response(transientIdentityJSON));
|
|
142
|
+
const identifier = 'transient_identifier';
|
|
143
|
+
const traits = { some_trait: 'some_value' };
|
|
144
|
+
const traitsInRequest = [{ trait_key: Object.keys(traits)[0], trait_value: traits.some_trait }];
|
|
145
|
+
const transient = true;
|
|
146
|
+
const flg = flagsmith();
|
|
147
|
+
const identityFlags = (await flg.getIdentityFlags(identifier, traits, transient)).allFlags();
|
|
148
|
+
|
|
149
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
150
|
+
`https://edge.api.flagsmith.com/api/v1/identities/`,
|
|
151
|
+
expect.objectContaining({
|
|
152
|
+
method: 'POST',
|
|
153
|
+
headers: { 'Content-Type': 'application/json', 'X-Environment-Key': 'sometestfakekey' },
|
|
154
|
+
body: JSON.stringify({ identifier, traits: traitsInRequest, transient })
|
|
155
|
+
})
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
expect(identityFlags[0].enabled).toBe(false);
|
|
159
|
+
expect(identityFlags[0].value).toBe('some-transient-identity-value');
|
|
160
|
+
expect(identityFlags[0].featureName).toBe('some_feature');
|
|
163
161
|
});
|
|
164
162
|
|
|
165
|
-
|
|
166
163
|
test('test_identity_with_transient_traits', async () => {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
164
|
+
fetch.mockResolvedValue(new Response(identityWithTransientTraitsJSON));
|
|
165
|
+
const identifier = 'transient_trait_identifier';
|
|
166
|
+
const traits = {
|
|
167
|
+
some_trait: 'some_value',
|
|
168
|
+
another_trait: { value: 'another_value', transient: true },
|
|
169
|
+
explicitly_non_transient_trait: { value: 'non_transient_value', transient: false }
|
|
170
|
+
};
|
|
171
|
+
const traitsInRequest = [
|
|
172
|
+
{
|
|
173
|
+
trait_key: Object.keys(traits)[0],
|
|
174
|
+
trait_value: traits.some_trait
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
trait_key: Object.keys(traits)[1],
|
|
178
|
+
trait_value: traits.another_trait.value,
|
|
179
|
+
transient: true
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
trait_key: Object.keys(traits)[2],
|
|
183
|
+
trait_value: traits.explicitly_non_transient_trait.value,
|
|
184
|
+
transient: false
|
|
185
|
+
}
|
|
186
|
+
];
|
|
187
|
+
const flg = flagsmith();
|
|
188
|
+
|
|
189
|
+
const identityFlags = (await flg.getIdentityFlags(identifier, traits)).allFlags();
|
|
190
|
+
expect(fetch).toHaveBeenCalledWith(
|
|
191
|
+
`https://edge.api.flagsmith.com/api/v1/identities/`,
|
|
192
|
+
expect.objectContaining({
|
|
193
|
+
method: 'POST',
|
|
194
|
+
headers: { 'Content-Type': 'application/json', 'X-Environment-Key': 'sometestfakekey' },
|
|
195
|
+
body: JSON.stringify({ identifier, traits: traitsInRequest })
|
|
196
|
+
})
|
|
197
|
+
);
|
|
198
|
+
expect(identityFlags[0].enabled).toBe(true);
|
|
199
|
+
expect(identityFlags[0].value).toBe('some-identity-with-transient-trait-value');
|
|
200
|
+
expect(identityFlags[0].featureName).toBe('some_feature');
|
|
204
201
|
});
|
|
205
202
|
|
|
206
203
|
test('getIdentityFlags fails if API call failed and no default flag handler was provided', async () => {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
})
|
|
204
|
+
const flg = flagsmith({
|
|
205
|
+
fetch: badFetch
|
|
206
|
+
});
|
|
207
|
+
await expect(flg.getIdentityFlags('user')).rejects.toThrow(
|
|
208
|
+
'getIdentityFlags failed and no default flag handler was provided'
|
|
209
|
+
);
|
|
210
|
+
});
|