1
1
/**
2
- * Copyright 2022, 2023 Optimizely
2
+ * Copyright 2022, 2023, 2024 Optimizely
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
18
18
19
19
import * as React from 'react' ;
20
20
import { act } from 'react-dom/test-utils' ;
21
- import { render , screen , waitFor } from '@testing-library/react' ;
21
+ import { render , renderHook , screen , waitFor } from '@testing-library/react' ;
22
22
import '@testing-library/jest-dom/extend-expect' ;
23
23
24
24
import { OptimizelyProvider } from './Provider' ;
25
25
import { OnReadyResult , ReactSDKClient , VariableValuesObject } from './client' ;
26
- import { useExperiment , useFeature , useDecision } from './hooks' ;
26
+ import { useExperiment , useFeature , useDecision , useTrackEvent , hooksLogger } from './hooks' ;
27
27
import { OptimizelyDecision } from './utils' ;
28
-
29
28
const defaultDecision : OptimizelyDecision = {
30
29
enabled : false ,
31
30
variables : { } ,
@@ -80,7 +79,7 @@ describe('hooks', () => {
80
79
let forcedVariationUpdateCallbacks : Array < ( ) => void > ;
81
80
let decideMock : jest . Mock < OptimizelyDecision > ;
82
81
let setForcedDecisionMock : jest . Mock < void > ;
83
-
82
+ let hooksLoggerErrorSpy : jest . SpyInstance ;
84
83
const REJECTION_REASON = 'A rejection reason you should never see in the test runner' ;
85
84
86
85
beforeEach ( ( ) => {
@@ -99,7 +98,6 @@ describe('hooks', () => {
99
98
) ;
100
99
} , timeout || mockDelay ) ;
101
100
} ) ;
102
-
103
101
activateMock = jest . fn ( ) ;
104
102
isFeatureEnabledMock = jest . fn ( ) ;
105
103
featureVariables = mockFeatureVariables ;
@@ -110,7 +108,7 @@ describe('hooks', () => {
110
108
forcedVariationUpdateCallbacks = [ ] ;
111
109
decideMock = jest . fn ( ) ;
112
110
setForcedDecisionMock = jest . fn ( ) ;
113
-
111
+ hooksLoggerErrorSpy = jest . spyOn ( hooksLogger , 'error' ) ;
114
112
optimizelyMock = ( {
115
113
activate : activateMock ,
116
114
onReady : jest . fn ( ) . mockImplementation ( config => getOnReadyPromise ( config || { } ) ) ,
@@ -141,6 +139,7 @@ describe('hooks', () => {
141
139
getForcedVariations : jest . fn ( ) . mockReturnValue ( { } ) ,
142
140
decide : decideMock ,
143
141
setForcedDecision : setForcedDecisionMock ,
142
+ track : jest . fn ( ) ,
144
143
} as unknown ) as ReactSDKClient ;
145
144
146
145
mockLog = jest . fn ( ) ;
@@ -168,6 +167,7 @@ describe('hooks', () => {
168
167
res => res . dataReadyPromise ,
169
168
err => null
170
169
) ;
170
+ hooksLoggerErrorSpy . mockReset ( ) ;
171
171
} ) ;
172
172
173
173
describe ( 'useExperiment' , ( ) => {
@@ -1048,4 +1048,53 @@ describe('hooks', () => {
1048
1048
await waitFor ( ( ) => expect ( screen . getByTestId ( 'result' ) ) . toHaveTextContent ( 'false|{}|true|false' ) ) ;
1049
1049
} ) ;
1050
1050
} ) ;
1051
+ describe ( 'useTrackEvent' , ( ) => {
1052
+ it ( 'returns track method and false states when optimizely is not provided' , ( ) => {
1053
+ const wrapper = ( { children } : { children : React . ReactNode } ) : React . ReactElement => {
1054
+ //@ts -ignore
1055
+ return < OptimizelyProvider > { children } </ OptimizelyProvider > ;
1056
+ } ;
1057
+ const { result } = renderHook ( ( ) => useTrackEvent ( ) , { wrapper } ) ;
1058
+ expect ( result . current [ 0 ] ) . toBeInstanceOf ( Function ) ;
1059
+ expect ( result . current [ 1 ] ) . toBe ( false ) ;
1060
+ expect ( result . current [ 2 ] ) . toBe ( false ) ;
1061
+ } ) ;
1062
+
1063
+ it ( 'returns track method along with clientReady and didTimeout state when optimizely instance is provided' , ( ) => {
1064
+ const wrapper = ( { children } : { children : React . ReactNode } ) : React . ReactElement => (
1065
+ < OptimizelyProvider optimizely = { optimizelyMock } isServerSide = { false } timeout = { 10000 } >
1066
+ { children }
1067
+ </ OptimizelyProvider >
1068
+ ) ;
1069
+
1070
+ const { result } = renderHook ( ( ) => useTrackEvent ( ) , { wrapper } ) ;
1071
+ expect ( result . current [ 0 ] ) . toBeInstanceOf ( Function ) ;
1072
+ expect ( typeof result . current [ 1 ] ) . toBe ( 'boolean' ) ;
1073
+ expect ( typeof result . current [ 2 ] ) . toBe ( 'boolean' ) ;
1074
+ } ) ;
1075
+
1076
+ it ( 'Log error when track method is called and optimizely instance is not provided' , ( ) => {
1077
+ const wrapper = ( { children } : { children : React . ReactNode } ) : React . ReactElement => {
1078
+ //@ts -ignore
1079
+ return < OptimizelyProvider > { children } </ OptimizelyProvider > ;
1080
+ } ;
1081
+ const { result } = renderHook ( ( ) => useTrackEvent ( ) , { wrapper } ) ;
1082
+ result . current [ 0 ] ( 'eventKey' ) ;
1083
+ expect ( hooksLogger . error ) . toHaveBeenCalledTimes ( 1 ) ;
1084
+ } ) ;
1085
+
1086
+ it ( 'Log error when track method is called and client is not ready' , ( ) => {
1087
+ optimizelyMock . isReady = jest . fn ( ) . mockReturnValue ( false ) ;
1088
+
1089
+ const wrapper = ( { children } : { children : React . ReactNode } ) : React . ReactElement => (
1090
+ < OptimizelyProvider optimizely = { optimizelyMock } isServerSide = { false } timeout = { 10000 } >
1091
+ { children }
1092
+ </ OptimizelyProvider >
1093
+ ) ;
1094
+
1095
+ const { result } = renderHook ( ( ) => useTrackEvent ( ) , { wrapper } ) ;
1096
+ result . current [ 0 ] ( 'eventKey' ) ;
1097
+ expect ( hooksLogger . error ) . toHaveBeenCalledTimes ( 1 ) ;
1098
+ } ) ;
1099
+ } ) ;
1051
1100
} ) ;
0 commit comments