saucy 0.11.2 → 0.11.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ 0.11.3
2
+
3
+ Bugfix: Billing emails previously used an arbitrarily chosen transaction.
4
+ Now they always use the most recent one.
5
+
1
6
  0.11.0
2
7
 
3
8
  Update Saucy to be compatible with Rails 3.1 which includes:
data/README.md CHANGED
@@ -43,10 +43,17 @@ Personalizable emails such as trial expiration notice and activation encourageme
43
43
 
44
44
  If you have an account with Braintree with multiple merchant accounts you'll want to configure the merchant account for this application:
45
45
 
46
- Saucy::Configuration.merchant_account_id = 'your merchant account id'
46
+ Saucy::Configuration.merchant_account_id = 'your merchant account id'
47
47
 
48
48
  In addition, there are a number of strings such as application name, support url, automated emails, etc. that are provided and customized with i18n translations. You can customize these in your app, and you can see what they are by looking at config/locales/en.yml in saucy.
49
49
 
50
+ Saucy comes with a basic admin area, which has http auth protection. This defaults to admin/admin:
51
+
52
+ Saucy::Configuration.admin_username = 'admin'
53
+ Saucy::Configuration.admin_password = 'admin'
54
+
55
+ You definitely should change that in your config.
56
+
50
57
  There is a `saucy:daily` rake task which should be run on a regular basis to send receipts and payment processing problem emails.
51
58
 
52
59
  Saucy accounts become "activated" once an initial setup step is complete.
@@ -12,6 +12,7 @@ class BillingMailer < ActionMailer::Base
12
12
 
13
13
  def problem(account, transaction)
14
14
  @account = account
