acquiring-sdk-ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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