@@ -5,30 +5,31 @@ import { syncRefund, syncRes, syncResEventNotification, syncResEventNotification
5
5
import Client from "../client" ;
6
6
import TerminalCloudAPI from "../services/terminalCloudAPI" ;
7
7
import { terminal } from "../typings" ;
8
+ import { EnvironmentEnum } from "../config" ;
8
9
9
10
let client : Client ;
10
11
let terminalCloudAPI : TerminalCloudAPI ;
11
12
let scope : nock . Scope ;
12
13
13
14
beforeEach ( ( ) : void => {
14
- if ( ! nock . isActive ( ) ) {
15
- nock . activate ( ) ;
16
- }
17
- client = createClient ( process . env . ADYEN_TERMINAL_APIKEY ) ;
15
+ if ( ! nock . isActive ( ) ) {
16
+ nock . activate ( ) ;
17
+ }
18
+ client = createClient ( process . env . ADYEN_TERMINAL_APIKEY ) ;
18
19
19
- terminalCloudAPI = new TerminalCloudAPI ( client ) ;
20
- scope = nock ( `${ client . config . terminalApiCloudEndpoint } ` ) ;
20
+ terminalCloudAPI = new TerminalCloudAPI ( client ) ;
21
+ scope = nock ( `${ client . config . terminalApiCloudEndpoint } ` ) ;
21
22
} ) ;
22
23
23
24
afterEach ( ( ) : void => {
24
- nock . cleanAll ( ) ;
25
+ nock . cleanAll ( ) ;
25
26
} ) ;
26
27
27
28
describe ( "Terminal Cloud API" , ( ) : void => {
28
- test ( "should make an async payment request" , async ( ) : Promise < void > => {
29
- scope . post ( "/async" ) . reply ( 200 , asyncRes ) ;
29
+ test ( "should make an async payment request" , async ( ) : Promise < void > => {
30
+ scope . post ( "/async" ) . reply ( 200 , asyncRes ) ;
30
31
31
- const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
32
+ const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
32
33
33
34
const requestResponse = await terminalCloudAPI . async ( terminalAPIPaymentRequest ) ;
34
35
@@ -54,88 +55,152 @@ describe("Terminal Cloud API", (): void => {
54
55
test ( "should make a sync payment request" , async ( ) : Promise < void > => {
55
56
scope . post ( "/sync" ) . reply ( 200 , syncRes ) ;
56
57
57
- const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
58
- const terminalAPIResponse : terminal . TerminalApiResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
58
+ const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
59
+ const terminalAPIResponse : terminal . TerminalApiResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
59
60
60
- expect ( terminalAPIResponse . SaleToPOIResponse ?. PaymentResponse ) . toBeDefined ( ) ;
61
- expect ( terminalAPIResponse . SaleToPOIResponse ?. MessageHeader ) . toBeDefined ( ) ;
62
- } ) ;
61
+ expect ( terminalAPIResponse . SaleToPOIResponse ?. PaymentResponse ) . toBeDefined ( ) ;
62
+ expect ( terminalAPIResponse . SaleToPOIResponse ?. MessageHeader ) . toBeDefined ( ) ;
63
+ } ) ;
63
64
64
- test ( "should make a sync payment request with additional attributes" , async ( ) : Promise < void > => {
65
- scope . post ( "/sync" ) . reply ( 200 , syncTerminalPaymentResponse ) ;
65
+ test ( "should make a sync payment request with additional attributes" , async ( ) : Promise < void > => {
66
+ scope . post ( "/sync" ) . reply ( 200 , syncTerminalPaymentResponse ) ;
66
67
67
- const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
68
+ const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
68
69
69
- await expect ( async ( ) => {
70
- const terminalAPIResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
71
- expect ( terminalAPIResponse . SaleToPOIResponse ?. PaymentResponse ) . toBeDefined ( ) ;
72
- expect ( terminalAPIResponse . SaleToPOIResponse ?. MessageHeader ) . toBeDefined ( ) ;
73
- } ) . not . toThrow ( ) ;
70
+ await expect ( async ( ) => {
71
+ const terminalAPIResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
72
+ expect ( terminalAPIResponse . SaleToPOIResponse ?. PaymentResponse ) . toBeDefined ( ) ;
73
+ expect ( terminalAPIResponse . SaleToPOIResponse ?. MessageHeader ) . toBeDefined ( ) ;
74
+ } ) . not . toThrow ( ) ;
74
75
75
- } ) ;
76
+ } ) ;
76
77
77
- test ( "should return event notification Reject" , async ( ) : Promise < void > => {
78
+ test ( "should return event notification Reject" , async ( ) : Promise < void > => {
78
79
79
- const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
80
- scope . post ( "/sync" ) . reply ( 200 , syncResEventNotification ) ;
80
+ const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
81
+ scope . post ( "/sync" ) . reply ( 200 , syncResEventNotification ) ;
81
82
82
- const terminalAPIResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
83
+ const terminalAPIResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
83
84
84
- expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ) . toBeDefined ( ) ;
85
- expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ?. EventToNotify ) . toBe ( "Reject" ) ;
85
+ expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ) . toBeDefined ( ) ;
86
+ expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ?. EventToNotify ) . toBe ( "Reject" ) ;
86
87
87
- } ) ;
88
+ } ) ;
88
89
89
- test ( "should return event notification Shutdown with additional attributes" , async ( ) : Promise < void > => {
90
+ test ( "should return event notification Shutdown with additional attributes" , async ( ) : Promise < void > => {
90
91
91
- const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
92
- scope . post ( "/sync" ) . reply ( 200 , syncResEventNotificationWithAdditionalAttributes ) ;
93
-
94
- await expect ( async ( ) => {
95
- const terminalAPIResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
96
- expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ) . toBeDefined ( ) ;
97
- expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ?. EventToNotify ) . toBe ( "Shutdown" ) ;
98
- expect ( terminalAPIResponse . SaleToPOIRequest ?. MessageHeader ) . toBeDefined ( ) ;
99
- } ) . not . toThrow ( ) ;
100
- } ) ;
92
+ const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
93
+ scope . post ( "/sync" ) . reply ( 200 , syncResEventNotificationWithAdditionalAttributes ) ;
101
94
102
- test ( "should return event notification with unknown enum" , async ( ) : Promise < void > => {
95
+ await expect ( async ( ) => {
96
+ const terminalAPIResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
97
+ expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ) . toBeDefined ( ) ;
98
+ expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ?. EventToNotify ) . toBe ( "Shutdown" ) ;
99
+ expect ( terminalAPIResponse . SaleToPOIRequest ?. MessageHeader ) . toBeDefined ( ) ;
100
+ } ) . not . toThrow ( ) ;
101
+ } ) ;
103
102
104
- const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
105
- scope . post ( "/sync" ) . reply ( 200 , syncResEventNotificationWithUnknownEnum ) ;
103
+ test ( "should return event notification with unknown enum" , async ( ) : Promise < void > => {
106
104
107
- await expect ( async ( ) => {
108
- const terminalAPIResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
109
- expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ) . toBeDefined ( ) ;
110
- // EventToNotify is unknown, so it holds whatever value is found in the payload
111
- expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ?. EventToNotify ) . toBe ( "this is unknown" ) ;
105
+ const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
106
+ scope . post ( "/sync" ) . reply ( 200 , syncResEventNotificationWithUnknownEnum ) ;
112
107
113
- } ) . not . toThrow ( ) ;
114
- } ) ;
108
+ await expect ( async ( ) => {
109
+ const terminalAPIResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
110
+ expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ) . toBeDefined ( ) ;
111
+ // EventToNotify is unknown, so it holds whatever value is found in the payload
112
+ expect ( terminalAPIResponse . SaleToPOIRequest ?. EventNotification ?. EventToNotify ) . toBe ( "this is unknown" ) ;
115
113
116
- test ( "should make an async refund request" , async ( ) : Promise < void > => {
117
- scope . post ( "/sync" ) . reply ( 200 , syncRes ) ;
114
+ } ) . not . toThrow ( ) ;
115
+ } ) ;
118
116
119
- const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
120
- const terminalAPIResponse : terminal . TerminalApiResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
117
+ test ( "should make an async refund request" , async ( ) : Promise < void > => {
118
+ scope . post ( "/ sync" ) . reply ( 200 , syncRes ) ;
121
119
122
- const pOITransactionId = terminalAPIResponse . SaleToPOIResponse ! . PaymentResponse ! . POIData ! . POITransactionID ;
123
- expect ( pOITransactionId ) . toBeTruthy ( ) ;
120
+ const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
121
+ const terminalAPIResponse : terminal . TerminalApiResponse = await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
124
122
125
- scope . post ( "/sync" ) . reply ( 200 , syncRefund ) ;
123
+ const pOITransactionId = terminalAPIResponse . SaleToPOIResponse ! . PaymentResponse ! . POIData ! . POITransactionID ;
124
+ expect ( pOITransactionId ) . toBeTruthy ( ) ;
126
125
127
- const terminalAPIRefundRequest = createTerminalAPIRefundRequest ( pOITransactionId ) ;
128
- const id = Math . floor ( Math . random ( ) * Math . floor ( 10000000 ) ) . toString ( ) ;
129
- terminalAPIRefundRequest . SaleToPOIRequest . MessageHeader . ServiceID = id ;
130
- const saleToAcquirerData : terminal . SaleToAcquirerData = new terminal . SaleToAcquirerData ( ) ;
131
- saleToAcquirerData . currency = "EUR" ;
132
- terminalAPIRefundRequest . SaleToPOIRequest . ReversalRequest ! . SaleData ! . SaleToAcquirerData = saleToAcquirerData ;
133
- const terminalAPIRefundResponse = await terminalCloudAPI . sync ( terminalAPIRefundRequest ) ;
126
+ scope . post ( "/sync" ) . reply ( 200 , syncRefund ) ;
134
127
135
- expect ( terminalAPIRefundResponse . SaleToPOIResponse ?. ReversalResponse ?. Response . Result ) . toBe ( "Success" ) ;
136
- } , 20000 ) ;
137
- } ) ;
128
+ const terminalAPIRefundRequest = createTerminalAPIRefundRequest ( pOITransactionId ) ;
129
+ const id = Math . floor ( Math . random ( ) * Math . floor ( 10000000 ) ) . toString ( ) ;
130
+ terminalAPIRefundRequest . SaleToPOIRequest . MessageHeader . ServiceID = id ;
131
+ const saleToAcquirerData : terminal . SaleToAcquirerData = new terminal . SaleToAcquirerData ( ) ;
132
+ saleToAcquirerData . currency = "EUR" ;
133
+ terminalAPIRefundRequest . SaleToPOIRequest . ReversalRequest ! . SaleData ! . SaleToAcquirerData = saleToAcquirerData ;
134
+ const terminalAPIRefundResponse = await terminalCloudAPI . sync ( terminalAPIRefundRequest ) ;
135
+
136
+ expect ( terminalAPIRefundResponse . SaleToPOIResponse ?. ReversalResponse ?. Response . Result ) . toBe ( "Success" ) ;
137
+ } , 20000 ) ;
138
+
139
+ test ( "async should handle 308" , async ( ) : Promise < void > => {
138
140
141
+ const terminalApiHost = "https://terminal-api-test.adyen.com" ;
142
+
143
+ const client = new Client ( { apiKey : "YOUR_API_KEY" , environment : EnvironmentEnum . TEST } ) ;
144
+ const terminalCloudAPI = new TerminalCloudAPI ( client ) ;
145
+
146
+ const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
147
+ // custom value to trigger mock 308 response
148
+ terminalAPIPaymentRequest . SaleToPOIRequest . MessageHeader . SaleID = "response-with-redirect" ;
149
+
150
+ // Mock first request: returns a 308 redirect with Location header
151
+ nock ( terminalApiHost )
152
+ . post ( "/async" , ( body ) => {
153
+ return body ?. SaleToPOIRequest ?. MessageHeader ?. SaleID === "response-with-redirect" ;
154
+ } )
155
+ . reply ( 308 , "" , { Location : `${ terminalApiHost } /async?redirect=false` } ) ;
156
+
157
+ // Mock follow-up request: returns successful response 'ok'
158
+ nock ( terminalApiHost )
159
+ . post ( "/async?redirect=false" )
160
+ . reply ( 200 , "ok" ) ;
161
+
162
+ const terminalAPIResponse = await terminalCloudAPI . async ( terminalAPIPaymentRequest ) ;
163
+
164
+ expect ( terminalAPIResponse ) . toEqual ( "ok" ) ;
165
+ } ) ;
166
+
167
+ test ( "sync should validate 308 location header" , async ( ) : Promise < void > => {
168
+ const terminalApiHost = "https://terminal-api-test.adyen.com" ;
169
+
170
+ const client = new Client ( { apiKey : "YOUR_API_KEY" , environment : EnvironmentEnum . TEST } ) ;
171
+ const terminalCloudAPI = new TerminalCloudAPI ( client ) ;
172
+
173
+ const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest ( ) ;
174
+ // custom value to trigger mock 308 response
175
+ terminalAPIPaymentRequest . SaleToPOIRequest . MessageHeader . SaleID = "response-with-redirect" ;
176
+
177
+ // Mock first request: returns a 308 redirect with invalid Location header
178
+ nock ( terminalApiHost )
179
+ . post ( "/sync" , ( body ) => {
180
+ return body ?. SaleToPOIRequest ?. MessageHeader ?. SaleID === "response-with-redirect" ;
181
+ } )
182
+ . reply ( 308 , "" , { Location : "https://example.org/sync?redirect=false" } ) ;
183
+
184
+ // Mock follow-up request: returns successful response
185
+ nock ( terminalApiHost )
186
+ . post ( "/sync?redirect=false" )
187
+ . reply ( 200 , {
188
+ SaleToPOIResponse : {
189
+ PaymentResponse : { Response : "Authorised" } ,
190
+ MessageHeader : { SaleID : "001-308" } ,
191
+ } ,
192
+ } ) ;
193
+
194
+ try {
195
+ await terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ;
196
+ fail ( "No exception was thrown" ) ;
197
+ } catch ( e ) {
198
+ expect ( e ) . toBeInstanceOf ( Error ) ;
199
+ }
200
+
201
+ } ) ;
202
+
203
+ } ) ;
139
204
140
205
export const syncTerminalPaymentResponse = {
141
206
"SaleToPOIResponse" : {
0 commit comments