@@ -5,30 +5,31 @@ import { syncRefund, syncRes, syncResEventNotification, syncResEventNotification
55import  Client  from  "../client" ; 
66import  TerminalCloudAPI  from  "../services/terminalCloudAPI" ; 
77import  {  terminal  }  from  "../typings" ; 
8+ import  {  EnvironmentEnum  }  from  "../config" ; 
89
910let  client : Client ; 
1011let  terminalCloudAPI : TerminalCloudAPI ; 
1112let  scope : nock . Scope ; 
1213
1314beforeEach ( ( ) : 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 ) ; 
1819
19-      terminalCloudAPI  =  new  TerminalCloudAPI ( client ) ; 
20-      scope  =  nock ( `${ client . config . terminalApiCloudEndpoint }  ) ; 
20+   terminalCloudAPI  =  new  TerminalCloudAPI ( client ) ; 
21+   scope  =  nock ( `${ client . config . terminalApiCloudEndpoint }  ) ; 
2122} ) ; 
2223
2324afterEach ( ( ) : void =>  { 
24-      nock . cleanAll ( ) ; 
25+   nock . cleanAll ( ) ; 
2526} ) ; 
2627
2728describe ( "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 ) ; 
3031
31-          const  terminalAPIPaymentRequest  =  createTerminalAPIPaymentRequest ( ) ; 
32+     const  terminalAPIPaymentRequest  =  createTerminalAPIPaymentRequest ( ) ; 
3233
3334        const  requestResponse  =  await  terminalCloudAPI . async ( terminalAPIPaymentRequest ) ; 
3435
@@ -54,88 +55,152 @@ describe("Terminal Cloud API", (): void => {
5455    test ( "should make a sync payment request" ,  async  ( ) : Promise < void >  =>  { 
5556        scope . post ( "/sync" ) . reply ( 200 ,  syncRes ) ; 
5657
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 ) ; 
5960
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+   } ) ; 
6364
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 ) ; 
6667
67-          const  terminalAPIPaymentRequest  =  createTerminalAPIPaymentRequest ( ) ; 
68+     const  terminalAPIPaymentRequest  =  createTerminalAPIPaymentRequest ( ) ; 
6869
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 ( ) ; 
7475
75-      } ) ; 
76+   } ) ; 
7677
77-      test ( "should return event notification Reject" ,  async  ( ) : Promise < void >  =>  { 
78+   test ( "should return event notification Reject" ,  async  ( ) : Promise < void >  =>  { 
7879
79-          const  terminalAPIPaymentRequest  =  createTerminalAPIPaymentRequest ( ) ; 
80-          scope . post ( "/sync" ) . reply ( 200 ,  syncResEventNotification ) ; 
80+     const  terminalAPIPaymentRequest  =  createTerminalAPIPaymentRequest ( ) ; 
81+     scope . post ( "/sync" ) . reply ( 200 ,  syncResEventNotification ) ; 
8182
82-          const  terminalAPIResponse  =  await  terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ; 
83+     const  terminalAPIResponse  =  await  terminalCloudAPI . sync ( terminalAPIPaymentRequest ) ; 
8384
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" ) ; 
8687
87-      } ) ; 
88+   } ) ; 
8889
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 >  =>  { 
9091
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 ) ; 
10194
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+   } ) ; 
103102
104-         const  terminalAPIPaymentRequest  =  createTerminalAPIPaymentRequest ( ) ; 
105-         scope . post ( "/sync" ) . reply ( 200 ,  syncResEventNotificationWithUnknownEnum ) ; 
103+   test ( "should return event notification with unknown enum" ,  async  ( ) : Promise < void >  =>  { 
106104
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 ) ; 
112107
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" ) ; 
115113
116-     test ( "should make an async refund request" ,   async   ( ) :  Promise < void >   =>   { 
117-          scope . post ( "/sync" ) . reply ( 200 ,   syncRes ) ; 
114+     } ) . not . toThrow ( ) ; 
115+   } ) ; 
118116
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 ) ; 
121119
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 ) ; 
124122
125-         scope . post ( "/sync" ) . reply ( 200 ,  syncRefund ) ; 
123+     const  pOITransactionId  =  terminalAPIResponse . SaleToPOIResponse ! . PaymentResponse ! . POIData ! . POITransactionID ; 
124+     expect ( pOITransactionId ) . toBeTruthy ( ) ; 
126125
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 ) ; 
134127
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 >  =>  { 
138140
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 }   } ) ; 
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+ } ) ; 
139204
140205export  const  syncTerminalPaymentResponse  =  { 
141206  "SaleToPOIResponse" : { 
0 commit comments