15
+ @transaction = transaction
15
16
  mail(:to => account.customer.email,
16
17
  :subject => I18n.t(:subject,
17
18
  :scope => [:saucy, :mailers, :billing_mailer, :problem],
@@ -1,4 +1,4 @@
1
- <p>Unfortunately there was a problem processing your latest payment for your <%= @account.name -%> account on <%= t("app_name") %>.</p>
1
+ <p>Unfortunately there was a problem processing your latest payment on <%= @transaction.created_at.to_s(:short_date) %> for your <%= @account.name -%> account on <%= t("app_name") %>.</p>
2
2
 
3
3
  <p>Some functionality of your <%= @account.name -%> account on <%= t("app_name") %> is now disabled.</p>
4
4
 
@@ -1,4 +1,4 @@
1
- Unfortunately there was a problem processing your latest payment for your <%= @account.name -%> account on <%= t("app_name") %>.
1
+ Unfortunately there was a problem processing your latest payment on <%= @transaction.created_at.to_s(:short_date) %> for your <%= @account.name -%> account on <%= t("app_name") %>.
2
2
 
3
3
  Some functionality of your <%= @account.name -%> account on <%= t("app_name") %> is now disabled.
4
4
 
@@ -65,6 +65,10 @@ module Saucy
65
65
  subscription_status == Braintree::Subscription::Status::PastDue
66
66
  end
67
67
 
68
+ def most_recent_transaction
69
+ subscription.transactions.sort_by(&:created_at).last
70
+ end
71
+
68
72
  private
69
73
 
70
74
  def within_limits_for?(new_plan)
@@ -228,9 +232,9 @@ module Saucy
228
232
  account.next_billing_date = account.subscription.next_billing_date
229
233
  account.save!
230
234
  if account.past_due?
231
- BillingMailer.problem(account, account.subscription.transactions.last).deliver!
235
+ BillingMailer.problem(account, account.most_recent_transaction).deliver!
232
236
  else
233
- BillingMailer.receipt(account, account.subscription.transactions.last).deliver!
237
+ BillingMailer.receipt(account, account.most_recent_transaction).deliver!
234
238
  Saucy::Notifications.notify_observers("billed", :account => account)
235
239
  end
236
240
  end
@@ -30,6 +30,11 @@ describe "with an account and transaction" do
30
30
  it "sets the problem mail reply-to to the support address" do
31
31
  subject.reply_to.should == [Saucy::Configuration.support_email_address]
32
32
  end
33
+
34
+ it "includes the attempted billing date" do
35
+ billing_date = account.subscription.transactions.first.created_at
36
+ subject.to_s.should include(billing_date.to_s(:short_date))
37
+ end
33
38
  end
34
39
 
35
40
  describe BillingMailer, "expiring trial" do
@@ -339,6 +339,81 @@ describe Account, "with a paid subscription" do
339
339
  end
340
340
  end
341
341
 
342
+ context "with multiple historical transactions" do
343
+ let(:subscription) { FakeBraintree.subscriptions[subject.subscription_token] }
344
+
345
+ let!(:earlier_transaction_date) { 2.months.ago }
346
+ let!(:later_transaction_date) { 1.month.ago }
347
+
348
+ def build_transaction(attributes)
349
+ common_transaction_attributes = {
350
+ :status => Braintree::Transaction::Status::Settled,
351
+ :subscription_id => subject.subscription_token
352
+ }
353
+
354
+ FakeBraintree.transaction = common_transaction_attributes.merge(attributes)
355
+ FakeBraintree.generated_transaction
356
+ end
357
+
358
+ before do
359
+ subscription["next_billing_date"] = 2.months.from_now
360
+ end
361
+
362
+ context "and a past due account" do
363
+ let(:earlier_transaction) {
364
+ build_transaction(:created_at => earlier_transaction_date, :status => Braintree::Transaction::Status::Failed)
365
+ }
366
+
367
+ let(:later_transaction) {
368
+ build_transaction(:created_at => later_transaction_date, :status => Braintree::Transaction::Status::Failed)
369
+ }
370
+
371
+ before do
372
+ subscription["status"] = Braintree::Subscription::Status::PastDue
373
+ subscription["transactions"] = [later_transaction, earlier_transaction]
374
+ end
375
+
376
+ it "receives a problem email with the correct transaction" do
377
+ Timecop.travel(subject.next_billing_date + 1.day) do
378
+ ActionMailer::Base.deliveries.clear
379
+ Account.update_subscriptions!
380
+
381
+ ActionMailer::Base.deliveries.any? do |email|
382
+ email.subject =~ /problem/i &&
383
+ email.to_s.include?(later_transaction_date.strftime("%x"))
384
+ end.should be
385
+ end
386
+ end
387
+ end
388
+
389
+ context "and an actively billed account" do
390
+ let(:earlier_transaction) {
391
+ build_transaction(:created_at => earlier_transaction_date, :status => Braintree::Transaction::Status::Settled)
392
+ }
393
+
394
+ let(:later_transaction) {
395
+ build_transaction(:created_at => later_transaction_date, :status => Braintree::Transaction::Status::Settled)
396
+ }
397
+
398
+ before do
399
+ subscription["status"] = Braintree::Subscription::Status::Active
400
+ subscription["transactions"] = [later_transaction, earlier_transaction]
401
+ end
402
+
403
+ it "receives a receipt email with the correct transaction for active accounts" do
404
+ Timecop.travel(subject.next_billing_date + 1.day) do
405
+ ActionMailer::Base.deliveries.clear
406
+ Account.update_subscriptions!
407
+
408
+ ActionMailer::Base.deliveries.any? do |email|
409
+ email.subject =~ /receipt/i &&
410
+ email.to_s.include?(later_transaction_date.strftime("%x"))
411
+ end.should be
412
+ end
413
+ end
414
+ end
415
+ end
416
+
342
417
  context "and an active subscription due 2 months from now" do
343
418
  let(:subscription) { FakeBraintree.subscriptions[subject.subscription_token] }
344
419
 
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saucy
3
3
  version: !ruby/object:Gem::Version
4
- hash: 55
5
4
  prerelease:
6
- segments:
7
- - 0
8
- - 11
9
- - 2
10
- version: 0.11.2
5
+ version: 0.11.3
11
6
  platform: ruby
12
7
  authors:
13
8
  - thoughtbot, inc.
@@ -20,118 +15,84 @@ autorequire:
20
15
  bindir: bin
21
16
  cert_chain: []
22
17
 
23
- date: 2011-09-12 00:00:00 Z
18
+ date: 2011-10-03 00:00:00 Z
24
19
  dependencies:
25
20
  - !ruby/object:Gem::Dependency
26
21
  name: clearance
27
- prerelease: false
28
22
  requirement: &id001 !ruby/object:Gem::Requirement
29
23
  none: false
30
24
  requirements:
31
25
  - - ~>
32
26
  - !ruby/object:Gem::Version
33
- hash: 55
34
- segments:
35
- - 0
36
- - 11
37
- - 2
38
27
  version: 0.11.2
39
28
  type: :runtime
29
+ prerelease: false
40
30
  version_requirements: *id001
41
31
  - !ruby/object:Gem::Dependency
42
32
  name: formtastic
43
- prerelease: false
44
33
  requirement: &id002 !ruby/object:Gem::Requirement
45
34
  none: false
46
35
  requirements:
47
36
  - - ">="
48
37
  - !ruby/object:Gem::Version
49
- hash: 11
50
- segments:
51
- - 1
52
- - 2
53
38
  version: "1.2"
54
39
  type: :runtime
40
+ prerelease: false
55
41
  version_requirements: *id002
56
42
  - !ruby/object:Gem::Dependency
57
43
  name: railties
58
- prerelease: false
59
44
  requirement: &id003 !ruby/object:Gem::Requirement
60
45
  none: false
61
46
  requirements:
62
47
  - - ">="
63
48
  - !ruby/object:Gem::Version
64
- hash: 1
65
- segments:
66
- - 3
67
- - 0
68
- - 3
69
49
  version: 3.0.3
70
50
  type: :runtime
51
+ prerelease: false
71
52
  version_requirements: *id003
72
53
  - !ruby/object:Gem::Dependency
73
54
  name: braintree
74
- prerelease: false
75
55
  requirement: &id004 !ruby/object:Gem::Requirement
76
56
  none: false
77
57
  requirements:
78
58
  - - ">="
79
59
  - !ruby/object:Gem::Version
80
- hash: 19
81
- segments:
82
- - 2
83
- - 6
84
- - 2
85
60
  version: 2.6.2
86
61
  type: :runtime
62
+ prerelease: false
87
63
  version_requirements: *id004
88
64
  - !ruby/object:Gem::Dependency
89
65
  name: sham_rack
90
- prerelease: false
91
66
  requirement: &id005 !ruby/object:Gem::Requirement
92
67
  none: false
93
68
  requirements:
94
69
  - - "="
95
70
  - !ruby/object:Gem::Version
96
- hash: 29
97
- segments:
98
- - 1
99
- - 3
100
- - 3
101
71
  version: 1.3.3
102
72
  type: :runtime
73
+ prerelease: false
103
74
  version_requirements: *id005
104
75
  - !ruby/object:Gem::Dependency
105
76
  name: sinatra
106
- prerelease: false
107
77
  requirement: &id006 !ruby/object:Gem::Requirement
108
78
  none: false
109
79
  requirements:
110
80
  - - ">="
111
81
  - !ruby/object:Gem::Version
112
- hash: 23
113
- segments:
114
- - 1
115
- - 1
116
- - 2
117
82
  version: 1.1.2
118
83
  type: :runtime
84
+ prerelease: false
119
85
  version_requirements: *id006
120
86
  - !ruby/object:Gem::Dependency
121
87
  name: aruba
122
- prerelease: false
123
88
  requirement: &id007 !ruby/object:Gem::Requirement
124
89
  none: false
125
90
  requirements:
126
91
  - - "="
127
92
  - !ruby/object:Gem::Version
128
- hash: 27
129
- segments:
130
- - 0
131
- - 2
132
- - 6
133
93
  version: 0.2.6
134
94
  type: :development
95
+ prerelease: false
135
96
  version_requirements: *id007
136
97
  description: Clearance-based Rails engine for Software as a Service (Saas) that provides account and project management
137
98
  email: support@thoughtbot.com
@@ -326,7 +287,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
326
287
  requirements:
327
288
  - - ">="
328
289
  - !ruby/object:Gem::Version
329
- hash: 3
290
+ hash: 1978592027769739368
330
291
  segments:
331
292
  - 0
332
293
  version: "0"
@@ -335,9 +296,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
335
296
  requirements:
336
297
  - - ">="
337
298
  - !ruby/object:Gem::Version
338
- hash: 3
339
- segments:
340
- - 0
341
299
  version: "0"
342
300
  requirements: []
343
301