mlins-google-checkout 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/History.txt +14 -0
  2. data/MIT-LICENSE.txt +23 -0
  3. data/README.txt +143 -0
  4. data/Rakefile +34 -0
  5. data/VERSION.yml +4 -0
  6. data/examples/google_notifications_controller.rb +159 -0
  7. data/lib/duck_punches/hpricot.rb +24 -0
  8. data/lib/google-checkout.rb +65 -0
  9. data/lib/google-checkout/cart.rb +302 -0
  10. data/lib/google-checkout/command.rb +191 -0
  11. data/lib/google-checkout/geography.rb +7 -0
  12. data/lib/google-checkout/geography/area.rb +11 -0
  13. data/lib/google-checkout/geography/postal.rb +26 -0
  14. data/lib/google-checkout/geography/us_country.rb +24 -0
  15. data/lib/google-checkout/geography/us_state.rb +22 -0
  16. data/lib/google-checkout/geography/us_zip.rb +22 -0
  17. data/lib/google-checkout/geography/world.rb +12 -0
  18. data/lib/google-checkout/merchant_calculation.rb +30 -0
  19. data/lib/google-checkout/notification.rb +212 -0
  20. data/lib/google-checkout/shipping.rb +8 -0
  21. data/lib/google-checkout/shipping/filters.rb +32 -0
  22. data/lib/google-checkout/shipping/flat_rate.rb +26 -0
  23. data/lib/google-checkout/shipping/merchant_calculated.rb +29 -0
  24. data/lib/google-checkout/shipping/method.rb +11 -0
  25. data/lib/google-checkout/shipping/pickup.rb +22 -0
  26. data/lib/google-checkout/shipping/restrictions.rb +32 -0
  27. data/spec/fixtures/google/checkout-shopping-cart.xml +22 -0
  28. data/spec/fixtures/google/commands/add-merchant-order-number.xml +5 -0
  29. data/spec/fixtures/google/commands/add-tracking-data.xml +8 -0
  30. data/spec/fixtures/google/commands/archive-order.xml +3 -0
  31. data/spec/fixtures/google/commands/authorize-order.xml +2 -0
  32. data/spec/fixtures/google/commands/cancel-order.xml +5 -0
  33. data/spec/fixtures/google/commands/charge-order.xml +4 -0
  34. data/spec/fixtures/google/commands/deliver-order.xml +9 -0
  35. data/spec/fixtures/google/commands/process-order.xml +2 -0
  36. data/spec/fixtures/google/commands/refund-order.xml +6 -0
  37. data/spec/fixtures/google/commands/send-buyer-message.xml +7 -0
  38. data/spec/fixtures/google/commands/unarchive-order.xml +2 -0
  39. data/spec/fixtures/google/merchant_calculations/shipping.xml +40 -0
  40. data/spec/fixtures/google/notifications/authorization-amount-notification.xml +10 -0
  41. data/spec/fixtures/google/notifications/charge-amount-notification.xml +8 -0
  42. data/spec/fixtures/google/notifications/chargeback-amount-notification.xml +8 -0
  43. data/spec/fixtures/google/notifications/new-order-notification.xml +85 -0
  44. data/spec/fixtures/google/notifications/order-state-change-notification.xml +11 -0
  45. data/spec/fixtures/google/notifications/refund-amount-notification.xml +8 -0
  46. data/spec/fixtures/google/notifications/risk-information-notification.xml +23 -0
  47. data/spec/fixtures/google/responses/checkout-redirect.xml +5 -0
  48. data/spec/fixtures/google/responses/error.xml +5 -0
  49. data/spec/fixtures/google/responses/request-received.xml +3 -0
  50. data/spec/google-checkout/cart_spec.rb +110 -0
  51. data/spec/google-checkout/command_spec.rb +131 -0
  52. data/spec/google-checkout/geography/postal_spec.rb +26 -0
  53. data/spec/google-checkout/geography/us_country_spec.rb +26 -0
  54. data/spec/google-checkout/geography/us_state_spec.rb +11 -0
  55. data/spec/google-checkout/geography/us_zip_spec.rb +11 -0
  56. data/spec/google-checkout/geography/world_spec.rb +12 -0
  57. data/spec/google-checkout/merchant_calculation_spec.rb +17 -0
  58. data/spec/google-checkout/notification_spec.rb +175 -0
  59. data/spec/google-checkout/response_spec.rb +49 -0
  60. data/spec/google-checkout/shipping/flat_rate_spec.rb +46 -0
  61. data/spec/google-checkout/shipping/merchant_calculated_spec.rb +70 -0
  62. data/spec/google-checkout/shipping/pickup_spec.rb +22 -0
  63. data/spec/google-checkout_spec.rb +15 -0
  64. data/spec/spec_helper.rb +47 -0
  65. data/support/cacert.pem +7815 -0
  66. metadata +140 -0
