saucy 0.2.20 → 0.2.21
Sign up to get free protection for your applications and to get access to all the features.
- data/app/views/plans/_plan.html.erb +4 -0
- data/config/locales/en.yml +8 -0
- data/lib/generators/saucy/features/features_generator.rb +3 -0
- data/lib/generators/saucy/features/templates/features/trial_plans.feature +48 -0
- data/lib/generators/saucy/features/templates/step_definitions/account_steps.rb +5 -0
- data/lib/generators/saucy/install/templates/create_saucy_tables.rb +2 -1
- data/lib/saucy/account.rb +9 -1
- data/lib/saucy/account_authorization.rb +14 -6
- data/lib/saucy/subscription.rb +11 -3
- data/spec/models/account_spec.rb +15 -0
- metadata +6 -4
data/config/locales/en.yml
CHANGED
@@ -4,3 +4,11 @@ en:
|
|
4
4
|
support_email: support@example.com
|
5
5
|
saucy:
|
6
6
|
billing_address: Billing Address
|
7
|
+
errors:
|
8
|
+
past_due:
|
9
|
+
admin: There was an issue processing the credit card you have on file. Please update your credit card information.
|
10
|
+
user: There was an issue processing the credit card on file for this account. Please have an administrator on the account update the credit card information.
|
11
|
+
expired:
|
12
|
+
admin: Your account's trial has expired. Please upgrade to another plan.
|
13
|
+
user: This account's trial has expired. Please have an administrator on the account upgrade to another plan.
|
14
|
+
|
@@ -51,6 +51,9 @@ DESC
|
|
51
51
|
when /^the billing page for the "([^"]+)" account$/
|
52
52
|
account = Account.find_by_name!($1)
|
53
53
|
account_billing_path(account)
|
54
|
+
when /^the upgrade plan page for the "([^"]+)" account$/
|
55
|
+
account = Account.find_by_name!($1)
|
56
|
+
edit_account_plan_path(account)
|
54
57
|
PATHS
|
55
58
|
|
56
59
|
replace_in_file "features/support/paths.rb",
|
@@ -0,0 +1,48 @@
|
|
1
|
+
Feature: Trial plans
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given the following plan exists:
|
5
|
+
| name | price | trial |
|
6
|
+
| Trial | 0 | true |
|
7
|
+
| Eternal | 0 | false |
|
8
|
+
|
9
|
+
Scenario: Sign up for a trial plan
|
10
|
+
When I go to the list of plans page
|
11
|
+
And I follow "Trial"
|
12
|
+
And I should see "Your trial will expire after 30 days"
|
13
|
+
And I fill in "Email" with "email@person.com"
|
14
|
+
And I fill in "Password" with "password"
|
15
|
+
And I fill in "Confirm password" with "password"
|
16
|
+
And I fill in "Your name" with "Robot"
|
17
|
+
And I fill in "Company Name" with "Robots, Inc"
|
18
|
+
And I fill in "Keyword" with "robotsinc"
|
19
|
+
And I press "Sign up"
|
20
|
+
Then I should see "created"
|
21
|
+
|
22
|
+
Scenario: use an account during the trial
|
23
|
+
Given a "Trial" account exists with a name of "Test" created 29 days ago
|
24
|
+
And I am signed in as an admin of the "Test" account
|
25
|
+
When I go to the projects page for the "Test" account
|
26
|
+
Then I should see "Test"
|
27
|
+
And I should not see "expired"
|
28
|
+
|
29
|
+
Scenario: Try to use an expired trial plan
|
30
|
+
Given a "Trial" account exists with a name of "Test" created 30 days ago
|
31
|
+
And I am signed in as an admin of the "Test" account
|
32
|
+
When I go to the projects page for the "Test" account
|
33
|
+
Then I should be on the upgrade plan page for the "Test" account
|
34
|
+
And I should see "expired"
|
35
|
+
And the "Trial" plan should be disabled
|
36
|
+
|
37
|
+
Scenario: Sign up for a non-trial plan
|
38
|
+
When I go to the list of plans page
|
39
|
+
And I follow "Eternal"
|
40
|
+
Then I should not see "trial"
|
41
|
+
|
42
|
+
Scenario: Use a non-trial plan forever
|
43
|
+
Given an "Eternal" account exists with a name of "Test" created 30 days ago
|
44
|
+
And I am signed in as an admin of the "Test" account
|
45
|
+
When I go to the projects page for the "Test" account
|
46
|
+
Then I should see "Test"
|
47
|
+
And I should not see "expired"
|
48
|
+
|
@@ -30,7 +30,7 @@ class CreateSaucyTables < ActiveRecord::Migration
|
|
30
30
|
table.integer :account_id
|
31
31
|
table.boolean :admin
|
32
32
|
table.string :code
|
33
|
-
table.boolean :used
|
33
|
+
table.boolean :used, :default => false, :null => false
|
34
34
|
table.datetime :created_at
|
35
35
|
table.datetime :updated_at
|
36
36
|
end
|
@@ -64,6 +64,7 @@ class CreateSaucyTables < ActiveRecord::Migration
|
|
64
64
|
create_table :plans do |t|
|
65
65
|
t.string :name
|
66
66
|
t.integer :price, :null => false, :default => 0
|
67
|
+
t.boolean :trial, :default => false, :null => false
|
67
68
|
|
68
69
|
t.timestamps
|
69
70
|
end
|
data/lib/saucy/account.rb
CHANGED
@@ -14,7 +14,7 @@ module Saucy
|
|
14
14
|
|
15
15
|
belongs_to :plan
|
16
16
|
|
17
|
-
delegate :free?, :billed?, :to => :plan
|
17
|
+
delegate :free?, :billed?, :trial?, :to => :plan
|
18
18
|
|
19
19
|
validates_uniqueness_of :name, :keyword
|
20
20
|
validates_presence_of :name, :keyword, :plan_id
|
@@ -50,6 +50,14 @@ module Saucy
|
|
50
50
|
def memberships_by_name
|
51
51
|
memberships.by_name
|
52
52
|
end
|
53
|
+
|
54
|
+
def expired?
|
55
|
+
trial? && past_trial?
|
56
|
+
end
|
57
|
+
|
58
|
+
def past_trial?
|
59
|
+
created_at < 30.days.ago
|
60
|
+
end
|
53
61
|
end
|
54
62
|
end
|
55
63
|
end
|
@@ -39,15 +39,23 @@ module Saucy
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def ensure_active_account
|
42
|
-
if current_account?
|
43
|
-
if
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
if current_account?
|
43
|
+
if current_account.past_due?
|
44
|
+
redirect_unusable_account account_billing_path(current_account),
|
45
|
+
"past_due"
|
46
|
+
end
|
47
|
+
if current_account.expired?
|
48
|
+
redirect_unusable_account edit_account_plan_path(current_account),
|
49
|
+
"expired"
|
47
50
|
end
|
48
|
-
redirect_to account_billing_path(current_account)
|
49
51
|
end
|
50
52
|
end
|
53
|
+
|
54
|
+
def redirect_unusable_account(path, failure)
|
55
|
+
role = current_user.admin_of?(current_account) ? 'admin' : 'user'
|
56
|
+
flash[:alert] = t("saucy.errors.#{failure}.#{role}")
|
57
|
+
redirect_to path
|
58
|
+
end
|
51
59
|
end
|
52
60
|
end
|
53
61
|
end
|
data/lib/saucy/subscription.rb
CHANGED
@@ -55,9 +55,7 @@ module Saucy
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def can_change_plan_to?(new_plan)
|
58
|
-
|
59
|
-
new_plan.limit(limit.name).value >= send(limit.name).count
|
60
|
-
end
|
58
|
+
within_limits_for?(new_plan) && !past_trial_for?(new_plan)
|
61
59
|
end
|
62
60
|
|
63
61
|
def past_due?
|
@@ -66,6 +64,16 @@ module Saucy
|
|
66
64
|
|
67
65
|
private
|
68
66
|
|
67
|
+
def within_limits_for?(new_plan)
|
68
|
+
new_plan.limits.where(:value_type => :number).all? do |limit|
|
69
|
+
new_plan.limit(limit.name).value >= send(limit.name).count
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def past_trial_for?(new_plan)
|
74
|
+
new_plan.trial? && past_trial?
|
75
|
+
end
|
76
|
+
|
69
77
|
def retry_subscription_charge!
|
70
78
|
authorized_transaction = Braintree::Subscription.retry_charge(subscription.id).transaction
|
71
79
|
result = Braintree::Transaction.submit_for_settlement(authorized_transaction.id)
|
data/spec/models/account_spec.rb
CHANGED
@@ -65,4 +65,19 @@ describe Account do
|
|
65
65
|
|
66
66
|
result.should == expected
|
67
67
|
end
|
68
|
+
|
69
|
+
it "is expired with a trial plan after 30 days" do
|
70
|
+
trial = Factory(:plan, :trial => true)
|
71
|
+
Factory(:account, :created_at => 30.days.ago, :plan => trial).should be_expired
|
72
|
+
end
|
73
|
+
|
74
|
+
it "isn't expired with a trial plan before 30 days" do
|
75
|
+
trial = Factory(:plan, :trial => true)
|
76
|
+
Factory(:account, :created_at => 29.days.ago, :plan => trial).should_not be_expired
|
77
|
+
end
|
78
|
+
|
79
|
+
it "isn't expired with a non-trial plan after 30 days" do
|
80
|
+
forever = Factory(:plan, :trial => false)
|
81
|
+
Factory(:account, :created_at => 30.days.ago, :plan => forever).should_not be_expired
|
82
|
+
end
|
68
83
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saucy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 61
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 21
|
10
|
+
version: 0.2.21
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- thoughtbot, inc.
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2011-02-
|
20
|
+
date: 2011-02-14 00:00:00 -05:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|
@@ -176,6 +176,7 @@ files:
|
|
176
176
|
- lib/generators/saucy/base.rb
|
177
177
|
- lib/generators/saucy/features/features_generator.rb
|
178
178
|
- lib/generators/saucy/features/templates/factories.rb
|
179
|
+
- lib/generators/saucy/features/templates/step_definitions/account_steps.rb
|
179
180
|
- lib/generators/saucy/features/templates/step_definitions/braintree_steps.rb
|
180
181
|
- lib/generators/saucy/features/templates/step_definitions/email_steps.rb
|
181
182
|
- lib/generators/saucy/features/templates/step_definitions/factory_girl_steps.rb
|
@@ -226,6 +227,7 @@ files:
|
|
226
227
|
- lib/generators/saucy/features/templates/features/new_account.feature
|
227
228
|
- lib/generators/saucy/features/templates/features/sign_up.feature
|
228
229
|
- lib/generators/saucy/features/templates/features/sign_up_paid.feature
|
230
|
+
- lib/generators/saucy/features/templates/features/trial_plans.feature
|
229
231
|
- lib/generators/saucy/features/templates/README
|
230
232
|
- spec/controllers/accounts_controller_spec.rb
|
231
233
|
- spec/controllers/application_controller_spec.rb
|