saasaparilla 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/Gemfile +36 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +39 -0
- data/app/controllers/saasaparilla/admin/plans_controller.rb +87 -0
- data/app/controllers/saasaparilla/admin/subscriptions_controller.rb +34 -0
- data/app/controllers/saasaparilla/admin/transactions_controller.rb +14 -0
- data/app/controllers/saasaparilla/application_controller.rb +4 -0
- data/app/controllers/saasaparilla/billing_history_controller.rb +9 -0
- data/app/controllers/saasaparilla/contact_info_controller.rb +31 -0
- data/app/controllers/saasaparilla/credit_card_controller.rb +41 -0
- data/app/controllers/saasaparilla/invoices_controller.rb +19 -0
- data/app/controllers/saasaparilla/payments_controller.rb +71 -0
- data/app/controllers/saasaparilla/plans_controller.rb +34 -0
- data/app/controllers/saasaparilla/subscription_controller.rb +71 -0
- data/app/helpers/application_helper.rb +3 -0
- data/app/helpers/plans_helper.rb +2 -0
- data/app/helpers/saasaparilla/billing_history_helper.rb +4 -0
- data/app/mailers/saasaparilla/notifier.rb +38 -0
- data/app/models/billing_activity.rb +12 -0
- data/app/models/contact_info.rb +107 -0
- data/app/models/credit_card.rb +109 -0
- data/app/models/invoice.rb +31 -0
- data/app/models/invoice_line_item.rb +3 -0
- data/app/models/payment.rb +39 -0
- data/app/models/plan.rb +36 -0
- data/app/models/subscription.rb +363 -0
- data/app/models/transaction.rb +32 -0
- data/app/views/layouts/saasaparilla.html.haml +9 -0
- data/app/views/saasaparilla/admin/plans/_form.html.haml +45 -0
- data/app/views/saasaparilla/admin/plans/edit.html.erb +4 -0
- data/app/views/saasaparilla/admin/plans/index.html.erb +31 -0
- data/app/views/saasaparilla/admin/plans/new.html.haml +4 -0
- data/app/views/saasaparilla/admin/plans/show.html.haml +20 -0
- data/app/views/saasaparilla/admin/subscriptions/_subscription.html.haml +7 -0
- data/app/views/saasaparilla/admin/subscriptions/index.html.haml +14 -0
- data/app/views/saasaparilla/admin/subscriptions/show.html.haml +52 -0
- data/app/views/saasaparilla/admin/transactions/_transaction.html.haml +6 -0
- data/app/views/saasaparilla/admin/transactions/index.html.haml +16 -0
- data/app/views/saasaparilla/billing_history/_billing_activity.html.haml +10 -0
- data/app/views/saasaparilla/billing_history/show.html.haml +11 -0
- data/app/views/saasaparilla/contact_info/edit.html.haml +8 -0
- data/app/views/saasaparilla/credit_card/edit.html.haml +18 -0
- data/app/views/saasaparilla/invoices/show.html.haml +17 -0
- data/app/views/saasaparilla/notifier/billing_failed.html.haml +5 -0
- data/app/views/saasaparilla/notifier/billing_successful.html.haml +5 -0
- data/app/views/saasaparilla/notifier/invoice_created.html.haml +24 -0
- data/app/views/saasaparilla/notifier/pending_cancellation_notice.html.haml +6 -0
- data/app/views/saasaparilla/notifier/subscription_canceled.html.haml +4 -0
- data/app/views/saasaparilla/notifier/subscription_created.html.haml +5 -0
- data/app/views/saasaparilla/payments/edit.html.haml +10 -0
- data/app/views/saasaparilla/payments/new.html.haml +10 -0
- data/app/views/saasaparilla/payments/show.html.haml +8 -0
- data/app/views/saasaparilla/plans/edit.html.haml +34 -0
- data/app/views/saasaparilla/subscription/_contact_info_form.html.haml +19 -0
- data/app/views/saasaparilla/subscription/_credit_card_form.html.haml +10 -0
- data/app/views/saasaparilla/subscription/new.html.haml +24 -0
- data/app/views/saasaparilla/subscription/show.html.haml +73 -0
- data/autotest/discover.rb +2 -0
- data/config/routes.rb +27 -0
- data/lib/country_select/MIT-LICENSE +20 -0
- data/lib/country_select/README +15 -0
- data/lib/country_select/init.rb +1 -0
- data/lib/country_select/install.rb +2 -0
- data/lib/country_select/lib/country_select.rb +88 -0
- data/lib/country_select/uninstall.rb +1 -0
- data/lib/extensions/action_controller/base.rb +7 -0
- data/lib/extensions/active_record/nested_attributes.rb +36 -0
- data/lib/extensions/active_record/statuses.rb +16 -0
- data/lib/extensions/billable.rb +12 -0
- data/lib/generators/saasaparilla/install/install_generator.rb +29 -0
- data/lib/generators/saasaparilla/install/templates/create_saasaparilla_tables.rb +106 -0
- data/lib/generators/saasaparilla/install/templates/saasaparilla.yml +32 -0
- data/lib/initializers/auth_dot_net.rb +25 -0
- data/lib/initializers/simple_form.rb +77 -0
- data/lib/initializers/time_format.rb +3 -0
- data/lib/saasaparilla.rb +16 -0
- data/lib/saasaparilla/authentication.rb +18 -0
- data/lib/saasaparilla/authorization.rb +26 -0
- data/lib/saasaparilla/engine.rb +30 -0
- data/lib/saasaparilla/version.rb +3 -0
- data/saasaparilla.gemspec +48 -0
- data/spec/.livereload +21 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +11 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/model/user.rb +4 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +46 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +30 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/simple_form.rb +77 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/locales/simple_form.en.yml +24 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/config/saasaparilla.yml +32 -0
- data/spec/dummy/lib/templates/erb/scaffold/_form.html.erb +13 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/index.html +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/jquery.js +8374 -0
- data/spec/dummy/public/javascripts/jquery.min.js +16 -0
- data/spec/dummy/public/javascripts/rails.js +159 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/MIT-LICENSE +20 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/README +32 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/Rakefile +23 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/init.rb +1 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/install.rb +1 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/lib/authorize_net_cim_gateway_test.rb +492 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/lib/authorize_net_gateway_test.rb +133 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/lib/paypal_express_gateway_test.rb +138 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/tasks/activemerchant_testing_tasks.rake +4 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/test/activemerchant_testing_test.rb +8 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/test/test_helper.rb +3 -0
- data/spec/dummy/vendor/plugins/active_merchant_testing/uninstall.rb +1 -0
- data/spec/factories/factories.rb +75 -0
- data/spec/integration/navigation_spec.rb +9 -0
- data/spec/mailers/notifier_spec.rb +167 -0
- data/spec/models/billing_activity_spec.rb +27 -0
- data/spec/models/contact_info_spec.rb +32 -0
- data/spec/models/credit_card_spec.rb +57 -0
- data/spec/models/invoice_line_item_spec.rb +7 -0
- data/spec/models/invoice_spec.rb +25 -0
- data/spec/models/payment_spec.rb +29 -0
- data/spec/models/plan_spec.rb +16 -0
- data/spec/models/subscription_spec.rb +414 -0
- data/spec/requests/admin_plans_spec.rb +32 -0
- data/spec/requests/admin_subscriptions_spec.rb +31 -0
- data/spec/requests/billing_history_spec.rb +26 -0
- data/spec/requests/contact_info_controller_spec.rb +42 -0
- data/spec/requests/credit_cards_spec.rb +79 -0
- data/spec/requests/invoices_spec.rb +23 -0
- data/spec/requests/payments_spec.rb +89 -0
- data/spec/requests/subscription_plans_spec.rb +34 -0
- data/spec/requests/subscriptions_spec.rb +80 -0
- data/spec/spec_helper.rb +68 -0
- data/spec/spec_helpers/spec_helpers.rb +8 -0
- metadata +611 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BillingActivity do
|
4
|
+
it { should belong_to :subscription }
|
5
|
+
it { should have_one :invoice }
|
6
|
+
|
7
|
+
describe 'on charge' do
|
8
|
+
before(:each) do
|
9
|
+
plan = Factory.build(:plan, :name => "Gold", :price => 20)
|
10
|
+
contact_info = Factory.build(:contact_info)
|
11
|
+
|
12
|
+
credit_card = Factory.build(:credit_card)
|
13
|
+
@subscription = Factory(:subscription, :contact_info => contact_info, :plan => plan, :credit_card => credit_card)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should create a new billing activity on successful charge' do
|
17
|
+
@subscription.bill!
|
18
|
+
@subscription.billing_activities.count.should == 2
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should create link to invoice in message if it has an invoice' do
|
23
|
+
@subscription.invoice!
|
24
|
+
@subscription.billing_activities.last.message.should include "<a href"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ContactInfo do
|
4
|
+
|
5
|
+
it { should belong_to :subscription }
|
6
|
+
it { should validate_presence_of :first_name}
|
7
|
+
it { should validate_presence_of :last_name}
|
8
|
+
it { should validate_presence_of :email}
|
9
|
+
it { should validate_presence_of :address}
|
10
|
+
it { should validate_presence_of :city}
|
11
|
+
it { should validate_presence_of :state}
|
12
|
+
it { should validate_presence_of :zip}
|
13
|
+
it { should validate_presence_of :country}
|
14
|
+
|
15
|
+
it 'should make full name' do
|
16
|
+
contact_info = Factory(:contact_info)
|
17
|
+
contact_info.full_name.should == "#{contact_info.first_name} #{contact_info.last_name}"
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should have a valid phone numer' do
|
21
|
+
contact_info = Factory(:contact_info)
|
22
|
+
contact_info.update_attributes :phone_area_code => "123", :phone_prefix => "123", :phone_suffix => "1234"
|
23
|
+
contact_info.should be_valid
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should have errors with an invalid phone number' do
|
27
|
+
contact_info = Factory(:contact_info)
|
28
|
+
contact_info.update_attributes :phone_area_code => "1", :phone_prefix => "1", :phone_suffix => "1"
|
29
|
+
contact_info.should_not be_valid
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CreditCard do
|
4
|
+
|
5
|
+
it { should belong_to :subscription }
|
6
|
+
|
7
|
+
|
8
|
+
it 'should produce credit card from valid attributes' do
|
9
|
+
credit_card = Factory(:credit_card)
|
10
|
+
credit_card.active_merchant_card.class.should == ActiveMerchant::Billing::CreditCard
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'Card create' do
|
14
|
+
before(:each) do
|
15
|
+
@credit_card = Factory(:credit_card)
|
16
|
+
end
|
17
|
+
it 'should retain card number' do
|
18
|
+
@credit_card.card_number.should_not == nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should retain masked card number' do
|
22
|
+
@credit_card.card_number.should == "XXXXXXXXXXXX1111"
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should retain expiration date' do
|
26
|
+
@credit_card.expiration_date.should == "10/2011"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
describe 'Card Update' do
|
32
|
+
before(:each) do
|
33
|
+
@plan = Factory.build(:plan, :name => "Gold", :price => 20)
|
34
|
+
@contact_info = Factory.build(:contact_info)
|
35
|
+
|
36
|
+
@credit_card = Factory.build(:credit_card)
|
37
|
+
@subscription = Factory(:subscription, :contact_info => @contact_info, :plan => @plan, :credit_card => @credit_card)
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
it 'should update card on auth.net' do
|
42
|
+
@credit_card.should_receive(:update_payment_profile)
|
43
|
+
@credit_card.update_attributes(
|
44
|
+
# :first_name =>"new",
|
45
|
+
# :last_name => "value",
|
46
|
+
:card_type => "Visa",
|
47
|
+
:card_number => "4111111111111111",
|
48
|
+
:card_verification => "545",
|
49
|
+
:expiry_month => "10",
|
50
|
+
:expiry_year => "2011")
|
51
|
+
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Invoice do
|
4
|
+
it { should belong_to :billing_activity }
|
5
|
+
it { should have_many :invoice_line_items }
|
6
|
+
|
7
|
+
describe 'on create' do
|
8
|
+
|
9
|
+
before(:all) do
|
10
|
+
plan = Factory.build(:plan, :name => "Gold", :price => 20.0)
|
11
|
+
contact_info = Factory.build(:contact_info)
|
12
|
+
credit_card = Factory.build(:credit_card)
|
13
|
+
@subscription = Factory.build(:subscription, :contact_info => contact_info, :plan => plan, :credit_card => credit_card)
|
14
|
+
@subscription.save
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should send invoice_created email' do
|
18
|
+
ActionMailer::Base.deliveries = [];
|
19
|
+
@subscription.invoice!
|
20
|
+
ActionMailer::Base.deliveries.first.subject.should =~ /Invoice Created/
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe Payment do
|
3
|
+
before(:each) do
|
4
|
+
@plan = Factory.build(:plan, :name => "Gold", :price => 20)
|
5
|
+
@contact_info = Factory.build(:contact_info)
|
6
|
+
|
7
|
+
@credit_card = Factory.build(:credit_card)
|
8
|
+
|
9
|
+
@subscription = Factory(:subscription, :contact_info => @contact_info, :plan => @plan, :credit_card => @credit_card)
|
10
|
+
|
11
|
+
@subscription.update_attributes(:balance => 15)
|
12
|
+
@payment = Factory(:payment, :amount => 12, :subscription => @subscription)
|
13
|
+
@user = Factory(:user, :subscription => @subscription)
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
it 'should create a successful transaction on update' do
|
19
|
+
@payment.should_receive(:charge_subscription)
|
20
|
+
@payment.save
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should set status to paid after bill!' do
|
24
|
+
@payment.save
|
25
|
+
@payment.status.should == 'paid'
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Plan do
|
4
|
+
it {should validate_presence_of :name}
|
5
|
+
it {should validate_presence_of :billing_period}
|
6
|
+
it {should validate_numericality_of :price}
|
7
|
+
it {should validate_presence_of :price}
|
8
|
+
it {should allow_mass_assignment_of [:name, :billing_period]}
|
9
|
+
it { should have_many :subscriptions}
|
10
|
+
|
11
|
+
it 'should have dynamic attributes' do
|
12
|
+
p = Factory.create(:plan)
|
13
|
+
p.update_attributes(:field_testing => "test")
|
14
|
+
p.testing.should == "test"
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,414 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Subscription do
|
4
|
+
|
5
|
+
it { should have_one :contact_info }
|
6
|
+
it { should have_many :billing_activities }
|
7
|
+
it { should have_one :credit_card }
|
8
|
+
|
9
|
+
describe 'on create' do
|
10
|
+
before(:each) do
|
11
|
+
plan = Factory.build(:plan, :name => "Gold", :price => 20.0)
|
12
|
+
contact_info = Factory.build(:contact_info)
|
13
|
+
credit_card = Factory.build(:credit_card)
|
14
|
+
@subscription = Factory.build(:subscription, :contact_info => contact_info, :plan => plan, :credit_card => credit_card)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should be invalid with invalid contact_info' do
|
18
|
+
@subscription.contact_info.update_attributes(:phone_area_code => "1", :phone_prefix => "1", :phone_suffix => "1")
|
19
|
+
@subscription.should_not be_valid
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should make parent billable if is_billable' do
|
23
|
+
|
24
|
+
user = Factory.create(:user, :subscription => @subscription)
|
25
|
+
user.billable?
|
26
|
+
user.subscription.billable.should == user
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should add cim number on create' do
|
30
|
+
@subscription.save
|
31
|
+
@subscription.customer_cim_id.should_not be_nil
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should have contact_info' do
|
35
|
+
@subscription.save
|
36
|
+
@subscription.reload
|
37
|
+
@subscription.contact_info.should_not be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should create payment profile after create' do
|
41
|
+
@subscription.save
|
42
|
+
@subscription.customer_payment_profile_id.should_not == nil
|
43
|
+
end
|
44
|
+
|
45
|
+
# it 'should have an inital balance' do
|
46
|
+
# @subscription.should_receive(:balance=).with(20.0)
|
47
|
+
# @subscription.save
|
48
|
+
# end
|
49
|
+
|
50
|
+
it 'should send subscription_created email' do
|
51
|
+
ActionMailer::Base.deliveries = [];
|
52
|
+
@subscription.save
|
53
|
+
ActionMailer::Base.deliveries.last.subject.should =~ /Subscription Created/
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should have status active' do
|
57
|
+
@subscription.save
|
58
|
+
@subscription.active?.should == true
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
it 'should have status of active after successful billing' do
|
63
|
+
@subscription.save
|
64
|
+
@subscription.stub!(:charge_amount).with(@subscription.balance).and_return true
|
65
|
+
|
66
|
+
@subscription.bill!
|
67
|
+
@subscription.active?.should == true
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should have status of overdue after unsuccessful billing' do
|
71
|
+
#Pending
|
72
|
+
# @subscription.save
|
73
|
+
# @subscription.stub!(:charge_amount).with(@subscription.balance).and_return false
|
74
|
+
#
|
75
|
+
# @subscription.do_inital_billing
|
76
|
+
# @subscription.overdue?.should == true
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should return set subscription balance to 0 on successful charge' do
|
80
|
+
@subscription.save
|
81
|
+
@subscription.bill!
|
82
|
+
@subscription.balance.should == 0
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should keep status at :ok on successful charge' do
|
87
|
+
@subscription.save
|
88
|
+
@subscription.bill!
|
89
|
+
@subscription.active?.should == true
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should charge an inital balance' do
|
94
|
+
@subscription.should_receive(:charge_amount).with(20.0)
|
95
|
+
@subscription.save
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should have an billing activity after inital charge' do
|
99
|
+
@subscription.save
|
100
|
+
@subscription.billing_activities.count.should == 1
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should set billing date after inital charge' do
|
104
|
+
@subscription.save
|
105
|
+
@subscription.billing_date.should == Date.today + 1.months
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'should create a billing activity on charge' do
|
109
|
+
@subscription.save
|
110
|
+
@subscription.billing_activities.count.should == 1
|
111
|
+
@subscription.update_attributes(:balance => 30.0)
|
112
|
+
@subscription.bill!(30.00)
|
113
|
+
@subscription.billing_activities.count.should == 2
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should send billing_successful email on charge' do
|
117
|
+
ActionMailer::Base.deliveries = [];
|
118
|
+
@subscription.save
|
119
|
+
@subscription.update_attributes(:balance => 30.0)
|
120
|
+
@subscription.bill!
|
121
|
+
ActionMailer::Base.deliveries.first.subject.should =~ /Account Billing Successful/
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should subtract balance on bill!' do
|
125
|
+
@subscription.save
|
126
|
+
@subscription.billing_activities.count.should == 1
|
127
|
+
@subscription.update_attributes(:balance => 30.0)
|
128
|
+
@subscription.bill!(10.00)
|
129
|
+
@subscription.balance.should == 20.0
|
130
|
+
end
|
131
|
+
it 'should not change status if oustanding balance not paid' do
|
132
|
+
@subscription.save
|
133
|
+
@subscription.billing_activities.count.should == 1
|
134
|
+
@subscription.update_attributes(:balance => 30.0, :status => "overdue")
|
135
|
+
@subscription.bill!(10.00)
|
136
|
+
@subscription.status.should == "overdue"
|
137
|
+
|
138
|
+
end
|
139
|
+
it 'should change status if oustanding balancepaid' do
|
140
|
+
@subscription.save
|
141
|
+
@subscription.billing_activities.count.should == 1
|
142
|
+
@subscription.update_attributes(:balance => 30.0, :status => "overdue")
|
143
|
+
@subscription.bill!(30.00)
|
144
|
+
@subscription.status.should == "active"
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should set cancel status to pending_cancel' do
|
149
|
+
@subscription.save
|
150
|
+
@subscription.cancel
|
151
|
+
@subscription.status.should == "canceled"
|
152
|
+
|
153
|
+
end
|
154
|
+
it 'should return last transaction date' do
|
155
|
+
@subscription.save
|
156
|
+
@subscription.last_transaction_date.should == Date.today.to_s(:month_day_year)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should return - if no transactions on last transaction date' do
|
160
|
+
@subscription.last_transaction_date.should == '-'
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should return plan name' do
|
164
|
+
@subscription.plan_name.should == "Gold"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe 'on update' do
|
169
|
+
before(:each) do
|
170
|
+
@plan1 = Factory.build(:plan, :name => "Basic", :price => 10.0)
|
171
|
+
@plan2 = Factory.build(:plan, :name => "Premium", :price => 20.0)
|
172
|
+
contact_info = Factory.build(:contact_info)
|
173
|
+
credit_card = Factory.build(:credit_card)
|
174
|
+
@subscription = Factory.build(:subscription, :contact_info => contact_info, :plan => @plan1, :credit_card => credit_card)
|
175
|
+
@subscription.save
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should bill correct amount with pro-rated credit for mid-cycle upgrades' do
|
179
|
+
@subscription.update_attributes(:billing_date => Date.today + 15.days)
|
180
|
+
@subscription.update_attributes(:plan => @plan2)
|
181
|
+
@subscription.billing_activities.count.should == 2
|
182
|
+
@subscription.billing_activities.last.amount.should == 15.0
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should bill correct amount with pro-rated credit for early-cycle upgrades' do
|
186
|
+
@subscription.update_attributes(:billing_date => Date.today + 29.days)
|
187
|
+
@subscription.update_attributes(:plan => @plan2)
|
188
|
+
@subscription.billing_activities.count.should == 2
|
189
|
+
@subscription.billing_activities.last.amount.should == 10.3
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should not bill for upgrades on currently invoiced accounts' do
|
193
|
+
@subscription.update_attributes(:billing_date => Date.today + 3.days)
|
194
|
+
@subscription.update_attributes(:plan => @plan2)
|
195
|
+
@subscription.billing_activities.count.should == 1
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should reactivate canceled accounts' do
|
199
|
+
@subscription.update_attributes(:status => "canceled")
|
200
|
+
@subscription.reactivate!
|
201
|
+
@subscription.status.should == "active"
|
202
|
+
@subscription.billing_activities.count.should == 2
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
end
|
207
|
+
|
208
|
+
describe 'billing' do
|
209
|
+
before(:each) do
|
210
|
+
plan = Factory(:plan, :name => "Gold", :price => 20.0)
|
211
|
+
plan2 = Factory(:plan, :name => "Gold", :price => 20.0, :billing_period => "annually")
|
212
|
+
contact_info1 = Factory.build(:contact_info)
|
213
|
+
contact_info2 = Factory.build(:contact_info)
|
214
|
+
contact_info3 = Factory.build(:contact_info)
|
215
|
+
contact_info4 = Factory.build(:contact_info)
|
216
|
+
credit_card1 = Factory.build(:credit_card)
|
217
|
+
credit_card2 = Factory.build(:credit_card)
|
218
|
+
credit_card3 = Factory.build(:credit_card)
|
219
|
+
credit_card4 = Factory.build(:credit_card)
|
220
|
+
@subscription1 = Factory(:subscription, :contact_info => contact_info1, :plan => plan, :credit_card => credit_card1)
|
221
|
+
@subscription2 = Factory(:subscription, :contact_info => contact_info2, :plan => plan, :credit_card => credit_card2)
|
222
|
+
@subscription3 = Factory(:subscription, :contact_info => contact_info3, :plan => plan, :credit_card => credit_card3)
|
223
|
+
@subscription4 = Factory(:subscription, :contact_info => contact_info4, :plan => plan2, :credit_card => credit_card4)
|
224
|
+
@subscription1.update_attributes(:balance => 12, :billing_date => Date.today)
|
225
|
+
@subscription2.update_attributes(:balance => 12, :billing_date => Date.today)
|
226
|
+
@subscription3.update_attributes(:balance => 12, :billing_date => Date.today + 1.days)
|
227
|
+
@subscription4.update_attributes(:balance => 12, :billing_date => Date.today - 1.days)
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'should find all non canceled subscriptions' do
|
231
|
+
@subscription2.cancel
|
232
|
+
Subscription.active.count.should == 3
|
233
|
+
end
|
234
|
+
it 'should find billable models' do
|
235
|
+
|
236
|
+
|
237
|
+
Subscription.active.all_billable_subscriptions(Date.today).count.should == 3
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'should find invoiceable models' do
|
241
|
+
@subscription1.update_attributes(:billing_date => (Date.today + 1.days))
|
242
|
+
@subscription2.update_attributes(:billing_date => (Date.today + 6.days))
|
243
|
+
@subscription3.update_attributes(:billing_date => (Date.today + 5.days), :invoiced_on => Date.today - 1.months)
|
244
|
+
@subscription4.update_attributes(:billing_date => (Date.today + 5.days), :invoiced_on => Date.today - 2.days)
|
245
|
+
@subscriptions = Subscription.active.all_invoiceable(Date.today)
|
246
|
+
@subscriptions.count.should == 2
|
247
|
+
@subscriptions.should include @subscription1
|
248
|
+
@subscriptions.should include @subscription4
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'should find billable models' do
|
252
|
+
@subscription1.update_attributes(:balance => 0)
|
253
|
+
@subscription4.update_attributes(:balance => 12, :status => "canceled")
|
254
|
+
Subscription.active.all_billable_subscriptions(Date.today).count.should == 1
|
255
|
+
end
|
256
|
+
|
257
|
+
describe 'recurring billing' do
|
258
|
+
describe 'trial period' do
|
259
|
+
before(:each) do
|
260
|
+
Saasaparilla::CONFIG["trial_period"] = 3
|
261
|
+
plan = Factory(:plan, :name => "Gold", :price => 20.0)
|
262
|
+
contact_info = Factory.build(:contact_info)
|
263
|
+
credit_card = Factory.build(:credit_card)
|
264
|
+
@subscription = Factory(:subscription, :contact_info => contact_info, :plan => plan, :credit_card => credit_card)
|
265
|
+
end
|
266
|
+
after(:each) do
|
267
|
+
Saasaparilla::CONFIG["trial_period"] = 0
|
268
|
+
end
|
269
|
+
it "should not bill on create if grace period " do
|
270
|
+
|
271
|
+
@subscription.billing_activities.count.should == 0
|
272
|
+
|
273
|
+
end
|
274
|
+
it "shouldn't charge subscrition until after trial period" do
|
275
|
+
|
276
|
+
Date.should_receive(:today).any_number_of_times.and_return(Time.now.to_date + 2.months)
|
277
|
+
Subscription.find_and_bill_recurring_subscriptions
|
278
|
+
@subscription.billing_activities.count.should == 0
|
279
|
+
|
280
|
+
|
281
|
+
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should charge subscription after trial period" do
|
285
|
+
Date.should_receive(:today).any_number_of_times.and_return(Time.now.to_date + 3.months )
|
286
|
+
Subscription.find_and_bill_recurring_subscriptions
|
287
|
+
@subscription.billing_activities.count.should == 1
|
288
|
+
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
292
|
+
it 'should reset charge subscription' do
|
293
|
+
Subscription.find_and_bill_recurring_subscriptions
|
294
|
+
@subscription1.billing_activities.count.should == 2
|
295
|
+
@subscription2.billing_activities.count.should == 2
|
296
|
+
@subscription3.billing_activities.count.should == 1
|
297
|
+
@subscription4.billing_activities.count.should == 2
|
298
|
+
end
|
299
|
+
|
300
|
+
it 'should change status of subscription to overdue if failed billing' do
|
301
|
+
GATEWAYCIM.success = false
|
302
|
+
Subscription.find_and_bill_recurring_subscriptions
|
303
|
+
GATEWAYCIM.success = true
|
304
|
+
@subscription1.reload.overdue?.should == true
|
305
|
+
end
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
it 'should send billing_failed email if failed billing' do
|
310
|
+
GATEWAYCIM.success = false
|
311
|
+
ActionMailer::Base.deliveries = [];
|
312
|
+
@subscription2.update_attributes(:status => 'canceled')
|
313
|
+
@subscription3.update_attributes(:status => 'canceled')
|
314
|
+
@subscription4.update_attributes(:status => 'canceled')
|
315
|
+
Subscription.find_and_bill_recurring_subscriptions
|
316
|
+
ActionMailer::Base.deliveries.first.subject.should =~ /Account Billing Failed/
|
317
|
+
GATEWAYCIM.success = true
|
318
|
+
end
|
319
|
+
|
320
|
+
it 'should change status of subscription to canceled if failed over grace period' do
|
321
|
+
@subscription1.update_attributes(:billing_date => Date.today - 11.days, :status => "overdue")
|
322
|
+
GATEWAYCIM.success = false
|
323
|
+
Subscription.find_and_bill_recurring_subscriptions
|
324
|
+
GATEWAYCIM.success = true
|
325
|
+
@subscription1.reload.canceled?.should == true
|
326
|
+
end
|
327
|
+
|
328
|
+
it 'should send subscription_canceled email if failed over grace period' do
|
329
|
+
ActionMailer::Base.deliveries = [];
|
330
|
+
@subscription1.update_attributes(:billing_date => Date.today - 11.days, :status => "overdue")
|
331
|
+
@subscription2.update_attributes(:status => 'canceled')
|
332
|
+
@subscription3.update_attributes(:status => 'canceled')
|
333
|
+
@subscription4.update_attributes(:status => 'canceled')
|
334
|
+
GATEWAYCIM.success = false
|
335
|
+
Subscription.find_and_bill_recurring_subscriptions
|
336
|
+
GATEWAYCIM.success = true
|
337
|
+
ActionMailer::Base.deliveries.first.subject.should =~ /Your subscription has been canceled/
|
338
|
+
end
|
339
|
+
|
340
|
+
it 'should send pending_cancellation_notice email if failed and 1 day before over grace period' do
|
341
|
+
GATEWAYCIM.success = false
|
342
|
+
ActionMailer::Base.deliveries = [];
|
343
|
+
@subscription1.update_attributes(:billing_date => Date.today - 9.days, :status => "overdue")
|
344
|
+
@subscription2.update_attributes(:status => 'canceled')
|
345
|
+
@subscription3.update_attributes(:status => 'canceled')
|
346
|
+
@subscription4.update_attributes(:status => 'canceled')
|
347
|
+
Subscription.find_and_bill_recurring_subscriptions
|
348
|
+
ActionMailer::Base.deliveries.first.subject.should =~ /Your subscription will be canceled soon/
|
349
|
+
GATEWAYCIM.success = true
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'should not change status if subscription not past grace period on failed billing' do
|
353
|
+
@subscription2.update_attributes(:billing_date => Date.today - 9.days, :status => "overdue", :overdue_on => Date.today - 9.days)
|
354
|
+
GATEWAYCIM.success = false
|
355
|
+
Subscription.find_and_bill_recurring_subscriptions
|
356
|
+
GATEWAYCIM.success = true
|
357
|
+
@subscription2.reload.overdue?.should == true
|
358
|
+
end
|
359
|
+
|
360
|
+
it 'should set overdue_on to todays date when payment failed' do
|
361
|
+
@subscription1.update_attributes(:billing_date => Date.today , :status => "active")
|
362
|
+
GATEWAYCIM.success = false
|
363
|
+
Subscription.find_and_bill_recurring_subscriptions
|
364
|
+
GATEWAYCIM.success = true
|
365
|
+
@subscription1.reload.overdue?.should == true
|
366
|
+
@subscription1.overdue_on.should == Date.today
|
367
|
+
end
|
368
|
+
it 'should set billing date to next month' do
|
369
|
+
@billing_date1_old = @subscription1.billing_date
|
370
|
+
@billing_date2_old = @subscription2.billing_date
|
371
|
+
@billing_date4_old = @subscription4.billing_date
|
372
|
+
Subscription.find_and_bill_recurring_subscriptions
|
373
|
+
@subscription1.reload.billing_date.should == @billing_date1_old + 1.months
|
374
|
+
@subscription2.reload.billing_date.should == @billing_date2_old + 1.months
|
375
|
+
@subscription4.reload.billing_date.should == @billing_date4_old + 1.years
|
376
|
+
end
|
377
|
+
|
378
|
+
it 'should set balance on invoice' do
|
379
|
+
@subscription1.balance.should == 12.0
|
380
|
+
@subscription1.invoice!
|
381
|
+
@subscription1.reload
|
382
|
+
@subscription1.balance.should == 32.0
|
383
|
+
end
|
384
|
+
it 'should create invoice on invoice' do
|
385
|
+
@subscription1.invoice!
|
386
|
+
|
387
|
+
@subscription1.billing_activities.last.invoice.should_not == nil
|
388
|
+
end
|
389
|
+
|
390
|
+
it 'should get amount on invoice after create invoice' do
|
391
|
+
@subscription1.invoice!
|
392
|
+
@subscription1.billing_activities.last.invoice.amount.should == 20.0
|
393
|
+
end
|
394
|
+
it 'should set invoiced_on after invoice' do
|
395
|
+
@subscription1.invoice!
|
396
|
+
@subscription1.invoiced_on.should == Date.today
|
397
|
+
end
|
398
|
+
|
399
|
+
it 'should set to and from date on invoice after invoice' do
|
400
|
+
@subscription1.invoice!
|
401
|
+
@subscription1.billing_activities.last.invoice.invoice_line_items.first.to.should == @subscription1.billing_date
|
402
|
+
end
|
403
|
+
|
404
|
+
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
|
409
|
+
|
410
|
+
|
411
|
+
|
412
|
+
|
413
|
+
|
414
|
+
end
|