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 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, :expiring_tiral],
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")) %>
@@ -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 { |account| BillingMailer.expiring_trial(account).deliver }
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
- joins(:plan).
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
@@ -1,6 +1,7 @@
1
1
  module Saucy
2
2
  module Cron
3
3
  def self.run_daily
4
+ ::Account.deliver_new_unactivated_notifications
4
5
  ::Account.deliver_expiring_trial_notifications
5
6
  end
6
7
  end
@@ -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: 41
4
+ hash: 87
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 31
10
- version: 0.2.31
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