@@ -0,0 +1,131 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe "basic command", :shared => true do
4
+
5
+ it "should include XML header" do
6
+ @order.to_xml.should match(/^<\?xml version=\"1\.0\" encoding=\"UTF-8\"\?>/)
7
+ end
8
+
9
+ end
10
+
11
+ describe GoogleCheckout, "Command class" do
12
+
13
+ it "should read SSL certs" do
14
+ GoogleCheckout::Command.x509_store.should be_kind_of(OpenSSL::X509::Store)
15
+ end
16
+
17
+ end
18
+
19
+ describe GoogleCheckout, "Command instance" do
20
+
21
+ before(:each) do
22
+ @command = GoogleCheckout::Command.new("my_id", "my_key")
23
+ end
24
+
25
+ it "should generate sandbox url" do
26
+ GoogleCheckout.use_sandbox
27
+ @command.url.should match(/sandbox/)
28
+ end
29
+
30
+ it "should generate production url" do
31
+ GoogleCheckout.use_production
32
+ @command.url.should match(/checkout\.google\.com/)
33
+ end
34
+
35
+ end
36
+
37
+ describe GoogleCheckout, "Charge Order" do
38
+
39
+ before(:each) do
40
+ @order = GoogleCheckout::ChargeOrder.new("my_id", "my_key", "1234567890")
41
+ GoogleCheckout.use_sandbox
42
+ @order.amount = 123.45
43
+ end
44
+
45
+ it_should_behave_like "basic command"
46
+
47
+ it "should retrieve order number" do
48
+ @order.google_order_number.should == '1234567890'
49
+ end
50
+
51
+ it "should get merchant_id" do
52
+ @order.merchant_id.should == 'my_id'
53
+ end
54
+
55
+ it "should get merchant_key" do
56
+ @order.merchant_key.should == 'my_key'
57
+ end
58
+
59
+ it "should generate XML" do
60
+ @order.to_xml.should match(/amount currency="USD"/)
61
+ @order.to_xml.should match(/123\.45<\/amount>/)
62
+ end
63
+
64
+ it "should post request to Google successfully" do
65
+ # :null_object means eat all other methods and return self
66
+ net_http = mock("net_http", { :null_object => true })
67
+ Net::HTTP.should_receive(:new).and_return(net_http)
68
+
69
+ success_response = Net::HTTPSuccess.new(Net::HTTP.version_1_2, 200, "OK")
70
+ success_response.should_receive(:body).and_return(read_xml_fixture('responses/request-received'))
71
+ net_http.should_receive(:request).and_return(success_response)
72
+
73
+ response = @order.post
74
+ response.should be_kind_of(GoogleCheckout::RequestReceived)
75
+ response.should_not be_error
76
+ response.serial_number.should == 'bea6bc1b-e1e2-44fe-80ff-0180e33a2614'
77
+ end
78
+
79
+ it "should post request to Google and return error" do
80
+ # :null_object means eat all other methods and return self
81
+ net_http = mock("net_http", { :null_object => true })
82
+ Net::HTTP.should_receive(:new).and_return(net_http)
83
+
84
+ # NOTE HTTP response code is irrelevant here.
85
+ error_response = Net::HTTPSuccess.new(Net::HTTP.version_1_2, 200, "OK")
86
+ error_response.should_receive(:body).and_return(read_xml_fixture('responses/error'))
87
+ net_http.should_receive(:request).and_return(error_response)
88
+
89
+ lambda { @order.post }.should raise_error(GoogleCheckout::APIError)
90
+ end
91
+
92
+ end
93
+
94
+ describe GoogleCheckout, "Checkout API Request (with Cart)" do
95
+
96
+ it "should use HTTP Basic Auth"
97
+
98
+ it "should use proper content type"
99
+
100
+ it "should use proper accept type"
101
+
102
+ it "should report success of request"
103
+
104
+ it "should report error and error message"
105
+
106
+ it "should return redirect url"
107
+
108
+ end
109
+
110
+
111
+ describe GoogleCheckout, "Send Buyer Email" do
112
+
113
+ before(:each) do
114
+ @command = GoogleCheckout::SendBuyerMessage.new("my_id", "my_key", "1234567890", "Thanks for the order!")
115
+ end
116
+
117
+ # <send-buyer-message xmlns="http://checkout.google.com/schema/2"
118
+ # google-order-number="841171949013218">
119
+ # <message>Due to high volume, your order will ship
120
+ # next week. Thank you for your patience.</message>
121
+ # <send-email>true</send-email>
122
+ # </send-buyer-message>
123
+
124
+ it "should post email to the buyer" do
125
+ xml = @command.to_xml
126
+ xml.should match(%r{google-order-number="1234567890"})
127
+ xml.should match(%r{<message>Thanks for the order!</message>})
128
+ xml.should match(%r{<send-email>true</send-email>})
129
+ end
130
+
131
+ end
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe GoogleCheckout::Geography::Postal do
4
+ before(:each) do
5
+ @area = GoogleCheckout::Geography::Postal.new('US')
6
+ end
7
+
8
+ it 'should generate the postal area tag' do
9
+ @area.to_xml.should match(%r{<postal-area>.*</postal-area>})
10
+ end
11
+
12
+ it 'should include the country in the generated xml' do
13
+ @area.country = 'CA'
14
+ @area.to_xml.should match(%r{<country-code>CA</country-code>})
15
+ end
16
+
17
+ it 'should not include the postal pattern by default' do
18
+ @area.to_xml.should_not match(%r{<postal-code-pattern>})
19
+ end
20
+
21
+ it 'should include the postal pattern when set' do
22
+ @area.postal_pattern = '53*'
23
+ @area.to_xml.should match(%r{<postal-code-pattern>53\*</postal-code-pattern>})
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe GoogleCheckout::Geography::UsCountry do
4
+ before(:each) do
5
+ @area = GoogleCheckout::Geography::UsCountry.new(:all)
6
+ end
7
+
8
+ it 'should generate the us country area tag with the ALL region' do
9
+ @area.to_xml.should match(%r{<us-country-area country-area="ALL"/>})
10
+ end
11
+
12
+ it 'should generate the us country area tag with the CONTINENTAL_48 region' do
13
+ @area.region = :continental_48
14
+ @area.to_xml.should match(%r{<us-country-area country-area="CONTINENTAL_48"/>})
15
+ end
16
+
17
+ it 'should generate the us country area tag with the FULL_50_STATES region' do
18
+ @area.region = :full_50_states
19
+ @area.to_xml.should match(%r{<us-country-area country-area="FULL_50_STATES"/>})
20
+ end
21
+
22
+ it 'should not allow invalid regions' do
23
+ lambda {GoogleCheckout::Geography::UsCountry.new(:my_house).to_xml}.should raise_error(ArgumentError)
24
+ end
25
+
26
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe GoogleCheckout::Geography::UsState do
4
+ before(:each) do
5
+ @area = GoogleCheckout::Geography::UsState.new('WI')
6
+ end
7
+
8
+ it 'should include the state' do
9
+ @area.to_xml.should match(%r{<us-state-area><state>WI</state></us-state-area>})
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe GoogleCheckout::Geography::UsZip do
4
+ before(:each) do
5
+ @area = GoogleCheckout::Geography::UsZip.new('53*')
6
+ end
7
+
8
+ it 'should generate the us zip area tag' do
9
+ @area.to_xml.should match(%r{<us-zip-area>.*</us-zip-area>})
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe GoogleCheckout::Geography::World do
4
+ before(:each) do
5
+ @area = GoogleCheckout::Geography::World.new
6
+ end
7
+
8
+ it 'should generate a self closing world tag' do
9
+ @area.to_xml.should eql("<world-area/>")
10
+ end
11
+
12
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe GoogleCheckout, "Merchant Calculation" do
4
+
5
+ before(:each) do
6
+ @calculation = GoogleCheckout::MerchantCalculation.parse(read_xml_fixture('merchant_calculations/shipping'))
7
+ end
8
+
9
+ it "should find buyer language" do
10
+ @calculation.buyer_language.should == 'en_US'
11
+ end
12
+
13
+ it "should find the address id" do
14
+ @calculation.address_id.should == "739030698069958"
15
+ end
16
+
17
+ end
@@ -0,0 +1,175 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe "basic notification", :shared => true do
4
+
5
+ it "should get serial number" do
6
+ @notification.serial_number.should == 'bea6bc1b-e1e2-44fe-80ff-0180e33a2614'
7
+ end
8
+
9
+ it "should get google order number" do
10
+ @notification.google_order_number.should == '841171949013218'
11
+ end
12
+
13
+ it "should generate acknowledgment XML" do
14
+ @notification.acknowledgment_xml.should match(/notification-acknowledgment/)
15
+ end
16
+
17
+ end
18
+
19
+ describe GoogleCheckout, "New Order Notification" do
20
+
21
+ before(:each) do
22
+ @notification = GoogleCheckout::Notification.parse(read_xml_fixture('notifications/new-order-notification'))
23
+ end
24
+
25
+ it "should identify type of notification" do
26
+ @notification.should be_kind_of(GoogleCheckout::NewOrderNotification)
27
+ end
28
+
29
+ it_should_behave_like "basic notification"
30
+
31
+ it "should find fulfillment order state" do
32
+ @notification.fulfillment_order_state.should == 'NEW'
33
+ end
34
+
35
+ it "should find financial order state" do
36
+ @notification.financial_order_state.should == 'REVIEWING'
37
+ end
38
+
39
+ it "should use financial state shortcut" do
40
+ @notification.state.should == "REVIEWING"
41
+ end
42
+
43
+ it "should create Money object from order total" do
44
+ @notification.order_total.should be_kind_of(Money)
45
+ @notification.order_total.cents.should == 19098
46
+ @notification.order_total.currency.should == 'USD'
47
+ end
48
+
49
+ it "should throw error when accessing non-existent value" do
50
+ lambda { @notification.there_is_no_field_with_this_name }.should raise_error(NoMethodError)
51
+ end
52
+
53
+ it "should find sub-keys of merchant-private-data as if they were at the root" do
54
+ @notification.peepcode_order_number.should == '1234-5678-9012'
55
+ end
56
+
57
+ it "should find total tax" do
58
+ @notification.total_tax.should be_kind_of(Money)
59
+ @notification.total_tax.cents.should == 0
60
+ end
61
+
62
+ it "should find email marketing allowed" do
63
+ @notification.email_allowed.should be_false
64
+ end
65
+
66
+ it "should get email or buyer-shipping-address/email or buyer-billing-address/email"
67
+
68
+ end
69
+
70
+
71
+ describe GoogleCheckout, "Order State Change Notification" do
72
+
73
+ before(:each) do
74
+ @notification = GoogleCheckout::Notification.parse(read_xml_fixture('notifications/order-state-change-notification'))
75
+ end
76
+
77
+ it_should_behave_like "basic notification"
78
+
79
+ it "should identify type of notification" do
80
+ @notification.should be_kind_of(GoogleCheckout::OrderStateChangeNotification)
81
+ end
82
+
83
+ it "should find new financial state" do
84
+ @notification.new_financial_order_state.should == 'CHARGING'
85
+ end
86
+
87
+ it "should find new fulfillment state" do
88
+ @notification.new_fulfillment_order_state.should == 'NEW'
89
+ end
90
+
91
+ it "should use financial state shortcut" do
92
+ @notification.state.should == 'CHARGING'
93
+ end
94
+
95
+ end
96
+
97
+ describe GoogleCheckout, "Risk Information Notification" do
98
+
99
+ before(:each) do
100
+ @notification = GoogleCheckout::Notification.parse(read_xml_fixture('notifications/risk-information-notification'))
101
+ end
102
+
103
+ it "should identify type of notification" do
104
+ @notification.should be_kind_of(GoogleCheckout::RiskInformationNotification)
105
+ end
106
+
107
+ it_should_behave_like "basic notification"
108
+
109
+ end
110
+
111
+ describe GoogleCheckout, "Charge Amount Notification" do
112
+
113
+ before(:each) do
114
+ @notification = GoogleCheckout::Notification.parse(read_xml_fixture('notifications/charge-amount-notification'))
115
+ end
116
+
117
+ it_should_behave_like "basic notification"
118
+
119
+ it "should identify type of notification" do
120
+ @notification.should be_kind_of(GoogleCheckout::ChargeAmountNotification)
121
+ end
122
+
123
+ it "should get latest charge amount" do
124
+ @notification.latest_charge_amount.should be_kind_of(Money)
125
+ end
126
+
127
+ it "should get total charge amount" do
128
+ @notification.total_charge_amount.should be_kind_of(Money)
129
+ @notification.total_charge_amount.cents.should == 22606
130
+ end
131
+
132
+ end
133
+
134
+ describe GoogleCheckout, "Authorization Amount Notification" do
135
+
136
+ before(:each) do
137
+ @notification = GoogleCheckout::Notification.parse(read_xml_fixture('notifications/authorization-amount-notification'))
138
+ end
139
+
140
+ it_should_behave_like "basic notification"
141
+
142
+ it "should identify type of notification" do
143
+ @notification.should be_kind_of(GoogleCheckout::AuthorizationAmountNotification)
144
+ end
145
+
146
+ end
147
+
148
+ describe GoogleCheckout, "Chargeback Amount Notification" do
149
+
150
+ before(:each) do
151
+ @notification = GoogleCheckout::Notification.parse(read_xml_fixture('notifications/chargeback-amount-notification'))
152
+ end
153
+
154
+ it_should_behave_like "basic notification"
155
+
156
+ it "should identify type of notification" do
157
+ @notification.should be_kind_of(GoogleCheckout::ChargebackAmountNotification)
158
+ end
159
+
160
+ end
161
+
162
+ describe GoogleCheckout, "Refund Amount Notification" do
163
+
164
+ before(:each) do
165
+ @notification = GoogleCheckout::Notification.parse(read_xml_fixture('notifications/refund-amount-notification'))
166
+ end
167
+
168
+ it_should_behave_like "basic notification"
169
+
170
+ it "should identify type of notification" do
171
+ @notification.should be_kind_of(GoogleCheckout::RefundAmountNotification)
172
+ end
173
+
174
+ end
175
+
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ # Responses
4
+
5
+ describe GoogleCheckout, "Checkout Redirect" do
6
+
7
+ before(:each) do
8
+ @response = GoogleCheckout::Notification.parse(read_xml_fixture('responses/checkout-redirect'))
9
+ end
10
+
11
+ it "should identify type of notification" do
12
+ @response.should be_kind_of(GoogleCheckout::CheckoutRedirect)
13
+ end
14
+
15
+ it "should unescape url" do
16
+ @response.redirect_url.should == 'https://checkout.google.com/buy?foo=bar&id=8572098456'
17
+ end
18
+
19
+ end
20
+
21
+ describe GoogleCheckout, "Request Received" do
22
+
23
+ before(:each) do
24
+ @response = GoogleCheckout::Notification.parse(read_xml_fixture('responses/request-received'))
25
+ end
26
+
27
+ it "should identify type of notification" do
28
+ @response.should be_kind_of(GoogleCheckout::RequestReceived)
29
+ end
30
+
31
+ end
32
+
33
+ # Errors
34
+
35
+ describe GoogleCheckout, "Error" do
36
+
37
+ before(:each) do
38
+ @response = GoogleCheckout::Notification.parse(read_xml_fixture('responses/error'))
39
+ end
40
+
41
+ it "should identify type of notification" do
42
+ @response.should be_kind_of(GoogleCheckout::Error)
43
+ end
44
+
45
+ it "should read error message" do
46
+ @response.message.should == 'Bad username and/or password for API Access.'
47
+ end
48
+
49
+ end