Skip to content

Commit 1d4add2

Browse files
committed
Moar tests
1 parent e8f38da commit 1d4add2

File tree

4 files changed

+76
-29
lines changed

4 files changed

+76
-29
lines changed

spec/digestor_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def template.virtual_path=(path)
5959

6060
# Ruby 2.7 removed taint checking mechanism
6161
# https://blog.saeloun.com/2020/02/18/ruby-2-7-access-and-setting-of-safe-warned-will-become-global-variable.html
62-
it "should marshal and taint the digest", if: Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.7.0") do
62+
it "should marshal and taint the digest", if: ruby_version_satisfies?('< 2.7.0') do
6363
digestor = SignedForm::Digestor.new(template)
6464
data = Marshal.dump digestor
6565
digestor = Marshal.load data

spec/form_builder_spec.rb

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,19 +113,21 @@ class MockBuilder < ActionView::Helpers::FormBuilder; end
113113
end
114114

115115
describe "sign_destination" do
116-
after do
117-
@data.should include(:_options_)
118-
@data[:_options_].should include(:method, :url)
119-
@data[:_options_][:method].should == :post
120-
@data[:_options_][:url].should == '/users/new'
116+
def assert_method_and_url(content, method = :post, url = '/users/new')
117+
data = get_data_from_form(content)
118+
119+
expect(data).to include(:_options_)
120+
expect(data[:_options_]).to include(:method, :url)
121+
expect(data[:_options_][:method]).to eql(method)
122+
expect(data[:_options_][:url]).to eql(url)
121123
end
122124

123125
it "should set a target" do
124126
content = form_for(User.new, signed: true, sign_destination: true) do |f|
125127
f.text_field :name
126128
end
127129

128-
@data = get_data_from_form(content)
130+
assert_method_and_url(content)
129131
end
130132

131133
it "should set a target when the default options are enabled" do
@@ -135,7 +137,51 @@ class MockBuilder < ActionView::Helpers::FormBuilder; end
135137
f.text_field :name
136138
end
137139

138-
@data = get_data_from_form(content)
140+
assert_method_and_url(content)
141+
end
142+
143+
it "should read method from options -> html" do
144+
SignedForm.options[:sign_destination] = true
145+
146+
content = form_for(User.new, signed: true, html: { method: :get }) do |f|
147+
f.text_field :name
148+
end
149+
150+
assert_method_and_url(content, :get)
151+
end
152+
153+
it "should read method from options" do
154+
SignedForm.options[:sign_destination] = true
155+
156+
content = form_for(User.new, signed: true, method: :get) do |f|
157+
f.text_field :name
158+
end
159+
160+
assert_method_and_url(content, :get)
161+
end
162+
163+
it "should infer method from object persisted state", if: rails_version_satisfies?('>= 7.2') do
164+
SignedForm.options[:sign_destination] = true
165+
166+
user = User.new
167+
allow(user).to receive(:persisted?).and_return(true)
168+
169+
content = form_for(user, signed: true) do |f|
170+
f.text_field :name
171+
end
172+
173+
# URL is funky because stubbing is imperfect
174+
assert_method_and_url(content, :patch, '/users/new?model=1')
175+
end
176+
177+
it "should read url from options", if: rails_version_satisfies?('< 7.0') do
178+
SignedForm.options[:sign_destination] = true
179+
180+
content = form_for(User.new, signed: true, url: '/other/url') do |f|
181+
f.text_field :name
182+
end
183+
184+
assert_method_and_url(content, :post, '/other/url')
139185
end
140186
end
141187

@@ -383,7 +429,7 @@ class MockBuilder < ActionView::Helpers::FormBuilder; end
383429

384430
describe "fields_for" do
385431
it "should nest attributes" do
386-
user.stub(widgets: [widget])
432+
allow(user).to receive(:widgets).and_return([widget])
387433

388434
content = form_for(user, signed: true) do |f|
389435
f.fields_for :widgets do |ff|

spec/permit_signed_params_spec.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ def marshal_and_sign(data)
2828
before do
2929
SignedForm.secret_key = "abc123"
3030

