sage_pay 0.1.0 → 0.2.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.
- data/Rakefile +10 -27
- data/lib/sage_pay/server/address.rb +45 -0
- data/lib/sage_pay/server/signature_verification_details.rb +14 -0
- data/lib/sage_pay/server/transaction_code.rb +18 -0
- data/lib/sage_pay/server/transaction_notification.rb +169 -0
- data/lib/sage_pay/server/transaction_notification_response.rb +62 -0
- data/lib/sage_pay/server/transaction_registration.rb +176 -0
- data/lib/sage_pay/server/transaction_registration_response.rb +94 -0
- data/lib/sage_pay/server.rb +31 -0
- data/lib/sage_pay.rb +20 -2
- data/lib/validatable-ext.rb +28 -0
- data/lib/validations/validates_inclusion_of.rb +22 -0
- data/sage_pay.gemspec +30 -5
- data/spec/integration/sage_pay/server_spec.rb +57 -0
- data/spec/sage_pay/server/address_spec.rb +119 -0
- data/spec/sage_pay/server/signature_verification_details_spec.rb +26 -0
- data/spec/sage_pay/server/transaction_code_spec.rb +15 -0
- data/spec/sage_pay/server/transaction_notification_response_spec.rb +75 -0
- data/spec/sage_pay/server/transaction_notification_spec.rb +142 -0
- data/spec/sage_pay/server/transaction_registration_response_spec.rb +231 -0
- data/spec/sage_pay/server/transaction_registration_spec.rb +619 -0
- data/spec/sage_pay/server_spec.rb +72 -0
- data/spec/sage_pay_spec.rb +7 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/factories.rb +58 -0
- data/spec/support/integration.rb +9 -0
- data/spec/support/validation_matchers.rb +71 -0
- metadata +79 -7
@@ -0,0 +1,619 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include SagePay::Server
|
4
|
+
|
5
|
+
describe TransactionRegistration do
|
6
|
+
|
7
|
+
it "should work straight from the factory" do
|
8
|
+
lambda {
|
9
|
+
transaction_registration_factory.should be_valid
|
10
|
+
}.should_not raise_error
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should report protocol version 2.23" do
|
14
|
+
transaction_registration = TransactionRegistration.new
|
15
|
+
transaction_registration.vps_protocol.should == "2.23"
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "conversions" do
|
19
|
+
it "should accept a float for the amount and convert it to a BigDecimal interally" do
|
20
|
+
transaction_registration = transaction_registration_factory(:amount => 12.34)
|
21
|
+
transaction_registration.should be_valid
|
22
|
+
transaction_registration.amount.should == BigDecimal.new("12.34")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should accept an integer for the amount and convert it to a BigDecimal interally" do
|
26
|
+
transaction_registration = transaction_registration_factory(:amount => 12)
|
27
|
+
transaction_registration.should be_valid
|
28
|
+
transaction_registration.amount.should == BigDecimal.new("12")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should accept a string for the amount and convert it to a BigDecimal interally" do
|
32
|
+
transaction_registration = transaction_registration_factory(:amount => "12")
|
33
|
+
transaction_registration.should be_valid
|
34
|
+
transaction_registration.amount.should == BigDecimal.new("12")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "validations" do
|
39
|
+
it { validates_the_presence_of(:transaction_registration, :mode) }
|
40
|
+
it { validates_the_presence_of(:transaction_registration, :tx_type) }
|
41
|
+
it { validates_the_presence_of(:transaction_registration, :vendor) }
|
42
|
+
it { validates_the_presence_of(:transaction_registration, :vendor_tx_code) }
|
43
|
+
it { validates_the_presence_of(:transaction_registration, :amount) }
|
44
|
+
it { validates_the_presence_of(:transaction_registration, :currency) }
|
45
|
+
it { validates_the_presence_of(:transaction_registration, :description) }
|
46
|
+
it { validates_the_presence_of(:transaction_registration, :notification_url) }
|
47
|
+
it { validates_the_presence_of(:transaction_registration, :billing_address) }
|
48
|
+
it { validates_the_presence_of(:transaction_registration, :delivery_address) }
|
49
|
+
|
50
|
+
it { does_not_require_the_presence_of(:transaction_registration, :customer_email) }
|
51
|
+
it { does_not_require_the_presence_of(:transaction_registration, :basket) }
|
52
|
+
it { does_not_require_the_presence_of(:transaction_registration, :allow_gift_aid) }
|
53
|
+
it { does_not_require_the_presence_of(:transaction_registration, :apply_avs_cv2) }
|
54
|
+
it { does_not_require_the_presence_of(:transaction_registration, :apply_3d_secure) }
|
55
|
+
it { does_not_require_the_presence_of(:transaction_registration, :profile) }
|
56
|
+
it { does_not_require_the_presence_of(:transaction_registration, :billing_agreement) }
|
57
|
+
it { does_not_require_the_presence_of(:transaction_registration, :account_type) }
|
58
|
+
|
59
|
+
it { validates_the_length_of(:transaction_registration, :vendor, :max => 15) }
|
60
|
+
it { validates_the_length_of(:transaction_registration, :vendor_tx_code, :max => 40) }
|
61
|
+
it { validates_the_length_of(:transaction_registration, :currency, :exactly => 3) }
|
62
|
+
it { validates_the_length_of(:transaction_registration, :description, :max => 100) }
|
63
|
+
it { validates_the_length_of(:transaction_registration, :notification_url, :max => 255) }
|
64
|
+
it { validates_the_length_of(:transaction_registration, :notification_url, :max => 255) }
|
65
|
+
it { validates_the_length_of(:transaction_registration, :customer_email, :max => 255) }
|
66
|
+
it { validates_the_length_of(:transaction_registration, :basket, :max => 7500) }
|
67
|
+
|
68
|
+
it "should allow the amount to be a minimum of 0.01" do
|
69
|
+
transaction_registration = transaction_registration_factory(:amount => "0.01")
|
70
|
+
transaction_registration.should be_valid
|
71
|
+
|
72
|
+
transaction_registration = transaction_registration_factory(:amount => "0.00")
|
73
|
+
transaction_registration.should_not be_valid
|
74
|
+
transaction_registration.errors.on(:amount).should include("is less than the minimum value (0.01)")
|
75
|
+
|
76
|
+
transaction_registration = transaction_registration_factory(:amount => "-23")
|
77
|
+
transaction_registration.should_not be_valid
|
78
|
+
transaction_registration.errors.on(:amount).should include("is less than the minimum value (0.01)")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should allow the amount to be a maximum of 100,000.00" do
|
82
|
+
transaction_registration = transaction_registration_factory(:amount => "100000")
|
83
|
+
transaction_registration.should be_valid
|
84
|
+
|
85
|
+
transaction_registration = transaction_registration_factory(:amount => "100000.01")
|
86
|
+
transaction_registration.should_not be_valid
|
87
|
+
transaction_registration.errors.on(:amount).should include("is greater than the maximum value (100,000.00)")
|
88
|
+
|
89
|
+
transaction_registration = transaction_registration_factory(:amount => "123456")
|
90
|
+
transaction_registration.should_not be_valid
|
91
|
+
transaction_registration.errors.on(:amount).should include("is greater than the maximum value (100,000.00)")
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should allow the transaction type to be one of :payment, :deferred or :authenticate" do
|
95
|
+
transaction_registration = transaction_registration_factory(:tx_type => :payment)
|
96
|
+
transaction_registration.should be_valid
|
97
|
+
|
98
|
+
transaction_registration = transaction_registration_factory(:tx_type => :deferred)
|
99
|
+
transaction_registration.should be_valid
|
100
|
+
|
101
|
+
transaction_registration = transaction_registration_factory(:tx_type => :authenticate)
|
102
|
+
transaction_registration.should be_valid
|
103
|
+
|
104
|
+
transaction_registration = transaction_registration_factory(:tx_type => :chickens)
|
105
|
+
transaction_registration.should_not be_valid
|
106
|
+
transaction_registration.errors.on(:tx_type).should include("is not in the list")
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should allow the mode to be one of :simulator, :test or :live" do
|
110
|
+
transaction_registration = transaction_registration_factory(:mode => :simulator)
|
111
|
+
transaction_registration.should be_valid
|
112
|
+
|
113
|
+
transaction_registration = transaction_registration_factory(:mode => :test)
|
114
|
+
transaction_registration.should be_valid
|
115
|
+
|
116
|
+
transaction_registration = transaction_registration_factory(:mode => :live)
|
117
|
+
transaction_registration.should be_valid
|
118
|
+
|
119
|
+
transaction_registration = transaction_registration_factory(:mode => :chickens)
|
120
|
+
transaction_registration.should_not be_valid
|
121
|
+
transaction_registration.errors.on(:mode).should include("is not in the list")
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should allow the gift aid setting to be true or false" do
|
125
|
+
transaction_registration = transaction_registration_factory(:allow_gift_aid => true)
|
126
|
+
transaction_registration.should be_valid
|
127
|
+
|
128
|
+
transaction_registration = transaction_registration_factory(:allow_gift_aid => false)
|
129
|
+
transaction_registration.should be_valid
|
130
|
+
|
131
|
+
transaction_registration = transaction_registration_factory(:allow_gift_aid => "chickens")
|
132
|
+
transaction_registration.should_not be_valid
|
133
|
+
transaction_registration.errors.on(:allow_gift_aid).should include("is not in the list")
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should allow apply_avs_cv2 to be 0 through 3 (see docs for what that means)" do
|
137
|
+
transaction_registration = transaction_registration_factory(:apply_avs_cv2 => 0)
|
138
|
+
transaction_registration.should be_valid
|
139
|
+
|
140
|
+
transaction_registration = transaction_registration_factory(:apply_avs_cv2 => 1)
|
141
|
+
transaction_registration.should be_valid
|
142
|
+
|
143
|
+
transaction_registration = transaction_registration_factory(:apply_avs_cv2 => 2)
|
144
|
+
transaction_registration.should be_valid
|
145
|
+
|
146
|
+
transaction_registration = transaction_registration_factory(:apply_avs_cv2 => 3)
|
147
|
+
transaction_registration.should be_valid
|
148
|
+
|
149
|
+
transaction_registration = transaction_registration_factory(:apply_avs_cv2 => 4)
|
150
|
+
transaction_registration.should_not be_valid
|
151
|
+
transaction_registration.errors.on(:apply_avs_cv2).should include("is not in the list")
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should allow apply_3d_secure to be 0 through 3 (see docs for what that means)" do
|
155
|
+
transaction_registration = transaction_registration_factory(:apply_3d_secure => 0)
|
156
|
+
transaction_registration.should be_valid
|
157
|
+
|
158
|
+
transaction_registration = transaction_registration_factory(:apply_3d_secure => 1)
|
159
|
+
transaction_registration.should be_valid
|
160
|
+
|
161
|
+
transaction_registration = transaction_registration_factory(:apply_3d_secure => 2)
|
162
|
+
transaction_registration.should be_valid
|
163
|
+
|
164
|
+
transaction_registration = transaction_registration_factory(:apply_3d_secure => 3)
|
165
|
+
transaction_registration.should be_valid
|
166
|
+
|
167
|
+
transaction_registration = transaction_registration_factory(:apply_3d_secure => 4)
|
168
|
+
transaction_registration.should_not be_valid
|
169
|
+
transaction_registration.errors.on(:apply_3d_secure).should include("is not in the list")
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should allow profile to be normal or low" do
|
173
|
+
transaction_registration = transaction_registration_factory(:profile => :normal)
|
174
|
+
transaction_registration.should be_valid
|
175
|
+
|
176
|
+
transaction_registration = transaction_registration_factory(:profile => :low)
|
177
|
+
transaction_registration.should be_valid
|
178
|
+
|
179
|
+
transaction_registration = transaction_registration_factory(:profile => :chickens)
|
180
|
+
transaction_registration.should_not be_valid
|
181
|
+
transaction_registration.errors.on(:profile).should include("is not in the list")
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should allow billing_agreement to be true or false" do
|
185
|
+
transaction_registration = transaction_registration_factory(:billing_agreement => true)
|
186
|
+
transaction_registration.should be_valid
|
187
|
+
|
188
|
+
transaction_registration = transaction_registration_factory(:billing_agreement => false)
|
189
|
+
transaction_registration.should be_valid
|
190
|
+
|
191
|
+
transaction_registration = transaction_registration_factory(:billing_agreement => "chickens")
|
192
|
+
transaction_registration.should_not be_valid
|
193
|
+
transaction_registration.errors.on(:billing_agreement).should include("is not in the list")
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should allow the account type to be one of ecommerce, continuous authority or mail order" do
|
197
|
+
transaction_registration = transaction_registration_factory(:account_type => :ecommerce)
|
198
|
+
transaction_registration.should be_valid
|
199
|
+
|
200
|
+
transaction_registration = transaction_registration_factory(:account_type => :continuous_authority)
|
201
|
+
transaction_registration.should be_valid
|
202
|
+
|
203
|
+
transaction_registration = transaction_registration_factory(:account_type => :mail_order)
|
204
|
+
transaction_registration.should be_valid
|
205
|
+
|
206
|
+
transaction_registration = transaction_registration_factory(:account_type => :chickens)
|
207
|
+
transaction_registration.should_not be_valid
|
208
|
+
transaction_registration.errors.on(:account_type).should include("is not in the list")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe "url generation" do
|
213
|
+
it "should pick the correct url for the simulator mode" do
|
214
|
+
transaction_registration = transaction_registration_factory(:mode => :simulator)
|
215
|
+
transaction_registration.url.should == "https://test.sagepay.com/simulator/VSPServerGateway.asp?Service=VendorRegisterTx"
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should pick the correct url for the test mode" do
|
219
|
+
transaction_registration = transaction_registration_factory(:mode => :test)
|
220
|
+
transaction_registration.url.should == "https://test.sagepay.com/gateway/service/vspserver-register.vsp"
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should pick the correct url for the live mode" do
|
224
|
+
transaction_registration = transaction_registration_factory(:mode => :live)
|
225
|
+
transaction_registration.url.should == "https://live.sagepay.com/gateway/service/vspserver-register.vsp"
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should raise an error if the mode has been set to something dodgy" do
|
229
|
+
lambda {
|
230
|
+
transaction_registration = transaction_registration_factory(:mode => :dead_chickens)
|
231
|
+
transaction_registration.url
|
232
|
+
}.should raise_error(ArgumentError, "Invalid transaction mode")
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe "post params generation" do
|
237
|
+
context "given one or more invalid parameters" do
|
238
|
+
it "should raise an error when trying to generate the URL" do
|
239
|
+
transaction_registration = transaction_registration_factory(:tx_type => :invalid)
|
240
|
+
lambda { transaction_registration.post_params }.should raise_error(ArgumentError, "Invalid transaction registration options (see errors hash for details)")
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context "given the minimum set of required parameters" do
|
245
|
+
before(:each) do
|
246
|
+
billing_address = address_factory(
|
247
|
+
:first_names => "Billing First",
|
248
|
+
:surname => "Billing Surname",
|
249
|
+
:address_1 => "Billing Address 1",
|
250
|
+
:city => "Billing City",
|
251
|
+
:post_code => "BI11 1NG",
|
252
|
+
:country => "GB"
|
253
|
+
)
|
254
|
+
|
255
|
+
delivery_address = address_factory(
|
256
|
+
:first_names => "Delivery First",
|
257
|
+
:surname => "Delivery Surname",
|
258
|
+
:address_1 => "Delivery Address 1",
|
259
|
+
:city => "Delivery City",
|
260
|
+
:post_code => "DE11 3RY",
|
261
|
+
:country => "GB"
|
262
|
+
)
|
263
|
+
|
264
|
+
@transaction_registration = transaction_registration_factory(
|
265
|
+
:mode => :simulator,
|
266
|
+
:tx_type => :payment,
|
267
|
+
:vendor => "vendorname",
|
268
|
+
:vendor_tx_code => "unique-tx-code",
|
269
|
+
:amount => 57.93,
|
270
|
+
:currency => "GBP",
|
271
|
+
:description => "A sample transaction",
|
272
|
+
:notification_url => "http://test.host/sample/notification",
|
273
|
+
:billing_address => billing_address,
|
274
|
+
:delivery_address => delivery_address
|
275
|
+
)
|
276
|
+
end
|
277
|
+
|
278
|
+
describe "the posted params" do
|
279
|
+
it "should contain the transaction type" do
|
280
|
+
@transaction_registration.post_params["TxType"].should == "PAYMENT"
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should contain the vendor" do
|
284
|
+
@transaction_registration.post_params["Vendor"].should == "vendorname"
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should contain the vendor tx code" do
|
288
|
+
@transaction_registration.post_params["VendorTxCode"].should == "unique-tx-code"
|
289
|
+
end
|
290
|
+
|
291
|
+
it "should contain the amount" do
|
292
|
+
@transaction_registration.post_params["Amount"].should == "57.93"
|
293
|
+
end
|
294
|
+
|
295
|
+
it "should contain the currency" do
|
296
|
+
@transaction_registration.post_params["Currency"].should == "GBP"
|
297
|
+
end
|
298
|
+
|
299
|
+
it "should contain the description" do
|
300
|
+
@transaction_registration.post_params["Description"].should == "A sample transaction"
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should contain the notification URL" do
|
304
|
+
@transaction_registration.post_params["NotificationURL"].should == "http://test.host/sample/notification"
|
305
|
+
end
|
306
|
+
|
307
|
+
it "should contain the billing surname" do
|
308
|
+
@transaction_registration.post_params["BillingSurname"].should == "Billing Surname"
|
309
|
+
end
|
310
|
+
|
311
|
+
it "should contain the billing first names" do
|
312
|
+
@transaction_registration.post_params["BillingFirstnames"].should == "Billing First"
|
313
|
+
end
|
314
|
+
|
315
|
+
it "should contain the billing address 1" do
|
316
|
+
@transaction_registration.post_params["BillingAddress1"].should == "Billing Address 1"
|
317
|
+
end
|
318
|
+
|
319
|
+
it "should contain the billing city" do
|
320
|
+
@transaction_registration.post_params["BillingCity"].should == "Billing City"
|
321
|
+
end
|
322
|
+
|
323
|
+
it "should contain the billing post code" do
|
324
|
+
@transaction_registration.post_params["BillingPostCode"].should == "BI11 1NG"
|
325
|
+
end
|
326
|
+
|
327
|
+
it "should contain the billing country" do
|
328
|
+
@transaction_registration.post_params["BillingCountry"].should == "GB"
|
329
|
+
end
|
330
|
+
|
331
|
+
it "should contain the delivery surname" do
|
332
|
+
@transaction_registration.post_params["DeliverySurname"].should == "Delivery Surname"
|
333
|
+
end
|
334
|
+
|
335
|
+
it "should contain the delivery first names" do
|
336
|
+
@transaction_registration.post_params["DeliveryFirstnames"].should == "Delivery First"
|
337
|
+
end
|
338
|
+
|
339
|
+
it "should contain the delivery address 1" do
|
340
|
+
@transaction_registration.post_params["DeliveryAddress1"].should == "Delivery Address 1"
|
341
|
+
end
|
342
|
+
|
343
|
+
it "should contain the delivery city" do
|
344
|
+
@transaction_registration.post_params["DeliveryCity"].should == "Delivery City"
|
345
|
+
end
|
346
|
+
|
347
|
+
it "should contain the delivery post code" do
|
348
|
+
@transaction_registration.post_params["DeliveryPostCode"].should == "DE11 3RY"
|
349
|
+
end
|
350
|
+
|
351
|
+
it "should contain the delivery country" do
|
352
|
+
@transaction_registration.post_params["DeliveryCountry"].should == "GB"
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
context "with each of the optional parameters" do
|
357
|
+
it "should contain the billing address 2 only if supplied" do
|
358
|
+
transaction_registration = transaction_registration_factory
|
359
|
+
transaction_registration.post_params.keys.should_not include('BillingAddress2')
|
360
|
+
|
361
|
+
transaction_registration.billing_address.address_2 = "Some Area"
|
362
|
+
transaction_registration.post_params['BillingAddress2'].should == "Some Area"
|
363
|
+
end
|
364
|
+
|
365
|
+
it "should contain the billing state only if supplied" do
|
366
|
+
transaction_registration = transaction_registration_factory
|
367
|
+
transaction_registration.post_params.keys.should_not include('BillingState')
|
368
|
+
|
369
|
+
transaction_registration.billing_address.state = "KY"
|
370
|
+
transaction_registration.post_params['BillingState'].should == "KY"
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should contain the billing phone only if supplied" do
|
374
|
+
transaction_registration = transaction_registration_factory
|
375
|
+
transaction_registration.post_params.keys.should_not include('BillingPhone')
|
376
|
+
|
377
|
+
transaction_registration.billing_address.phone = "0123456789"
|
378
|
+
transaction_registration.post_params['BillingPhone'].should == "0123456789"
|
379
|
+
end
|
380
|
+
|
381
|
+
it "should contain the delivery address 2 only if supplied" do
|
382
|
+
transaction_registration = transaction_registration_factory
|
383
|
+
transaction_registration.post_params.keys.should_not include('DeliveryAddress2')
|
384
|
+
|
385
|
+
transaction_registration.delivery_address.address_2 = "Some Area"
|
386
|
+
transaction_registration.post_params['DeliveryAddress2'].should == "Some Area"
|
387
|
+
end
|
388
|
+
|
389
|
+
it "should contain the delivery state only if supplied" do
|
390
|
+
transaction_registration = transaction_registration_factory
|
391
|
+
transaction_registration.post_params.keys.should_not include('DeliveryState')
|
392
|
+
|
393
|
+
transaction_registration.delivery_address.state = "KY"
|
394
|
+
transaction_registration.post_params['DeliveryState'].should == "KY"
|
395
|
+
end
|
396
|
+
|
397
|
+
it "should contain the delivery phone only if supplied" do
|
398
|
+
transaction_registration = transaction_registration_factory
|
399
|
+
transaction_registration.post_params.keys.should_not include('DeliveryPhone')
|
400
|
+
|
401
|
+
transaction_registration.delivery_address.phone = "0123456789"
|
402
|
+
transaction_registration.post_params['DeliveryPhone'].should == "0123456789"
|
403
|
+
end
|
404
|
+
|
405
|
+
it "should contain the customer email only if supplied" do
|
406
|
+
transaction_registration = transaction_registration_factory
|
407
|
+
transaction_registration.post_params.keys.should_not include('CustomerEmail')
|
408
|
+
|
409
|
+
transaction_registration.customer_email = "jimbob@example.com"
|
410
|
+
transaction_registration.post_params['CustomerEmail'].should == "jimbob@example.com"
|
411
|
+
end
|
412
|
+
|
413
|
+
it "should contain the basket only if supplied" do
|
414
|
+
transaction_registration = transaction_registration_factory
|
415
|
+
transaction_registration.post_params.keys.should_not include('Basket')
|
416
|
+
|
417
|
+
transaction_registration.basket = "Sample basket"
|
418
|
+
transaction_registration.post_params['Basket'].should == "Sample basket"
|
419
|
+
end
|
420
|
+
|
421
|
+
it "should contain allow_gift_aid only if supplied" do
|
422
|
+
transaction_registration = transaction_registration_factory
|
423
|
+
transaction_registration.post_params.keys.should_not include('AllowGiftAid')
|
424
|
+
|
425
|
+
transaction_registration.allow_gift_aid = true
|
426
|
+
transaction_registration.post_params['AllowGiftAid'].should == "1"
|
427
|
+
|
428
|
+
transaction_registration.allow_gift_aid = false
|
429
|
+
transaction_registration.post_params['AllowGiftAid'].should == "0"
|
430
|
+
end
|
431
|
+
|
432
|
+
it "should contain apply_avs_cv2 only if supplied" do
|
433
|
+
transaction_registration = transaction_registration_factory
|
434
|
+
transaction_registration.post_params.keys.should_not include('ApplyAVSCV2')
|
435
|
+
|
436
|
+
transaction_registration.apply_avs_cv2 = 0
|
437
|
+
transaction_registration.post_params['ApplyAVSCV2'].should == "0"
|
438
|
+
|
439
|
+
transaction_registration.apply_avs_cv2 = 1
|
440
|
+
transaction_registration.post_params['ApplyAVSCV2'].should == "1"
|
441
|
+
|
442
|
+
transaction_registration.apply_avs_cv2 = 2
|
443
|
+
transaction_registration.post_params['ApplyAVSCV2'].should == "2"
|
444
|
+
|
445
|
+
transaction_registration.apply_avs_cv2 = 3
|
446
|
+
transaction_registration.post_params['ApplyAVSCV2'].should == "3"
|
447
|
+
end
|
448
|
+
|
449
|
+
it "should contain apply_3d_secure only if supplied" do
|
450
|
+
transaction_registration = transaction_registration_factory
|
451
|
+
transaction_registration.post_params.keys.should_not include('ApplyAVSCV2')
|
452
|
+
|
453
|
+
transaction_registration.apply_3d_secure = 0
|
454
|
+
transaction_registration.post_params['Apply3DSecure'].should == "0"
|
455
|
+
|
456
|
+
transaction_registration.apply_3d_secure = 1
|
457
|
+
transaction_registration.post_params['Apply3DSecure'].should == "1"
|
458
|
+
|
459
|
+
transaction_registration.apply_3d_secure = 2
|
460
|
+
transaction_registration.post_params['Apply3DSecure'].should == "2"
|
461
|
+
|
462
|
+
transaction_registration.apply_3d_secure = 3
|
463
|
+
transaction_registration.post_params['Apply3DSecure'].should == "3"
|
464
|
+
end
|
465
|
+
|
466
|
+
it "should contain profile only if supplied" do
|
467
|
+
transaction_registration = transaction_registration_factory
|
468
|
+
transaction_registration.post_params.keys.should_not include('Profile')
|
469
|
+
|
470
|
+
transaction_registration.profile = :normal
|
471
|
+
transaction_registration.post_params['Profile'].should == "NORMAL"
|
472
|
+
|
473
|
+
transaction_registration.profile = :low
|
474
|
+
transaction_registration.post_params['Profile'].should == "LOW"
|
475
|
+
end
|
476
|
+
|
477
|
+
it "should contain billing_agreement only if supplied" do
|
478
|
+
transaction_registration = transaction_registration_factory
|
479
|
+
transaction_registration.post_params.keys.should_not include('BillingAgreement')
|
480
|
+
|
481
|
+
transaction_registration.billing_agreement = true
|
482
|
+
transaction_registration.post_params['BillingAgreement'].should == "1"
|
483
|
+
|
484
|
+
transaction_registration.billing_agreement = false
|
485
|
+
transaction_registration.post_params['BillingAgreement'].should == "0"
|
486
|
+
end
|
487
|
+
|
488
|
+
it "should contain account type only if supplied" do
|
489
|
+
transaction_registration = transaction_registration_factory
|
490
|
+
transaction_registration.post_params.keys.should_not include('AccountType')
|
491
|
+
|
492
|
+
transaction_registration.account_type = :ecommerce
|
493
|
+
transaction_registration.post_params['AccountType'].should == "E"
|
494
|
+
|
495
|
+
transaction_registration.account_type = :continuous_authority
|
496
|
+
transaction_registration.post_params['AccountType'].should == "C"
|
497
|
+
|
498
|
+
transaction_registration.account_type = :mail_order
|
499
|
+
transaction_registration.post_params['AccountType'].should == "M"
|
500
|
+
end
|
501
|
+
end
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
describe "#register!" do
|
506
|
+
context "if SagePay is having a bad day" do
|
507
|
+
before(:each) do
|
508
|
+
@transaction_registration = transaction_registration_factory
|
509
|
+
@transaction_registration.stub(:post).and_return(mock("HTTP Response", :code => "500"))
|
510
|
+
end
|
511
|
+
|
512
|
+
it "should raise an exception to say that we couldn't talk to SagePay" do
|
513
|
+
lambda {
|
514
|
+
@transaction_registration.register!
|
515
|
+
}.should raise_error RuntimeError, "I guess SagePay doesn't like us today."
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
context "when SagePay can return a useful response" do
|
520
|
+
before(:each) do
|
521
|
+
@mock_http_response = mock("HTTP response", :code => "200", :body => "mock response body")
|
522
|
+
@mock_response = mock("Transaction registration response")
|
523
|
+
@transaction_registration = transaction_registration_factory
|
524
|
+
@transaction_registration.stub(:post).and_return(@mock_http_response)
|
525
|
+
TransactionRegistrationResponse.stub(:from_response_body).and_return @mock_response
|
526
|
+
end
|
527
|
+
|
528
|
+
it "should return a newly created TransactionRegistrationResponse with the response" do
|
529
|
+
response = @transaction_registration.register!
|
530
|
+
response.should == @mock_response
|
531
|
+
end
|
532
|
+
|
533
|
+
it "should pass the response body to TransactionRegistrationResponse.from_response_body to let it parse and initialize" do
|
534
|
+
TransactionRegistrationResponse.should_receive(:from_response_body).with("mock response body")
|
535
|
+
@transaction_registration.register!
|
536
|
+
end
|
537
|
+
|
538
|
+
it "should post the request to SagePay" do
|
539
|
+
@transaction_registration.should_receive(:post)
|
540
|
+
@transaction_registration.register!
|
541
|
+
end
|
542
|
+
|
543
|
+
it "should not allow us to attempt to register twice with the same vendor transaction code" do
|
544
|
+
@transaction_registration.register!
|
545
|
+
lambda {
|
546
|
+
@transaction_registration.register!
|
547
|
+
}.should raise_error(RuntimeError, "This vendor transaction code has already been registered")
|
548
|
+
end
|
549
|
+
|
550
|
+
it "should allow us to register twice if we change the vendor transaction code in between times" do
|
551
|
+
@transaction_registration.register!
|
552
|
+
lambda {
|
553
|
+
@transaction_registration.vendor_tx_code = TransactionCode.random
|
554
|
+
@transaction_registration.register!.should == @mock_response
|
555
|
+
}.should_not raise_error(RuntimeError, "This vendor transaction code has already been registered")
|
556
|
+
end
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
describe "#signature_verification_details" do
|
561
|
+
before(:each) do
|
562
|
+
mock_response = mock("Transaction registration response", :vps_tx_id => "sage pay transaction id", :security_key => 'security key')
|
563
|
+
|
564
|
+
@transaction_registration = transaction_registration_factory :vendor_tx_code => "vendor transaction id", :vendor => "vendor"
|
565
|
+
@transaction_registration.stub(:handle_response).and_return(mock_response)
|
566
|
+
@transaction_registration.stub(:post)
|
567
|
+
end
|
568
|
+
|
569
|
+
context "before registering a transaction" do
|
570
|
+
it "should raise an error" do
|
571
|
+
lambda {
|
572
|
+
@transaction_registration.signature_verification_details
|
573
|
+
}.should raise_error(RuntimeError, "Transaction not yet registered")
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
577
|
+
context "with a transaction which failed" do
|
578
|
+
before(:each) do
|
579
|
+
mock_response = mock("Transaction registration response", :failed? => true)
|
580
|
+
@transaction_registration.stub(:handle_response).and_return(mock_response)
|
581
|
+
@transaction_registration.register!
|
582
|
+
end
|
583
|
+
|
584
|
+
it "should raise an error" do
|
585
|
+
lambda {
|
586
|
+
@transaction_registration.signature_verification_details
|
587
|
+
}.should raise_error(RuntimeError, "Transaction registration failed")
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
context "with a good transaction" do
|
592
|
+
before(:each) do
|
593
|
+
mock_response = mock("Transaction registration response", :failed? => false, :vps_tx_id => "sage pay transaction id", :security_key => 'security key')
|
594
|
+
@transaction_registration.stub(:handle_response).and_return(mock_response)
|
595
|
+
@transaction_registration.register!
|
596
|
+
end
|
597
|
+
|
598
|
+
it "should know the SagePay transaction id" do
|
599
|
+
sig_details = @transaction_registration.signature_verification_details
|
600
|
+
sig_details.vps_tx_id.should == "sage pay transaction id"
|
601
|
+
end
|
602
|
+
|
603
|
+
it "should know the vendor transaction id" do
|
604
|
+
sig_details = @transaction_registration.signature_verification_details
|
605
|
+
sig_details.vendor_tx_code.should == "vendor transaction id"
|
606
|
+
end
|
607
|
+
|
608
|
+
it "should know the vendor" do
|
609
|
+
sig_details = @transaction_registration.signature_verification_details
|
610
|
+
sig_details.vendor.should == "vendor"
|
611
|
+
end
|
612
|
+
|
613
|
+
it "should know the security key" do
|
614
|
+
sig_details = @transaction_registration.signature_verification_details
|
615
|
+
sig_details.security_key.should == "security key"
|
616
|
+
end
|
617
|
+
end
|
618
|
+
end
|
619
|
+
end
|