saucy 0.10.10 → 0.11.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +8 -8
- data/Gemfile +1 -2
- data/Gemfile.lock +141 -128
- data/README.md +8 -9
- data/Rakefile +2 -2
- data/app/models/invitation.rb +1 -0
- data/app/views/accounts/edit.html.erb +4 -28
- data/app/views/shared/_project_dropdown.html.erb +1 -1
- data/config/locales/en.yml +0 -3
- data/features/run_features.feature +24 -25
- data/features/step_definitions/clearance_steps.rb +3 -3
- data/features/step_definitions/rails_steps.rb +2 -2
- data/features/support/env.rb +5 -2
- data/lib/generators/saucy/features/templates/features/manage_account.feature +1 -12
- data/lib/generators/saucy/features/templates/step_definitions/braintree_steps.rb +1 -1
- data/lib/generators/saucy/features/templates/step_definitions/cron_steps.rb +3 -1
- data/lib/generators/saucy/features/templates/step_definitions/session_steps.rb +2 -2
- data/lib/saucy/configuration.rb +0 -2
- data/lib/saucy/engine.rb +1 -4
- data/lib/saucy/fake_braintree.rb +1 -1
- data/lib/saucy/routing_extensions.rb +2 -7
- data/lib/saucy/subscription.rb +3 -31
- data/public/saucy/stylesheets/screen.css +1 -5
- data/spec/environment.rb +6 -5
- data/spec/models/subscription_spec.rb +14 -68
- data/spec/saucy/configuration_spec.rb +0 -14
- data/spec/spec_helper.rb +2 -2
- data/spec/support/clearance_matchers.rb +1 -1
- data/spec/support/notifications.rb +1 -1
- metadata +8 -24
data/CHANGELOG.md
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
0.
|
1
|
+
0.11.0
|
2
2
|
|
3
|
-
|
3
|
+
Update Saucy to be compatible with Rails 3.1 which includes:
|
4
4
|
|
5
|
-
|
5
|
+
* Update testing dependencies
|
6
|
+
* Update test application path configuration
|
7
|
+
* Update route extension to not rely on `initialize` to be called
|
8
|
+
* Use `shoulda-matchers` instead of `shoulda`
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
0.10.8
|
10
|
-
|
11
|
-
Backport merchant account TZ fixes from 0.13.1
|
10
|
+
If you are still using Saucy with Rails 3.0.x, please still use 0.10.x version
|
11
|
+
of saucy, which now branched to `0-10-stable` branch.
|
12
12
|
|
13
13
|
0.10.7
|
14
14
|
|
data/Gemfile
CHANGED
@@ -6,7 +6,7 @@ gem "rspec-rails", :require => false
|
|
6
6
|
gem "rails", ">= 3.0.3"
|
7
7
|
gem "thin"
|
8
8
|
gem "clearance", "~> 0.11.0"
|
9
|
-
gem "shoulda", :require => false
|
9
|
+
gem "shoulda-matchers", "~> 1.0.0.beta3", :require => false
|
10
10
|
gem "bourne", :require => false
|
11
11
|
gem "sqlite3", :require => false
|
12
12
|
gem "factory_girl", :require => false
|
@@ -14,7 +14,6 @@ gem "sinatra"
|
|
14
14
|
gem "sham_rack"
|
15
15
|
gem "braintree"
|
16
16
|
gem "timecop"
|
17
|
-
gem "airbrake"
|
18
17
|
|
19
18
|
# used by the rails app in cucumber
|
20
19
|
gem "cucumber-rails", :require => false
|
data/Gemfile.lock
CHANGED
@@ -1,176 +1,189 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
rack (~> 1.
|
15
|
-
rack-mount (~> 0.
|
16
|
-
rack-test (~> 0.
|
17
|
-
|
18
|
-
activemodel (3.0
|
19
|
-
activesupport (= 3.0
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
arel (2.
|
35
|
-
aruba (0.
|
36
|
-
|
37
|
-
|
38
|
-
|
4
|
+
actionmailer (3.1.0)
|
5
|
+
actionpack (= 3.1.0)
|
6
|
+
mail (~> 2.3.0)
|
7
|
+
actionpack (3.1.0)
|
8
|
+
activemodel (= 3.1.0)
|
9
|
+
activesupport (= 3.1.0)
|
10
|
+
builder (~> 3.0.0)
|
11
|
+
erubis (~> 2.7.0)
|
12
|
+
i18n (~> 0.6)
|
13
|
+
rack (~> 1.3.2)
|
14
|
+
rack-cache (~> 1.0.3)
|
15
|
+
rack-mount (~> 0.8.2)
|
16
|
+
rack-test (~> 0.6.1)
|
17
|
+
sprockets (~> 2.0.0)
|
18
|
+
activemodel (3.1.0)
|
19
|
+
activesupport (= 3.1.0)
|
20
|
+
bcrypt-ruby (~> 3.0.0)
|
21
|
+
builder (~> 3.0.0)
|
22
|
+
i18n (~> 0.6)
|
23
|
+
activerecord (3.1.0)
|
24
|
+
activemodel (= 3.1.0)
|
25
|
+
activesupport (= 3.1.0)
|
26
|
+
arel (~> 2.2.1)
|
27
|
+
tzinfo (~> 0.3.29)
|
28
|
+
activeresource (3.1.0)
|
29
|
+
activemodel (= 3.1.0)
|
30
|
+
activesupport (= 3.1.0)
|
31
|
+
activesupport (3.1.0)
|
32
|
+
multi_json (~> 1.0)
|
33
|
+
addressable (2.2.6)
|
34
|
+
arel (2.2.1)
|
35
|
+
aruba (0.4.6)
|
36
|
+
bcat (>= 0.6.1)
|
37
|
+
childprocess (>= 0.2.0)
|
38
|
+
cucumber (>= 1.0.2)
|
39
|
+
rdiscount (>= 1.6.8)
|
40
|
+
rspec (>= 2.6.0)
|
41
|
+
bcat (0.6.2)
|
42
|
+
rack (~> 1.0)
|
43
|
+
bcrypt-ruby (3.0.0)
|
39
44
|
bourne (1.0)
|
40
45
|
mocha (= 0.9.8)
|
41
|
-
braintree (2.
|
42
|
-
builder
|
43
|
-
builder (
|
44
|
-
capybara (
|
45
|
-
celerity (>= 0.7.9)
|
46
|
-
culerity (>= 0.2.4)
|
46
|
+
braintree (2.11.0)
|
47
|
+
builder (>= 2.0.0)
|
48
|
+
builder (3.0.0)
|
49
|
+
capybara (1.1.1)
|
47
50
|
mime-types (>= 1.16)
|
48
51
|
nokogiri (>= 1.3.3)
|
49
52
|
rack (>= 1.0.0)
|
50
53
|
rack-test (>= 0.5.4)
|
51
|
-
selenium-webdriver (
|
52
|
-
xpath (~> 0.1.
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
clearance (0.11.1)
|
54
|
+
selenium-webdriver (~> 2.0)
|
55
|
+
xpath (~> 0.1.4)
|
56
|
+
childprocess (0.2.2)
|
57
|
+
ffi (~> 1.0.6)
|
58
|
+
clearance (0.11.2)
|
57
59
|
diesel (~> 0.1.4)
|
58
|
-
rails (
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
cucumber (
|
68
|
-
|
69
|
-
daemons (1.1.
|
70
|
-
database_cleaner (0.6.
|
71
|
-
diesel (0.1.
|
72
|
-
railties
|
73
|
-
diff-lcs (1.1.
|
74
|
-
dynamic_form (1.1.
|
75
|
-
erubis (2.
|
76
|
-
abstract (>= 1.0.0)
|
60
|
+
rails (>= 3.0)
|
61
|
+
cucumber (1.0.4)
|
62
|
+
builder (>= 2.1.2)
|
63
|
+
diff-lcs (>= 1.1.2)
|
64
|
+
gherkin (~> 2.4.18)
|
65
|
+
json (>= 1.4.6)
|
66
|
+
term-ansicolor (>= 1.0.6)
|
67
|
+
cucumber-rails (1.0.3)
|
68
|
+
capybara (>= 1.1.1)
|
69
|
+
cucumber (~> 1.0.4)
|
70
|
+
nokogiri (>= 1.5.0)
|
71
|
+
daemons (1.1.4)
|
72
|
+
database_cleaner (0.6.7)
|
73
|
+
diesel (0.1.5)
|
74
|
+
railties
|
75
|
+
diff-lcs (1.1.3)
|
76
|
+
dynamic_form (1.1.4)
|
77
|
+
erubis (2.7.0)
|
77
78
|
eventmachine (0.12.10)
|
78
|
-
factory_girl (1.
|
79
|
-
factory_girl_rails (1.0)
|
80
|
-
factory_girl (~> 1.
|
81
|
-
|
82
|
-
ffi (0.
|
83
|
-
|
84
|
-
formtastic (1.2.2)
|
79
|
+
factory_girl (2.1.0)
|
80
|
+
factory_girl_rails (1.2.0)
|
81
|
+
factory_girl (~> 2.1.0)
|
82
|
+
railties (>= 3.0.0)
|
83
|
+
ffi (1.0.9)
|
84
|
+
formtastic (1.2.4)
|
85
85
|
actionpack (>= 2.3.7)
|
86
86
|
activesupport (>= 2.3.7)
|
87
|
-
i18n (
|
88
|
-
gherkin (2.
|
89
|
-
json (
|
90
|
-
|
91
|
-
i18n (0.
|
92
|
-
jquery-rails (1.0)
|
93
|
-
|
87
|
+
i18n (~> 0.4)
|
88
|
+
gherkin (2.4.18)
|
89
|
+
json (>= 1.4.6)
|
90
|
+
hike (1.2.1)
|
91
|
+
i18n (0.6.0)
|
92
|
+
jquery-rails (1.0.14)
|
93
|
+
railties (~> 3.0)
|
94
94
|
thor (~> 0.14)
|
95
|
-
json (1.4
|
96
|
-
json_pure (1.5.
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
mail (2.
|
101
|
-
activesupport (>= 2.3.6)
|
95
|
+
json (1.5.4)
|
96
|
+
json_pure (1.5.4)
|
97
|
+
spruz (~> 0.2.8)
|
98
|
+
launchy (2.0.5)
|
99
|
+
addressable (~> 2.2.6)
|
100
|
+
mail (2.3.0)
|
102
101
|
i18n (>= 0.4.0)
|
103
102
|
mime-types (~> 1.16)
|
104
103
|
treetop (~> 1.4.8)
|
105
104
|
mime-types (1.16)
|
106
105
|
mocha (0.9.8)
|
107
106
|
rake
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
rack
|
107
|
+
multi_json (1.0.3)
|
108
|
+
nokogiri (1.5.0)
|
109
|
+
polyglot (0.3.2)
|
110
|
+
rack (1.3.2)
|
111
|
+
rack-cache (1.0.3)
|
112
|
+
rack (>= 0.4)
|
113
|
+
rack-mount (0.8.3)
|
112
114
|
rack (>= 1.0.0)
|
113
|
-
rack-
|
115
|
+
rack-ssl (1.3.2)
|
116
|
+
rack
|
117
|
+
rack-test (0.6.1)
|
114
118
|
rack (>= 1.0)
|
115
|
-
rails (3.0
|
116
|
-
actionmailer (= 3.0
|
117
|
-
actionpack (= 3.0
|
118
|
-
activerecord (= 3.0
|
119
|
-
activeresource (= 3.0
|
120
|
-
activesupport (= 3.0
|
119
|
+
rails (3.1.0)
|
120
|
+
actionmailer (= 3.1.0)
|
121
|
+
actionpack (= 3.1.0)
|
122
|
+
activerecord (= 3.1.0)
|
123
|
+
activeresource (= 3.1.0)
|
124
|
+
activesupport (= 3.1.0)
|
121
125
|
bundler (~> 1.0)
|
122
|
-
railties (= 3.0
|
123
|
-
railties (3.0
|
124
|
-
actionpack (= 3.0
|
125
|
-
activesupport (= 3.0
|
126
|
+
railties (= 3.1.0)
|
127
|
+
railties (3.1.0)
|
128
|
+
actionpack (= 3.1.0)
|
129
|
+
activesupport (= 3.1.0)
|
130
|
+
rack-ssl (~> 1.3.2)
|
126
131
|
rake (>= 0.8.7)
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
132
|
+
rdoc (~> 3.4)
|
133
|
+
thor (~> 0.14.6)
|
134
|
+
rake (0.9.2)
|
135
|
+
rdiscount (1.6.8)
|
136
|
+
rdoc (3.9.4)
|
137
|
+
rspec (2.6.0)
|
138
|
+
rspec-core (~> 2.6.0)
|
139
|
+
rspec-expectations (~> 2.6.0)
|
140
|
+
rspec-mocks (~> 2.6.0)
|
141
|
+
rspec-core (2.6.4)
|
142
|
+
rspec-expectations (2.6.0)
|
135
143
|
diff-lcs (~> 1.1.2)
|
136
|
-
rspec-mocks (2.
|
137
|
-
rspec-rails (2.
|
144
|
+
rspec-mocks (2.6.0)
|
145
|
+
rspec-rails (2.6.1)
|
138
146
|
actionpack (~> 3.0)
|
139
147
|
activesupport (~> 3.0)
|
140
148
|
railties (~> 3.0)
|
141
|
-
rspec (~> 2.
|
149
|
+
rspec (~> 2.6.0)
|
142
150
|
rubyzip (0.9.4)
|
143
|
-
selenium-webdriver (
|
144
|
-
childprocess (
|
145
|
-
ffi (
|
151
|
+
selenium-webdriver (2.5.0)
|
152
|
+
childprocess (>= 0.2.1)
|
153
|
+
ffi (>= 1.0.7)
|
146
154
|
json_pure
|
147
155
|
rubyzip
|
148
156
|
sham_rack (1.3.3)
|
149
157
|
rack
|
150
|
-
shoulda (
|
151
|
-
sinatra (1.
|
158
|
+
shoulda-matchers (1.0.0.beta3)
|
159
|
+
sinatra (1.2.6)
|
152
160
|
rack (~> 1.1)
|
153
|
-
tilt (
|
154
|
-
|
155
|
-
|
156
|
-
|
161
|
+
tilt (< 2.0, >= 1.2.2)
|
162
|
+
sprockets (2.0.0)
|
163
|
+
hike (~> 1.2)
|
164
|
+
rack (~> 1.0)
|
165
|
+
tilt (!= 1.3.0, ~> 1.1)
|
166
|
+
spruz (0.2.13)
|
167
|
+
sqlite3 (1.3.4)
|
168
|
+
term-ansicolor (1.0.6)
|
169
|
+
thin (1.2.11)
|
157
170
|
daemons (>= 1.0.9)
|
158
171
|
eventmachine (>= 0.12.6)
|
159
172
|
rack (>= 1.0.0)
|
160
173
|
thor (0.14.6)
|
161
|
-
tilt (1.
|
174
|
+
tilt (1.3.3)
|
162
175
|
timecop (0.3.5)
|
163
|
-
treetop (1.4.
|
176
|
+
treetop (1.4.10)
|
177
|
+
polyglot
|
164
178
|
polyglot (>= 0.3.1)
|
165
|
-
tzinfo (0.3.
|
166
|
-
xpath (0.1.
|
179
|
+
tzinfo (0.3.29)
|
180
|
+
xpath (0.1.4)
|
167
181
|
nokogiri (~> 1.3)
|
168
182
|
|
169
183
|
PLATFORMS
|
170
184
|
ruby
|
171
185
|
|
172
186
|
DEPENDENCIES
|
173
|
-
airbrake
|
174
187
|
aruba
|
175
188
|
bourne
|
176
189
|
braintree
|
@@ -189,7 +202,7 @@ DEPENDENCIES
|
|
189
202
|
rake
|
190
203
|
rspec-rails
|
191
204
|
sham_rack
|
192
|
-
shoulda
|
205
|
+
shoulda-matchers (~> 1.0.0.beta3)
|
193
206
|
sinatra
|
194
207
|
sqlite3
|
195
208
|
thin
|
data/README.md
CHANGED
@@ -21,6 +21,10 @@ In your Gemfile:
|
|
21
21
|
|
22
22
|
gem "saucy"
|
23
23
|
|
24
|
+
If you're using Rails 3.0.x, instead use the 0.10.x version of this gem:
|
25
|
+
|
26
|
+
gem "saucy", "~> 0.10.7"
|
27
|
+
|
24
28
|
After you bundle, run the generator:
|
25
29
|
|
26
30
|
rails generate saucy:install
|
@@ -53,6 +57,7 @@ followup emails being sent to users that have already set up their accounts.
|
|
53
57
|
It will also send an "Activated" event to Kissmetrics through Saucy-kiss, if
|
54
58
|
Saucy-kiss is installed.
|
55
59
|
|
60
|
+
|
56
61
|
Development environment
|
57
62
|
-----------------------
|
58
63
|
|
@@ -82,13 +87,13 @@ To use seed data in your Cucumber, add this to features/support/seed.rb:
|
|
82
87
|
Customization
|
83
88
|
-------------
|
84
89
|
|
85
|
-
By default Saucy uses and provides a `saucy.html.erb` layout. To change the
|
86
|
-
layout for a controller inside of saucy, add a line like this to your
|
90
|
+
By default Saucy uses and provides a `saucy.html.erb` layout. To change the
|
91
|
+
layout for a controller inside of saucy, add a line like this to your
|
87
92
|
config/application.rb:
|
88
93
|
|
89
94
|
config.saucy.layouts.accounts.index = "custom"
|
90
95
|
|
91
|
-
In addition to just the normal yield, your layout should yield the following
|
96
|
+
In addition to just the normal yield, your layout should yield the following
|
92
97
|
items in order to get everything from saucy views:
|
93
98
|
|
94
99
|
* :header
|
@@ -122,9 +127,3 @@ Make sure you don't do this in ApplicationController:
|
|
122
127
|
|
123
128
|
Saucy's internal controllers don't skip any before filters.
|
124
129
|
|
125
|
-
If your billing merchant account is not configured to run in the Eastern
|
126
|
-
timezone, you can override the timezone in Saucy configuration as
|
127
|
-
merchant_account_time_zone. You'll want this set accurately so that the daily
|
128
|
-
cronjob which syncs the Braintree subscription billing cycle dates runs for the
|
129
|
-
correct accounts. If this is set incorrectly, you will occasionally see
|
130
|
-
duplicate receipt emails being delivered.
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler/setup'
|
3
3
|
require 'rake'
|
4
|
-
require '
|
4
|
+
require 'rubygems/package_task'
|
5
5
|
require 'cucumber/rake/task'
|
6
6
|
require 'rspec/core/rake_task'
|
7
7
|
|
@@ -19,7 +19,7 @@ RSpec::Core::RakeTask.new do |t|
|
|
19
19
|
end
|
20
20
|
|
21
21
|
eval("$specification = begin; #{IO.read('saucy.gemspec')}; end")
|
22
|
-
|
22
|
+
Gem::PackageTask.new($specification) do |package|
|
23
23
|
package.need_zip = true
|
24
24
|
package.need_tar = true
|
25
25
|
end
|
data/app/models/invitation.rb
CHANGED
@@ -24,34 +24,10 @@
|
|
24
24
|
<%= form.buttons do %>
|
25
25
|
<%= form.commit_button "Update" %>
|
26
26
|
<li>
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
</p>
|
32
|
-
|
33
|
-
<%= link_to t("saucy.confirm_account_deletion", :default => "I understand, delete my account"),
|
34
|
-
@account,
|
35
|
-
:class => "button warning",
|
36
|
-
:method => :delete,
|
37
|
-
:confirm => "Are you sure? All data will be irreversibly deleted." %>
|
38
|
-
|
39
|
-
<%= link_to t("saucy.cancel_account_deletion", :default => "On second thought, don't delete my account."),
|
40
|
-
root_path, :class => "cancel-account-deletion" %>
|
41
|
-
</div>
|
42
|
-
|
43
|
-
<%= link_to t(".delete", :default => "Delete my account"), "#", :class => "prompt-to-delete" %>
|
44
|
-
|
45
|
-
<% content_for :javascript do %>
|
46
|
-
<script type="text/javascript">
|
47
|
-
$(function() {
|
48
|
-
$("a.prompt-to-delete").click(function(event) {
|
49
|
-
$(event.target).hide();
|
50
|
-
$('#account-deletion-warning').slideDown();
|
51
|
-
});
|
52
|
-
});
|
53
|
-
</script>
|
54
|
-
<% end %>
|
27
|
+
<%= link_to t(".delete", :default => "Delete my account"),
|
28
|
+
@account,
|
29
|
+
:method => :delete,
|
30
|
+
:confirm => "Are you sure? All data will be irreversibly deleted." %>
|
55
31
|
</li>
|
56
32
|
<% end %>
|
57
33
|
<% end %>
|
@@ -9,7 +9,7 @@
|
|
9
9
|
<span>Projects</span>
|
10
10
|
<% end -%>
|
11
11
|
<% if current_user.memberships.admin.any? || current_user.projects.active.any? -%>
|
12
|
-
|
12
|
+
<%= image_tag "arrow-down.png", :alt => "arrow down" %>
|
13
13
|
<% end -%>
|
14
14
|
<% end %>
|
15
15
|
</h1>
|
data/config/locales/en.yml
CHANGED
@@ -3,9 +3,6 @@ en:
|
|
3
3
|
app_url: 'http://example.com'
|
4
4
|
support_email: support@example.com
|
5
5
|
saucy:
|
6
|
-
account_deletion_effects_warning: When you cancel your account, all of your data will be deleted from %{app_name}, and you will not be able to recover your data.
|
7
|
-
cancel_account_deletion: On second thought, don't delete my account.
|
8
|
-
confirm_account_deletion: I understand, delete my account
|
9
6
|
billing_address: Billing Address
|
10
7
|
errors:
|
11
8
|
past_due:
|
@@ -2,7 +2,7 @@
|
|
2
2
|
Feature: generate a saucy application and run rake
|
3
3
|
|
4
4
|
Background:
|
5
|
-
When I successfully run
|
5
|
+
When I successfully run `bundle exec rails new testapp`
|
6
6
|
And I cd to "testapp"
|
7
7
|
And I copy the locked Gemfile from this project
|
8
8
|
And I append to "Gemfile" with:
|
@@ -16,23 +16,22 @@ Feature: generate a saucy application and run rake
|
|
16
16
|
gem "formtastic"
|
17
17
|
gem "rspec-rails"
|
18
18
|
gem "bourne"
|
19
|
-
gem "shoulda"
|
19
|
+
gem "shoulda-matchers"
|
20
20
|
gem "launchy"
|
21
21
|
gem "timecop"
|
22
22
|
gem "jquery-rails"
|
23
23
|
"""
|
24
24
|
When I add the "saucy" gem from this project as a dependency
|
25
|
-
And I successfully run
|
26
|
-
And I successfully run "rails generate jquery:install --force"
|
25
|
+
And I successfully run `bundle install`
|
27
26
|
And I bootstrap the application for clearance
|
28
27
|
And I bootstrap the application for saucy
|
29
28
|
|
30
29
|
Scenario: generate a saucy application and run rake
|
31
|
-
When I successfully run
|
32
|
-
And I successfully run
|
33
|
-
And I successfully run
|
34
|
-
And I successfully run
|
35
|
-
And I run
|
30
|
+
When I successfully run `rails generate saucy:install`
|
31
|
+
And I successfully run `rails generate saucy:specs`
|
32
|
+
And I successfully run `rails generate saucy:features`
|
33
|
+
And I successfully run `bundle exec rake db:migrate`
|
34
|
+
And I run `bundle exec rake`
|
36
35
|
Then it should pass with:
|
37
36
|
"""
|
38
37
|
passed
|
@@ -41,13 +40,13 @@ Feature: generate a saucy application and run rake
|
|
41
40
|
And the output should not contain "Could not find generator"
|
42
41
|
|
43
42
|
Scenario: A new saucy app with custom views
|
44
|
-
When I successfully run
|
45
|
-
And I successfully run
|
46
|
-
And I successfully run
|
47
|
-
And I successfully run
|
48
|
-
And I successfully run
|
43
|
+
When I successfully run `rails generate saucy:install`
|
44
|
+
And I successfully run `rails generate saucy:specs`
|
45
|
+
And I successfully run `rails generate saucy:features`
|
46
|
+
And I successfully run `rails generate saucy:views`
|
47
|
+
And I successfully run `bundle exec rake db:migrate`
|
49
48
|
And I give a more detailed new account message
|
50
|
-
And I run
|
49
|
+
And I run `bundle exec rake`
|
51
50
|
Then it should pass with:
|
52
51
|
"""
|
53
52
|
passed
|
@@ -56,12 +55,12 @@ Feature: generate a saucy application and run rake
|
|
56
55
|
And the output should not contain "Could not find generator"
|
57
56
|
|
58
57
|
Scenario: A new saucy app with custom layouts
|
59
|
-
When I successfully run
|
60
|
-
And I successfully run
|
61
|
-
And I successfully run
|
62
|
-
And I successfully run
|
58
|
+
When I successfully run `rails generate saucy:install`
|
59
|
+
And I successfully run `rails generate saucy:specs`
|
60
|
+
And I successfully run `rails generate saucy:features`
|
61
|
+
And I successfully run `bundle exec rake db:migrate`
|
63
62
|
And I add a custom layout to the accounts index
|
64
|
-
And I run
|
63
|
+
And I run `bundle exec rake`
|
65
64
|
Then it should pass with:
|
66
65
|
"""
|
67
66
|
passed
|
@@ -70,12 +69,12 @@ Feature: generate a saucy application and run rake
|
|
70
69
|
And the output should not contain "Could not find generator"
|
71
70
|
|
72
71
|
Scenario: run specs
|
73
|
-
When I successfully run
|
74
|
-
And I successfully run
|
75
|
-
And I successfully run
|
76
|
-
And I successfully run
|
72
|
+
When I successfully run `rails generate saucy:install`
|
73
|
+
And I successfully run `rails generate saucy:specs`
|
74
|
+
And I successfully run `rails generate saucy:features`
|
75
|
+
And I successfully run `bundle exec rake db:migrate`
|
77
76
|
And I copy the specs for this project
|
78
|
-
And I run
|
77
|
+
And I run `bundle exec rake spec`
|
79
78
|
Then it should pass with:
|
80
79
|
"""
|
81
80
|
0 failures
|
@@ -1,9 +1,9 @@
|
|
1
1
|
When /^I bootstrap the application for clearance$/ do
|
2
2
|
steps %{
|
3
3
|
When I remove the file "public/index.html"
|
4
|
-
And I successfully run
|
5
|
-
And I successfully run
|
6
|
-
And I successfully run
|
4
|
+
And I successfully run `rails generate cucumber:install`
|
5
|
+
And I successfully run `rails generate clearance:install`
|
6
|
+
And I successfully run `rails generate clearance:features`
|
7
7
|
And I configure ActionMailer to use "www.example.com" as a host
|
8
8
|
And I add flash messages to the layout
|
9
9
|
And I add session links to the layout
|
@@ -28,7 +28,7 @@ When /^I give a more detailed new account message$/ do
|
|
28
28
|
When I go to the sign up page for the "Free" plan
|
29
29
|
Then I should see "Please sign up now"
|
30
30
|
HERE
|
31
|
-
|
31
|
+
write_file('features/new_account_message.feature', scenario)
|
32
32
|
end
|
33
33
|
|
34
34
|
When /^I add a custom layout to the accounts index$/ do
|
@@ -44,7 +44,7 @@ When /^I add a custom layout to the accounts index$/ do
|
|
44
44
|
/(class .* < Rails::Application)/,
|
45
45
|
"\\1\n#{layout_config}"
|
46
46
|
|
47
|
-
|
47
|
+
write_file('features/custom_accounts_index_layout.feature', <<-SCENARIO)
|
48
48
|
Feature: The accounts index should have a custom layout
|
49
49
|
Scenario: Custom layout
|
50
50
|
Given I am signed up as "email@person.com"
|
data/features/support/env.rb
CHANGED
@@ -24,23 +24,12 @@ Feature: Manage account
|
|
24
24
|
When I follow "Users"
|
25
25
|
Then I should see "captain@awesome.com"
|
26
26
|
|
27
|
-
@javascript
|
28
27
|
Scenario: Delete account
|
29
28
|
Given an account exists with a name of "Chocolate"
|
30
29
|
And I am signed in as an admin of the "Chocolate" account
|
31
30
|
When I go to the settings page for the "Chocolate" account
|
32
|
-
And I follow "Delete
|
33
|
-
Then I should see "Warning"
|
34
|
-
When I follow "I understand"
|
31
|
+
And I follow "Delete"
|
35
32
|
Then I should see "Your account has been deleted"
|
36
33
|
When I go to the dashboard page
|
37
34
|
Then I should not see "Chocolate"
|
38
35
|
|
39
|
-
@javascript
|
40
|
-
Scenario: Cancel deleting account
|
41
|
-
Given an account exists with a name of "Chocolate"
|
42
|
-
And I am signed in as an admin of the "Chocolate" account
|
43
|
-
When I go to the settings page for the "Chocolate" account
|
44
|
-
And I follow "Delete my account"
|
45
|
-
And I follow "don't delete my account"
|
46
|
-
Then I should not see "Your account has been deleted"
|
@@ -18,7 +18,7 @@ Given /^the following transaction exist for the "([^"]*)" account:$/ do |account
|
|
18
18
|
table.hashes.each do |transaction|
|
19
19
|
FakeBraintree.transaction = { :status => transaction["status"],
|
20
20
|
:amount => transaction["amount"],
|
21
|
-
:created_at =>
|
21
|
+
:created_at => DateTime.parse(transaction["created_at"]),
|
22
22
|
:subscription_id => account.subscription_token }
|
23
23
|
subscription["transactions"] << FakeBraintree.generated_transaction
|
24
24
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'rake'
|
2
2
|
|
3
3
|
module RakeHelpers
|
4
|
+
include Rake::DSL
|
5
|
+
|
4
6
|
def fake_rake
|
5
7
|
old_rake = Rake.application
|
6
8
|
rake = Rake::Application.new
|
@@ -16,7 +18,7 @@ World(RakeHelpers)
|
|
16
18
|
|
17
19
|
When /^the daily Saucy jobs are processed$/ do
|
18
20
|
fake_rake do |rake|
|
19
|
-
Saucy::Engine.
|
21
|
+
Saucy::Engine.load_tasks
|
20
22
|
rake['saucy:daily'].invoke
|
21
23
|
end
|
22
24
|
end
|
@@ -33,6 +33,6 @@ end
|
|
33
33
|
When /^I authenticate as the site owner$/ do
|
34
34
|
name, password = Saucy::Configuration.admin_username, Saucy::Configuration.admin_password
|
35
35
|
# This is done differently in various capybara versions, you may need to change it to
|
36
|
-
# page.driver.
|
37
|
-
page.driver.basic_authorize name, password
|
36
|
+
# page.driver.basic_authorize - or - page.driver.basic_auth
|
37
|
+
page.driver.browser.basic_authorize name, password
|
38
38
|
end
|
data/lib/saucy/configuration.rb
CHANGED
@@ -8,7 +8,6 @@ module Saucy
|
|
8
8
|
cattr_accessor :merchant_account_id
|
9
9
|
cattr_accessor :admin_username
|
10
10
|
cattr_accessor :admin_password
|
11
|
-
cattr_accessor :merchant_account_time_zone
|
12
11
|
|
13
12
|
def initialize
|
14
13
|
@@manager_email_address = 'manager@example.com'
|
@@ -16,7 +15,6 @@ module Saucy
|
|
16
15
|
@@layouts = Layouts.new
|
17
16
|
@@admin_username = 'admin'
|
18
17
|
@@admin_password = 'admin'
|
19
|
-
@@merchant_account_time_zone = 'Eastern Time (US & Canada)'
|
20
18
|
end
|
21
19
|
|
22
20
|
end
|
data/lib/saucy/engine.rb
CHANGED
data/lib/saucy/fake_braintree.rb
CHANGED
@@ -102,7 +102,7 @@ ShamRack.at("www.braintreegateway.com", 443).sinatra do
|
|
102
102
|
subscription["transactions"] = []
|
103
103
|
subscription["add_ons"] = []
|
104
104
|
subscription["discounts"] = []
|
105
|
-
subscription["next_billing_date"] = 1.month.from_now
|
105
|
+
subscription["next_billing_date"] = 1.month.from_now
|
106
106
|
subscription["status"] = Braintree::Subscription::Status::Active
|
107
107
|
FakeBraintree.subscriptions[subscription["id"]] = subscription
|
108
108
|
[201, { "Content-Encoding" => "gzip" }, ActiveSupport::Gzip.compress(subscription.to_xml(:root => 'subscription'))]
|
@@ -6,13 +6,8 @@
|
|
6
6
|
# project_path(@project), because the account can be inferred from the project.
|
7
7
|
module Saucy
|
8
8
|
module MapperExtensions
|
9
|
-
def initialize(*args)
|
10
|
-
@through_scope = []
|
11
|
-
super
|
12
|
-
end
|
13
|
-
|
14
9
|
def through(parent, &block)
|
15
|
-
@through_scope << parent
|
10
|
+
(@through_scope ||= []) << parent
|
16
11
|
resources(parent, :only => [], &block)
|
17
12
|
@through_scope.pop
|
18
13
|
end
|
@@ -82,7 +77,7 @@ end
|
|
82
77
|
ActionDispatch::Routing::Mapper::Base.class_eval do
|
83
78
|
def match_with_through(path, options=nil)
|
84
79
|
match_without_through(path, options)
|
85
|
-
|
80
|
+
if @through_scope.present?
|
86
81
|
route = @set.routes.last
|
87
82
|
@set.named_routes.add_through_alias(route, @through_scope) if route.name
|
88
83
|
end
|
data/lib/saucy/subscription.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'airbrake'
|
2
|
-
|
3
1
|
module Saucy
|
4
2
|
module Subscription
|
5
3
|
extend ActiveSupport::Concern
|
@@ -88,10 +86,9 @@ module Saucy
|
|
88
86
|
end
|
89
87
|
|
90
88
|
def update_subscription_cache!
|
91
|
-
zone = ActiveSupport::TimeZone[Saucy::Configuration.merchant_account_time_zone]
|
92
89
|
flush_cache :subscription
|
93
90
|
update_attribute(:subscription_status, subscription.status)
|
94
|
-
update_attribute(:next_billing_date,
|
91
|
+
update_attribute(:next_billing_date, subscription.next_billing_date)
|
95
92
|
end
|
96
93
|
|
97
94
|
def changing_plan?(attributes)
|
@@ -113,20 +110,7 @@ module Saucy
|
|
113
110
|
if valid?
|
114
111
|
result = Braintree::Customer.update(customer_token, customer_attributes)
|
115
112
|
handle_customer_result(result)
|
116
|
-
if !result.success?
|
117
|
-
Airbrake.notify(
|
118
|
-
:error_class => "Customer update",
|
119
|
-
:error_message => "Customer update failed",
|
120
|
-
:parameters => { :customer_token => customer_token, :customer_attributes => customer_attributes }
|
121
|
-
)
|
122
|
-
end
|
123
113
|
result.success?
|
124
|
-
else
|
125
|
-
Airbrake.notify(
|
126
|
-
:error_class => "Subscription Validation",
|
127
|
-
:error_message => "Customer failed validation",
|
128
|
-
:parameters => customer_attributes
|
129
|
-
)
|
130
114
|
end
|
131
115
|
end
|
132
116
|
|
@@ -191,11 +175,6 @@ module Saucy
|
|
191
175
|
end
|
192
176
|
|
193
177
|
def handle_errors(result, remote_errors)
|
194
|
-
Airbrake.notify(
|
195
|
-
:error_class => "handle_errors",
|
196
|
-
:error_message => "handle_errors",
|
197
|
-
:parameters => { :result => result, :remote_errors => remote_errors }
|
198
|
-
)
|
199
178
|
if result && result.status == "processor_declined"
|
200
179
|
errors[:card_number] << "was denied by the payment processor with the message: #{result.processor_response_text}"
|
201
180
|
elsif result && result.status == "gateway_rejected"
|
@@ -218,16 +197,10 @@ module Saucy
|
|
218
197
|
def create_subscription
|
219
198
|
result = Braintree::Subscription.create(subscription_attributes)
|
220
199
|
if result.success?
|
221
|
-
zone = ActiveSupport::TimeZone[Saucy::Configuration.merchant_account_time_zone]
|
222
200
|
self.subscription_token = result.subscription.id
|
223
|
-
self.next_billing_date =
|
201
|
+
self.next_billing_date = result.subscription.next_billing_date
|
224
202
|
self.subscription_status = result.subscription.status
|
225
203
|
else
|
226
|
-
Airbrake.notify(
|
227
|
-
:error_class => "Subscription creation",
|
228
|
-
:error_message => "Subscription creation failed",
|
229
|
-
:parameters => subscription_attributes
|
230
|
-
)
|
231
204
|
false
|
232
205
|
end
|
233
206
|
end
|
@@ -251,9 +224,8 @@ module Saucy
|
|
251
224
|
def update_subscriptions!
|
252
225
|
recently_billed = where("next_billing_date <= ?", Time.now)
|
253
226
|
recently_billed.each do |account|
|
254
|
-
zone = ActiveSupport::TimeZone[Saucy::Configuration.merchant_account_time_zone]
|
255
227
|
account.subscription_status = account.subscription.status
|
256
|
-
account.next_billing_date =
|
228
|
+
account.next_billing_date = account.subscription.next_billing_date
|
257
229
|
account.save!
|
258
230
|
if account.past_due?
|
259
231
|
BillingMailer.problem(account, account.subscription.transactions.last).deliver!
|
data/spec/environment.rb
CHANGED
@@ -31,11 +31,11 @@ module Testapp
|
|
31
31
|
class Application < Rails::Application
|
32
32
|
config.action_mailer.default_url_options = { :host => 'localhost' }
|
33
33
|
config.encoding = "utf-8"
|
34
|
-
config.paths
|
35
|
-
config.paths
|
36
|
-
config.paths
|
37
|
-
config.paths
|
38
|
-
config.paths
|
34
|
+
config.paths['config/database'] = "spec/scaffold/config/database.yml"
|
35
|
+
config.paths['app/models'] << "lib/generators/saucy/install/templates/models"
|
36
|
+
config.paths['config/routes'] << "spec/scaffold/config/routes.rb"
|
37
|
+
config.paths['app/views'] << "spec/scaffold/views"
|
38
|
+
config.paths['log'] = "tmp/log"
|
39
39
|
config.cache_classes = true
|
40
40
|
config.whiny_nils = true
|
41
41
|
config.consider_all_requests_local = true
|
@@ -48,6 +48,7 @@ module Testapp
|
|
48
48
|
end
|
49
49
|
|
50
50
|
Testapp::Application.initialize!
|
51
|
+
ActionController::Base.send :include, Rails.application.routes.url_helpers
|
51
52
|
|
52
53
|
require "./lib/generators/saucy/features/templates/factories"
|
53
54
|
require "./lib/generators/saucy/install/templates/create_saucy_tables"
|
@@ -122,9 +122,8 @@ describe Account, "with a paid plan" do
|
|
122
122
|
subject.subscription.should_not be_nil
|
123
123
|
end
|
124
124
|
|
125
|
-
it "has a next_billing_date
|
126
|
-
|
127
|
-
subject.next_billing_date.should == Time.parse("Sun, 16 Oct 2011 00:00:00 EDT -04:00")
|
125
|
+
it "has a next_billing_date" do
|
126
|
+
subject.next_billing_date.should_not be_nil
|
128
127
|
end
|
129
128
|
|
130
129
|
it "has an active subscription status" do
|
@@ -295,18 +294,15 @@ describe Account, "with a paid subscription" do
|
|
295
294
|
:plan => Factory(:paid_plan))
|
296
295
|
end
|
297
296
|
|
298
|
-
let(:merchant_time_zone) { ActiveSupport::TimeZone[Saucy::Configuration.merchant_account_time_zone] }
|
299
|
-
|
300
297
|
it "gets marked as past due and updates its next_billing_date when subscriptions are updated and it has been rejected by the gateway" do
|
301
|
-
next_billing_date_string = 2.months.from_now.to_s(:braintree_date)
|
302
298
|
subscription = FakeBraintree.subscriptions[subject.subscription_token]
|
303
299
|
subscription["status"] = Braintree::Subscription::Status::PastDue
|
304
|
-
subscription["next_billing_date"] =
|
300
|
+
subscription["next_billing_date"] = 2.months.from_now
|
305
301
|
|
306
302
|
Timecop.travel(subject.next_billing_date + 1.day) do
|
307
303
|
Account.update_subscriptions!
|
308
304
|
subject.reload.subscription_status.should == Braintree::Subscription::Status::PastDue
|
309
|
-
subject.next_billing_date.should ==
|
305
|
+
subject.next_billing_date.to_s.should == subscription["next_billing_date"].to_s
|
310
306
|
subject.past_due?.should be
|
311
307
|
end
|
312
308
|
end
|
@@ -316,7 +312,7 @@ describe Account, "with a paid subscription" do
|
|
316
312
|
|
317
313
|
before do
|
318
314
|
subscription["status"] = Braintree::Subscription::Status::PastDue
|
319
|
-
subscription["next_billing_date"] = 2.months.from_now
|
315
|
+
subscription["next_billing_date"] = 2.months.from_now
|
320
316
|
FakeBraintree.transaction = { :status => Braintree::Transaction::Status::Failed,
|
321
317
|
:subscription_id => subject.subscription_token }
|
322
318
|
subscription["transactions"] = [FakeBraintree.generated_transaction]
|
@@ -343,57 +339,12 @@ describe Account, "with a paid subscription" do
|
|
343
339
|
end
|
344
340
|
end
|
345
341
|
|
346
|
-
context "with a merchant account timezone different from the system timezone" do
|
347
|
-
def build_subscription(account)
|
348
|
-
subscription = FakeBraintree.subscriptions[account.subscription_token]
|
349
|
-
subscription["status"] = Braintree::Subscription::Status::Active
|
350
|
-
subscription["transactions"] = [FakeBraintree.generated_transaction]
|
351
|
-
subscription
|
352
|
-
end
|
353
|
-
|
354
|
-
before do
|
355
|
-
@old_env_tz = ENV['TZ']
|
356
|
-
ENV['TZ'] = "Europe/Paris"
|
357
|
-
|
358
|
-
Saucy::Configuration.merchant_account_time_zone = "Eastern Time (US & Canada)"
|
359
|
-
subject.next_billing_date = "2011-08-15"
|
360
|
-
subject.save!
|
361
|
-
|
362
|
-
subscription = build_subscription(subject)
|
363
|
-
subscription["next_billing_date"] = "2011-09-15"
|
364
|
-
|
365
|
-
Time.stubs(:now => Time.parse("2011-08-16 02:00 -0000"))
|
366
|
-
Account.update_subscriptions!
|
367
|
-
ActionMailer::Base.deliveries.clear
|
368
|
-
|
369
|
-
subject.reload.next_billing_date.should == Time.parse("2011-09-15 00:00 -0400")
|
370
|
-
end
|
371
|
-
|
372
|
-
after do
|
373
|
-
ENV['TZ'] = @old_env_tz
|
374
|
-
end
|
375
|
-
|
376
|
-
it "does not update accounts if their billing date hasn't elapsed from the merchant account's perspective" do
|
377
|
-
Time.stubs(:now => Time.parse("2011-09-15 02:00 -0000"))
|
378
|
-
Account.update_subscriptions!
|
379
|
-
ActionMailer::Base.deliveries.should be_empty
|
380
|
-
end
|
381
|
-
|
382
|
-
it "does update accounts if their billing date has elapsed from the merchant account's perspective" do
|
383
|
-
Time.stubs(:now => Time.parse("2011-09-16 02:00 -0000"))
|
384
|
-
Account.update_subscriptions!
|
385
|
-
ActionMailer::Base.deliveries.should_not be_empty
|
386
|
-
end
|
387
|
-
end
|
388
|
-
|
389
342
|
context "and an active subscription due 2 months from now" do
|
390
343
|
let(:subscription) { FakeBraintree.subscriptions[subject.subscription_token] }
|
391
|
-
let(:next_billing_date_string) { 2.months.from_now.to_s(:braintree_date) }
|
392
|
-
let(:zone) { ActiveSupport::TimeZone[Saucy::Configuration.merchant_account_time_zone] }
|
393
344
|
|
394
345
|
before do
|
395
346
|
subscription["status"] = Braintree::Subscription::Status::Active
|
396
|
-
subscription["next_billing_date"] =
|
347
|
+
subscription["next_billing_date"] = 2.months.from_now
|
397
348
|
FakeBraintree.transaction = { :status => Braintree::Transaction::Status::Settled,
|
398
349
|
:subscription_id => subject.subscription_token }
|
399
350
|
subscription["transactions"] = [FakeBraintree.generated_transaction]
|
@@ -403,7 +354,7 @@ describe Account, "with a paid subscription" do
|
|
403
354
|
Timecop.travel(subject.next_billing_date + 1.day) do
|
404
355
|
Account.update_subscriptions!
|
405
356
|
subject.reload.subscription_status.should == Braintree::Subscription::Status::Active
|
406
|
-
subject.next_billing_date.should ==
|
357
|
+
subject.next_billing_date.to_s.should == subscription["next_billing_date"].to_s
|
407
358
|
end
|
408
359
|
end
|
409
360
|
|
@@ -464,7 +415,7 @@ describe Account, "with a paid subscription that is past due" do
|
|
464
415
|
before do
|
465
416
|
subscription = FakeBraintree.subscriptions[subject.subscription_token]
|
466
417
|
subscription["status"] = Braintree::Subscription::Status::PastDue
|
467
|
-
subscription["next_billing_date"] = 2.months.from_now
|
418
|
+
subscription["next_billing_date"] = 2.months.from_now
|
468
419
|
|
469
420
|
Timecop.travel(subject.next_billing_date + 1.day) do
|
470
421
|
Account.update_subscriptions!
|
@@ -472,13 +423,10 @@ describe Account, "with a paid subscription that is past due" do
|
|
472
423
|
subject.reload
|
473
424
|
end
|
474
425
|
|
475
|
-
let(:zone) { ActiveSupport::TimeZone[Saucy::Configuration.merchant_account_time_zone] }
|
476
|
-
|
477
426
|
it "retries the subscription charge and updates the subscription when the billing information is correctly updated" do
|
478
|
-
next_billing_date_string = 1.day.from_now.to_s(:braintree_date)
|
479
427
|
subscription = FakeBraintree.subscriptions[subject.subscription_token]
|
480
428
|
subscription["status"] = Braintree::Subscription::Status::Active
|
481
|
-
subscription["next_billing_date"] =
|
429
|
+
subscription["next_billing_date"] = 2.months.from_now
|
482
430
|
FakeBraintree.transaction = { :status => Braintree::Transaction::Status::Settled,
|
483
431
|
:subscription_id => subject.subscription_token }
|
484
432
|
transaction = FakeBraintree.generated_transaction
|
@@ -496,14 +444,13 @@ describe Account, "with a paid subscription that is past due" do
|
|
496
444
|
:expiration_year => 2012).should be
|
497
445
|
|
498
446
|
subject.reload.subscription_status.should == Braintree::Subscription::Status::Active
|
499
|
-
subject.next_billing_date.should ==
|
447
|
+
subject.next_billing_date.to_s.should == subscription["next_billing_date"].to_s
|
500
448
|
end
|
501
449
|
|
502
450
|
it "retries the subscription charge and updates the subscription when the payment processing fails" do
|
503
|
-
next_billing_date_string = 2.months.from_now.to_s(:braintree_date)
|
504
451
|
subscription = FakeBraintree.subscriptions[subject.subscription_token]
|
505
452
|
subscription["status"] = Braintree::Subscription::Status::PastDue
|
506
|
-
subscription["next_billing_date"] =
|
453
|
+
subscription["next_billing_date"] = 1.day.from_now
|
507
454
|
FakeBraintree.transaction = { :status => Braintree::Transaction::Status::Failed,
|
508
455
|
:subscription_id => subject.subscription_token }
|
509
456
|
transaction = FakeBraintree.generated_transaction
|
@@ -522,14 +469,13 @@ describe Account, "with a paid subscription that is past due" do
|
|
522
469
|
|
523
470
|
subject.errors[:card_number].should include("was denied by the payment processor with the message: no good")
|
524
471
|
subject.reload.subscription_status.should == Braintree::Subscription::Status::PastDue
|
525
|
-
subject.next_billing_date.should ==
|
472
|
+
subject.next_billing_date.to_s.should == subscription["next_billing_date"].to_s
|
526
473
|
end
|
527
474
|
|
528
475
|
it "retries the subscription charge and updates the subscription when the settlement fails" do
|
529
|
-
next_billing_date_string = 1.day.from_now.to_s(:braintree_date)
|
530
476
|
subscription = FakeBraintree.subscriptions[subject.subscription_token]
|
531
477
|
subscription["status"] = Braintree::Subscription::Status::PastDue
|
532
|
-
subscription["next_billing_date"] =
|
478
|
+
subscription["next_billing_date"] = 1.day.from_now
|
533
479
|
FakeBraintree.transaction = { :status => Braintree::Transaction::Status::Failed,
|
534
480
|
:subscription_id => subject.subscription_token }
|
535
481
|
transaction = FakeBraintree.generated_transaction
|
@@ -548,7 +494,7 @@ describe Account, "with a paid subscription that is past due" do
|
|
548
494
|
|
549
495
|
subject.errors[:card_number].should include("no good")
|
550
496
|
subject.reload.subscription_status.should == Braintree::Subscription::Status::PastDue
|
551
|
-
subject.next_billing_date.should ==
|
497
|
+
subject.next_billing_date.to_s.should == subscription["next_billing_date"].to_s
|
552
498
|
end
|
553
499
|
end
|
554
500
|
|
@@ -36,18 +36,4 @@ describe Saucy::Configuration do
|
|
36
36
|
subject.support_email_address = old_address
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
40
|
-
it "can assign a merchant_account_time_zone" do
|
41
|
-
old_merchant_account_time_zone = subject.merchant_account_time_zone
|
42
|
-
begin
|
43
|
-
subject.merchant_account_time_zone = "International Date Line West"
|
44
|
-
subject.merchant_account_time_zone.should == "International Date Line West"
|
45
|
-
ensure
|
46
|
-
subject.merchant_account_time_zone = old_merchant_account_time_zone
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
it "defaults merchant_account_time_zone to 'Eastern Time (US & Canada)'" do
|
51
|
-
subject.merchant_account_time_zone.should == "Eastern Time (US & Canada)"
|
52
|
-
end
|
53
39
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
ENV["RAILS_ENV"] ||= 'test'
|
3
3
|
|
4
4
|
if File.exist?("config/environment.rb")
|
5
|
-
require "config/environment"
|
5
|
+
require "./config/environment"
|
6
6
|
else
|
7
7
|
require File.expand_path("../environment", __FILE__)
|
8
8
|
end
|
9
9
|
|
10
10
|
require 'rspec/rails'
|
11
|
-
require 'shoulda'
|
11
|
+
require 'shoulda/matchers'
|
12
12
|
require 'timecop'
|
13
13
|
|
14
14
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
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:
|
4
|
+
hash: 55
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 11
|
9
|
+
- 2
|
10
|
+
version: 0.11.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- thoughtbot, inc.
|
@@ -20,7 +20,7 @@ autorequire:
|
|
20
20
|
bindir: bin
|
21
21
|
cert_chain: []
|
22
22
|
|
23
|
-
date: 2011-
|
23
|
+
date: 2011-09-12 00:00:00 Z
|
24
24
|
dependencies:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: clearance
|
@@ -117,26 +117,10 @@ dependencies:
|
|
117
117
|
version: 1.1.2
|
118
118
|
type: :runtime
|
119
119
|
version_requirements: *id006
|
120
|
-
- !ruby/object:Gem::Dependency
|
121
|
-
name: airbrake
|
122
|
-
prerelease: false
|
123
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
124
|
-
none: false
|
125
|
-
requirements:
|
126
|
-
- - ">="
|
127
|
-
- !ruby/object:Gem::Version
|
128
|
-
hash: 15
|
129
|
-
segments:
|
130
|
-
- 3
|
131
|
-
- 0
|
132
|
-
- 4
|
133
|
-
version: 3.0.4
|
134
|
-
type: :runtime
|
135
|
-
version_requirements: *id007
|
136
120
|
- !ruby/object:Gem::Dependency
|
137
121
|
name: aruba
|
138
122
|
prerelease: false
|
139
|
-
requirement: &
|
123
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
140
124
|
none: false
|
141
125
|
requirements:
|
142
126
|
- - "="
|
@@ -148,7 +132,7 @@ dependencies:
|
|
148
132
|
- 6
|
149
133
|
version: 0.2.6
|
150
134
|
type: :development
|
151
|
-
version_requirements: *
|
135
|
+
version_requirements: *id007
|
152
136
|
description: Clearance-based Rails engine for Software as a Service (Saas) that provides account and project management
|
153
137
|
email: support@thoughtbot.com
|
154
138
|
executables: []
|
@@ -358,7 +342,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
358
342
|
requirements: []
|
359
343
|
|
360
344
|
rubyforge_project:
|
361
|
-
rubygems_version: 1.8.
|
345
|
+
rubygems_version: 1.8.10
|
362
346
|
signing_key:
|
363
347
|
specification_version: 3
|
364
348
|
summary: Clearance-based Rails engine for SaaS
|