saucy 0.2.20 → 0.2.21
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.
- 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
|