saucy 0.11.5 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ 0.12.0
2
+
3
+ * Add a dependency on Airbrake for exception notification.
4
+ * Notify Airbrake if an expiring/completed/unactivated notification fails, and
5
+ continue.
6
+
7
+ If you use Saucy in a project without Airbrake, it will fail to deliver some
8
+ account-related emails.
9
+
1
10
  0.11.5
2
11
 
3
12
  Trying to fix gemspec.
data/Gemfile CHANGED
@@ -14,6 +14,7 @@ gem "sinatra"
14
14
  gem "sham_rack"
15
15
  gem "braintree"
16
16
  gem "timecop"
17
+ gem "airbrake", "~> 3.0.4"
17
18
 
18
19
  # used by the rails app in cucumber
19
20
  gem "cucumber-rails", :require => false
data/Gemfile.lock CHANGED
@@ -31,6 +31,9 @@ GEM
31
31
  activesupport (3.1.0)
32
32
  multi_json (~> 1.0)
33
33
  addressable (2.2.6)
34
+ airbrake (3.0.4)
35
+ activesupport
36
+ builder
34
37
  arel (2.2.1)
35
38
  aruba (0.4.6)
36
39
  bcat (>= 0.6.1)
@@ -184,6 +187,7 @@ PLATFORMS
184
187
  ruby
185
188
 
186
189
  DEPENDENCIES
190
+ airbrake (~> 3.0.4)
187
191
  aruba
188
192
  bourne
189
193
  braintree
data/README.md CHANGED
@@ -56,6 +56,8 @@ You definitely should change that in your config.
56
56
 
57
57
  There is a `saucy:daily` rake task which should be run on a regular basis to send receipts and payment processing problem emails.
58
58
 
59
+ Saucy depends on having an Airbrake account to deliver exception notifications.
60
+
59
61
  Saucy accounts become "activated" once an initial setup step is complete.
60
62
  This could be creating the first bug for a bug tracker, or setting up a client
61
63
  gem for a server API. Once the application detects that the account is
data/lib/saucy/account.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'airbrake'
2
+
1
3
  module Saucy
2
4
  module Account
3
5
  extend ActiveSupport::Concern
@@ -102,25 +104,37 @@ module Saucy
102
104
 
103
105
  def deliver_new_unactivated_notifications
104
106
  new_unactivated.each do |account|
105
- BillingMailer.new_unactivated(account).deliver
106
- account.asked_to_activate = true
107
- account.save!
107
+ begin
108
+ BillingMailer.new_unactivated(account).deliver
109
+ account.asked_to_activate = true
110
+ account.save!
111
+ rescue Exception => e
112
+ Airbrake.notify(e)
113
+ end
108
114
  end
109
115
  end
110
116
 
111
117
  def deliver_expiring_trial_notifications
112
118
  trial_expiring.each do |account|
113
- BillingMailer.expiring_trial(account).deliver
114
- account.notified_of_expiration = true
115
- account.save!
119
+ begin
120
+ BillingMailer.expiring_trial(account).deliver
121
+ account.notified_of_expiration = true
122
+ account.save!
123
+ rescue Exception => e
124
+ Airbrake.notify(e)
125
+ end
116
126
  end
117
127
  end
118
128
 
119
129
  def deliver_completed_trial_notifications
120
130
  trial_completed.each do |account|
121
- BillingMailer.completed_trial(account).deliver
122
- account.notified_of_completed_trial = true
123
- account.save!
131
+ begin
132
+ BillingMailer.completed_trial(account).deliver
133
+ account.notified_of_completed_trial = true
134
+ account.save!
135
+ rescue Exception => e
136
+ Airbrake.notify(e)
137
+ end
124
138
  end
125
139
  end
126
140
 
@@ -133,87 +133,138 @@ describe Account do
133
133
  account.should_not be_expired
134
134
  end
135
135
 
136
- it "sends notifications for expiring accounts" do
137
- trial = Factory(:plan, :trial => true)
138
- forever = Factory(:plan, :trial => false)
139
-
140
- created_23_days = Factory(:account, :plan => trial, :created_at => 23.days.ago)
141
- expires_7_days = Factory(:account, :plan => trial, :created_at => 1.day.ago)
142
- expiring = [created_23_days, expires_7_days]
143
- forever = Factory(:account, :plan => forever, :created_at => 23.days.ago)
144
- new_trial = Factory(:account, :plan => trial, :created_at => 22.days.ago)
145
- already_notified = Factory(:account, :plan => trial,
146
- :created_at => 24.days.ago,
147
- :notified_of_expiration => true)
136
+ context "with expiring accounts" do
137
+ before do
138
+ trial = Factory(:plan, :trial => true)
139
+ forever = Factory(:plan, :trial => false)
140
+
141
+ created_23_days = Factory(:account, :plan => trial, :created_at => 23.days.ago)
142
+ expires_7_days = Factory(:account, :plan => trial, :created_at => 1.day.ago)
143
+ @expiring = [created_23_days, expires_7_days]
144
+ forever = Factory(:account, :plan => forever, :created_at => 23.days.ago)
145
+ new_trial = Factory(:account, :plan => trial, :created_at => 22.days.ago)
146
+ already_notified = Factory(:account, :plan => trial,
147
+ :created_at => 24.days.ago,
148
+ :notified_of_expiration => true)
149
+
150
+ expires_7_days.trial_expires_at = 7.days.from_now
151
+ expires_7_days.save!
152
+
153
+ @mail = stub('mail', :deliver => true)
154
+ BillingMailer.stubs(:expiring_trial => @mail)
155
+ Airbrake.stubs(:notify => true)
156
+ end
148
157
 
