ambethia-mousetrap 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,132 @@
1
+ module Mousetrap
2
+ class Subscription < Resource
3
+ # Attributes we send _to_ the API.
4
+ attr_accessor \
5
+ :plan_code,
6
+ :billing_first_name,
7
+ :billing_last_name,
8
+ :credit_card_number,
9
+ :credit_card_expiration_month,
10
+ :credit_card_expiration_year,
11
+ :billing_zip_code,
12
+ :initial_bill_date,
13
+ :plan,
14
+
15
+ :customer_code # belongs to customer
16
+
17
+ # Attributes that come _from_ the API.
18
+ attr_reader \
19
+ :id,
20
+ :canceled_at,
21
+ :created_at,
22
+ :credit_card_expiration_date,
23
+ :credit_card_last_four_digits,
24
+ :credit_card_type
25
+
26
+ def self.[](code)
27
+ raise_api_unsupported_error
28
+ end
29
+
30
+ def self.all
31
+ raise_api_unsupported_error
32
+ end
33
+
34
+ def self.destroy_all
35
+ raise_api_unsupported_error
36
+ end
37
+
38
+ def self.exists?(code)
39
+ raise_api_unsupported_error
40
+ end
41
+
42
+ def attributes
43
+ {
44
+ :id => id,
45
+ :plan_code => plan_code,
46
+ :billing_first_name => billing_first_name,
47
+ :billing_last_name => billing_last_name,
48
+ :credit_card_number => credit_card_number,
49
+ :credit_card_expiration_month => credit_card_expiration_month,
50
+ :credit_card_expiration_year => credit_card_expiration_year,
51
+ :billing_zip_code => billing_zip_code,
52
+ :initial_bill_date => initial_bill_date,
53
+ }
54
+ end
55
+
56
+ def attributes_for_api
57
+ self.class.attributes_for_api(attributes)
58
+ end
59
+
60
+ def destroy
61
+ self.class.raise_api_unsupported_error
62
+ end
63
+
64
+ def exists?
65
+ self.class.raise_api_unsupported_error
66
+ end
67
+
68
+ def self.new_from_api(attributes)
69
+ subscription = new(attributes_from_api(attributes))
70
+ subscription.plan = Plan.new_from_api(attributes['plans']['plan'])
71
+ subscription
72
+ end
73
+
74
+ def self.update(customer_code, attributes)
75
+ mutated_attributes = attributes_for_api(attributes)
76
+
77
+ mutated_attributes.delete_if { |k, v| v.blank? }
78
+
79
+ response = put_resource(
80
+ 'customers',
81
+ 'edit-subscription',
82
+ customer_code,
83
+ mutated_attributes
84
+ )
85
+
86
+ raise response['error'] if response['error']
87
+ end
88
+
89
+
90
+ protected
91
+
92
+ attr_writer \
93
+ :id,
94
+ :canceled_at,
95
+ :created_at,
96
+ :credit_card_expiration_date,
97
+ :credit_card_last_four_digits,
98
+ :credit_card_type
99
+
100
+ def self.plural_resource_name
101
+ 'subscriptions'
102
+ end
103
+
104
+ def self.singular_resource_name
105
+ 'subscription'
106
+ end
107
+
108
+ def self.attributes_for_api(attributes)
109
+ {
110
+ :planCode => attributes[:plan_code],
111
+ :ccFirstName => attributes[:billing_first_name],
112
+ :ccLastName => attributes[:billing_last_name],
113
+ :ccNumber => attributes[:credit_card_number],
114
+ :ccExpMonth => ("%02d" % attributes[:credit_card_expiration_month] if attributes[:credit_card_expiration_month]),
115
+ :ccExpYear => attributes[:credit_card_expiration_year],
116
+ :ccZip => attributes[:billing_zip_code],
117
+ :initialBillDate => attributes[:initial_bill_date],
118
+ }
119
+ end
120
+
121
+ def self.attributes_from_api(attributes)
122
+ {
123
+ :id => attributes['id'],
124
+ :canceled_at => attributes['canceledDatetime'],
125
+ :created_at => attributes['createdDatetime'],
126
+ :credit_card_expiration_date => attributes['ccExpirationDate'],
127
+ :credit_card_last_four_digits => attributes['ccLastFour'],
128
+ :credit_card_type => attributes['ccType'],
129
+ }
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,3 @@
1
+ settings = YAML.load_file(File.expand_path('../cheddar_getter.yml', __FILE__))
2
+ Mousetrap.authenticate settings['user'], settings['password']
3
+ Mousetrap.product_code = settings['product_code']
@@ -0,0 +1,3 @@
1
+ user: you@example.com
2
+ password: abc123
3
+ product_code: MOUSETRAP_TEST
@@ -0,0 +1 @@
1
+ irb -r ubygems -r lib/mousetrap.rb -r factory_girl -r spec/support/random_data.rb -r script/authenticate.rb
@@ -0,0 +1,30 @@
1
+ Factory.define :new_customer, :class => Mousetrap::Customer, :default_strategy => :stub do |f|
2
+ f.email { random_email_address }
3
+ f.first_name { random_string }
4
+ f.last_name { random_string }
5
+ f.company { random_string }
6
+ f.code { |me| me.email }
7
+ f.add_attribute :id, nil
8
+ f.subscription_attributes { Factory.attributes_for(:subscription).merge(:initial_bill_date => "2012-01-01") }
9
+ end
10
+
11
+ Factory.define :existing_customer, :parent => :new_customer, :default_strategy => :stub do |f|
12
+ f.add_attribute :id, '2d1244e8-e338-102c-a92d-40402145ee8b'
13
+ end
14
+
15
+ Factory.define :subscription, :class => Mousetrap::Subscription, :default_strategy => :stub do |f|
16
+ f.plan_code 'TEST'
17
+ f.billing_first_name { random_string }
18
+ f.billing_last_name { random_string }
19
+ f.credit_card_number '4111111111111111'
20
+ f.credit_card_expiration_month '12'
21
+ f.credit_card_expiration_year '2012'
22
+ f.billing_zip_code '90210'
23
+ end
24
+
25
+ Factory.define :alternate_subscription, :parent => :subscription, :default_strategy => :stub do |f|
26
+ f.credit_card_number '5555555555554444'
27
+ f.credit_card_expiration_month '7'
28
+ f.credit_card_expiration_year '2013'
29
+ f.billing_zip_code '12345'
30
+ end
@@ -0,0 +1,6 @@
1
+ # Replace user and password with your CheddarGetter credentials.
2
+ user: 'lark@example.com'
3
+ password: 'abc123'
4
+
5
+ # Go create a product in the CheddarGetter web admin interface named "mousetrap_test".
6
+ product_code: 'mousetrap_test'
@@ -0,0 +1,345 @@
1
+ require File.expand_path('../../../lib/mousetrap', __FILE__)
2
+
3
+ require 'spec'
4
+ require 'spec/autorun'
5
+ require 'factory_girl'
6
+ require 'active_support'
7
+ require 'yaml'
8
+
9
+ Dir["#{File.dirname(__FILE__)}/../support/**/*.rb"].each {|f| require f}
10
+
11
+ settings = YAML.load_file(File.dirname(__FILE__) + '/settings.yml')
12
+ Mousetrap.authenticate(settings['user'], settings['password'])
13
+ Mousetrap.product_code = settings['product_code']
14
+
15
+ Spec::Runner.configure do |config|
16
+ config.before :suite do
17
+ begin
18
+ Mousetrap::Customer.destroy_all
19
+ rescue
20
+ end
21
+ end
22
+ end
23
+
24
+ shared_examples_for "a Customer record from CheddarGetter" do
25
+ describe "And I get the customer" do
26
+ before :all do
27
+ @api_customer = Mousetrap::Customer[@customer.code]
28
+ end
29
+
30
+ it "Then I should see first name" do
31
+ @api_customer.first_name.should == @customer.first_name
32
+ end
33
+
34
+ it "And I should see last name" do
35
+ @api_customer.last_name.should == @customer.last_name
36
+ end
37
+
38
+ it "And I should see company" do
39
+ @api_customer.company.should == @customer.company
40
+ end
41
+
42
+ it "And I should see the code" do
43
+ @api_customer.code.should == @customer.code
44
+ end
45
+
46
+ it "And I should see the ID" do
47
+ @api_customer.id.should == @customer.id
48
+ end
49
+ end
50
+ end
51
+
52
+ shared_examples_for "an active Subscription record from CheddarGetter" do
53
+ describe "And I get the subscription" do
54
+ before :all do
55
+ @api_customer = Mousetrap::Customer[@customer.code]
56
+ @api_subscription = @api_customer.subscription
57
+ end
58
+
59
+ it "Then ID is set" do
60
+ @api_subscription.id.should be
61
+ end
62
+
63
+ it "Then canceled_at is not set" do
64
+ @api_subscription.canceled_at.should be_nil
65
+ end
66
+
67
+ it "Then created_at is set" do
68
+ @api_subscription.created_at.should be
69
+ end
70
+
71
+ it "Then I should see the credit card expiration" do
72
+ expiration_date_from_api = Date.parse(@api_subscription.credit_card_expiration_date)
73
+ expiration_date = Date.parse("#{@customer.subscription.credit_card_expiration_year}-#{@customer.subscription.credit_card_expiration_month}-31")
74
+ expiration_date_from_api.should == expiration_date
75
+ end
76
+
77
+ it "Then I should see the credit card last four digits" do
78
+ @api_subscription.credit_card_last_four_digits.should == @customer.subscription.credit_card_number[-4..-1]
79
+ end
80
+
81
+ it "Then I should see the credit card type" do
82
+ @api_subscription.credit_card_type.should == (@credit_card_type || 'visa')
83
+ end
84
+ end
85
+ end
86
+
87
+ describe "The Wrapper Gem" do
88
+ describe Mousetrap::Customer do
89
+ describe ".all" do
90
+ describe "Given a few customers on CheddarGetter" do
91
+ before :all do
92
+ 3.times { Factory(:new_customer).save }
93
+ violated "Couldn't save customers" unless Mousetrap::Customer.all.size == 3
94
+ end
95
+
96
+ describe "When I call .all" do
97
+ before :all do
98
+ @all_customers = Mousetrap::Customer.all
99
+ end
100
+
101
+ it "Then I should get all the customers" do
102
+ @all_customers.size.should == 3
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ describe ".create" do
109
+ describe "When I create a customer" do
110
+ before :all do
111
+ attributes = Factory.attributes_for :new_customer
112
+ @customer = Mousetrap::Customer.create attributes
113
+ end
114
+
115
+ it_should_behave_like "a Customer record from CheddarGetter"
116
+ it_should_behave_like "an active Subscription record from CheddarGetter"
117
+ end
118
+ end
119
+
120
+ describe ".destroy_all" do
121
+ describe "Given a few customers on CheddarGetter" do
122
+ before :all do
123
+ Mousetrap::Customer.destroy_all
124
+ 3.times { Factory(:new_customer).save }
125
+ violated "Couldn't save customers" unless Mousetrap::Customer.all.size == 3
126
+ end
127
+
128
+ describe "When I call .destroy_all" do
129
+ before :all do
130
+ Mousetrap::Customer.destroy_all
131
+ end
132
+
133
+ it "Then there should be no customers" do
134
+ Mousetrap::Customer.all.size.should == 0
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ describe ".update" do
141
+ describe "Given a customer" do
142
+ before :all do
143
+ @customer = Factory :new_customer
144
+ @api_customer = nil
145
+
146
+ # TODO: figure out why multiple records are being created even though
147
+ # we use "before :all". Until then, here's the kludge...
148
+ if Mousetrap::Customer.all.size == 1
149
+ @api_customer = Mousetrap::Customer.all.first
150
+ @customer = @api_customer
151
+ else
152
+ @customer.save
153
+ @api_customer = Mousetrap::Customer[@customer.code]
154
+ end
155
+ end
156
+
157
+ describe "When I update the customer, with only customer attributes" do
158
+ before :all do
159
+ @api_customer = Mousetrap::Customer[@customer.code]
160
+
161
+ updated_attributes = {
162
+ :first_name => 'new_first',
163
+ :last_name => 'new_last',
164
+ :email => 'new_email@example.com',
165
+ :company => 'new_company'
166
+ }
167
+
168
+ @customer = Mousetrap::Customer.new updated_attributes
169
+ @customer.code = @api_customer.code
170
+ @customer.id = @api_customer.id
171
+
172
+ Mousetrap::Customer.update(@api_customer.code, updated_attributes)
173
+ end
174
+
175
+ it_should_behave_like "a Customer record from CheddarGetter"
176
+ end
177
+
178
+ describe "When I update the customer, with customer and subscription attributes" do
179
+ before :all do
180
+ @api_customer = Mousetrap::Customer[@customer.code]
181
+
182
+ updated_attributes = {
183
+ :first_name => 'new_first',
184
+ :last_name => 'new_last',
185
+ :email => 'new_email@example.com',
186
+ :company => 'new_company',
187
+ :subscription_attributes => {
188
+ :plan_code => 'TEST',
189
+ :billing_first_name => 'new_billing_first',
190
+ :billing_last_name => 'new_billing_last',
191
+ :credit_card_number => '5555555555554444',
192
+ :credit_card_expiration_month => '01',
193
+ :credit_card_expiration_year => '2013',
194
+ :billing_zip_code => '12345'
195
+ }
196
+ }
197
+
198
+ @credit_card_type = 'mc'
199
+
200
+ @customer = Mousetrap::Customer.new updated_attributes
201
+
202
+ # set up our test comparison objects as if they came from API gets
203
+ @customer.code = @api_customer.code
204
+ @customer.id = @api_customer.id
205
+ @customer.subscription.send(:id=, @api_customer.subscription.id)
206
+
207
+ Mousetrap::Customer.update(@api_customer.code, updated_attributes)
208
+ end
209
+
210
+ it_should_behave_like "a Customer record from CheddarGetter"
211
+ it_should_behave_like "an active Subscription record from CheddarGetter"
212
+ end
213
+ end
214
+ end
215
+
216
+ describe "#cancel" do
217
+ describe "Given a customer" do
218
+ before :all do
219
+ @customer = Factory :new_customer
220
+ @api_customer = nil
221
+
222
+ if Mousetrap::Customer.all.size == 1
223
+ @api_customer = Mousetrap::Customer.all.first
224
+ @customer = @api_customer
225
+ else
226
+ @customer.save
227
+ @api_customer = Mousetrap::Customer[@customer.code]
228
+ end
229
+ end
230
+
231
+ describe "When I cancel" do
232
+ before :all do
233
+ @api_customer.cancel
234
+ end
235
+
236
+ describe "And I get the customer" do
237
+ before :all do
238
+ @api_customer = Mousetrap::Customer[@customer.code]
239
+ end
240
+
241
+ it "Then I should see a cancellation date on subscription" do
242
+ @api_customer.subscription.canceled_at.should be
243
+ end
244
+
245
+ describe "When I resubscribe them" do
246
+ before :all do
247
+ @customer = Factory :new_customer, :email => @api_customer.email, :code => @api_customer.email
248
+ @customer.save
249
+ end
250
+
251
+ it_should_behave_like "a Customer record from CheddarGetter"
252
+ it_should_behave_like "an active Subscription record from CheddarGetter"
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
258
+
259
+ describe "#save" do
260
+ describe "When I save a customer" do
261
+ before :all do
262
+ @customer = Factory :new_customer
263
+ @customer.save
264
+ end
265
+
266
+ it_should_behave_like "a Customer record from CheddarGetter"
267
+
268
+ describe "When I save it again, with different attributes" do
269
+ before :all do
270
+ attributes = Factory.attributes_for :new_customer
271
+ @customer.first_name = attributes[:first_name]
272
+ @customer.last_name = attributes[:last_name]
273
+ @customer.email = attributes[:email]
274
+ @customer.company = attributes[:company]
275
+ @customer.save
276
+ end
277
+
278
+ it_should_behave_like "a Customer record from CheddarGetter"
279
+ end
280
+
281
+ context "When I update subscription information" do
282
+ before :all do
283
+ @subscription = Mousetrap::Subscription.new(Factory.attributes_for(:alternate_subscription))
284
+ @credit_card_type = 'mc'
285
+ @customer.subscription = @subscription
286
+ @customer.save
287
+ end
288
+
289
+ it_should_behave_like "an active Subscription record from CheddarGetter"
290
+ end
291
+ end
292
+ end
293
+
294
+ describe '#switch_to_plan' do
295
+ describe "Given an existing CheddarGetter customer" do
296
+ before :all do
297
+ @customer = Factory :new_customer
298
+ @customer.save
299
+ end
300
+
301
+ describe 'When I switch plans' do
302
+ before :all do
303
+ @customer.switch_to_plan('TEST_2')
304
+ end
305
+
306
+ describe "And I get the customer" do
307
+ before :all do
308
+ @api_customer = Mousetrap::Customer[@customer.code]
309
+ end
310
+
311
+ it 'Then they should be on the new plan' do
312
+ @api_customer.subscription.plan.code.should == 'TEST_2'
313
+ end
314
+ end
315
+ end
316
+ end
317
+ end
318
+ end
319
+
320
+ describe Mousetrap::Subscription do
321
+ describe "Given a customer on CheddarGetter" do
322
+ before :all do
323
+ @customer = Factory :new_customer
324
+ violated "Use a visa for setup" unless @customer.subscription.credit_card_number == '4111111111111111'
325
+ @customer.save
326
+ end
327
+
328
+ describe "When I update a subscription field" do
329
+ before :all do
330
+ Mousetrap::Subscription.update @customer.code, :credit_card_number => '5555555555554444'
331
+ end
332
+
333
+ describe "And I get the customer" do
334
+ before :all do
335
+ @api_customer = Mousetrap::Customer[@customer.code]
336
+ end
337
+
338
+ it 'Then I should see the updated field' do
339
+ @api_customer.subscription.credit_card_last_four_digits.should == '4444'
340
+ end
341
+ end
342
+ end
343
+ end
344
+ end
345
+ end