acquiring-sdk-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +140 -0
  5. data/Rakefile +34 -0
  6. data/acquiring-sdk-ruby.gemspec +30 -0
  7. data/lib/worldline/acquiring/sdk/api_resource.rb +53 -0
  8. data/lib/worldline/acquiring/sdk/authentication/authenticator.rb +21 -0
  9. data/lib/worldline/acquiring/sdk/authentication/authorization_type.rb +17 -0
  10. data/lib/worldline/acquiring/sdk/authentication/oauth2_authenticator.rb +142 -0
  11. data/lib/worldline/acquiring/sdk/authentication/oauth2_exception.rb +15 -0
  12. data/lib/worldline/acquiring/sdk/authentication.rb +1 -0
  13. data/lib/worldline/acquiring/sdk/call_context.rb +9 -0
  14. data/lib/worldline/acquiring/sdk/client.rb +69 -0
  15. data/lib/worldline/acquiring/sdk/communication/communication_exception.rb +21 -0
  16. data/lib/worldline/acquiring/sdk/communication/connection.rb +50 -0
  17. data/lib/worldline/acquiring/sdk/communication/default_connection.rb +429 -0
  18. data/lib/worldline/acquiring/sdk/communication/metadata_provider.rb +162 -0
  19. data/lib/worldline/acquiring/sdk/communication/multipart_form_data_object.rb +54 -0
  20. data/lib/worldline/acquiring/sdk/communication/multipart_form_data_request.rb +15 -0
  21. data/lib/worldline/acquiring/sdk/communication/not_found_exception.rb +21 -0
  22. data/lib/worldline/acquiring/sdk/communication/param_request.rb +16 -0
  23. data/lib/worldline/acquiring/sdk/communication/pooled_connection.rb +28 -0
  24. data/lib/worldline/acquiring/sdk/communication/request_header.rb +64 -0
  25. data/lib/worldline/acquiring/sdk/communication/request_param.rb +30 -0
  26. data/lib/worldline/acquiring/sdk/communication/response_exception.rb +58 -0
  27. data/lib/worldline/acquiring/sdk/communication/response_header.rb +80 -0
  28. data/lib/worldline/acquiring/sdk/communication.rb +1 -0
  29. data/lib/worldline/acquiring/sdk/communicator.rb +506 -0
  30. data/lib/worldline/acquiring/sdk/communicator_configuration.rb +197 -0
  31. data/lib/worldline/acquiring/sdk/domain/data_object.rb +34 -0
  32. data/lib/worldline/acquiring/sdk/domain/shopping_cart_extension.rb +62 -0
  33. data/lib/worldline/acquiring/sdk/domain/uploadable_file.rb +35 -0
  34. data/lib/worldline/acquiring/sdk/domain.rb +1 -0
  35. data/lib/worldline/acquiring/sdk/factory.rb +183 -0
  36. data/lib/worldline/acquiring/sdk/json/default_marshaller.rb +36 -0
  37. data/lib/worldline/acquiring/sdk/json/marshaller.rb +29 -0
  38. data/lib/worldline/acquiring/sdk/json/marshaller_syntax_exception.rb +11 -0
  39. data/lib/worldline/acquiring/sdk/json.rb +1 -0
  40. data/lib/worldline/acquiring/sdk/logging/communicator_logger.rb +26 -0
  41. data/lib/worldline/acquiring/sdk/logging/log_message_builder.rb +91 -0
  42. data/lib/worldline/acquiring/sdk/logging/logging_capable.rb +19 -0
  43. data/lib/worldline/acquiring/sdk/logging/obfuscation/body_obfuscator.rb +101 -0
  44. data/lib/worldline/acquiring/sdk/logging/obfuscation/header_obfuscator.rb +54 -0
  45. data/lib/worldline/acquiring/sdk/logging/obfuscation/obfuscation_capable.rb +23 -0
  46. data/lib/worldline/acquiring/sdk/logging/obfuscation/obfuscation_rule.rb +49 -0
  47. data/lib/worldline/acquiring/sdk/logging/obfuscation.rb +1 -0
  48. data/lib/worldline/acquiring/sdk/logging/request_log_message_builder.rb +52 -0
  49. data/lib/worldline/acquiring/sdk/logging/response_log_message_builder.rb +43 -0
  50. data/lib/worldline/acquiring/sdk/logging/ruby_communicator_logger.rb +63 -0
  51. data/lib/worldline/acquiring/sdk/logging/stdout_communicator_logger.rb +33 -0
  52. data/lib/worldline/acquiring/sdk/logging.rb +1 -0
  53. data/lib/worldline/acquiring/sdk/proxy_configuration.rb +76 -0
  54. data/lib/worldline/acquiring/sdk/v1/acquirer/acquirer_client.rb +35 -0
  55. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/accountverifications/account_verifications_client.rb +60 -0
  56. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/accountverifications.rb +4 -0
  57. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/dynamiccurrencyconversion/dynamic_currency_conversion_client.rb +60 -0
  58. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/dynamiccurrencyconversion.rb +4 -0
  59. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/merchant_client.rb +66 -0
  60. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/payments/get_payment_status_params.rb +34 -0
  61. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/payments/payments_client.rb +224 -0
  62. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/payments.rb +4 -0
  63. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/refunds/get_refund_params.rb +34 -0
  64. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/refunds/refunds_client.rb +157 -0
  65. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/refunds.rb +4 -0
  66. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/technicalreversals/technical_reversals_client.rb +64 -0
  67. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant/technicalreversals.rb +4 -0
  68. data/lib/worldline/acquiring/sdk/v1/acquirer/merchant.rb +4 -0
  69. data/lib/worldline/acquiring/sdk/v1/acquirer.rb +4 -0
  70. data/lib/worldline/acquiring/sdk/v1/api_exception.rb +63 -0
  71. data/lib/worldline/acquiring/sdk/v1/authorization_exception.rb +23 -0
  72. data/lib/worldline/acquiring/sdk/v1/domain/address_verification_data.rb +41 -0
  73. data/lib/worldline/acquiring/sdk/v1/domain/amount_data.rb +48 -0
  74. data/lib/worldline/acquiring/sdk/v1/domain/api_account_verification_request.rb +70 -0
  75. data/lib/worldline/acquiring/sdk/v1/domain/api_account_verification_response.rb +87 -0
  76. data/lib/worldline/acquiring/sdk/v1/domain/api_action_response.rb +71 -0
  77. data/lib/worldline/acquiring/sdk/v1/domain/api_action_response_for_refund.rb +71 -0
  78. data/lib/worldline/acquiring/sdk/v1/domain/api_capture_request.rb +75 -0
  79. data/lib/worldline/acquiring/sdk/v1/domain/api_capture_request_for_refund.rb +43 -0
  80. data/lib/worldline/acquiring/sdk/v1/domain/api_increment_request.rb +61 -0
  81. data/lib/worldline/acquiring/sdk/v1/domain/api_increment_response.rb +43 -0
  82. data/lib/worldline/acquiring/sdk/v1/domain/api_payment_error_response.rb +62 -0
  83. data/lib/worldline/acquiring/sdk/v1/domain/api_payment_refund_request.rb +77 -0
  84. data/lib/worldline/acquiring/sdk/v1/domain/api_payment_request.rb +95 -0
  85. data/lib/worldline/acquiring/sdk/v1/domain/api_payment_resource.rb +103 -0
  86. data/lib/worldline/acquiring/sdk/v1/domain/api_payment_response.rb +126 -0
  87. data/lib/worldline/acquiring/sdk/v1/domain/api_payment_reversal_request.rb +61 -0
  88. data/lib/worldline/acquiring/sdk/v1/domain/api_payment_summary_for_response.rb +66 -0
  89. data/lib/worldline/acquiring/sdk/v1/domain/api_references_for_responses.rb +48 -0
  90. data/lib/worldline/acquiring/sdk/v1/domain/api_refund_request.rb +88 -0
  91. data/lib/worldline/acquiring/sdk/v1/domain/api_refund_resource.rb +110 -0
  92. data/lib/worldline/acquiring/sdk/v1/domain/api_refund_response.rb +133 -0
  93. data/lib/worldline/acquiring/sdk/v1/domain/api_refund_summary_for_response.rb +66 -0
  94. data/lib/worldline/acquiring/sdk/v1/domain/api_reversal_response.rb +36 -0
  95. data/lib/worldline/acquiring/sdk/v1/domain/api_technical_reversal_request.rb +50 -0
  96. data/lib/worldline/acquiring/sdk/v1/domain/api_technical_reversal_response.rb +62 -0
  97. data/lib/worldline/acquiring/sdk/v1/domain/card_data_for_dcc.rb +48 -0
  98. data/lib/worldline/acquiring/sdk/v1/domain/card_on_file_data.rb +52 -0
  99. data/lib/worldline/acquiring/sdk/v1/domain/card_payment_data.rb +114 -0
  100. data/lib/worldline/acquiring/sdk/v1/domain/card_payment_data_for_refund.rb +82 -0
  101. data/lib/worldline/acquiring/sdk/v1/domain/card_payment_data_for_resource.rb +43 -0
  102. data/lib/worldline/acquiring/sdk/v1/domain/card_payment_data_for_response.rb +52 -0
  103. data/lib/worldline/acquiring/sdk/v1/domain/card_payment_data_for_verification.rb +91 -0
  104. data/lib/worldline/acquiring/sdk/v1/domain/dcc_data.rb +55 -0
  105. data/lib/worldline/acquiring/sdk/v1/domain/dcc_proposal.rb +60 -0
  106. data/lib/worldline/acquiring/sdk/v1/domain/e_commerce_data.rb +52 -0
  107. data/lib/worldline/acquiring/sdk/v1/domain/e_commerce_data_for_account_verification.rb +45 -0
  108. data/lib/worldline/acquiring/sdk/v1/domain/e_commerce_data_for_response.rb +41 -0
  109. data/lib/worldline/acquiring/sdk/v1/domain/get_dcc_rate_request.rb +75 -0
  110. data/lib/worldline/acquiring/sdk/v1/domain/get_dcc_rate_response.rb +57 -0
  111. data/lib/worldline/acquiring/sdk/v1/domain/initial_card_on_file_data.rb +41 -0
  112. data/lib/worldline/acquiring/sdk/v1/domain/merchant_data.rb +76 -0
  113. data/lib/worldline/acquiring/sdk/v1/domain/network_token_data.rb +41 -0
  114. data/lib/worldline/acquiring/sdk/v1/domain/payment_references.rb +48 -0
  115. data/lib/worldline/acquiring/sdk/v1/domain/plain_card_data.rb +48 -0
  116. data/lib/worldline/acquiring/sdk/v1/domain/point_of_sale_data.rb +34 -0
  117. data/lib/worldline/acquiring/sdk/v1/domain/point_of_sale_data_for_dcc.rb +41 -0
  118. data/lib/worldline/acquiring/sdk/v1/domain/rate_data.rb +64 -0
  119. data/lib/worldline/acquiring/sdk/v1/domain/sub_operation.rb +94 -0
  120. data/lib/worldline/acquiring/sdk/v1/domain/sub_operation_for_refund.rb +87 -0
  121. data/lib/worldline/acquiring/sdk/v1/domain/subsequent_card_on_file_data.rb +48 -0
  122. data/lib/worldline/acquiring/sdk/v1/domain/three_d_secure.rb +62 -0
  123. data/lib/worldline/acquiring/sdk/v1/domain/transaction_data_for_dcc.rb +52 -0
  124. data/lib/worldline/acquiring/sdk/v1/domain.rb +4 -0
  125. data/lib/worldline/acquiring/sdk/v1/exception_factory.rb +48 -0
  126. data/lib/worldline/acquiring/sdk/v1/ping/ping_client.rb +52 -0
  127. data/lib/worldline/acquiring/sdk/v1/ping.rb +4 -0
  128. data/lib/worldline/acquiring/sdk/v1/platform_exception.rb +23 -0
  129. data/lib/worldline/acquiring/sdk/v1/reference_exception.rb +23 -0
  130. data/lib/worldline/acquiring/sdk/v1/v1_client.rb +43 -0
  131. data/lib/worldline/acquiring/sdk/v1/validation_exception.rb +23 -0
  132. data/lib/worldline/acquiring/sdk/v1.rb +4 -0
  133. data/lib/worldline/acquiring/sdk.rb +1 -0
  134. data/spec/comparable_extension.rb +29 -0
  135. data/spec/fixtures/resources/authentication/oauth2AccessToken.expired.json +4 -0
  136. data/spec/fixtures/resources/authentication/oauth2AccessToken.invalidClient.json +4 -0
  137. data/spec/fixtures/resources/authentication/oauth2AccessToken.json +4 -0
  138. data/spec/fixtures/resources/communication/getWithQueryParams.json +3 -0
  139. data/spec/fixtures/resources/communication/getWithoutQueryParams.json +3 -0
  140. data/spec/fixtures/resources/communication/notFound.html +1 -0
  141. data/spec/fixtures/resources/communication/postWithBadRequestResponse.json +11 -0
  142. data/spec/fixtures/resources/communication/postWithCreatedResponse.json +6 -0
  143. data/spec/fixtures/resources/communication/unknownServerError.json +10 -0
  144. data/spec/fixtures/resources/logging/bodyNoObfuscation.json +7 -0
  145. data/spec/fixtures/resources/logging/bodyWithBinObfuscated.json +3 -0
  146. data/spec/fixtures/resources/logging/bodyWithBinOriginal.json +3 -0
  147. data/spec/fixtures/resources/logging/bodyWithCardCustomObfuscated.json +13 -0
  148. data/spec/fixtures/resources/logging/bodyWithCardObfuscated.json +13 -0
  149. data/spec/fixtures/resources/logging/bodyWithCardOriginal.json +13 -0
  150. data/spec/fixtures/resources/logging/bodyWithObjectObfuscated.json +5 -0
  151. data/spec/fixtures/resources/logging/bodyWithObjectOriginal.json +5 -0
  152. data/spec/fixtures/resources/properties.oauth2.yml +8 -0
  153. data/spec/fixtures/resources/properties.proxy.yml +14 -0
  154. data/spec/integration/connection_pooling_spec.rb +74 -0
  155. data/spec/integration/multipart_form_data_spec.rb +216 -0
  156. data/spec/integration/process_payment_spec.rb +43 -0
  157. data/spec/integration/request_dcc_rate_spec.rb +24 -0
  158. data/spec/integration/sdk_proxy_spec.rb +70 -0
  159. data/spec/integration_setup.rb +111 -0
  160. data/spec/lib/authentication/oauth2_authenticator_spec.rb +68 -0
  161. data/spec/lib/client_spec.rb +47 -0
  162. data/spec/lib/communication/default_connection_logger_spec.rb +484 -0
  163. data/spec/lib/communication/default_connection_spec.rb +352 -0
  164. data/spec/lib/communication/metadata_provider_spec.rb +93 -0
  165. data/spec/lib/communicator_configuration_spec.rb +181 -0
  166. data/spec/lib/communicator_spec.rb +34 -0
  167. data/spec/lib/factory_spec.rb +38 -0
  168. data/spec/lib/json/default_marshaller_spec.rb +39 -0
  169. data/spec/lib/logging/obfuscation/body_obfuscator_spec.rb +86 -0
  170. data/spec/lib/logging/obfuscation/header_obfuscator_spec.rb +100 -0
  171. data/spec/lib/logging/ruby_communicator_logger_spec.rb +92 -0
  172. data/spec/lib/logging/stdout_communicator_logger_spec.rb +64 -0
  173. data/spec/spec_helper.rb +32 -0
  174. metadata +375 -0
