saucy 0.10.6 → 0.10.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +4 -0
- data/README.md +8 -1
- data/app/controllers/plans_controller.rb +6 -0
- data/lib/saucy/account.rb +8 -1
- data/spec/controllers/plans_controller_spec.rb +10 -0
- data/spec/models/subscription_spec.rb +27 -0
- data/spec/support/notifications.rb +16 -0
- metadata +31 -12
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -45,7 +45,14 @@ In addition, there are a number of strings such as application name, support url
|
|
45
45
|
|
46
46
|
There is a `saucy:daily` rake task which should be run on a regular basis to send receipts and payment processing problem emails.
|
47
47
|
|
48
|
-
Saucy accounts become "activated" once an initial setup step is complete.
|
48
|
+
Saucy accounts become "activated" once an initial setup step is complete.
|
49
|
+
This could be creating the first bug for a bug tracker, or setting up a client
|
50
|
+
gem for a server API. Once the application detects that the account is
|
51
|
+
activated, it should set "activated" to true on the account. This will prevent
|
52
|
+
followup emails being sent to users that have already set up their accounts.
|
53
|
+
It will also send an "Activated" event to Kissmetrics through Saucy-kiss, if
|
54
|
+
Saucy-kiss is installed.
|
55
|
+
|
49
56
|
|
50
57
|
Development environment
|
51
58
|
-----------------------
|
@@ -3,6 +3,7 @@ class PlansController < ApplicationController
|
|
3
3
|
|
4
4
|
def index
|
5
5
|
@plans = Plan.ordered
|
6
|
+
notify_observers_of_plan_list_view
|
6
7
|
end
|
7
8
|
|
8
9
|
def edit
|
@@ -31,6 +32,11 @@ class PlansController < ApplicationController
|
|
31
32
|
notify_observers("plan_downgraded", from_plan, to_plan) if from_plan.price > to_plan.price
|
32
33
|
end
|
33
34
|
|
35
|
+
def notify_observers_of_plan_list_view
|
36
|
+
Saucy::Notifications.notify_observers("plan_list_viewed",
|
37
|
+
:request => request)
|
38
|
+
end
|
39
|
+
|
34
40
|
def notify_observers(event_name, from_plan, to_plan)
|
35
41
|
Saucy::Notifications.notify_observers(event_name,
|
36
42
|
:account => @account,
|
data/lib/saucy/account.rb
CHANGED
@@ -30,6 +30,7 @@ module Saucy
|
|
30
30
|
:message => "must be only lower case letters and underscores."
|
31
31
|
|
32
32
|
before_create :set_trial_expiration
|
33
|
+
after_save :record_new_activations
|
33
34
|
end
|
34
35
|
|
35
36
|
module InstanceMethods
|
@@ -75,7 +76,13 @@ module Saucy
|
|
75
76
|
else
|
76
77
|
30
|
77
78
|
end
|
78
|
-
self.trial_expires_at = number_free_days.days.from_now(created_at || Time.now)
|
79
|
+
self.trial_expires_at = number_free_days.days.from_now(created_at || Time.zone.now)
|
80
|
+
end
|
81
|
+
|
82
|
+
def record_new_activations
|
83
|
+
if activated_changed? && activated?
|
84
|
+
Saucy::Notifications.notify_observers("activated", :account => self)
|
85
|
+
end
|
79
86
|
end
|
80
87
|
|
81
88
|
def users_count
|
@@ -69,3 +69,13 @@ describe PlansController, "successful update that does not change the plan", :as
|
|
69
69
|
should_not notify_observers("plan_downgraded", :account => account, :request => request, :from_plan => original_plan, :to_plan => original_plan)
|
70
70
|
end
|
71
71
|
end
|
72
|
+
|
73
|
+
describe PlansController, "viewing plan list" do
|
74
|
+
before do
|
75
|
+
get :index
|
76
|
+
end
|
77
|
+
|
78
|
+
it "notifies observers" do
|
79
|
+
should notify_observers("plan_list_viewed", :request => request)
|
80
|
+
end
|
81
|
+
end
|
@@ -497,3 +497,30 @@ describe Account, "with a paid subscription that is past due" do
|
|
497
497
|
subject.next_billing_date.to_s.should == subscription["next_billing_date"].to_s
|
498
498
|
end
|
499
499
|
end
|
500
|
+
|
501
|
+
describe Account, "that is activated" do
|
502
|
+
subject do
|
503
|
+
Factory(:account,
|
504
|
+
:cardholder_name => "Ralph Robot",
|
505
|
+
:billing_email => "ralph@example.com",
|
506
|
+
:card_number => "4111111111111111",
|
507
|
+
:verification_code => "123",
|
508
|
+
:expiration_month => 5,
|
509
|
+
:expiration_year => 2012,
|
510
|
+
:plan => Factory(:paid_plan))
|
511
|
+
end
|
512
|
+
|
513
|
+
it "notifies observers of activations" do
|
514
|
+
subject.activated = true
|
515
|
+
subject.save!
|
516
|
+
should notify_observers("activated", :account => subject)
|
517
|
+
end
|
518
|
+
|
519
|
+
it "notifies observers of activation only once" do
|
520
|
+
2.times do
|
521
|
+
subject.activated = true
|
522
|
+
subject.save!
|
523
|
+
end
|
524
|
+
should notify_observers_once("activated", :account => subject)
|
525
|
+
end
|
526
|
+
end
|
@@ -58,6 +58,22 @@ RSpec::Matchers.define :notify_observers do |event_name, data|
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
+
RSpec::Matchers.define :notify_observers_once do |event_name, data|
|
62
|
+
match do |ignored_subject|
|
63
|
+
@event = RecordedEvent.new(event_name, data)
|
64
|
+
recorder.events.select{|ev| ev == @event }.size.should == 1
|
65
|
+
end
|
66
|
+
|
67
|
+
failure_message do
|
68
|
+
times_notified = recorder.events.select{|ev| ev == @event }.size
|
69
|
+
"Expected event 1 time:\n#{@event.inspect}\n\nGot event #{times_notified} times"
|
70
|
+
end
|
71
|
+
|
72
|
+
def recorder
|
73
|
+
RecordingObserver.instance
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
61
77
|
RSpec.configure do |config|
|
62
78
|
config.before do
|
63
79
|
Saucy::Notifications.clear_observers
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: saucy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 57
|
5
|
+
prerelease:
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 10
|
8
|
-
-
|
9
|
-
version: 0.10.
|
9
|
+
- 7
|
10
|
+
version: 0.10.7
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- thoughtbot, inc.
|
@@ -19,105 +20,119 @@ autorequire:
|
|
19
20
|
bindir: bin
|
20
21
|
cert_chain: []
|
21
22
|
|
22
|
-
date: 2011-
|
23
|
+
date: 2011-08-12 00:00:00 -04:00
|
23
24
|
default_executable:
|
24
25
|
dependencies:
|
25
26
|
- !ruby/object:Gem::Dependency
|
26
27
|
name: clearance
|
27
28
|
prerelease: false
|
29
|
+
type: :runtime
|
28
30
|
requirement: &id001 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
29
32
|
requirements:
|
30
33
|
- - ~>
|
31
34
|
- !ruby/object:Gem::Version
|
35
|
+
hash: 55
|
32
36
|
segments:
|
33
37
|
- 0
|
34
38
|
- 11
|
35
39
|
- 2
|
36
40
|
version: 0.11.2
|
37
|
-
type: :runtime
|
38
41
|
version_requirements: *id001
|
39
42
|
- !ruby/object:Gem::Dependency
|
40
43
|
name: formtastic
|
41
44
|
prerelease: false
|
45
|
+
type: :runtime
|
42
46
|
requirement: &id002 !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
43
48
|
requirements:
|
44
49
|
- - ">="
|
45
50
|
- !ruby/object:Gem::Version
|
51
|
+
hash: 11
|
46
52
|
segments:
|
47
53
|
- 1
|
48
54
|
- 2
|
49
55
|
version: "1.2"
|
50
|
-
type: :runtime
|
51
56
|
version_requirements: *id002
|
52
57
|
- !ruby/object:Gem::Dependency
|
53
58
|
name: railties
|
54
59
|
prerelease: false
|
60
|
+
type: :runtime
|
55
61
|
requirement: &id003 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
56
63
|
requirements:
|
57
64
|
- - ">="
|
58
65
|
- !ruby/object:Gem::Version
|
66
|
+
hash: 1
|
59
67
|
segments:
|
60
68
|
- 3
|
61
69
|
- 0
|
62
70
|
- 3
|
63
71
|
version: 3.0.3
|
64
|
-
type: :runtime
|
65
72
|
version_requirements: *id003
|
66
73
|
- !ruby/object:Gem::Dependency
|
67
74
|
name: braintree
|
68
75
|
prerelease: false
|
76
|
+
type: :runtime
|
69
77
|
requirement: &id004 !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
70
79
|
requirements:
|
71
80
|
- - ">="
|
72
81
|
- !ruby/object:Gem::Version
|
82
|
+
hash: 19
|
73
83
|
segments:
|
74
84
|
- 2
|
75
85
|
- 6
|
76
86
|
- 2
|
77
87
|
version: 2.6.2
|
78
|
-
type: :runtime
|
79
88
|
version_requirements: *id004
|
80
89
|
- !ruby/object:Gem::Dependency
|
81
90
|
name: sham_rack
|
82
91
|
prerelease: false
|
92
|
+
type: :runtime
|
83
93
|
requirement: &id005 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
84
95
|
requirements:
|
85
96
|
- - "="
|
86
97
|
- !ruby/object:Gem::Version
|
98
|
+
hash: 29
|
87
99
|
segments:
|
88
100
|
- 1
|
89
101
|
- 3
|
90
102
|
- 3
|
91
103
|
version: 1.3.3
|
92
|
-
type: :runtime
|
93
104
|
version_requirements: *id005
|
94
105
|
- !ruby/object:Gem::Dependency
|
95
106
|
name: sinatra
|
96
107
|
prerelease: false
|
108
|
+
type: :runtime
|
97
109
|
requirement: &id006 !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
98
111
|
requirements:
|
99
112
|
- - ">="
|
100
113
|
- !ruby/object:Gem::Version
|
114
|
+
hash: 23
|
101
115
|
segments:
|
102
116
|
- 1
|
103
117
|
- 1
|
104
118
|
- 2
|
105
119
|
version: 1.1.2
|
106
|
-
type: :runtime
|
107
120
|
version_requirements: *id006
|
108
121
|
- !ruby/object:Gem::Dependency
|
109
122
|
name: aruba
|
110
123
|
prerelease: false
|
124
|
+
type: :development
|
111
125
|
requirement: &id007 !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
112
127
|
requirements:
|
113
128
|
- - "="
|
114
129
|
- !ruby/object:Gem::Version
|
130
|
+
hash: 27
|
115
131
|
segments:
|
116
132
|
- 0
|
117
133
|
- 2
|
118
134
|
- 6
|
119
135
|
version: 0.2.6
|
120
|
-
type: :development
|
121
136
|
version_requirements: *id007
|
122
137
|
description: Clearance-based Rails engine for Software as a Service (Saas) that provides account and project management
|
123
138
|
email: support@thoughtbot.com
|
@@ -309,23 +324,27 @@ rdoc_options: []
|
|
309
324
|
require_paths:
|
310
325
|
- lib
|
311
326
|
required_ruby_version: !ruby/object:Gem::Requirement
|
327
|
+
none: false
|
312
328
|
requirements:
|
313
329
|
- - ">="
|
314
330
|
- !ruby/object:Gem::Version
|
331
|
+
hash: 3
|
315
332
|
segments:
|
316
333
|
- 0
|
317
334
|
version: "0"
|
318
335
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
336
|
+
none: false
|
319
337
|
requirements:
|
320
338
|
- - ">="
|
321
339
|
- !ruby/object:Gem::Version
|
340
|
+
hash: 3
|
322
341
|
segments:
|
323
342
|
- 0
|
324
343
|
version: "0"
|
325
344
|
requirements: []
|
326
345
|
|
327
346
|
rubyforge_project:
|
328
|
-
rubygems_version: 1.
|
347
|
+
rubygems_version: 1.6.1
|
329
348
|
signing_key:
|
330
349
|
specification_version: 3
|
331
350
|
summary: Clearance-based Rails engine for SaaS
|