vizjerai-google-checkout 0.3.0 → 0.4.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/.gitignore +1 -0
- data/{History.txt → CHANGELOG.md} +14 -1
- data/lib/google-checkout.rb +0 -5
- data/lib/google-checkout/cart.rb +28 -17
- data/lib/google-checkout/command.rb +2 -2
- data/lib/google-checkout/notification.rb +19 -7
- data/lib/google-checkout/version.rb +1 -3
- data/spec/google-checkout/cart_spec.rb +77 -19
- data/spec/google-checkout/command_spec.rb +2 -2
- data/spec/google-checkout/notification_spec.rb +17 -3
- data/spec/support/shared_example_groups/basic_notification.rb +1 -0
- metadata +4 -4
data/.gitignore
CHANGED
@@ -1,4 +1,17 @@
|
|
1
|
-
|
1
|
+
## 0.4.0 / 2012-07-27
|
2
|
+
|
3
|
+
### New Features
|
4
|
+
- Allow cart contents to be read.
|
5
|
+
|
6
|
+
### Bug Fix
|
7
|
+
- Fix not knowing if it was a google error or one caused by the gem.
|
8
|
+
|
9
|
+
## 0.3.0 / 2012-07-27
|
10
|
+
|
11
|
+
### Bug Fix
|
12
|
+
- Changed Command.post to always return a Notification instead of raising an error.
|
13
|
+
|
14
|
+
## 0.2.0 / 2007-08-14
|
2
15
|
|
3
16
|
* Significant rewrite!
|
4
17
|
* Added rSpec specifications.
|
data/lib/google-checkout.rb
CHANGED
@@ -4,11 +4,6 @@
|
|
4
4
|
# https://sandbox.google.com/checkout/cws/v2/Merchant/MERCHANT_ID/merchantCheckout
|
5
5
|
# https://checkout.google.com/cws/v2/Merchant/MERCHANT_ID/merchantCheckout
|
6
6
|
|
7
|
-
$: << File.dirname(__FILE__)
|
8
|
-
$: << File.dirname(__FILE__) + "/vendor/ruby-hmac/lib"
|
9
|
-
|
10
|
-
require 'google-checkout/version'
|
11
|
-
|
12
7
|
require 'active_support'
|
13
8
|
|
14
9
|
require 'openssl'
|
data/lib/google-checkout/cart.rb
CHANGED
@@ -62,15 +62,13 @@ module GoogleCheckout
|
|
62
62
|
# Beware using symbols as values. They may be set as sub-keys instead of values,
|
63
63
|
# so use a String or other datatype.
|
64
64
|
|
65
|
-
attr_accessor :merchant_private_data
|
66
|
-
|
67
65
|
attr_accessor :edit_cart_url
|
68
66
|
attr_accessor :continue_shopping_url
|
69
67
|
|
70
68
|
attr_accessor :merchant_calculations_url
|
71
|
-
|
69
|
+
attr_writer :parameterized_urls
|
72
70
|
|
73
|
-
|
71
|
+
attr_writer :shipping_methods
|
74
72
|
|
75
73
|
# The default options for drawing in the button that are filled in when
|
76
74
|
# checkout_button or button_url is called.
|
@@ -87,14 +85,19 @@ module GoogleCheckout
|
|
87
85
|
# or more items to put inside the cart.
|
88
86
|
def initialize(merchant_id, merchant_key, *items)
|
89
87
|
super(merchant_id, merchant_key)
|
90
|
-
@contents = []
|
91
|
-
@merchant_private_data = ''
|
92
|
-
@shipping_methods = []
|
93
88
|
items.each { |i| add_item i }
|
94
89
|
end
|
95
90
|
|
96
91
|
def empty?
|
97
|
-
|
92
|
+
contents.empty?
|
93
|
+
end
|
94
|
+
|
95
|
+
def contents
|
96
|
+
@contents ||= []
|
97
|
+
end
|
98
|
+
|
99
|
+
def merchant_private_data
|
100
|
+
@merchant_private_data ||= ''
|
98
101
|
end
|
99
102
|
|
100
103
|
def merchant_private_data=(value)
|
@@ -109,9 +112,17 @@ module GoogleCheckout
|
|
109
112
|
end
|
110
113
|
end
|
111
114
|
|
115
|
+
def parameterized_urls
|
116
|
+
@parameterized_urls ||= []
|
117
|
+
end
|
118
|
+
|
119
|
+
def shipping_methods
|
120
|
+
@shipping_methods ||= []
|
121
|
+
end
|
122
|
+
|
112
123
|
# Number of items in the cart.
|
113
124
|
def size
|
114
|
-
|
125
|
+
contents.size
|
115
126
|
end
|
116
127
|
|
117
128
|
def submit_domain
|
@@ -169,7 +180,7 @@ module GoogleCheckout
|
|
169
180
|
"Required keys missing: #{missing_keys.inspect}"
|
170
181
|
end
|
171
182
|
|
172
|
-
|
183
|
+
contents << { :quantity => 1, :currency => 'USD' }.merge(item)
|
173
184
|
item
|
174
185
|
end
|
175
186
|
|
@@ -186,7 +197,7 @@ module GoogleCheckout
|
|
186
197
|
@xml = xml.tag!('checkout-shopping-cart', :xmlns => "http://checkout.google.com/schema/2") {
|
187
198
|
xml.tag!("shopping-cart") {
|
188
199
|
xml.items {
|
189
|
-
|
200
|
+
contents.each { |item|
|
190
201
|
xml.item {
|
191
202
|
if item.key?(:item_id)
|
192
203
|
xml.tag!('merchant-item-id', item[:item_id])
|
@@ -268,9 +279,9 @@ module GoogleCheckout
|
|
268
279
|
}
|
269
280
|
}
|
270
281
|
}
|
271
|
-
unless
|
282
|
+
unless merchant_private_data.empty?
|
272
283
|
xml.tag!("merchant-private-data") {
|
273
|
-
xml <<
|
284
|
+
xml << merchant_private_data
|
274
285
|
}
|
275
286
|
end
|
276
287
|
}
|
@@ -288,7 +299,7 @@ module GoogleCheckout
|
|
288
299
|
# TODO tax-tables
|
289
300
|
|
290
301
|
xml.tag!('parameterized-urls') {
|
291
|
-
|
302
|
+
parameterized_urls.each do |param_url|
|
292
303
|
xml.tag!('parameterized-url', :url => param_url[:url]) {
|
293
304
|
next if param_url[:parameters].nil?
|
294
305
|
next if param_url[:parameters].empty?
|
@@ -299,10 +310,10 @@ module GoogleCheckout
|
|
299
310
|
}
|
300
311
|
}
|
301
312
|
end
|
302
|
-
} unless
|
313
|
+
} unless parameterized_urls.empty?
|
303
314
|
|
304
315
|
xml.tag!('shipping-methods') {
|
305
|
-
|
316
|
+
shipping_methods.each do |shipping_method|
|
306
317
|
xml << shipping_method.to_xml
|
307
318
|
end
|
308
319
|
}
|
@@ -368,7 +379,7 @@ module GoogleCheckout
|
|
368
379
|
|
369
380
|
def button_url(opts = {})
|
370
381
|
opts = DefaultButtonOpts.merge opts
|
371
|
-
opts[:buy_or_checkout] ||=
|
382
|
+
opts[:buy_or_checkout] ||= contents.size > 1 ? :checkout : :buy_now
|
372
383
|
opts.merge! ButtonSizes[opts[:buy_or_checkout]][opts[:size]]
|
373
384
|
bname = opts[:buy_or_checkout] == :buy_now ? 'buy.gif' : 'checkout.gif'
|
374
385
|
opts.delete :size
|
@@ -61,9 +61,9 @@ module GoogleCheckout
|
|
61
61
|
when Net::HTTPSuccess, Net::HTTPClientError
|
62
62
|
Notification.parse(response.body)
|
63
63
|
when Net::HTTPRedirection, Net::HTTPServerError, Net::HTTPInformation
|
64
|
-
|
64
|
+
ApiError.new("Unexpected response code (#{response.class}): #{response.code} - #{response.message}")
|
65
65
|
else
|
66
|
-
|
66
|
+
ApiError.new("Unknown response code: #{response.code} - #{response.message}")
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
@@ -353,18 +353,30 @@ module GoogleCheckout
|
|
353
353
|
|
354
354
|
class Error < Notification
|
355
355
|
|
356
|
-
|
357
|
-
|
358
|
-
super(doc)
|
359
|
-
end
|
356
|
+
##
|
357
|
+
# Alias for +_error_message+
|
360
358
|
|
361
|
-
def
|
362
|
-
|
359
|
+
def message
|
360
|
+
(doc/'error-message').inner_html
|
363
361
|
end
|
364
|
-
alias :message :error_message
|
365
362
|
|
366
363
|
end
|
367
364
|
|
368
365
|
class RequestReceived < Notification; end
|
369
366
|
|
367
|
+
class ApiError < Notification
|
368
|
+
attr_reader :error_message
|
369
|
+
|
370
|
+
def initialize(message='')
|
371
|
+
@error_message = message
|
372
|
+
end
|
373
|
+
|
374
|
+
def error?
|
375
|
+
true
|
376
|
+
end
|
377
|
+
|
378
|
+
alias :message :error_message
|
379
|
+
|
380
|
+
end
|
381
|
+
|
370
382
|
end
|
@@ -1,38 +1,96 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe GoogleCheckout, "Cart (generic)" do
|
4
|
+
let(:item) { {:name => "PeepCode Screencast", :description => "A few screencasts", :price => 9.00} }
|
4
5
|
|
5
|
-
before
|
6
|
-
@cart = GoogleCheckout::Cart.new("my_id", "my_key",
|
7
|
-
:name => "PeepCode Screencast",
|
8
|
-
:description => "A few screencasts",
|
9
|
-
:price => 9.00
|
10
|
-
})
|
11
|
-
GoogleCheckout.use_sandbox
|
6
|
+
before do
|
7
|
+
@cart = GoogleCheckout::Cart.new("my_id", "my_key", item)
|
12
8
|
end
|
13
9
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
context 'when using production' do
|
11
|
+
before do
|
12
|
+
GoogleCheckout.use_production
|
13
|
+
end
|
18
14
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
it "should generate proper live buy button_url" do
|
16
|
+
@cart.button_url.should match(%r{http://checkout\.google\.com/buttons/buy\.gif})
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should generate proper live checkout button_url" do
|
20
|
+
@cart.button_url(:buy_or_checkout => :checkout).should match(%r{http://checkout\.google\.com/buttons/checkout\.gif})
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
23
|
+
it "should generate proper live checkout button url with https" do
|
24
|
+
@cart.button_url(:buy_or_checkout => :checkout, :https => true).should match(%r{https://checkout\.google\.com/buttons/checkout\.gif})
|
25
|
+
end
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
context 'when using sandbox' do
|
29
|
+
before do
|
30
|
+
GoogleCheckout.use_sandbox
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should generate proper sandbox buy button_url" do
|
34
|
+
@cart.button_url.should match(%r{http://sandbox\.google\.com/checkout/buttons/buy\.gif})
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should generate proper sandbox checkout button_url" do
|
38
|
+
@cart.button_url(:buy_or_checkout => :checkout).should match(%r{http://sandbox\.google\.com/checkout/buttons/checkout\.gif})
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should generate proper sandbox checkout button url with https" do
|
42
|
+
@cart.button_url(:buy_or_checkout => :checkout, :https => true).should match(%r{https://sandbox\.google\.com/checkout/buttons/checkout\.gif})
|
43
|
+
end
|
30
44
|
end
|
31
45
|
|
32
46
|
it "should generate checkout button" do
|
33
47
|
@cart.checkout_button.should match(/buy\.gif/)
|
34
48
|
end
|
35
49
|
|
50
|
+
describe '.contents' do
|
51
|
+
subject { @cart.contents }
|
52
|
+
it { should == [{:quantity => 1, :currency => 'USD'}.merge(item)] }
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '.merchant_private_data' do
|
56
|
+
subject { @cart.merchant_private_data }
|
57
|
+
it { should == '' }
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '.parameterized_urls' do
|
61
|
+
subject { @cart.parameterized_urls }
|
62
|
+
it { should == [] }
|
63
|
+
|
64
|
+
context 'with parameterized urls' do
|
65
|
+
let(:param_urls) { [{:url => 'http://checkout.google.com'}] }
|
66
|
+
before { @cart.parameterized_urls = param_urls }
|
67
|
+
it { should == param_urls }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '.shipping_methods' do
|
72
|
+
subject { @cart.shipping_methods }
|
73
|
+
it { should == [] }
|
74
|
+
|
75
|
+
context 'with flat rate' do
|
76
|
+
let(:shipping_method) { GoogleCheckout::Shipping::FlatRate.new('FedEx', 1234) }
|
77
|
+
before { @cart.shipping_methods = [shipping_method] }
|
78
|
+
it { should == [shipping_method] }
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'with merchant calculated' do
|
82
|
+
let(:shipping_method) { GoogleCheckout::Shipping::MerchantCalculated.new('FedEx Ground', 1234) }
|
83
|
+
before { @cart.shipping_methods = [shipping_method] }
|
84
|
+
it { should == [shipping_method] }
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'with pickup' do
|
88
|
+
let(:shipping_method) { GoogleCheckout::Shipping::Pickup.new('Pickup', 1234) }
|
89
|
+
before { @cart.shipping_methods = [shipping_method] }
|
90
|
+
it { should == [shipping_method] }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
36
94
|
end
|
37
95
|
|
38
96
|
describe GoogleCheckout, "Cart Post" do
|
@@ -114,7 +114,7 @@ describe GoogleCheckout, "Charge Order" do
|
|
114
114
|
|
115
115
|
it "return error" do
|
116
116
|
response = @order.post
|
117
|
-
response.should be_kind_of(GoogleCheckout::
|
117
|
+
response.should be_kind_of(GoogleCheckout::ApiError)
|
118
118
|
response.should be_error
|
119
119
|
response.serial_number.should be_nil
|
120
120
|
response.message.should == 'Unexpected response code (Net::HTTPRedirection): 301 - Redirect'
|
@@ -132,7 +132,7 @@ describe GoogleCheckout, "Charge Order" do
|
|
132
132
|
|
133
133
|
it "return error" do
|
134
134
|
response = @order.post
|
135
|
-
response.should be_kind_of(GoogleCheckout::
|
135
|
+
response.should be_kind_of(GoogleCheckout::ApiError)
|
136
136
|
response.should be_error
|
137
137
|
response.serial_number.should be_nil
|
138
138
|
response.message.should == 'Unknown response code: 600 - Unknown Response'
|
@@ -257,9 +257,6 @@ end
|
|
257
257
|
|
258
258
|
describe GoogleCheckout, "Error Notification" do
|
259
259
|
let(:notification) { GoogleCheckout::Notification.parse(read_xml_fixture('responses/error')) }
|
260
|
-
before do
|
261
|
-
@notification = notification
|
262
|
-
end
|
263
260
|
|
264
261
|
it "should identify type of notication" do
|
265
262
|
notification.should be_kind_of GoogleCheckout::Error
|
@@ -274,3 +271,20 @@ describe GoogleCheckout, "Error Notification" do
|
|
274
271
|
end
|
275
272
|
|
276
273
|
end
|
274
|
+
|
275
|
+
describe GoogleCheckout, 'Api Error Notification' do
|
276
|
+
let(:notification) { GoogleCheckout::ApiError.new 'Unexpected Error' }
|
277
|
+
|
278
|
+
it "should identify type of notication" do
|
279
|
+
notification.should be_kind_of GoogleCheckout::ApiError
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should have error message" do
|
283
|
+
notification.error_message.should == 'Unexpected Error'
|
284
|
+
end
|
285
|
+
|
286
|
+
it "should have message" do
|
287
|
+
notification.message.should == 'Unexpected Error'
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
@@ -10,6 +10,7 @@ shared_examples_for "basic notification" do
|
|
10
10
|
|
11
11
|
it "should generate acknowledgment XML" do
|
12
12
|
@notification.acknowledgment_xml.should match(/notification-acknowledgment/)
|
13
|
+
@notification.acknowledgment_xml.should match(/serial-number="bea6bc1b-e1e2-44fe-80ff-0180e33a2614"/)
|
13
14
|
end
|
14
15
|
|
15
16
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vizjerai-google-checkout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 4
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Peter Elmore
|
@@ -135,8 +135,8 @@ extra_rdoc_files: []
|
|
135
135
|
|
136
136
|
files:
|
137
137
|
- .gitignore
|
138
|
+
- CHANGELOG.md
|
138
139
|
- Gemfile
|
139
|
-
- History.txt
|
140
140
|
- MIT-LICENSE.txt
|
141
141
|
- README.txt
|
142
142
|
- Rakefile
|