saucy 0.12.0 → 0.12.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +4 -0
- data/README.md +6 -0
- data/config/locales/en.yml +2 -2
- data/lib/saucy/account.rb +3 -3
- data/lib/saucy/configuration.rb +6 -0
- data/spec/models/account_spec.rb +54 -0
- data/spec/saucy/configuration_spec.rb +42 -0
- metadata +77 -83
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -128,6 +128,12 @@ You can override all the views by generating them into your app and customizing
|
|
128
128
|
|
129
129
|
rails g saucy:views
|
130
130
|
|
131
|
+
You can also customize the default trial length of 30 days, and the timing of expiration notification emails:
|
132
|
+
|
133
|
+
* Saucy::Configuration.trial_length - An integer. The length of the trial in days.
|
134
|
+
* Saucy::Configuration.unactivated_notice_on - An integer. The day of the trial in which the unactivated notice should be sent.
|
135
|
+
* Saucy::Configuration.expiring_notice_on - An integer. The number of days remaining that the expiration warning notice should be sent on.
|
136
|
+
|
131
137
|
## Gotchas
|
132
138
|
|
133
139
|
Make sure you don't do this in ApplicationController:
|
data/config/locales/en.yml
CHANGED
@@ -14,11 +14,11 @@ en:
|
|
14
14
|
billing_mailer:
|
15
15
|
expiring_trial:
|
16
16
|
greeting: Thanks for giving us a try!
|
17
|
-
expiration_notice: "Your
|
17
|
+
expiration_notice: "Your trial for %{account_name} is expiring soon. I hope that you've enjoyed %{app_name} enough to sign up for a paid subscription. If you'd like to continue using your account, please take a moment to choose a paid plan:"
|
18
18
|
contact: "If you need more time to evaluate %{app_name} or you have any questions, please don't hesitate to contact me."
|
19
19
|
completed_trial:
|
20
20
|
greeting: Thanks for giving us a try!
|
21
|
-
notice: "Your
|
21
|
+
notice: "Your trial for %{account_name} is over, and your account has become inactive. If you'd like to continue using your account, please take a moment to choose a paid plan:"
|
22
22
|
contact: "If you need more time to evaluate %{app_name} or you have any questions, please don't hesitate to contact me."
|
23
23
|
new_unactivated:
|
24
24
|
body: |-
|
data/lib/saucy/account.rb
CHANGED
@@ -76,7 +76,7 @@ module Saucy
|
|
76
76
|
number_free_days = if coupon
|
77
77
|
30 * coupon.free_months
|
78
78
|
else
|
79
|
-
|
79
|
+
Saucy::Configuration.trial_length
|
80
80
|
end
|
81
81
|
self.trial_expires_at = number_free_days.days.from_now(created_at || Time.zone.now)
|
82
82
|
end
|
@@ -141,11 +141,11 @@ module Saucy
|
|
141
141
|
def trial_expiring
|
142
142
|
trial.
|
143
143
|
where(:notified_of_expiration => false).
|
144
|
-
where(["accounts.trial_expires_at <= ?",
|
144
|
+
where(["accounts.trial_expires_at <= ?", Saucy::Configuration.expiring_notice_on.days.from_now])
|
145
145
|
end
|
146
146
|
|
147
147
|
def new_unactivated
|
148
|
-
where(["accounts.created_at <= ?",
|
148
|
+
where(["accounts.created_at <= ?", Saucy::Configuration.unactivated_notice_on.days.ago]).
|
149
149
|
where(:asked_to_activate => false, :activated => false)
|
150
150
|
end
|
151
151
|
|
data/lib/saucy/configuration.rb
CHANGED
@@ -8,6 +8,9 @@ module Saucy
|
|
8
8
|
cattr_accessor :merchant_account_id
|
9
9
|
cattr_accessor :admin_username
|
10
10
|
cattr_accessor :admin_password
|
11
|
+
cattr_accessor :trial_length
|
12
|
+
cattr_accessor :expiring_notice_on
|
13
|
+
cattr_accessor :unactivated_notice_on
|
11
14
|
|
12
15
|
def initialize
|
13
16
|
@@manager_email_address = 'manager@example.com'
|
@@ -15,6 +18,9 @@ module Saucy
|
|
15
18
|
@@layouts = Layouts.new
|
16
19
|
@@admin_username = 'admin'
|
17
20
|
@@admin_password = 'admin'
|
21
|
+
@@trial_length = 30
|
22
|
+
@@expiring_notice_on = 7
|
23
|
+
@@unactivated_notice_on = 7
|
18
24
|
end
|
19
25
|
|
20
26
|
end
|
data/spec/models/account_spec.rb
CHANGED
@@ -266,6 +266,60 @@ describe Account do
|
|
266
266
|
@mail.should have_received(:deliver).twice()
|
267
267
|
end
|
268
268
|
end
|
269
|
+
|
270
|
+
it "uses the unactivated_notice_on setting for new_unactivated" do
|
271
|
+
begin
|
272
|
+
unactivated = [Factory(:account, :created_at => 7.days.ago),
|
273
|
+
Factory(:account, :created_at => 8.days.ago)]
|
274
|
+
fresh = Factory(:account, :created_at => 6.days.ago)
|
275
|
+
Account.new_unactivated.order(:created_at).should == unactivated.reverse
|
276
|
+
Saucy::Configuration.unactivated_notice_on = 6
|
277
|
+
Account.new_unactivated.order(:created_at).should == (unactivated.reverse + [fresh]).flatten
|
278
|
+
ensure
|
279
|
+
Saucy::Configuration.unactivated_notice_on = 7
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
it "uses the expiring_notice_on for notifying expiring accounts" do
|
284
|
+
begin
|
285
|
+
trial = Factory(:plan, :trial => true)
|
286
|
+
forever = Factory(:plan, :trial => false)
|
287
|
+
|
288
|
+
expiring = Factory(:account, :plan => trial, :created_at => 1.day.ago)
|
289
|
+
expiring.trial_expires_at = 7.days.from_now
|
290
|
+
expiring.save!
|
291
|
+
|
292
|
+
Account.trial_expiring.should == [expiring]
|
293
|
+
|
294
|
+
Saucy::Configuration.expiring_notice_on = 8
|
295
|
+
expiring.trial_expires_at = 8.days.from_now
|
296
|
+
expiring.save!
|
297
|
+
|
298
|
+
Account.trial_expiring.should == [expiring]
|
299
|
+
ensure
|
300
|
+
Saucy::Configuration.expiring_notice_on = 7
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
context "with a trial length of 14 days" do
|
305
|
+
before(:each) do
|
306
|
+
Saucy::Configuration.trial_length = 14
|
307
|
+
end
|
308
|
+
|
309
|
+
after(:each) do
|
310
|
+
Saucy::Configuration.trial_length = 30
|
311
|
+
end
|
312
|
+
|
313
|
+
it "is expired with a trial plan after 14 days" do
|
314
|
+
trial = Factory(:plan, :trial => true)
|
315
|
+
Factory(:account, :created_at => 14.days.ago, :plan => trial).should be_expired
|
316
|
+
end
|
317
|
+
|
318
|
+
it "isn't expired with a trial plan before 14 days" do
|
319
|
+
trial = Factory(:plan, :trial => true)
|
320
|
+
Factory(:account, :created_at => 13.days.ago, :plan => trial).should_not be_expired
|
321
|
+
end
|
322
|
+
end
|
269
323
|
|
270
324
|
it "searches records for keyword and name" do
|
271
325
|
name = Factory :account, :name => 'match'
|
@@ -13,6 +13,18 @@ describe Saucy::Configuration do
|
|
13
13
|
subject.support_email_address.should_not be_nil
|
14
14
|
end
|
15
15
|
|
16
|
+
it "has a trial_length of 30 days" do
|
17
|
+
subject.trial_length.should == 30
|
18
|
+
end
|
19
|
+
|
20
|
+
it "has an expiring_notice_on of 7 days" do
|
21
|
+
subject.expiring_notice_on.should == 7
|
22
|
+
end
|
23
|
+
|
24
|
+
it "has an unactivated_notice_on of 7 days" do
|
25
|
+
subject.expiring_notice_on.should == 7
|
26
|
+
end
|
27
|
+
|
16
28
|
it "has a nil merchant_account_id" do
|
17
29
|
subject.merchant_account_id.should be_nil
|
18
30
|
end
|
@@ -36,4 +48,34 @@ describe Saucy::Configuration do
|
|
36
48
|
subject.support_email_address = old_address
|
37
49
|
end
|
38
50
|
end
|
51
|
+
|
52
|
+
it "can assign a trial length" do
|
53
|
+
old_length = subject.trial_length
|
54
|
+
begin
|
55
|
+
subject.trial_length = 14
|
56
|
+
subject.trial_length.should == 14
|
57
|
+
ensure
|
58
|
+
subject.trial_length = old_length
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "can assign an expiring_notice_on length" do
|
63
|
+
old_length = subject.expiring_notice_on
|
64
|
+
begin
|
65
|
+
subject.expiring_notice_on = 14
|
66
|
+
subject.expiring_notice_on.should == 14
|
67
|
+
ensure
|
68
|
+
subject.expiring_notice_on = old_length
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "can assign a unactivated_notice_on length" do
|
73
|
+
old_length = subject.unactivated_notice_on
|
74
|
+
begin
|
75
|
+
subject.unactivated_notice_on = 14
|
76
|
+
subject.unactivated_notice_on.should == 14
|
77
|
+
ensure
|
78
|
+
subject.unactivated_notice_on = old_length
|
79
|
+
end
|
80
|
+
end
|
39
81
|
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: saucy
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.12.1
|
4
5
|
prerelease:
|
5
|
-
version: 0.12.0
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- thoughtbot, inc.
|
9
9
|
- Joe Ferris
|
10
10
|
- Mike Burns
|
@@ -14,106 +14,103 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
17
|
+
date: 2011-10-06 00:00:00.000000000Z
|
18
|
+
dependencies:
|
19
|
+
- !ruby/object:Gem::Dependency
|
21
20
|
name: clearance
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
21
|
+
requirement: &70295759633320 !ruby/object:Gem::Requirement
|
24
22
|
none: false
|
25
|
-
requirements:
|
23
|
+
requirements:
|
26
24
|
- - ~>
|
27
|
-
- !ruby/object:Gem::Version
|
25
|
+
- !ruby/object:Gem::Version
|
28
26
|
version: 0.11.2
|
29
27
|
type: :runtime
|
30
|
-
version_requirements: *id001
|
31
|
-
- !ruby/object:Gem::Dependency
|
32
|
-
name: formtastic
|
33
28
|
prerelease: false
|
34
|
-
|
29
|
+
version_requirements: *70295759633320
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: formtastic
|
32
|
+
requirement: &70295759632840 !ruby/object:Gem::Requirement
|
35
33
|
none: false
|
36
|
-
requirements:
|
37
|
-
- -
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version:
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.2'
|
40
38
|
type: :runtime
|
41
|
-
version_requirements: *id002
|
42
|
-
- !ruby/object:Gem::Dependency
|
43
|
-
name: railties
|
44
39
|
prerelease: false
|
45
|
-
|
40
|
+
version_requirements: *70295759632840
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: railties
|
43
|
+
requirement: &70295759632380 !ruby/object:Gem::Requirement
|
46
44
|
none: false
|
47
|
-
requirements:
|
48
|
-
- -
|
49
|
-
- !ruby/object:Gem::Version
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
50
48
|
version: 3.0.3
|
51
49
|
type: :runtime
|
52
|
-
version_requirements: *id003
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: braintree
|
55
50
|
prerelease: false
|
56
|
-
|
51
|
+
version_requirements: *70295759632380
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: braintree
|
54
|
+
requirement: &70295759631920 !ruby/object:Gem::Requirement
|
57
55
|
none: false
|
58
|
-
requirements:
|
59
|
-
- -
|
60
|
-
- !ruby/object:Gem::Version
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
61
59
|
version: 2.6.2
|
62
60
|
type: :runtime
|
63
|
-
version_requirements: *id004
|
64
|
-
- !ruby/object:Gem::Dependency
|
65
|
-
name: sham_rack
|
66
61
|
prerelease: false
|
67
|
-
|
62
|
+
version_requirements: *70295759631920
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: sham_rack
|
65
|
+
requirement: &70295759631460 !ruby/object:Gem::Requirement
|
68
66
|
none: false
|
69
|
-
requirements:
|
70
|
-
- -
|
71
|
-
- !ruby/object:Gem::Version
|
67
|
+
requirements:
|
68
|
+
- - =
|
69
|
+
- !ruby/object:Gem::Version
|
72
70
|
version: 1.3.3
|
73
71
|
type: :runtime
|
74
|
-
version_requirements: *id005
|
75
|
-
- !ruby/object:Gem::Dependency
|
76
|
-
name: sinatra
|
77
72
|
prerelease: false
|
78
|
-
|
73
|
+
version_requirements: *70295759631460
|
74
|
+
- !ruby/object:Gem::Dependency
|
75
|
+
name: sinatra
|
76
|
+
requirement: &70295759631000 !ruby/object:Gem::Requirement
|
79
77
|
none: false
|
80
|
-
requirements:
|
81
|
-
- -
|
82
|
-
- !ruby/object:Gem::Version
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
83
81
|
version: 1.1.2
|
84
82
|
type: :runtime
|
85
|
-
version_requirements: *id006
|
86
|
-
- !ruby/object:Gem::Dependency
|
87
|
-
name: airbrake
|
88
83
|
prerelease: false
|
89
|
-
|
84
|
+
version_requirements: *70295759631000
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: airbrake
|
87
|
+
requirement: &70295759630540 !ruby/object:Gem::Requirement
|
90
88
|
none: false
|
91
|
-
requirements:
|
89
|
+
requirements:
|
92
90
|
- - ~>
|
93
|
-
- !ruby/object:Gem::Version
|
91
|
+
- !ruby/object:Gem::Version
|
94
92
|
version: 3.0.4
|
95
93
|
type: :runtime
|
96
|
-
version_requirements: *id007
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: aruba
|
99
94
|
prerelease: false
|
100
|
-
|
95
|
+
version_requirements: *70295759630540
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: aruba
|
98
|
+
requirement: &70295759630080 !ruby/object:Gem::Requirement
|
101
99
|
none: false
|
102
|
-
requirements:
|
103
|
-
- -
|
104
|
-
- !ruby/object:Gem::Version
|
100
|
+
requirements:
|
101
|
+
- - =
|
102
|
+
- !ruby/object:Gem::Version
|
105
103
|
version: 0.2.6
|
106
104
|
type: :development
|
107
|
-
|
108
|
-
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: *70295759630080
|
107
|
+
description: Clearance-based Rails engine for Software as a Service (Saas) that provides
|
108
|
+
account and project management
|
109
109
|
email: support@thoughtbot.com
|
110
110
|
executables: []
|
111
|
-
|
112
111
|
extensions: []
|
113
|
-
|
114
112
|
extra_rdoc_files: []
|
115
|
-
|
116
|
-
files:
|
113
|
+
files:
|
117
114
|
- CHANGELOG.md
|
118
115
|
- Gemfile
|
119
116
|
- Gemfile.lock
|
@@ -287,32 +284,29 @@ files:
|
|
287
284
|
- spec/views/accounts/_account.html.erb_spec.rb
|
288
285
|
homepage: http://github.com/thoughtbot/saucy
|
289
286
|
licenses: []
|
290
|
-
|
291
287
|
post_install_message:
|
292
288
|
rdoc_options: []
|
293
|
-
|
294
|
-
require_paths:
|
289
|
+
require_paths:
|
295
290
|
- lib
|
296
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
291
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
297
292
|
none: false
|
298
|
-
requirements:
|
299
|
-
- -
|
300
|
-
- !ruby/object:Gem::Version
|
301
|
-
version:
|
302
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
293
|
+
requirements:
|
294
|
+
- - ! '>='
|
295
|
+
- !ruby/object:Gem::Version
|
296
|
+
version: '0'
|
297
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
303
298
|
none: false
|
304
|
-
requirements:
|
305
|
-
- -
|
306
|
-
- !ruby/object:Gem::Version
|
307
|
-
version:
|
299
|
+
requirements:
|
300
|
+
- - ! '>='
|
301
|
+
- !ruby/object:Gem::Version
|
302
|
+
version: '0'
|
308
303
|
requirements: []
|
309
|
-
|
310
304
|
rubyforge_project:
|
311
|
-
rubygems_version: 1.8.
|
305
|
+
rubygems_version: 1.8.6
|
312
306
|
signing_key:
|
313
307
|
specification_version: 3
|
314
308
|
summary: Clearance-based Rails engine for SaaS
|
315
|
-
test_files:
|
309
|
+
test_files:
|
316
310
|
- features/run_features.feature
|
317
311
|
- features/step_definitions/clearance_steps.rb
|
318
312
|
- features/step_definitions/rails_steps.rb
|