acts_as_subscription 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,204 @@
1
+ require 'spec_helper'
2
+ require 'acts_as_subscription/backend/chargify_client'
3
+
4
+ describe ActsAsSubscription::Subscription::Backend::ChargifyClient do
5
+
6
+ def active_subscriptions
7
+ Chargify::Subscription.find(:all, :params => {:state => 'active'})
8
+ end
9
+
10
+ before(:each) do
11
+ @config = backend_config(:chargify)
12
+ @free_attr = free_attributes
13
+ @paid_attr = paid_attributes
14
+ # Chargify uses '1' as the success card number for testing, and '2' for failure.
15
+ @paid_attr[:cc_number] = 1
16
+ @backend = ActsAsSubscription::Subscription::Backend::ChargifyClient.new(@config['user'], @config['password'], @config['product_code'])
17
+
18
+ # Cancel any active subscriptions before each test - no way to actually delete via the chargify API.
19
+ active_subscriptions.each do |sub|
20
+ sub.cancel
21
+ end
22
+ end
23
+
24
+ describe 'for all accounts' do
25
+
26
+ it 'should return a list of plans' do
27
+ plans = @backend.plans
28
+ plans.length.should == 3
29
+ plans.each do |plan|
30
+ plan[:code].should_not be_nil
31
+ plan[:billing_frequency].should_not be_nil
32
+ plan[:name].should_not be_nil
33
+ plan[:description].should_not be_nil
34
+ plan[:recurring_charge].should_not be_nil
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ describe 'for paid accounts' do
41
+
42
+ describe 'with valid parameters' do
43
+
44
+ it 'should create new subscriptions' do
45
+ @backend.create_subscription(Subscription.new(@paid_attr)).should == true
46
+ active_subscriptions.size.should == 1
47
+ end
48
+
49
+ it 'should update existing subscriptions' do
50
+ subscription = Subscription.new(@paid_attr)
51
+ @backend.create_subscription(subscription).should == true
52
+ subscription.email = 'updated@recursive-design.com'
53
+ @backend.update_subscription(subscription).should == true
54
+ customer = Chargify::Customer.find_by_reference(subscription.customer_code)
55
+ customer.attributes[:email].should == 'updated@recursive-design.com'
56
+ active_subscriptions.size.should == 1
57
+ end
58
+
59
+ it 'should allow downgrading to a free plan' do
60
+ subscription = Subscription.new(@paid_attr)
61
+ @backend.create_subscription(subscription).should == true
62
+ subscription.plan_code = @free_attr[:plan_code]
63
+ @backend.update_subscription(subscription).should == true
64
+ sub = Chargify::Subscription.find_by_customer_reference(subscription.customer_code)
65
+ sub.product.attributes[:handle].should == @free_attr[:plan_code].downcase
66
+ active_subscriptions.size.should == 1
67
+ end
68
+
69
+ it 'should cancel existing subscriptions' do
70
+ subscription = Subscription.new(@paid_attr)
71
+ @backend.create_subscription(subscription).should == true
72
+ customer = Chargify::Customer.find_by_reference(subscription.customer_code)
73
+ @backend.cancel_subscription!(subscription.customer_code).should == true
74
+ sub = Chargify::Subscription.find_by_customer_reference(subscription.customer_code)
75
+ sub.attributes[:state].should == 'canceled'
76
+ active_subscriptions.size.should == 0
77
+ end
78
+
79
+ end
80
+
81
+ describe 'with invalid parameters' do
82
+
83
+ it 'should not create new subscriptions' do
84
+ @backend.create_subscription(Subscription.new(@paid_attr.merge(:first_name => nil))).should_not == true
85
+ active_subscriptions.size.should == 0
86
+ end
87
+
88
+ it 'should not update existing subscriptions' do
89
+ subscription = Subscription.new(@paid_attr)
90
+ @backend.create_subscription(subscription).should == true
91
+ subscription.email = ''
92
+ @backend.update_subscription(subscription).should_not == true
93
+ customer = Chargify::Customer.find_by_reference(subscription.customer_code)
94
+ customer.attributes[:email].should == @paid_attr[:email]
95
+ active_subscriptions.size.should == 1
96
+ end
97
+
98
+ it 'should not allow downgrading to a free plan' do
99
+ subscription = Subscription.new(@paid_attr)
100
+ @backend.create_subscription(subscription).should == true
101
+ subscription.plan_code = @free_attr[:plan_code]
102
+ subscription.email = ''
103
+ @backend.update_subscription(subscription).should_not == true
104
+ sub = Chargify::Subscription.find_by_customer_reference(subscription.customer_code)
105
+ sub.product.attributes[:handle].should == @paid_attr[:plan_code].downcase
106
+ active_subscriptions.size.should == 1
107
+ end
108
+
109
+ it 'should fail to cancel invalid subscriptions' do
110
+ @backend.cancel_subscription!('invalid-customer-code').should == false
111
+ end
112
+
113
+ end
114
+
115
+ end
116
+
117
+ describe 'for free accounts' do
118
+
119
+ describe 'with valid parameters' do
120
+
121
+ it 'should create new subscriptions' do
122
+ @backend.create_subscription(Subscription.new(@free_attr)).should == true
123
+ active_subscriptions.size.should == 1
124
+ end
125
+
126
+ it 'should update existing subscriptions' do
127
+ subscription = Subscription.new(@free_attr)
128
+ @backend.create_subscription(subscription).should == true
129
+ subscription.email = 'updated@recursive-design.com'
130
+ @backend.update_subscription(subscription).should == true
131
+ customer = Chargify::Customer.find_by_reference(subscription.customer_code)
132
+ customer.attributes[:email].should == 'updated@recursive-design.com'
133
+ active_subscriptions.size.should == 1
134
+ end
135
+
136
+ it 'should allow upgrading to a paid plan' do
137
+ subscription = Subscription.new(@free_attr)
138
+ @backend.create_subscription(subscription).should == true
139
+ subscription.plan_code = @paid_attr[:plan_code]
140
+ subscription.cc_number = @paid_attr[:cc_number]
141
+ subscription.cc_expiration_month = @paid_attr[:cc_expiration_month]
142
+ subscription.cc_expiration_year = @paid_attr[:cc_expiration_year]
143
+ subscription.cc_verification_value = @paid_attr[:cc_verification_value]
144
+ subscription.zip_code = @paid_attr[:zip_code]
145
+ @backend.update_subscription(subscription).should == true
146
+ sub = Chargify::Subscription.find_by_customer_reference(subscription.customer_code)
147
+ sub.product.attributes[:handle].should == @paid_attr[:plan_code].downcase
148
+ active_subscriptions.size.should == 1
149
+ end
150
+
151
+ it 'should cancel existing subscriptions' do
152
+ subscription = Subscription.new(@free_attr)
153
+ @backend.create_subscription(subscription).should == true
154
+ customer = Chargify::Customer.find_by_reference(subscription.customer_code)
155
+ @backend.cancel_subscription!(subscription.customer_code).should == true
156
+ sub = Chargify::Subscription.find_by_customer_reference(subscription.customer_code)
157
+ sub.attributes[:state].should == 'canceled'
158
+ active_subscriptions.size.should == 0
159
+ end
160
+
161
+ end
162
+
163
+ describe 'with invalid parameters' do
164
+
165
+ it 'should not create new subscriptions' do
166
+ @backend.create_subscription(Subscription.new(@free_attr.merge(:first_name => nil))).should_not == true
167
+ active_subscriptions.size.should == 0
168
+ end
169
+
170
+ it 'should not update existing subscriptions' do
171
+ subscription = Subscription.new(@free_attr)
172
+ @backend.create_subscription(subscription).should == true
173
+ subscription.email = ''
174
+ @backend.update_subscription(subscription).should_not == true
175
+ customer = Chargify::Customer.find_by_reference(subscription.customer_code)
176
+ customer.attributes[:email].should == @free_attr[:email]
177
+ active_subscriptions.size.should == 1
178
+ end
179
+
180
+ it 'should not allow upgrading to a paid plan' do
181
+ subscription = Subscription.new(@free_attr)
182
+ @backend.create_subscription(subscription).should == true
183
+ subscription.plan_code = @paid_attr[:plan_code]
184
+ @backend.update_subscription(subscription).should_not == true
185
+ sub = Chargify::Subscription.find_by_customer_reference(subscription.customer_code)
186
+ sub.product.attributes[:handle].should == @free_attr[:plan_code].downcase
187
+ active_subscriptions.size.should == 1
188
+ end
189
+
190
+ end
191
+
192
+ end
193
+
194
+ end
195
+
196
+
197
+ module Chargify
198
+
199
+ class Customer < Base
200
+ def self.delete!
201
+ post(:destroy)
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,191 @@
1
+ require 'spec_helper'
2
+ require 'acts_as_subscription/backend/cheddar_getter_client'
3
+
4
+ describe ActsAsSubscription::Subscription::Backend::CheddarGetterClient do
5
+
6
+ before(:each) do
7
+ config = backend_config(:cheddar_getter)
8
+ @free_attr = free_attributes
9
+ @paid_attr = paid_attributes
10
+ @backend = ActsAsSubscription::Subscription::Backend::CheddarGetterClient.new(config['user'], config['password'], config['product_code'])
11
+
12
+ # Remove any existing customers before each test - quite slow unfortunately.
13
+ Mousetrap::Customer.all.each do |customer|
14
+ customer.delete if customer.email.match /@recursive-design.com$/
15
+ end
16
+ end
17
+
18
+ describe 'for all accounts' do
19
+
20
+ it 'should initialize the mousetrap gem' do
21
+ Mousetrap.product_code.should == 'ACTS_AS_SUBSCRIPTION_TEST'
22
+ end
23
+
24
+ it 'should return a list of plans' do
25
+ plans = @backend.plans
26
+ plans.length.should == 3
27
+ plans.each do |plan|
28
+ plan[:code].should_not be_nil
29
+ plan[:name].should_not be_nil
30
+ plan[:description].should_not be_nil
31
+ plan[:billing_frequency].should == 'month'
32
+ plan[:recurring_charge].should_not be_nil
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ describe 'for paid accounts' do
39
+
40
+ describe 'with valid parameters' do
41
+
42
+ it 'should create new subscriptions' do
43
+ @backend.create_subscription(Subscription.new(@paid_attr)).should == true
44
+ Mousetrap::Customer.all.size.should == 1
45
+ end
46
+
47
+ it 'should update existing subscriptions' do
48
+ subscription = Subscription.new(@paid_attr)
49
+ @backend.create_subscription(subscription)
50
+ subscription.email = 'updated@recursive-design.com'
51
+ @backend.update_subscription(subscription)
52
+ Mousetrap::Customer[subscription.customer_code].email.should == 'updated@recursive-design.com'
53
+ Mousetrap::Customer.all.size.should == 1
54
+ end
55
+
56
+ it 'should allow downgrading to a free plan' do
57
+ subscription = Subscription.new(@paid_attr)
58
+ @backend.create_subscription(subscription)
59
+ subscription.plan_code = @free_attr[:plan_code]
60
+ @backend.update_subscription(subscription)
61
+ Mousetrap::Customer[subscription.customer_code].subscription.plan.code.should == @free_attr[:plan_code]
62
+ Mousetrap::Customer.all.size.should == 1
63
+ end
64
+
65
+ it 'should cancel existing subscriptions' do
66
+ subscription = Subscription.new(@paid_attr)
67
+ @backend.create_subscription(subscription)
68
+ Mousetrap::Customer[subscription.customer_code].subscription.canceled_at.should == nil
69
+ @backend.cancel_subscription!(subscription.customer_code).should == true
70
+ Mousetrap::Customer[subscription.customer_code].subscription.canceled_at.should_not == nil
71
+ Mousetrap::Customer.all.size.should == 1
72
+ end
73
+
74
+ end
75
+
76
+ describe 'with invalid parameters' do
77
+
78
+ it 'should not create new subscriptions' do
79
+ @backend.create_subscription(Subscription.new(@paid_attr.merge(:first_name => nil))).should_not == true
80
+ Mousetrap::Customer.all.size.should == 0
81
+ end
82
+
83
+ it 'should not update existing subscriptions' do
84
+ subscription = Subscription.new(@paid_attr)
85
+ @backend.create_subscription(subscription)
86
+ subscription.email = ''
87
+ @backend.update_subscription(subscription)
88
+ Mousetrap::Customer[subscription.customer_code].email.should == 'dummy@recursive-design.com'
89
+ Mousetrap::Customer.all.size.should == 1
90
+ end
91
+
92
+ it 'should not allow downgrading to a free plan' do
93
+ subscription = Subscription.new(@paid_attr)
94
+ @backend.create_subscription(subscription)
95
+ subscription.plan_code = @free_attr[:plan_code]
96
+ subscription.email = ''
97
+ @backend.update_subscription(subscription)
98
+ Mousetrap::Customer[subscription.customer_code].subscription.plan.code.should == @paid_attr[:plan_code]
99
+ Mousetrap::Customer.all.size.should == 1
100
+ end
101
+
102
+ it 'should fail to cancel invalid subscriptions' do
103
+ @backend.cancel_subscription!('invalid-customer-code').should == false
104
+ end
105
+
106
+ end
107
+
108
+ end
109
+
110
+ describe 'for free accounts' do
111
+
112
+ describe 'with valid parameters' do
113
+
114
+ it 'should create new subscriptions' do
115
+ @backend.create_subscription(Subscription.new(@free_attr)).should == true
116
+ Mousetrap::Customer.all.size.should == 1
117
+ end
118
+
119
+ it 'should update existing subscriptions' do
120
+ subscription = Subscription.new(@free_attr)
121
+ @backend.create_subscription(subscription)
122
+ subscription.email = 'updated@recursive-design.com'
123
+ @backend.update_subscription(subscription)
124
+ Mousetrap::Customer[subscription.customer_code].email.should == 'updated@recursive-design.com'
125
+ Mousetrap::Customer.all.size.should == 1
126
+ end
127
+
128
+ it 'should allow upgrading to a paid plan' do
129
+ subscription = Subscription.new(@free_attr)
130
+ @backend.create_subscription(subscription)
131
+ subscription.plan_code = @paid_attr[:plan_code]
132
+ subscription.cc_number = @paid_attr[:cc_number]
133
+ subscription.cc_expiration_month = @paid_attr[:cc_expiration_month]
134
+ subscription.cc_expiration_year = @paid_attr[:cc_expiration_year]
135
+ subscription.cc_verification_value = @paid_attr[:cc_verification_value]
136
+ subscription.zip_code = @paid_attr[:zip_code]
137
+ @backend.update_subscription(subscription)
138
+ Mousetrap::Customer[subscription.customer_code].subscription.plan.code.should == @paid_attr[:plan_code]
139
+ Mousetrap::Customer.all.size.should == 1
140
+ end
141
+
142
+ it 'should cancel existing subscriptions' do
143
+ subscription = Subscription.new(@free_attr)
144
+ @backend.create_subscription(subscription)
145
+ Mousetrap::Customer[subscription.customer_code].subscription.canceled_at.should == nil
146
+ @backend.cancel_subscription!(subscription.customer_code).should == true
147
+ Mousetrap::Customer[subscription.customer_code].subscription.canceled_at.should_not == nil
148
+ Mousetrap::Customer.all.size.should == 1
149
+ end
150
+
151
+ end
152
+
153
+ describe 'with invalid parameters' do
154
+
155
+ it 'should not create new subscriptions' do
156
+ @backend.create_subscription(Subscription.new(@free_attr.merge(:first_name => nil))).should_not == true
157
+ Mousetrap::Customer.all.size.should == 0
158
+ end
159
+
160
+ it 'should not update existing subscriptions' do
161
+ subscription = Subscription.new(@free_attr)
162
+ @backend.create_subscription(subscription)
163
+ subscription.email = ''
164
+ @backend.update_subscription(subscription)
165
+ Mousetrap::Customer[subscription.customer_code].email.should == 'dummy@recursive-design.com'
166
+ Mousetrap::Customer.all.size.should == 1
167
+ end
168
+
169
+ it 'should not allow upgrading to a paid plan without credit card info' do
170
+ subscription = Subscription.new(@free_attr)
171
+ @backend.create_subscription(subscription)
172
+ subscription.plan_code = @paid_attr[:plan_code]
173
+ @backend.update_subscription(subscription)
174
+ Mousetrap::Customer[subscription.customer_code].subscription.plan.code.should == @free_attr[:plan_code]
175
+ Mousetrap::Customer.all.size.should == 1
176
+ end
177
+
178
+ end
179
+
180
+ end
181
+
182
+ end
183
+
184
+
185
+ module Mousetrap
186
+ class Customer
187
+ def delete
188
+ member_action 'delete' unless new_record?
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActsAsSubscription::Subscription::Backend do
4
+
5
+ before(:each) do
6
+ @attr = {
7
+ :backend => :dummy,
8
+ :product_code => 'DUMMY_TEST',
9
+ :user => 'user',
10
+ :password => 'pass'
11
+ }
12
+
13
+ @backend = ActsAsSubscription::Subscription::Backend
14
+ @backend.instance = nil
15
+ @subscription = Subscription.new(paid_attributes)
16
+ end
17
+
18
+ describe 'validation' do
19
+
20
+ it 'should require a :backend' do
21
+ lambda {
22
+ @backend.initialize(@attr.merge(:backend => nil))
23
+ }.should raise_error(ActsAsSubscription::Subscription::Error::ArgumentError)
24
+ end
25
+
26
+ it 'should make sure :backend exists' do
27
+ lambda {
28
+ @backend.initialize(@attr.merge(:backend => :non_existent))
29
+ }.should raise_error(ActsAsSubscription::Subscription::Error::BackendError)
30
+ end
31
+
32
+ it 'should accept a valid :backend' do
33
+ lambda {
34
+ @backend.initialize(@attr.merge(:backend => :dummy))
35
+ }.should_not raise_error(ActsAsSubscription::Subscription::Error::ArgumentError)
36
+ end
37
+
38
+ it 'should require a :product_code' do
39
+ lambda {
40
+ @backend.initialize(@attr.merge(:product_code => nil))
41
+ }.should raise_error(ActsAsSubscription::Subscription::Error::ArgumentError)
42
+ end
43
+
44
+ it 'should require a :user' do
45
+ lambda {
46
+ @backend.initialize(@attr.merge(:user => nil))
47
+ }.should raise_error(ActsAsSubscription::Subscription::Error::ArgumentError)
48
+ end
49
+
50
+ it 'should require a :password' do
51
+ lambda {
52
+ @backend.initialize(@attr.merge(:password => nil))
53
+ }.should raise_error(ActsAsSubscription::Subscription::Error::ArgumentError)
54
+ end
55
+
56
+ it 'should instantiate a backend given valid params' do
57
+ @backend.initialize(@attr)
58
+ @backend.instance.should_not == nil
59
+ end
60
+
61
+ end
62
+
63
+ describe 'operations' do
64
+
65
+ it 'should respond to create_subscription' do
66
+ @backend.initialize(@attr)
67
+ @backend.create_subscription(@subscription).should == true
68
+ end
69
+
70
+ it 'should respond to update_subscription' do
71
+ @backend.initialize(@attr)
72
+ @backend.update_subscription(@subscription).should == true
73
+ end
74
+
75
+ it 'should respond to cancel_subscription!' do
76
+ @backend.initialize(@attr)
77
+ @backend.cancel_subscription!(@subscription).should == true
78
+ end
79
+
80
+ end
81
+
82
+ end
@@ -0,0 +1,118 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe SubscriptionPlan do
4
+
5
+ before(:each) do
6
+ ActsAsSubscription::Subscription::Backend.config = {
7
+ :backend => :dummy,
8
+ :user => 'my_user',
9
+ :password => 'my_pass',
10
+ :product_code => 'my_product'
11
+ }
12
+
13
+ @attr = {
14
+ :code => 'FREE',
15
+ :name => 'free test plan',
16
+ :description => 'a bargain',
17
+ :billing_frequency => 'monthly',
18
+ :recurring_charge => 0.0
19
+ }
20
+
21
+ SubscriptionPlan.find(:all).each do |plan|
22
+ plan.destroy
23
+ end
24
+ end
25
+
26
+ describe 'validation' do
27
+
28
+ it 'should accept valid attributes' do
29
+ plan = SubscriptionPlan.new(@attr)
30
+ plan.should be_valid
31
+ lambda do
32
+ plan.save
33
+ end.should change(SubscriptionPlan, :count).by(1)
34
+ end
35
+
36
+ it 'should require a plan_code' do
37
+ plan = SubscriptionPlan.new(@attr.merge(:code => ''))
38
+ plan.should_not be_valid
39
+ end
40
+
41
+ it 'should ensure that plan_code is unique' do
42
+ plan = SubscriptionPlan.new(@attr.merge(:code => 'unique'))
43
+ plan.should be_valid
44
+ plan.save
45
+ plan = SubscriptionPlan.new(@attr.merge(:code => 'unique'))
46
+ plan.should_not be_valid
47
+ end
48
+
49
+ it 'should require a name' do
50
+ plan = SubscriptionPlan.new(@attr.merge(:name => ''))
51
+ plan.should_not be_valid
52
+ end
53
+
54
+ it 'should require a billing_frequency' do
55
+ plan = SubscriptionPlan.new(@attr.merge(:billing_frequency => ''))
56
+ plan.should_not be_valid
57
+ end
58
+
59
+ it 'should require a numeric recurring_charge' do
60
+ plan = SubscriptionPlan.new(@attr.merge(:recurring_charge => 'zero'))
61
+ plan.should_not be_valid
62
+ end
63
+
64
+ it 'should require a positive recurring_charge' do
65
+ plan = SubscriptionPlan.new(@attr.merge(:recurring_charge => -1))
66
+ plan.should_not be_valid
67
+ end
68
+
69
+ it 'should accept a recurring_charge of up to two decimal places' do
70
+ plan = SubscriptionPlan.new(@attr.merge(:name => 'test 1', :recurring_charge => 0))
71
+ plan.should be_valid
72
+ plan = SubscriptionPlan.new(@attr.merge(:name => 'test 2', :recurring_charge => 0.1))
73
+ plan.should be_valid
74
+ plan = SubscriptionPlan.new(@attr.merge(:name => 'test 3', :recurring_charge => 0.01))
75
+ plan.should be_valid
76
+ plan = SubscriptionPlan.new(@attr.merge(:name => 'test 4', :recurring_charge => 0.001))
77
+ plan.should_not be_valid
78
+ end
79
+
80
+ end
81
+
82
+ describe 'syncing' do
83
+
84
+ it 'should populate the database with plan records' do
85
+ SubscriptionPlan.sync!
86
+ SubscriptionPlan.find(:all).length.should == 3
87
+ end
88
+
89
+ it 'should update existing records if possible' do
90
+ plan = SubscriptionPlan.new(@attr)
91
+ plan.name.should == @attr[:name]
92
+ plan.save
93
+ SubscriptionPlan.sync!
94
+ SubscriptionPlan.find(:all).length.should == 3
95
+ SubscriptionPlan.find(plan.id).name.should_not == plan.name
96
+ end
97
+
98
+ end
99
+
100
+ describe 'form options' do
101
+
102
+ it 'should populate the form_options array' do
103
+ SubscriptionPlan.sync!
104
+ plans = SubscriptionPlan.find_all_by_active(true)
105
+ options = SubscriptionPlan.form_options
106
+ options.length.should == 3
107
+ plans.each do |plan|
108
+ if plan.recurring_charge > 0
109
+ options.include?(["#{plan.name} ($#{plan.recurring_charge})", plan.code]).should == true
110
+ else
111
+ options.include?([plan.name, plan.code]).should == true
112
+ end
113
+ end
114
+ end
115
+
116
+ end
117
+
118
+ end