149
- expires_7_days.trial_expires_at = 7.days.from_now
150
- expires_7_days.save!
158
+ it "sends notifications for expiring accounts" do
159
+ Account.deliver_expiring_trial_notifications
151
160
 
152
- mail = stub('mail', :deliver => true)
153
- BillingMailer.stubs(:expiring_trial => mail)
161
+ @expiring.each do |account|
162
+ BillingMailer.should have_received(:expiring_trial).with(account)
163
+ end
154
164
 
155
- Account.deliver_expiring_trial_notifications
165
+ @mail.should have_received(:deliver).twice
156
166
 
157
- expiring.each do |account|
158
- BillingMailer.should have_received(:expiring_trial).with(account)
167
+ @expiring.each { |account| account.reload.should be_notified_of_expiration }
159
168
  end
160
169
 
161
- mail.should have_received(:deliver).twice
170
+ it "notifies Airbrake if expiring account notifications fail" do
171
+ @mail.stubs(:deliver).raises(RuntimeError).then.returns(true)
172
+ Account.deliver_expiring_trial_notifications
173
+ Airbrake.should have_received(:notify).once()
174
+ end
162
175
 
163
- expiring.each { |account| account.reload.should be_notified_of_expiration }
176
+ it "delivers the rest of the emails even if one fails" do
177
+ @mail.stubs(:deliver).raises(RuntimeError)
178
+ Account.deliver_expiring_trial_notifications
179
+ @mail.should have_received(:deliver).twice()
180
+ end
164
181
  end
165
182
 
166
- it "sends notifications for completed trials" do
167
- trial = Factory(:plan, :trial => true)
168
- forever = Factory(:plan, :trial => false)
183
+ context "with completed trials" do
184
+ before do
185
+ trial = Factory(:plan, :trial => true)
186
+ forever = Factory(:plan, :trial => false)
169
187
 
170
- unexpired_trial = Factory(:account, :plan => trial, :created_at => 29.days.ago)
171
- unnotified_expired_trial = Factory(:account, :plan => trial, :created_at => 31.days.ago)
172
- expiring_now = Factory(:account, :plan => trial, :created_at => 1.day.ago)
173
- notified_expired_trial = Factory(:account, :plan => trial,
174
- :created_at => 31.days.ago,
175
- :notified_of_completed_trial => true)
176
- forever = Factory(:account, :plan => forever, :created_at => 31.days.ago)
188
+ unexpired_trial = Factory(:account, :plan => trial, :created_at => 29.days.ago)
189
+ unnotified_expired_trial = Factory(:account, :plan => trial, :created_at => 31.days.ago)
190
+ expiring_now = Factory(:account, :plan => trial, :created_at => 1.day.ago)
191
+ notified_expired_trial = Factory(:account, :plan => trial,
192
+ :created_at => 31.days.ago,
193
+ :notified_of_completed_trial => true)
194
+ forever = Factory(:account, :plan => forever, :created_at => 31.days.ago)
177
195
 
178
- expiring_now.trial_expires_at = 1.day.ago
179
- expiring_now.save!
196
+ expiring_now.trial_expires_at = 1.day.ago
197
+ expiring_now.save!
180
198
 
181
- requires_notification = [unnotified_expired_trial, expiring_now]
199
+ @requires_notification = [unnotified_expired_trial, expiring_now]
200
+
201
+ @mail = stub('mail', :deliver => true)
202
+ BillingMailer.stubs(:completed_trial => @mail)
203
+ Airbrake.stubs(:notify => true)
204
+ end
182
205
 
183
- mail = stub('mail', :deliver => true)
184
- BillingMailer.stubs(:completed_trial => mail)
206
+ it "sends notifications for completed trials" do
207
+ Account.deliver_completed_trial_notifications
185
208
 
186
- Account.deliver_completed_trial_notifications
209
+ @requires_notification.each do |account|
210
+ BillingMailer.should have_received(:completed_trial).with(account)
211
+ end
187
212
 
