@@ -18,17 +18,33 @@ import {GoFeatureFlagProxyResponse} from './model';
18
18
19
19
describe ( 'GoFeatureFlagProvider' , ( ) => {
20
20
const endpoint = 'http://go-feature-flag-relay-proxy.local:1031/' ;
21
+ const dataCollectorEndpoint = `${ endpoint } v1/data/collector` ;
21
22
const axiosMock = new MockAdapter ( axios ) ;
23
+ const validBoolResponse : GoFeatureFlagProxyResponse < boolean > = {
24
+ value : true ,
25
+ variationType : 'trueVariation' ,
26
+ reason : StandardResolutionReasons . TARGETING_MATCH ,
27
+ failed : false ,
28
+ trackEvents : true ,
29
+ version : '1.0.0' ,
30
+ metadata : {
31
+ description : 'a description of the flag' ,
32
+ issue_number : 1 ,
33
+ } ,
34
+ cacheable : true ,
35
+ } ;
22
36
let goff : GoFeatureFlagProvider ;
23
37
24
38
afterEach ( async ( ) => {
25
- axiosMock . reset ( ) ;
26
- axiosMock . resetHistory ( ) ;
27
- axiosMock . resetHandlers ( )
28
39
await OpenFeature . close ( ) ;
40
+ await axiosMock . reset ( ) ;
41
+ await axiosMock . resetHistory ( ) ;
29
42
} ) ;
30
43
31
- beforeEach ( ( ) => {
44
+ beforeEach ( async ( ) => {
45
+ await OpenFeature . close ( ) ;
46
+ await axiosMock . reset ( ) ;
47
+ await axiosMock . resetHistory ( ) ;
32
48
goff = new GoFeatureFlagProvider ( { endpoint} ) ;
33
49
} ) ;
34
50
@@ -663,20 +679,6 @@ describe('GoFeatureFlagProvider', () => {
663
679
} ) ;
664
680
} ) ;
665
681
describe ( 'cache testing' , ( ) => {
666
- const validBoolResponse : GoFeatureFlagProxyResponse < boolean > = {
667
- value : true ,
668
- variationType : 'trueVariation' ,
669
- reason : StandardResolutionReasons . TARGETING_MATCH ,
670
- failed : false ,
671
- trackEvents : true ,
672
- version : '1.0.0' ,
673
- metadata : {
674
- description : 'a description of the flag' ,
675
- issue_number : 1 ,
676
- } ,
677
- cacheable : true ,
678
- } ;
679
-
680
682
it ( 'should use the cache if we evaluate 2 times the same flag' , async ( ) => {
681
683
const flagName = 'random-flag' ;
682
684
const targetingKey = 'user-key' ;
@@ -793,4 +795,115 @@ describe('GoFeatureFlagProvider', () => {
793
795
expect ( axiosMock . history [ 'post' ] . length ) . toBe ( 2 ) ;
794
796
} ) ;
795
797
} ) ;
798
+ describe ( 'data collector testing' , ( ) => {
799
+ it ( 'should call the data collector when closing Open Feature' , async ( ) => {
800
+ const flagName = 'random-flag' ;
801
+ const targetingKey = 'user-key' ;
802
+ const dns = `${ endpoint } v1/feature/${ flagName } /eval` ;
803
+
804
+ axiosMock . onPost ( dns ) . reply ( 200 , validBoolResponse ) ;
805
+ const goff = new GoFeatureFlagProvider ( {
806
+ endpoint,
807
+ flagCacheTTL : 3000 ,
808
+ flagCacheSize : 100 ,
809
+ dataFlushInterval : 1000 , // in milliseconds
810
+ } )
811
+ const providerName = expect . getState ( ) . currentTestName || 'test' ;
812
+ OpenFeature . setProvider ( providerName , goff ) ;
813
+ const cli = OpenFeature . getClient ( providerName ) ;
814
+ await cli . getBooleanDetails ( flagName , false , { targetingKey} ) ;
815
+ await cli . getBooleanDetails ( flagName , false , { targetingKey} ) ;
816
+ await OpenFeature . close ( )
817
+ const collectorCalls = axiosMock . history [ 'post' ] . filter ( i => i . url === dataCollectorEndpoint ) ;
818
+ expect ( collectorCalls . length ) . toBe ( 1 ) ;
819
+ const got = JSON . parse ( collectorCalls [ 0 ] . data ) ;
820
+ expect ( isNaN ( got . events [ 0 ] . creationDate ) ) . toBe ( false ) ;
821
+ const want = {
822
+ events : [ {
823
+ contextKind : 'user' ,
824
+ kind : 'feature' ,
825
+ creationDate : got . events [ 0 ] . creationDate ,
826
+ default : false ,
827
+ key : 'random-flag' ,
828
+ value : true ,
829
+ variation : 'trueVariation' ,
830
+ userKey : 'user-key'
831
+ } ] , meta : { provider : 'open-feature-js-sdk' }
832
+ } ;
833
+ expect ( want ) . toEqual ( got ) ;
834
+ } ) ;
835
+
836
+ it ( 'should call the data collector when waiting more than the dataFlushInterval' , async ( ) => {
837
+ const flagName = 'random-flag' ;
838
+ const targetingKey = 'user-key' ;
839
+ const dns = `${ endpoint } v1/feature/${ flagName } /eval` ;
840
+
841
+ axiosMock . onPost ( dns ) . reply ( 200 , validBoolResponse ) ;
842
+ const goff = new GoFeatureFlagProvider ( {
843
+ endpoint,
844
+ flagCacheTTL : 3000 ,
845
+ flagCacheSize : 100 ,
846
+ dataFlushInterval : 100 , // in milliseconds
847
+ } )
848
+ const providerName = expect . getState ( ) . currentTestName || 'test' ;
849
+ OpenFeature . setProvider ( providerName , goff ) ;
850
+ const cli = OpenFeature . getClient ( providerName ) ;
851
+ await cli . getBooleanDetails ( flagName , false , { targetingKey} ) ;
852
+ await cli . getBooleanDetails ( flagName , false , { targetingKey} ) ;
853
+ await new Promise ( ( r ) => setTimeout ( r , 130 ) ) ;
854
+ const collectorCalls = axiosMock . history [ 'post' ] . filter ( i => i . url === dataCollectorEndpoint ) ;
855
+ expect ( collectorCalls . length ) . toBe ( 1 ) ;
856
+ } ) ;
857
+
858
+ it ( 'should call the data collector multiple time while waiting dataFlushInterval time' , async ( ) => {
859
+ const flagName = 'random-flag' ;
860
+ const targetingKey = 'user-key' ;
861
+ const dns = `${ endpoint } v1/feature/${ flagName } /eval` ;
862
+
863
+ axiosMock . onPost ( dns ) . reply ( 200 , validBoolResponse ) ;
864
+ const goff = new GoFeatureFlagProvider ( {
865
+ endpoint,
866
+ flagCacheTTL : 3000 ,
867
+ flagCacheSize : 100 ,
868
+ dataFlushInterval : 100 , // in milliseconds
869
+ } )
870
+ const providerName = expect . getState ( ) . currentTestName || 'test' ;
871
+ OpenFeature . setProvider ( providerName , goff ) ;
872
+ const cli = OpenFeature . getClient ( providerName ) ;
873
+ await cli . getBooleanDetails ( flagName , false , { targetingKey} ) ;
874
+ await cli . getBooleanDetails ( flagName , false , { targetingKey} ) ;
875
+ await new Promise ( ( r ) => setTimeout ( r , 130 ) ) ;
876
+ const collectorCalls = axiosMock . history [ 'post' ] . filter ( i => i . url === dataCollectorEndpoint ) ;
877
+ expect ( collectorCalls . length ) . toBe ( 1 ) ;
878
+ axiosMock . resetHistory ( ) ;
879
+ await cli . getBooleanDetails ( flagName , false , { targetingKey} ) ;
880
+ await cli . getBooleanDetails ( flagName , false , { targetingKey} ) ;
881
+ await new Promise ( ( r ) => setTimeout ( r , 130 ) ) ;
882
+ const collectorCalls2 = axiosMock . history [ 'post' ] . filter ( i => i . url === dataCollectorEndpoint ) ;
883
+ expect ( collectorCalls2 . length ) . toBe ( 1 ) ;
884
+ } ) ;
885
+
886
+ it ( 'should not call the data collector before the dataFlushInterval' , async ( ) => {
887
+ const flagName = 'random-flag' ;
888
+ const targetingKey = 'user-key' ;
889
+ const dns = `${ endpoint } v1/feature/${ flagName } /eval` ;
890
+
891
+ axiosMock . onPost ( dns ) . reply ( 200 , validBoolResponse ) ;
892
+ const goff = new GoFeatureFlagProvider ( {
893
+ endpoint,
894
+ flagCacheTTL : 3000 ,
895
+ flagCacheSize : 100 ,
896
+ dataFlushInterval : 200 , // in milliseconds
897
+ } )
898
+ const providerName = expect . getState ( ) . currentTestName || 'test' ;
899
+ OpenFeature . setProvider ( providerName , goff ) ;
900
+ const cli = OpenFeature . getClient ( providerName ) ;
901
+ await cli . getBooleanDetails ( flagName , false , { targetingKey} ) ;
902
+ await cli . getBooleanDetails ( flagName , false , { targetingKey} ) ;
903
+ await new Promise ( ( r ) => setTimeout ( r , 130 ) ) ;
904
+ const collectorCalls = axiosMock . history [ 'post' ] . filter ( i => i . url === dataCollectorEndpoint ) ;
905
+
906
+ expect ( collectorCalls . length ) . toBe ( 0 ) ;
907
+ } ) ;
908
+ } ) ;
796
909
} ) ;
0 commit comments