1
1
/* @flow */
2
2
/* eslint-disable eslint-comments/disable-enable-pair */
3
- /* eslint-disable no-restricted-globals, promise/no-native, compat/compat */
4
- import { describe , expect , vi } from "vitest" ;
3
+ import { describe , expect , vi , afterEach } from "vitest" ;
4
+ import { getEnv } from "@paypal/sdk-client/src" ;
5
+ import { FPTI_KEY } from "@paypal/sdk-constants/src" ;
5
6
6
7
import { ThreeDomainSecureComponent } from "./component" ;
7
8
@@ -11,9 +12,18 @@ const defaultSdkConfig = {
11
12
vi . mock ( "./utils" , async ( ) => {
12
13
return {
13
14
...( await vi . importActual ( "./utils" ) ) ,
14
- getThreeDomainSecureComponent : vi . fn ( ) ,
15
+ getFastlaneThreeDS : vi . fn ( ( ) => ( {
16
+ render : vi . fn ( ) . mockResolvedValue ( { } ) ,
17
+ close : vi . fn ( ) . mockResolvedValue ( { } ) ,
18
+ } ) ) ,
15
19
} ;
16
20
} ) ;
21
+ const mockThreeDSIframe = vi . fn ( ( ) => ( {
22
+ render : vi . fn ( ) . mockResolvedValue ( { } ) ,
23
+ close : vi . fn ( ) . mockResolvedValue ( { } ) ,
24
+ } ) ) ;
25
+ vi . mock ( "@paypal/sdk-client/src" ) ;
26
+ vi . mocked ( getEnv ) . mockReturnValue ( "stage" ) ;
17
27
const defaultEligibilityResponse = {
18
28
status : "PAYER_ACTION_REQUIRED" ,
19
29
links : [ { href : "https://testurl.com" , rel : "payer-action" } ] ,
@@ -23,6 +33,20 @@ const defaultMerchantPayload = {
23
33
amount : "1.00" ,
24
34
currency : "USD" ,
25
35
nonce : "test-nonce" ,
36
+ transactionContext : { } ,
37
+ } ;
38
+
39
+ const mockRestClient = {
40
+ setAccessToken : vi . fn ( ) . mockResolvedValue ( { } ) ,
41
+ request : vi . fn ( ) . mockResolvedValue ( {
42
+ status : "PAYER_ACTION_REQUIRED" ,
43
+ links : [
44
+ {
45
+ href : "https://paypal.com/auth" ,
46
+ rel : "payer-action" ,
47
+ } ,
48
+ ] ,
49
+ } ) ,
26
50
} ;
27
51
28
52
const mockEligibilityRequest = ( body = defaultEligibilityResponse ) => {
@@ -31,7 +55,7 @@ const mockEligibilityRequest = (body = defaultEligibilityResponse) => {
31
55
32
56
const createThreeDomainSecureComponent = ( {
33
57
sdkConfig = defaultSdkConfig ,
34
- restClient = mockEligibilityRequest ( ) ,
58
+ restClient = mockRestClient ,
35
59
graphQLClient = vi . fn ( ) ,
36
60
logger = {
37
61
info : vi . fn ( ) . mockReturnThis ( ) ,
@@ -56,8 +80,9 @@ afterEach(() => {
56
80
vi . clearAllMocks ( ) ;
57
81
} ) ;
58
82
59
- describe . skip ( "three domain secure component - isEligible method" , ( ) => {
83
+ describe ( "three domain secure component - isEligible method" , ( ) => {
60
84
test ( "should return true if payer action required" , async ( ) => {
85
+ mockRestClient . request = mockEligibilityRequest ( ) ;
61
86
const threeDomainSecureClient = createThreeDomainSecureComponent ( ) ;
62
87
const eligibility = await threeDomainSecureClient . isEligible (
63
88
defaultMerchantPayload
@@ -66,42 +91,34 @@ describe.skip("three domain secure component - isEligible method", () => {
66
91
} ) ;
67
92
68
93
test ( "should return false if payer action is not returned" , async ( ) => {
69
- const threeDomainSecureClient = createThreeDomainSecureComponent ( {
70
- restClient : ( ) =>
71
- Promise . resolve ( { ...defaultEligibilityResponse , status : "SUCCESS" } ) ,
72
- } ) ;
94
+ const inEligibilityResponse = {
95
+ status : "SUCCESS" ,
96
+ links : [ { href : "https://testurl.com" , rel : "order" } ] ,
97
+ } ;
98
+ mockRestClient . request = mockEligibilityRequest ( inEligibilityResponse ) ;
99
+ const threeDomainSecureClient = createThreeDomainSecureComponent ( ) ;
73
100
const eligibility = await threeDomainSecureClient . isEligible (
74
101
defaultMerchantPayload
75
102
) ;
76
103
expect ( eligibility ) . toEqual ( false ) ;
77
104
} ) ;
78
105
79
106
test ( "should assign correct URL to authenticationURL" , async ( ) => {
80
- const threeDomainSecureClient = createThreeDomainSecureComponent ( {
81
- restClient : ( ) =>
82
- Promise . resolve ( {
83
- ...defaultEligibilityResponse ,
84
- links : [
85
- { href : "https://not-payer-action.com" , rel : "not-payer-action" } ,
86
- ...defaultEligibilityResponse . links ,
87
- ] ,
88
- } ) ,
89
- } ) ;
107
+ mockRestClient . request = mockEligibilityRequest ( defaultEligibilityResponse ) ;
108
+ const threeDomainSecureClient = createThreeDomainSecureComponent ( ) ;
90
109
await threeDomainSecureClient . isEligible ( defaultMerchantPayload ) ;
91
110
expect ( threeDomainSecureClient . authenticationURL ) . toEqual (
92
111
"https://testurl.com"
93
112
) ;
94
113
} ) ;
95
114
96
- test ( "create payload with correctly parameters" , async ( ) => {
97
- const mockedRequest = mockEligibilityRequest ( ) ;
98
- const threeDomainSecureClient = createThreeDomainSecureComponent ( {
99
- restClient : mockedRequest ,
100
- } ) ;
115
+ test ( "create payload with correct parameters" , async ( ) => {
116
+ mockRestClient . request = mockEligibilityRequest ( ) ;
117
+ const threeDomainSecureClient = createThreeDomainSecureComponent ( ) ;
101
118
102
119
await threeDomainSecureClient . isEligible ( defaultMerchantPayload ) ;
103
120
104
- expect ( mockedRequest ) . toHaveBeenCalledWith (
121
+ expect ( mockRestClient . request ) . toHaveBeenCalledWith (
105
122
expect . objectContaining ( {
106
123
data : expect . objectContaining ( {
107
124
intent : "THREE_DS_VERIFICATION" ,
@@ -120,25 +137,66 @@ describe.skip("three domain secure component - isEligible method", () => {
120
137
) ;
121
138
} ) ;
122
139
123
- test . skip ( "catch errors from the API" , async ( ) => {
124
- const mockRequest = vi . fn ( ) . mockRejectedValue ( new Error ( "Error with API" ) ) ;
125
- const threeDomainSecureClient = createThreeDomainSecureComponent ( {
126
- restClient : mockRequest ,
127
- } ) ;
140
+ test ( "catch errors from the API" , async ( ) => {
141
+ mockRestClient . request = vi
142
+ . fn ( )
143
+ . mockRejectedValue ( new Error ( "Error with API" ) ) ;
144
+ const threeDomainSecureClient = createThreeDomainSecureComponent ( ) ;
128
145
129
146
expect . assertions ( 2 ) ;
130
147
await expect ( ( ) =>
131
148
threeDomainSecureClient . isEligible ( defaultMerchantPayload )
132
149
) . rejects . toThrow ( new Error ( "Error with API" ) ) ;
133
- expect ( mockRequest ) . toHaveBeenCalled ( ) ;
150
+ expect ( mockRestClient . request ) . toHaveBeenCalled ( ) ;
134
151
} ) ;
135
152
} ) ;
136
153
137
- describe ( "three domain descure component - show method" , ( ) => {
138
- test . todo ( "should return a zoid component" , ( ) => {
154
+ describe . todo ( "three domain descure component - show method" , ( ) => {
155
+ test ( "should resolve successfully when threeDSIframe onSuccess is called" , async ( ) => {
156
+ mockRestClient . request = mockEligibilityRequest ( ) ;
157
+ const threeDomainSecureClient = createThreeDomainSecureComponent ( ) ;
158
+ await threeDomainSecureClient . isEligible ( defaultMerchantPayload ) ;
159
+ // Arrange
160
+ const mockSuccessResponse = {
161
+ reference_id : "ref-123" ,
162
+ authentication_status : "authenticated" ,
163
+ liability_shift : true ,
164
+ } ;
165
+
166
+ const mockClose = vi . fn ( ) ;
167
+
168
+ mockThreeDSIframe . mockImplementation ( ( { onSuccess } ) => {
169
+ setTimeout ( ( ) => onSuccess ( mockSuccessResponse ) , 0 ) ;
170
+ return { close : mockClose } ;
171
+ } ) ;
172
+ const promise = threeDomainSecureClient . show ( ) ;
173
+
174
+ await expect ( promise ) . resolves . toBeUndefined ( ) ;
175
+ expect ( mockThreeDSIframe ) . toHaveBeenCalledWith ( {
176
+ payerActionUrl : "test-url" ,
177
+ onSuccess : expect . any ( Function ) ,
178
+ } ) ;
179
+ } ) ;
180
+ test ( "should create a zoid component and assign to threeDSIframe" , async ( ) => {
181
+ mockRestClient . request = mockEligibilityRequest ( ) ;
182
+ const threeDomainSecureClient = createThreeDomainSecureComponent ( ) ;
183
+ await threeDomainSecureClient . isEligible ( defaultMerchantPayload ) ;
184
+ expect ( threeDomainSecureClient . threeDSIframe ) . toBeDefined ( ) ;
185
+ threeDomainSecureClient . threeDSIframe = mockThreeDSIframe ;
186
+ expect ( await threeDomainSecureClient . show ( ) ) . toEqual ( {
187
+ liabilityShift : undefined ,
188
+ authenticationStatus : undefined ,
189
+ nonce : "test_nonce" ,
190
+ } ) ;
191
+ } ) ;
192
+
193
+ test ( "should render threeDS Iframe" , async ( ) => {
194
+ mockRestClient . request = mockEligibilityRequest ( ) ;
139
195
const threeDomainSecureClient = createThreeDomainSecureComponent ( ) ;
140
- threeDomainSecureClient . show ( ) ;
141
- // create test for zoid component
196
+ await threeDomainSecureClient . isEligible ( defaultMerchantPayload ) ;
197
+
198
+ await threeDomainSecureClient . show ( ) ;
199
+ expect ( threeDomainSecureClient . threeDSIframe ) . toBeCalled ( ) ;
142
200
} ) ;
143
201
} ) ;
144
202
@@ -155,4 +213,18 @@ describe("three domain secure component - initialization", () => {
155
213
`script data attribute sdk-client-token is required but was not passed`
156
214
) ;
157
215
} ) ;
216
+
217
+ test ( "should log FPTI info on initialization" , ( ) => {
218
+ const logger = {
219
+ info : vi . fn ( ) . mockReturnThis ( ) ,
220
+ track : vi . fn ( ) . mockReturnThis ( ) ,
221
+ } ;
222
+ createThreeDomainSecureComponent ( {
223
+ logger,
224
+ } ) ;
225
+ expect ( logger . info ) . toHaveBeenCalledWith ( "three domain secure v2 invoked" ) ;
226
+ expect ( logger . track ) . toHaveBeenCalledWith ( {
227
+ [ FPTI_KEY . TRANSITION ] : "three_DS_auth_v2" ,
228
+ } ) ;
229
+ } ) ;
158
230
} ) ;
0 commit comments