@@ -0,0 +1,484 @@
1
+ require 'spec_helper'
2
+ require 'httpclient'
3
+
4
+ # define module first so we can include them
5
+ # contains validation methods for messages logged in the tests
6
+ module ValidationDict
7
+ REQUEST_START = %r(Outgoing request \(requestId='([-a-zA-Z0-9]+)'\):)
8
+ RESPONSE_START = %r(Incoming response \(requestId='([-a-zA-Z0-9]+)', \d+.\d* ms\):)
9
+ GET_METHOD = %r(method: 'GET')
10
+ POST_METHOD = %r(method: 'POST')
11
+ DELETE_METHOD = %r(method: 'DELETE')
12
+ STATUS_200 = %r(status-code: '200')
13
+ STATUS_201 = %r(status-code: '201')
14
+ STATUS_204 = %r(status-code: '204')
15
+ STATUS_400 = %r(status-code: '400')
16
+ STATUS_402 = %r(status-code: '402')
17
+ STATUS_404 = %r(status-code: '404')
18
+ STATUS_500 = %r(status-code: '500')
19
+ DATE_HEADER = %r(Date="[^"]+")
20
+ META_INFO_HEADER = %r(X-WL-ServerMetaInfo="[^"]*")
21
+ AUTHORIZATION_HEADER = %r(Authorization="\*\*\*\*\*\*\*\*"[^']*')
22
+ DUMMY_HEADER = %r(Dummy="none")
23
+ DATA_JSON_HEADER = %r(Content-Type="application/json")
24
+ DATA_JSON = %r(content-type: 'application/json')
25
+ UNICODE_BODY_NAME= %r(Schröder)
26
+
27
+ def validate_request_headers(message)
28
+ expect(message).to match(DATE_HEADER)
29
+ expect(message).to match(META_INFO_HEADER)
30
+ expect(message).to match(AUTHORIZATION_HEADER)
31
+ end
32
+
33
+ def getWithQueryParams_request(message)
34
+ expect(message).to match(REQUEST_START)
35
+ message =~ REQUEST_START
36
+ id = $1 # capture id from the regular expression above
37
+ expect(message).to match(GET_METHOD)
38
+ expect(message).to match(%r(uri: '/v1/get\?source=EUR&target=USD&amount=1000'))
39
+ validate_request_headers(message)
40
+ id
41
+ end
42
+
43
+ def getWithQueryParams_response(message)
44
+ expect(message).to match(RESPONSE_START)
45
+ message =~ RESPONSE_START
46
+ id = $1 # capture id from the regular expression above
47
+ expect(message).to match(STATUS_200)
48
+ expect(message).to match(DATA_JSON_HEADER)
49
+ expect(message).to match(DATE_HEADER)
50
+ # expect(message).to match(DUMMY_HEADER)
51
+ expect(message).to match(%r(content-type: 'application/json'))
52
+ # token match to validate that a body is in the message
53
+ expect(message).to match(%r("convertedAmount" : 4547504))
54
+ id
55
+ end
56
+
57
+ def postWithBadRequestResponse_request(message)
58
+ expect(message).to match(REQUEST_START)
59
+ message =~ REQUEST_START
60
+ id = $1 # capture id from the regular expression above
61
+ expect(message).to match(POST_METHOD)
62
+ expect(message).to match(%r(uri: '/v1/bad-request'))
63
+ validate_request_headers(message)
64
+ expect(message).to match(DATA_JSON_HEADER)
65
+ expect(message).to match(DATA_JSON)
66
+ expect(message).to match(%r("card":)) # token match to validate that a body is in the message
67
+ id
68
+ end
69
+
70
+ def postWithBadRequestResponse_response(message)
71
+ expect(message).to match(RESPONSE_START)
72
+ message =~ RESPONSE_START
73
+ id = $1 # capture id from the regular expression above
74
+ expect(message).to match(STATUS_400)
75
+ expect(message).to match(DATA_JSON_HEADER)
76
+ # expect(message).to match(DUMMY_HEADER)
77
+ expect(message).to match(DATE_HEADER)
78
+ expect(message).to match(DATA_JSON)
79
+ # token match to validate that a body is in the message
80
+ expect(message).to match(%r("VALUE \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* OF FIELD CREDITCARDNUMBER DID NOT PASS THE LUHNCHECK"))
81
+ id
82
+ end
83
+
84
+ def postWithCreatedResponse_request(message)
85
+ expect(message).to match(REQUEST_START)
86
+ message =~ REQUEST_START
87
+ id = $1 # capture id from the regular expression above
88
+ expect(message).to match(POST_METHOD)
89
+ expect(message).to match(%r(uri: '/v1/created'))
90
+ validate_request_headers(message)
91
+ expect(message).to match(DATA_JSON_HEADER)
92
+ expect(message).to match(DATA_JSON)
93
+ # token match to validate that a body is in the message
94
+ expect(message).to match(%r("card":))
95
+ id
96
+ end
97
+
98
+ def postWithCreatedResponse_response(message)
99
+ expect(message).to match(RESPONSE_START)
100
+ message =~ RESPONSE_START
101
+ id = $1 # capture id from the regular expression above
102
+ expect(message).to match(STATUS_201)
103
+ expect(message).to match(%r(Location="api\.preprod\.acquiring\.worldline-solutions\.com/v1/created/000000123410000595980000100001"))
104
+ expect(message).to match(DATA_JSON_HEADER)
105
+ # expect(message).to match(DUMMY_HEADER)
106
+ expect(message).to match(DATE_HEADER)
107
+ expect(message).to match(DATA_JSON)
108
+ # token match to validate that a body is in the message
109
+ expect(message).to match(%r("id": "000000123410000595980000100001"))
110
+ id
111
+ end
112
+
113
+ def deleteWithVoidResponse_request(message)
114
+ expect(message).to match(REQUEST_START)
115
+ message =~ REQUEST_START
116
+ id = $1 # capture id from the regular expression above
117
+ expect(message).to match(DELETE_METHOD)
118
+ expect(message).to match(%r(uri: '/v1/void'))
119
+ validate_request_headers(message)
120
+ id
121
+ end
122
+
123
+ def deleteWithVoidResponse_response(message)
124
+ expect(message).to match(RESPONSE_START)
125
+ message =~ RESPONSE_START
126
+ id = $1 # capture id from the regular expression above
127
+ expect(message).to match(STATUS_204)
128
+ # expect(message).to match(DUMMY_HEADER)
129
+ expect(message).to match(DATE_HEADER)
130
+ id
131
+ end
132
+
133
+ def notFound_response(message)
134
+ expect(message).to match(RESPONSE_START)
135
+ message =~ RESPONSE_START
136
+ id = $1 # capture id from the regular expression above
137
+ expect(message).to match(STATUS_404)
138
+ # expect(message).to match(DUMMY_HEADER)
139
+ expect(message).to match(DATE_HEADER)
140
+ expect(message).to match(%r(Content-Type="text/html"))
141
+ expect(message).to match(%r(content-type: 'text/html'))
142
+ expect(message).to match(%r(body: 'Not Found'))
143
+ id
144
+ end
145
+
146
+ def getWithoutQueryParams_request(message)
147
+ expect(message).to match(REQUEST_START)
148
+ message =~ REQUEST_START
149
+ id = $1 # capture id from the regular expression above
150
+ expect(message).to match(GET_METHOD)
151
+ expect(message).to match(%r(uri: '/v1/get'))
152
+ validate_request_headers(message)
153
+ id
154
+ end
155
+
156
+ def getWithoutQueryParams_response(message)
157
+ expect(message).to match(RESPONSE_START)
158
+ message =~ RESPONSE_START
159
+ id = $1 # capture id from the regular expression above
160
+ expect(message).to match(STATUS_200)
161
+ # expect(message).to match(DUMMY_HEADER)
162
+ expect(message).to match(DATE_HEADER)
163
+ expect(message).to match(DATA_JSON_HEADER)
164
+ expect(message).to match(DATA_JSON)
165
+ # token match to validate that a body is in the message
166
+ expect(message).to match(%r("result": "OK"))
167
+ id
168
+ end
169
+
170
+ def unknownServerError_response(message)
171
+ expect(message).to match(RESPONSE_START)
172
+ message =~ RESPONSE_START
173
+ id = $1 # capture id from the regular expression above
174
+ expect(message).to match(STATUS_500)
175
+ expect(message).to match(DATA_JSON_HEADER)
176
+ # expect(message).to match(DUMMY_HEADER)
177
+ expect(message).to match(DATE_HEADER)
178
+ expect(message).to match(DATA_JSON)
179
+ # token match to validate that a body is in the message
180
+ expect(message).to match(%r("message": "UNKNOWN_SERVER_ERROR"))
181
+ id
182
+ end
183
+ end
184
+
185
+ class TestParamRequest < Worldline::Acquiring::SDK::Communication::ParamRequest
186
+ def initialize(params)
187
+ @params = params
188
+ end
189
+
190
+ def to_request_parameters
191
+ @params
192
+ end
193
+ end
194
+
195
+ class TestObject < Worldline::Acquiring::SDK::Domain::DataObject
196
+ attr_accessor :content
197
+
198
+ def to_h
199
+ @content
200
+ end
201
+
202
+ def from_hash(hash)
203
+ @content = hash
204
+ end
205
+ end
206
+
207
+ # -----test examples-----:
208
+
209
+ describe 'DefaultConnectionLogging' do
210
+
211
+ include ValidationDict
212
+
213
+ let(:logger){TestLogger.new}
214
+ base_headers = {'dummy' => 'none', 'Date' => 'Mon, 1 Jan 2000 00:00:00 GMT'}
215
+ resource_prefix = 'spec/fixtures/resources/communication/'
216
+
217
+ it 'should be able to log a simple request' do
218
+ response_body = IO.read(resource_prefix + 'getWithoutQueryParams.json')
219
+
220
+ stub_request(:get, 'https://api.preprod.acquiring.worldline-solutions.com/v1/get')
221
+ .to_return(status: 200, body: response_body,
222
+ headers: base_headers.merge({'Content-Type' => 'application/json'}))
223
+
224
+ COMMUNICATOR.enable_logging(logger)
225
+ response = COMMUNICATOR.get('/v1/get', nil, nil, TestObject, nil)
226
+
227
+ expect(response).to_not be_nil
228
+ expect(response.content).to_not be_nil
229
+ expect(response.content['result']).to eq('OK')
230
+
231
+ validate_request_and_response(logger.entries[0], logger.entries[1], 'getWithoutQueryParams')
232
+ end
233
+
234
+ it 'can log a GET request with parameters' do
235
+ response_body = IO.read(resource_prefix + 'getWithQueryParams.json')
236
+
237
+ stub_request(:get, 'https://api.preprod.acquiring.worldline-solutions.com/v1/get?source=EUR&target=USD&amount=1000')
238
+ .to_return(status: 200, body: response_body,
239
+ headers: base_headers.merge({'Content-Type' => 'application/json'}))
240
+
241
+ query_params = TestParamRequest.new([
242
+ RequestParam.new('source', 'EUR'),
243
+ RequestParam.new('target', 'USD'),
244
+ RequestParam.new('amount', '1000'),
245
+ ])
246
+ COMMUNICATOR.enable_logging(logger)
247
+
248
+ response = COMMUNICATOR.get('/v1/get', nil, query_params, TestObject, nil)
249
+
250
+ expect(response).to_not be_nil
251
+ expect(response.content).to_not be_nil
252
+ expect(response.content['convertedAmount']).to_not be_nil
253
+
254
+ validate_request_and_response(logger.entries[0], logger.entries[1], 'getWithQueryParams')
255
+ end
256
+
257
+ it 'can log DELETE requests' do
258
+ stub_request(:delete, 'https://api.preprod.acquiring.worldline-solutions.com/v1/void')
259
+ .to_return(status: 204, headers: base_headers)
260
+
261
+ COMMUNICATOR.enable_logging(logger)
262
+ response = COMMUNICATOR.delete('/v1/void', nil, nil, nil, nil)
263
+
264
+ expect(response).to_not be_nil
265
+
266
+ validate_request_and_response(logger.entries[0], logger.entries[1], 'deleteWithVoidResponse')
267
+ end
268
+
269
+ it 'can log POST responses' do
270
+ response_body = IO.read(resource_prefix + 'postWithCreatedResponse.json')
271
+ request = create_test_request
272
+
273
+ stub_request(:post, 'https://api.preprod.acquiring.worldline-solutions.com/v1/created')
274
+ .to_return(status: 201, body: response_body,
275
+ headers: base_headers.merge({'Content-Type' => 'application/json',
276
+ 'Location' => 'api.preprod.acquiring.worldline-solutions.com/v1/created/000000123410000595980000100001'}))
277
+
278
+ COMMUNICATOR.enable_logging(logger)
279
+ response = COMMUNICATOR.post('/v1/created', nil, nil, request, TestObject, nil)
280
+
281
+ expect(response).to_not be_nil
282
+ expect(response.content).to_not be_nil
283
+ expect(response.content['payment']).to_not be_nil
284
+ expect(response.content['payment']['id']).to_not be_nil
285
+
286
+ validate_request_and_response(logger.entries[0], logger.entries[1], 'postWithCreatedResponse')
287
+ end
288
+
289
+ it 'can log error responses' do
290
+ response_body = IO.read(resource_prefix + 'postWithBadRequestResponse.json')
291
+ request = create_test_request
292
+
293
+ stub_request(:post, 'https://api.preprod.acquiring.worldline-solutions.com/v1/bad-request')
294
+ .to_return(status: 400, body: response_body,
295
+ headers: base_headers.merge({'Content-Type' => 'application/json'}))
296
+
297
+ COMMUNICATOR.enable_logging(logger)
298
+ expect{COMMUNICATOR.post('/v1/bad-request', nil, nil, request, TestObject, nil)}.to raise_error(Worldline::Acquiring::SDK::Communication::ResponseException)
299
+
300
+ validate_request_and_response(logger.entries[0], logger.entries[1], 'postWithBadRequestResponse')
301
+ end
302
+
303
+ it 'logs general HTTP errors' do
304
+ response_body = IO.read(resource_prefix + 'unknownServerError.json')
305
+
306
+ stub_request(:get, 'https://api.preprod.acquiring.worldline-solutions.com/v1/get')
307
+ .to_return(status: 500, body: response_body,
308
+ headers: base_headers.merge({'Content-Type' => 'application/json'}))
309
+
310
+ COMMUNICATOR.enable_logging(logger)
311
+ expect{COMMUNICATOR.get('/v1/get', nil, nil, TestObject, nil)}.to raise_error(Worldline::Acquiring::SDK::Communication::ResponseException)
312
+
313
+ validate_request_and_response(logger.entries[0], logger.entries[1], 'getWithoutQueryParams', 'unknownServerError')
314
+ end
315
+
316
+ it 'logs non-json' do
317
+ response_body = IO.read(resource_prefix + 'notFound.html')
318
+
319
+ stub_request(:get, 'https://api.preprod.acquiring.worldline-solutions.com/v1/get')
320
+ .to_return(status: 404, body: response_body,
321
+ headers: base_headers.merge({'Content-Type' => 'text/html'}))
322
+
323
+ COMMUNICATOR.enable_logging(logger)
324
+ expect{COMMUNICATOR.get('/v1/get', nil, nil, TestObject, nil)}.to raise_error(Worldline::Acquiring::SDK::Communication::NotFoundException)
325
+
326
+ validate_request_and_response(logger.entries[0], logger.entries[1], 'getWithoutQueryParams', 'notFound')
327
+ end
328
+
329
+ it 'logs timeouts' do
330
+ stub_request(:get, 'https://api.preprod.acquiring.worldline-solutions.com/v1/get')
331
+ .to_raise(HTTPClient::ReceiveTimeoutError)
332
+
333
+ COMMUNICATOR.enable_logging(logger)
334
+ expect{COMMUNICATOR.get('/v1/get', nil, nil, TestObject, nil)}.to raise_error(Worldline::Acquiring::SDK::Communication::CommunicationException)
335
+
336
+ request = logger.entries[0]
337
+ expect(request[0]).to_not be_nil
338
+ expect(request[1]).to be_nil, "Error logged that should not have been thrown:/n#{request[1]}"
339
+
340
+ response = logger.entries[1]
341
+ expect(response[0]).to_not be_nil
342
+ expect(response[1]).to_not be_nil, 'A timeout error should have been logged'
343
+ expect(response[1]).to be_a(HTTPClient::TimeoutError)
344
+
345
+ validate_request_and_error(logger.entries[0], logger.entries[1], 'getWithoutQueryParams')
346
+ end
347
+
348
+ it 'can log requests individually' do
349
+ response_body = IO.read(resource_prefix + 'getWithoutQueryParams.json')
350
+
351
+ stub_request(:get, 'https://api.preprod.acquiring.worldline-solutions.com/v1/get')
352
+ .to_return{ |request| COMMUNICATOR.disable_logging
353
+ {body: response_body, status: 200, headers: base_headers.merge({'Content-type' => 'application/json'})}}
354
+
355
+ COMMUNICATOR.enable_logging(logger)
356
+ response = COMMUNICATOR.get('/v1/get', nil, nil, TestObject, nil)
357
+
358
+ expect(response).to_not be_nil
359
+ expect(response.content).to_not be_nil
360
+ expect(response.content['result']).to eq('OK')
361
+
362
+ request = logger.entries[0]
363
+ expect(request[0]).to_not be_nil
364
+ expect(request[1]).to be_nil, "Error logged that should not have been thrown:/n#{request[1]}"
365
+
366
+ validate_request(logger.entries[0], 'getWithoutQueryParams')
367
+ end
368
+
369
+ it 'can log responses individually' do
370
+ response_body = IO.read(resource_prefix + 'getWithoutQueryParams.json')
371
+
372
+ stub_request(:get, 'https://api.preprod.acquiring.worldline-solutions.com/v1/get')
373
+ .to_return{ |request| COMMUNICATOR.enable_logging(logger)
374
+ {body: response_body, status: 200, headers: base_headers.merge({'Content-type' => 'application/json'})}}
375
+
376
+ response = COMMUNICATOR.get('/v1/get', nil, nil, TestObject, nil)
377
+
378
+ expect(response).to_not be_nil
379
+ expect(response.content).to_not be_nil
380
+ expect(response.content['result']).to eq('OK')
381
+
382
+ response = logger.entries[0]
383
+ expect(response[0]).to_not be_nil
384
+ expect(response[1]).to be_nil, "Error logged that should not have been thrown:/n#{response[1]}"
385
+
386
+ validate_response(logger.entries[0], 'getWithoutQueryParams')
387
+ end
388
+
389
+ it 'can log errors individually' do
390
+ stub_request(:get, 'https://api.preprod.acquiring.worldline-solutions.com/v1/get')
391
+ .to_return{ |request| COMMUNICATOR.enable_logging(logger)
392
+ raise HTTPClient::ReceiveTimeoutError.new}
393
+
394
+ expect{COMMUNICATOR.get('/v1/get', nil, nil, TestObject, nil)}.to raise_error(Worldline::Acquiring::SDK::Communication::CommunicationException)
395
+
396
+ response = logger.entries[0]
397
+ expect(response[0]).to_not be_nil
398
+ expect(response[1]).to_not be_nil, 'A timeout error should have been logged'
399
+ expect(response[1]).to be_a(HTTPClient::TimeoutError)
400
+
401
+ validate_error(logger.entries[0])
402
+ end
403
+ end
404
+
405
+ # Asserts that the request and response contain messages and no errors.
406
+ # Asserts that the request and response messages match the format
407
+ # in request_resource_prefix.request and response_resource_prefix.response respectively.
408
+ # If response_resource_prefix is not given it is assumed to be the same as the request_resource_prefix.
409
+ def validate_request_and_response(request, response,
410
+ request_resource_prefix, response_resource_prefix=nil)
411
+ # for request and response, check that the message exists in the logs and there is no error logged
412
+ expect(request[0]).to_not be_nil
413
+ expect(request[1]).to be_nil, "Error logged that should not have been thrown:/n#{request[1]}"
414
+
415
+ expect(response[0]).to_not be_nil
416
+ expect(response[1]).to be_nil, "Error logged that should not have been thrown:/n#{response[1]}"
417
+
418
+ response_resource_prefix ||= request_resource_prefix
419
+ request_id = validate_request(request, request_resource_prefix)
420
+ fail if request_id.nil? # Request_id was not captured
421
+ validate_response(response, response_resource_prefix, request_id)
422
+ end
423
+
424
+ # Asserts that the request message matches the request format in _resource_prefix.request_
425
+ # and that the request and error id are the same.
426
+ # Resource prefix is the location of the request resource, which will be appended with _.request_ to get the file location.
427
+ def validate_request_and_error(request, response_error, resource_prefix)
428
+ request_id = validate_request(request, resource_prefix)
429
+ validate_error(response_error, request_id)
430
+ end
431
+
432
+ # Asserts that the request message matches the request format in _resource_prefix.request_.
433
+ # Resource prefix is the location of the request resource, which will be appended with _.request_ to get the file location.
434
+ # Returns the request_id found in the request so it can be matched with a possible response or error
435
+ def validate_request(request, request_resource_prefix)
436
+ method = (request_resource_prefix + '_request').to_sym
437
+ send(method, request[0])
438
+ end
439
+
440
+ # Asserts that the response message matches the response format in _resource_prefix.response_.
441
+ # Resource prefix is the location of the response resource, which will be appended with _.response_ to get the file location.
442
+ # If the parameter _request_id_ is given, it will be matched with the _request_id_ found in the response_message
443
+ def validate_response(response, response_resource_prefix, request_id=nil)
444
+ method = (response_resource_prefix + '_response').to_sym
445
+ response_id = send(method, response[0])
446
+ expect(response_id).to eq(request_id) unless request_id.nil?
447
+ end
448
+
449
+ # Validates that the error message contains a requestId
450
+ # If a request_id is provided, it is matched against the error_id found in the error
451
+ def validate_error(error, request_id=nil)
452
+ error_pattern_string = %r(Error occurred for outgoing request \(requestId='(?<error_id>[-a-zA-Z0-9]+)', \d+.\d* ms\))
453
+ expect(error[0]).to match(error_pattern_string)
454
+ error[0] =~ error_pattern_string # match to capture id
455
+ error_id = $1
456
+ expect(error_id).to eq(request_id) unless request_id.nil?
457
+ end
458
+
459
+
460
+ class TestLogger < Worldline::Acquiring::SDK::Logging::CommunicatorLogger
461
+
462
+ attr_accessor :entries
463
+
464
+ def initialize
465
+ @entries = []
466
+ end
467
+
468
+ def log(message, thrown = nil)
469
+ @entries << [message, thrown]
470
+ end
471
+ end
472
+
473
+
474
+ def create_test_request
475
+ object = TestObject.new
476
+ object.content = {
477
+ card: {
478
+ cardSecurityCode: '123',
479
+ cardNumber: '1234567890123456',
480
+ expiryDate: '122024',
481
+ }
482
+ }
483
+ object
484
+ end