acts_as_subscription 0.0.1

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.
@@ -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