@@ -30,12 +30,75 @@ class MockProvider implements Provider {
3030}
3131
3232describe ( 'Evaluation Context' , ( ) => {
33+ afterEach ( async ( ) => {
34+ await OpenFeature . clearContexts ( ) ;
35+ } ) ;
36+
3337 describe ( 'Requirement 3.2.2' , ( ) => {
34- it ( 'the API MUST have a method for setting the global evaluation context' , ( ) => {
38+ it ( 'the API MUST have a method for setting the global evaluation context' , async ( ) => {
3539 const context : EvaluationContext = { property1 : false } ;
36- OpenFeature . setContext ( context ) ;
40+ await OpenFeature . setContext ( context ) ;
3741 expect ( OpenFeature . getContext ( ) ) . toEqual ( context ) ;
3842 } ) ;
43+
44+ it ( 'the API MUST have a method for setting evaluation context for a named client' , async ( ) => {
45+ const context : EvaluationContext = { property1 : false } ;
46+ const clientName = 'valid' ;
47+ await OpenFeature . setContext ( clientName , context ) ;
48+ expect ( OpenFeature . getContext ( clientName ) ) . toEqual ( context ) ;
49+ } ) ;
50+
51+ it ( 'the API MUST return the default context if not match is found' , async ( ) => {
52+ const defaultContext : EvaluationContext = { name : 'test' } ;
53+ const nameContext : EvaluationContext = { property1 : false } ;
54+ await OpenFeature . setContext ( defaultContext ) ;
55+ await OpenFeature . setContext ( 'test' , nameContext ) ;
56+ expect ( OpenFeature . getContext ( 'invalid' ) ) . toEqual ( defaultContext ) ;
57+ } ) ;
58+
59+ describe ( 'Context Management' , ( ) => {
60+ it ( 'should reset global context' , async ( ) => {
61+ const globalContext : EvaluationContext = { scope : 'global' } ;
62+ await OpenFeature . setContext ( globalContext ) ;
63+ expect ( OpenFeature . getContext ( ) ) . toEqual ( globalContext ) ;
64+ await OpenFeature . clearContext ( ) ;
65+ expect ( OpenFeature . getContext ( ) ) . toEqual ( { } ) ;
66+ } ) ;
67+
68+ it ( 'should remove context from a name provider' , async ( ) => {
69+ const globalContext : EvaluationContext = { scope : 'global' } ;
70+ const testContext : EvaluationContext = { scope : 'test' } ;
71+ const clientName = 'test' ;
72+ await OpenFeature . setContext ( globalContext ) ;
73+ await OpenFeature . setContext ( clientName , testContext ) ;
74+ expect ( OpenFeature . getContext ( clientName ) ) . toEqual ( testContext ) ;
75+ await OpenFeature . clearContext ( clientName ) ;
76+ expect ( OpenFeature . getContext ( clientName ) ) . toEqual ( globalContext ) ;
77+ } ) ;
78+
79+ it ( 'should only call a providers onContextChange once when clearing context' , async ( ) => {
80+ const globalContext : EvaluationContext = { scope : 'global' } ;
81+ const testContext : EvaluationContext = { scope : 'test' } ;
82+ const clientName = 'test' ;
83+ await OpenFeature . setContext ( globalContext ) ;
84+ await OpenFeature . setContext ( clientName , testContext ) ;
85+
86+ const defaultProvider = new MockProvider ( ) ;
87+ const provider1 = new MockProvider ( ) ;
88+
89+ OpenFeature . setProvider ( defaultProvider ) ;
90+ OpenFeature . setProvider ( clientName , provider1 ) ;
91+
92+ // Spy on context changed handlers of all providers
93+ const contextChangedSpies = [ defaultProvider , provider1 ] . map ( ( provider ) =>
94+ jest . spyOn ( provider , 'onContextChange' ) ,
95+ ) ;
96+
97+ await OpenFeature . clearContexts ( ) ;
98+
99+ contextChangedSpies . forEach ( ( spy ) => expect ( spy ) . toHaveBeenCalledTimes ( 1 ) ) ;
100+ } ) ;
101+ } ) ;
39102 } ) ;
40103
41104 describe ( 'Requirement 3.2.4' , ( ) => {
@@ -55,15 +118,50 @@ describe('Evaluation Context', () => {
55118 OpenFeature . setProvider ( 'client2' , provider2 ) ;
56119
57120 // Spy on context changed handlers of all providers
58- const contextChangedSpys = [ defaultProvider , provider1 , provider2 ] . map ( ( provider ) =>
59- jest . spyOn ( provider , 'onContextChange' )
121+ const contextChangedSpies = [ defaultProvider , provider1 , provider2 ] . map ( ( provider ) =>
122+ jest . spyOn ( provider , 'onContextChange' ) ,
60123 ) ;
61124
62125 // Change context
63126 const newContext : EvaluationContext = { property1 : true , property2 : 'prop2' } ;
64127 await OpenFeature . setContext ( newContext ) ;
65128
66- contextChangedSpys . forEach ( ( spy ) => expect ( spy ) . toHaveBeenCalledWith ( context , newContext ) ) ;
129+ contextChangedSpies . forEach ( ( spy ) => expect ( spy ) . toHaveBeenCalledWith ( context , newContext ) ) ;
130+ } ) ;
131+
132+ it ( 'on only the providers using the default context' , async ( ) => {
133+ // Set initial context
134+ const context : EvaluationContext = { property1 : false } ;
135+ await OpenFeature . setContext ( context ) ;
136+
137+ // Set some providers
138+ const defaultProvider = new MockProvider ( ) ;
139+ const provider1 = new MockProvider ( ) ;
140+ const provider2 = new MockProvider ( ) ;
141+
142+ const client1 = 'client1' ;
143+ const client2 = 'client2' ;
144+
145+ OpenFeature . setProvider ( defaultProvider ) ;
146+ OpenFeature . setProvider ( client1 , provider1 ) ;
147+ OpenFeature . setProvider ( client2 , provider2 ) ;
148+
149+ // Set context for client1
150+ await OpenFeature . setContext ( client1 , { property1 : 'test' } ) ;
151+
152+ // Spy on context changed handlers of all providers
153+ const contextShouldChangeSpies = [ defaultProvider , provider2 ] . map ( ( provider ) =>
154+ jest . spyOn ( provider , 'onContextChange' ) ,
155+ ) ;
156+
157+ const contextShouldntChangeSpies = jest . spyOn ( provider1 , 'onContextChange' ) ;
158+
159+ // Change context
160+ const newContext : EvaluationContext = { property1 : true , property2 : 'prop2' } ;
161+ await OpenFeature . setContext ( newContext ) ;
162+
163+ contextShouldChangeSpies . forEach ( ( spy ) => expect ( spy ) . toHaveBeenCalledWith ( context , newContext ) ) ;
164+ expect ( contextShouldntChangeSpies ) . not . toHaveBeenCalled ( ) ;
67165 } ) ;
68166
69167 it ( 'on all registered providers even if one fails' , async ( ) => {
@@ -81,18 +179,18 @@ describe('Evaluation Context', () => {
81179 OpenFeature . setProvider ( 'client2' , provider2 ) ;
82180
83181 // Spy on context changed handlers of all providers
84- const contextChangedSpys = [ defaultProvider , provider1 , provider2 ] . map ( ( provider ) =>
85- jest . spyOn ( provider , 'onContextChange' )
182+ const contextChangedSpies = [ defaultProvider , provider1 , provider2 ] . map ( ( provider ) =>
183+ jest . spyOn ( provider , 'onContextChange' ) ,
86184 ) ;
87185
88186 // Let first handler fail
89- contextChangedSpys [ 0 ] . mockImplementation ( ( ) => Promise . reject ( new Error ( 'Error' ) ) ) ;
187+ contextChangedSpies [ 0 ] . mockImplementation ( ( ) => Promise . reject ( new Error ( 'Error' ) ) ) ;
90188
91189 // Change context
92190 const newContext : EvaluationContext = { property1 : true , property2 : 'prop2' } ;
93191 await OpenFeature . setContext ( newContext ) ;
94192
95- contextChangedSpys . forEach ( ( spy ) => expect ( spy ) . toHaveBeenCalledWith ( context , newContext ) ) ;
193+ contextChangedSpies . forEach ( ( spy ) => expect ( spy ) . toHaveBeenCalledWith ( context , newContext ) ) ;
96194 } ) ;
97195 } ) ;
98196 } ) ;
0 commit comments