188
- requires_notification.each do |account|
189
- BillingMailer.should have_received(:completed_trial).with(account)
213
+ @mail.should have_received(:deliver).twice
214
+
215
+ @requires_notification.each { |account| account.reload.should be_notified_of_completed_trial }
190
216
  end
191
217
 
192
- mail.should have_received(:deliver).twice
218
+ it "notifies Airbrake if completed trial notifications fail" do
219
+ @mail.stubs(:deliver).raises(RuntimeError).then.returns(true)
220
+ Account.deliver_completed_trial_notifications
221
+ Airbrake.should have_received(:notify).once()
222
+ end
193
223
 
194
- requires_notification.each { |account| account.reload.should be_notified_of_completed_trial }
224
+ it "delivers the rest of the emails even if one fails" do
225
+ @mail.stubs(:deliver).raises(RuntimeError)
226
+ Account.deliver_completed_trial_notifications
227
+ @mail.should have_received(:deliver).twice()
228
+ end
195
229
  end
196
230
 
197
- it "sends notifications for unactivated accounts after 7 days" do
198
- unactivated = [Factory(:account, :created_at => 7.days.ago),
199
- Factory(:account, :created_at => 8.days.ago)]
200
- fresh = Factory(:account, :created_at => 6.days.ago)
201
- activated = Factory(:account, :created_at => 9.days.ago, :activated => true)
202
- already_notified = Factory(:account, :created_at => 9.days.ago,
203
- :asked_to_activate => true)
231
+ context "with unactivated accounts" do
232
+ before do
233
+ @unactivated = [Factory(:account, :created_at => 7.days.ago),
234
+ Factory(:account, :created_at => 8.days.ago)]
235
+ fresh = Factory(:account, :created_at => 6.days.ago)
236
+ activated = Factory(:account, :created_at => 9.days.ago, :activated => true)
237
+ already_notified = Factory(:account, :created_at => 9.days.ago,
238
+ :asked_to_activate => true)
239
+
240
+ @mail = stub('mail', :deliver => true)
241
+ BillingMailer.stubs(:new_unactivated => @mail)
242
+ Airbrake.stubs(:notify => true)
243
+ end
204
244
 
205
- mail = stub('mail', :deliver => true)
206
- BillingMailer.stubs(:new_unactivated => mail)
245
+ it "sends notifications after 7 days" do
246
+ Account.deliver_new_unactivated_notifications
207
247
 
208
- Account.deliver_new_unactivated_notifications
248
+ @unactivated.each do |account|
249
+ BillingMailer.should have_received(:new_unactivated).with(account)
250
+ end
209
251
 
210
- unactivated.each do |account|
211
- BillingMailer.should have_received(:new_unactivated).with(account)
252
+ @mail.should have_received(:deliver).twice
253
+
254
+ @unactivated.each { |account| account.reload.should be_asked_to_activate }
212
255
  end
213
256
 
214
- mail.should have_received(:deliver).twice
257
+ it "notifies Airbrake if completed trial notifications fail" do
258
+ @mail.stubs(:deliver).raises(RuntimeError).then.returns(true)
259
+ Account.deliver_new_unactivated_notifications
260
+ Airbrake.should have_received(:notify).once()
261
+ end
215
262
 
216
- unactivated.each { |account| account.reload.should be_asked_to_activate }
263
+ it "delivers the rest of the emails even if one fails" do
264
+ @mail.stubs(:deliver).raises(RuntimeError)
265
+ Account.deliver_new_unactivated_notifications
266
+ @mail.should have_received(:deliver).twice()
267
+ end
217
268
  end
218
269
 
219
270
  it "searches records for keyword and name" do
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: saucy
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.11.5
5
+ version: 0.12.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - thoughtbot, inc.
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-10-04 00:00:00 Z
18
+ date: 2011-10-06 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: clearance
@@ -84,16 +84,27 @@ dependencies:
84
84
  type: :runtime
85
85
  version_requirements: *id006
86
86
  - !ruby/object:Gem::Dependency
87
- name: aruba
87
+ name: airbrake
88
88
  prerelease: false
89
89
  requirement: &id007 !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ version: 3.0.4
95
+ type: :runtime
96
+ version_requirements: *id007
97
+ - !ruby/object:Gem::Dependency
98
+ name: aruba
99
+ prerelease: false
100
+ requirement: &id008 !ruby/object:Gem::Requirement
90
101
  none: false
91
102
  requirements:
92
103
  - - "="
93
104
  - !ruby/object:Gem::Version
94
105
  version: 0.2.6
95
106
  type: :development
96
- version_requirements: *id007
107
+ version_requirements: *id008
97
108
  description: Clearance-based Rails engine for Software as a Service (Saas) that provides account and project management
98
109
  email: support@thoughtbot.com
99
110
  executables: []