saucy 0.2.31 → 0.2.32
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +12 -0
- data/app/mailers/billing_mailer.rb +11 -1
- data/app/views/billing_mailer/new_unactivated.text.erb +1 -0
- data/config/locales/en.yml +11 -0
- data/lib/generators/saucy/features/templates/features/trial_plans.feature +8 -0
- data/lib/generators/saucy/features/templates/step_definitions/email_steps.rb +10 -0
- data/lib/generators/saucy/install/templates/create_saucy_tables.rb +3 -0
- data/lib/saucy/account.rb +23 -2
- data/lib/saucy/cron.rb +1 -0
- data/spec/models/account_spec.rb +36 -0
- metadata +4 -3
data/Rakefile
CHANGED
@@ -24,3 +24,15 @@ Rake::GemPackageTask.new($specification) do |package|
|
|
24
24
|
package.need_tar = true
|
25
25
|
end
|
26
26
|
|
27
|
+
gem_file = "pkg/#{$specification.name}-#{$specification.version}.gem"
|
28
|
+
|
29
|
+
desc "Build and install the latest gem"
|
30
|
+
task :install => :gem do
|
31
|
+
sh("gem install --local #{gem_file}")
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Build and release the latest gem"
|
35
|
+
task :release => :gem do
|
36
|
+
sh("gem push #{gem_file}")
|
37
|
+
end
|
38
|
+
|
@@ -22,8 +22,18 @@ class BillingMailer < ActionMailer::Base
|
|
22
22
|
@account = account
|
23
23
|
mail(:to => account.customer.email,
|
24
24
|
:subject => I18n.t(:subject,
|
25
|
-
:scope => [:billing_mailer, :
|
25
|
+
:scope => [:billing_mailer, :expiring_trial],
|
26
26
|
:default => "Your trial is expiring soon"),
|
27
27
|
:from => Saucy::Configuration.mailer_sender)
|
28
28
|
end
|
29
|
+
|
30
|
+
def new_unactivated(account)
|
31
|
+
@account = account
|
32
|
+
mail(:to => account.admin_emails,
|
33
|
+
:subject => I18n.t(:subject,
|
34
|
+
:scope => [:billing_mailer, :new_unactivated],
|
35
|
+
:default => "A check in from %{app_name}",
|
36
|
+
:app_name => t("app_name")),
|
37
|
+
:from => Saucy::Configuration.mailer_sender)
|
38
|
+
end
|
29
39
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= t(".body", :app_name => t("app_name")) %>
|
data/config/locales/en.yml
CHANGED
@@ -16,4 +16,15 @@ en:
|
|
16
16
|
greeting: Thanks for giving us a try!
|
17
17
|
expiration_notice: "Your 30 day 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
|
+
new_unactivated:
|
20
|
+
body: |-
|
21
|
+
Hi,
|
22
|
+
|
23
|
+
I noticed that you're trying out %{app_name}, but you haven't set up any projects yet.
|
24
|
+
|
25
|
+
If you have any questions or need any help getting your %{app_name} account set up, feel free to respond to this email.
|
26
|
+
|
27
|
+
Thanks,
|
28
|
+
|
29
|
+
The %{app_name} Team
|
19
30
|
|
@@ -65,3 +65,11 @@ Feature: Trial plans
|
|
65
65
|
And I follow the link sent to "admin@example.com"
|
66
66
|
Then I should be on the upgrade plan page for the "Test" account
|
67
67
|
|
68
|
+
Scenario: Receive a reminder about setting up an account
|
69
|
+
Given an account exists with a name of "Test"
|
70
|
+
And a user exists with an email of "admin@example.com"
|
71
|
+
And "admin@example.com" is an admin of the "Test" account
|
72
|
+
And the "Test" account was created 7 days ago
|
73
|
+
When the daily Saucy jobs are processed
|
74
|
+
Then an email with subject "A check in from App Name" should be sent to "admin@example.com"
|
75
|
+
|
@@ -11,3 +11,13 @@ When /^I follow the link sent to "([^"]+)"$/ do |email_address|
|
|
11
11
|
visit url
|
12
12
|
end
|
13
13
|
|
14
|
+
Then /^an email with subject "([^"]*)" should be sent to "([^"]*)"$/ do |subject, to_address|
|
15
|
+
email = ActionMailer::Base.deliveries.detect do |tmail|
|
16
|
+
tmail.subject.include?(subject)
|
17
|
+
end or raise "No email with subject #{subject}"
|
18
|
+
|
19
|
+
unless email.to.include?(to_address)
|
20
|
+
raise "No email sent to #{to_address}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -21,10 +21,13 @@ class CreateSaucyTables < ActiveRecord::Migration
|
|
21
21
|
table.string :subscription_status
|
22
22
|
table.datetime :next_billing_date
|
23
23
|
table.boolean :notified_of_expiration, :default => false, :null => false
|
24
|
+
table.boolean :asked_to_activate, :default => false, :null => false
|
25
|
+
table.boolean :activated, :default => false, :null => false
|
24
26
|
end
|
25
27
|
add_index :accounts, :plan_id
|
26
28
|
add_index :accounts, :keyword
|
27
29
|
add_index :accounts, :next_billing_date
|
30
|
+
add_index :accounts, :created_at
|
28
31
|
|
29
32
|
create_table :invitations do |table|
|
30
33
|
table.string :email
|
data/lib/saucy/account.rb
CHANGED
@@ -58,19 +58,40 @@ module Saucy
|
|
58
58
|
def past_trial?
|
59
59
|
created_at < 30.days.ago
|
60
60
|
end
|
61
|
+
|
62
|
+
def admin_emails
|
63
|
+
admins.map(&:email)
|
64
|
+
end
|
61
65
|
end
|
62
66
|
|
63
67
|
module ClassMethods
|
68
|
+
def deliver_new_unactivated_notifications
|
69
|
+
new_unactivated.each do |account|
|
70
|
+
BillingMailer.new_unactivated(account).deliver
|
71
|
+
account.asked_to_activate = true
|
72
|
+
account.save!
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
64
76
|
def deliver_expiring_trial_notifications
|
65
|
-
trial_expiring.each
|
77
|
+
trial_expiring.each do |account|
|
78
|
+
BillingMailer.expiring_trial(account).deliver
|
79
|
+
account.notified_of_expiration = true
|
80
|
+
account.save!
|
81
|
+
end
|
66
82
|
end
|
67
83
|
|
68
84
|
def trial_expiring
|
69
|
-
|
85
|
+
includes(:plan).
|
70
86
|
where(:plans => { :trial => true }).
|
71
87
|
where(:notified_of_expiration => false).
|
72
88
|
where(["accounts.created_at <= ?", 23.days.ago])
|
73
89
|
end
|
90
|
+
|
91
|
+
def new_unactivated
|
92
|
+
where(["accounts.created_at <= ?", 7.days.ago]).
|
93
|
+
where(:asked_to_activate => false, :activated => false)
|
94
|
+
end
|
74
95
|
end
|
75
96
|
end
|
76
97
|
end
|
data/lib/saucy/cron.rb
CHANGED
data/spec/models/account_spec.rb
CHANGED
@@ -45,6 +45,18 @@ describe Account do
|
|
45
45
|
result.to_a.should =~ admins
|
46
46
|
end
|
47
47
|
|
48
|
+
it "finds emails for admin users" do
|
49
|
+
admins = [Factory(:user), Factory(:user)]
|
50
|
+
non_admin = Factory(:user)
|
51
|
+
non_member = Factory(:user)
|
52
|
+
admins.each do |admin|
|
53
|
+
Factory(:membership, :user => admin, :account => subject, :admin => true)
|
54
|
+
end
|
55
|
+
Factory(:membership, :user => non_admin, :account => subject, :admin => false)
|
56
|
+
|
57
|
+
subject.admin_emails.should == admins.map(&:email)
|
58
|
+
end
|
59
|
+
|
48
60
|
it "has a member with a membership" do
|
49
61
|
membership = Factory(:membership, :account => subject)
|
50
62
|
should have_member(membership.user)
|
@@ -103,6 +115,30 @@ describe Account do
|
|
103
115
|
end
|
104
116
|
|
105
117
|
mail.should have_received(:deliver).twice
|
118
|
+
|
119
|
+
expiring.each { |account| account.reload.should be_notified_of_expiration }
|
120
|
+
end
|
121
|
+
|
122
|
+
it "sends notifications for unactivated accounts after 7 days" do
|
123
|
+
unactivated = [Factory(:account, :created_at => 7.days.ago),
|
124
|
+
Factory(:account, :created_at => 8.days.ago)]
|
125
|
+
fresh = Factory(:account, :created_at => 6.days.ago)
|
126
|
+
activated = Factory(:account, :created_at => 9.days.ago, :activated => true)
|
127
|
+
already_notified = Factory(:account, :created_at => 9.days.ago,
|
128
|
+
:asked_to_activate => true)
|
129
|
+
|
130
|
+
mail = stub('mail', :deliver => true)
|
131
|
+
BillingMailer.stubs(:new_unactivated => mail)
|
132
|
+
|
133
|
+
Account.deliver_new_unactivated_notifications
|
134
|
+
|
135
|
+
unactivated.each do |account|
|
136
|
+
BillingMailer.should have_received(:new_unactivated).with(account)
|
137
|
+
end
|
138
|
+
|
139
|
+
mail.should have_received(:deliver).twice
|
140
|
+
|
141
|
+
unactivated.each { |account| account.reload.should be_asked_to_activate }
|
106
142
|
end
|
107
143
|
end
|
108
144
|
|
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: 87
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 32
|
10
|
+
version: 0.2.32
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- thoughtbot, inc.
|
@@ -151,6 +151,7 @@ files:
|
|
151
151
|
- app/views/accounts/index.html.erb
|
152
152
|
- app/views/accounts/new.html.erb
|
153
153
|
- app/views/billing_mailer/expiring_trial.text.erb
|
154
|
+
- app/views/billing_mailer/new_unactivated.text.erb
|
154
155
|
- app/views/billing_mailer/problem.html.erb
|
155
156
|
- app/views/billing_mailer/problem.text.erb
|
156
157
|
- app/views/billing_mailer/receipt.html.erb
|