saucy 0.11.5 → 0.12.0

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/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: []