31-
Controller.any_instance.stub(request: double('request', method: 'POST', request_method: 'POST', fullpath: '/users', url: '/users', variant: nil))
32-
Controller.any_instance.stub(params: ActionController::Parameters.new("user" => { name: "Erich Menge", occupation: 'developer' }))
31+
allow_any_instance_of(Controller).to receive_messages(
32+
request: double('request', method: 'POST', request_method: 'POST', fullpath: '/users', url: '/users', variant: nil),
33+
params: ActionController::Parameters.new("user" => { name: "Erich Menge", occupation: 'developer' })
34+
)
3335

34-
params.stub(:[]).and_call_original
35-
params.stub(:[]).with('user').and_return(params)
36+
allow(params).to receive(:[]).and_call_original
37+
allow(params).to receive(:[]).with('user').and_return(params)
3638
end
3739

3840
it "should raise if signature isn't valid" do
@@ -41,7 +43,7 @@ def marshal_and_sign(data)
4143
end
4244

4345
context "when the parameters are good" do
44-
before { params.should_receive(:permit).with(:name).and_return(params) }
46+
before { allow(params).to receive(:permit).with(:name).and_return(params) }
4547

4648
it "should permit attributes that are allowed" do
4749
params['form_signature'] = marshal_and_sign "user" => [:name]
@@ -51,7 +53,7 @@ def marshal_and_sign(data)
5153
it "should verify current url matches targeted url" do
5254
params['form_signature'] = marshal_and_sign("user" => [:name], :_options_ => { method: 'post', url: '/users' })
5355

54-
controller.request.should_receive(:fullpath).and_return '/users'
56+
allow(controller.request).to receive(:fullpath).and_return '/users'
5557
controller.permit_signed_form_data
5658
end
5759
end
@@ -67,7 +69,7 @@ def marshal_and_sign(data)
6769
end
6870

6971
context "when the digest is bad" do
70-
before { digestor.stub(:to_s).and_return "bad" }
72+
before { allow(digestor).to receive(:to_s).and_return "bad" }
7173

7274
it "should not reject if inside grace period" do
7375
params['form_signature'] = marshal_and_sign("user" => [:name], :_options_ => { digest: digestor, digest_expiration: Time.now + 20 })

spec/spec_helper.rb

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ module SignedFormViewHelper
1919
end
2020

2121
include ActionView::Context if defined?(ActionView::Context)
22-
include ActionView::RoutingUrlFor
2322

2423
include SignedForm::ActionView::FormHelper
2524

@@ -28,8 +27,6 @@ module SignedFormViewHelper
2827
resources :users, controller: :users
2928
end
3029

31-
Routes.default_url_options.merge!(host: 'test.host')
32-
3330
ActionView::RoutingUrlFor.include(Routes.url_helpers)
3431

3532
include ActionView::RoutingUrlFor
@@ -46,36 +43,36 @@ def protect_against_forgery?
4643
false
4744
end
4845

49-
def user_path(*)
50-
'/users'
51-
end
52-
5346
def polymorphic_path(*)
5447
'/users/new'
5548
end
5649

5750
def controller(*)
5851
@controller ||= UsersController.new.tap do |ctl|
59-
# path_parameters
6052
@request = ActionController::TestRequest.create(ctl.class)
6153
@request.path_parameters.merge!(controller: 'users', action: 'new')
6254

6355
ctl.singleton_class.include Routes.url_helpers
6456

6557
ctl.request = @request
66-
ctl.instance_variable_set :@routes, Routes.url_helpers
6758
end
6859
end
6960

70-
def default_url_options
71-
{}
72-
end
73-
7461
def get_data_from_form(content)
7562
Marshal.load Base64.strict_decode64(content.match(/name="form_signature" value="(.*)--/)[1])
7663
end
7764
end
7865

66+
module Helpers
67+
def ruby_version_satisfies?(ver)
68+
Gem::Requirement.new(ver).satisfied_by?(Gem::Version.new(RUBY_VERSION))
69+
end
70+
71+
def rails_version_satisfies?(ver)
72+
Gem::Requirement.new(ver).satisfied_by?(ActionPack::gem_version)
73+
end
74+
end
75+
7976
RSpec.configure do |config|
8077
config.run_all_when_everything_filtered = true
8178

@@ -85,6 +82,8 @@ def get_data_from_form(content)
8582

8683
config.order = 'random'
8784

85+
config.extend Helpers
86+
8887
config.around(:each) do |example|
8988
pristine_module = SignedForm.dup
9089
example.run

0 commit comments

Comments
 (0)