spamtrap 0.3.2 → 0.3.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0cec3797da20a8ab16dd95113f15c271acb6764478291372e14fc8d3556e0a3
4
- data.tar.gz: 960f481d33667095c861f91665786ab6e5a60c5a162e9f90fea709b99821b91e
3
+ metadata.gz: d3ff3c236a80418a4048beacd5cb3ff88c555a45d4736a8ea743a97a924d1283
4
+ data.tar.gz: 882c96f34aa70bfe8fab481704d96b97b8a9424c1d5b637140d7d60cb56abb30
5
5
  SHA512:
6
- metadata.gz: 846a83081e7139d5c6ba56674d3f5506abebc583c9f2fc62501fa8dc30d230f391f3a61a63a8a231456368a09c8ba20635d8af1176356d7574c97d1c4c0a9f9c
7
- data.tar.gz: fab5e0b02f702ee3f71bb2914d766a6a3ba1fedc90232189844497e5c818927b7cd31ff17eeb0fbf3583494b4e3e54c14e00511055df6a604608a5d850e3c0ad
6
+ metadata.gz: 2316d8928764a5071ff756e37717f3d52924f85f8e7fb34a6de9109bec0d103716e2cfe428456557d9664e0c117fb2c9c8b735d231c16440610ec391d77afb00
7
+ data.tar.gz: db528095a79dc96011fad7ee831f7164650c3d3cfb92004ea6edced38fec1aa39df5ce87d4cef793631c713ccc668dd040f61b9e56d70c6b8b174338732ed9ec
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Spamtrap
2
4
  module FormBuilderMutation
3
5
  include Spamtrap::Crypto
@@ -11,8 +13,45 @@ module Spamtrap
11
13
 
12
14
  MUTABLE_FIELDS.each do |m|
13
15
  define_method(m) do |field, *args, &blk|
14
- field = spamtrap_encrypt_field(field.to_s, @spamtrap_salt) if @spamtrap_salt
15
- super(field, *args, &blk)
16
+ if @spamtrap_salt
17
+ encrypted_field = spamtrap_encrypt_field(field.to_s, @spamtrap_salt)
18
+
19
+ opts =
20
+ if m == :check_box
21
+ args.first.is_a?(Hash) ? args.shift.dup : {}
22
+ else
23
+ args.last.is_a?(Hash) ? args.pop.dup : {}
24
+ end
25
+
26
+ model_value = object.respond_to?(field) ? object.public_send(field) : nil
27
+
28
+ case m
29
+ when :check_box
30
+ # :checked controls the checked state; :value is the submitted value ("1" by default)
31
+ opts[:checked] = !!model_value unless opts.key?(:checked)
32
+ super(encrypted_field, opts, *args, &blk)
33
+ when :select, :collection_select, :grouped_collection_select
34
+ # :selected belongs in the inner options hash, not html_options (the last hash).
35
+ # After popping html_options into opts, args.last is the options hash (if present).
36
+ if args.last.is_a?(Hash)
37
+ sel_opts = args.pop.dup
38
+ sel_opts[:selected] = model_value unless sel_opts.key?(:selected)
39
+ args.push(sel_opts)
40
+ else
41
+ opts[:selected] = model_value unless opts.key?(:selected)
42
+ end
43
+
44
+ super(encrypted_field, *args, opts, &blk)
45
+ when :label
46
+ # label renders a <label> element and does not read a value from the model object
47
+ super(encrypted_field, *args, opts, &blk)
48
+ else
49
+ opts[:value] = model_value unless opts.key?(:value)
50
+ super(encrypted_field, *args, opts, &blk)
51
+ end
52
+ else
53
+ super(field, *args, &blk)
54
+ end
16
55
  end
17
56
  end
18
57
 
@@ -1,5 +1,5 @@
1
1
  module Spamtrap
2
2
 
3
- VERSION = '0.3.2'
3
+ VERSION = '0.3.3'
4
4
 
5
5
  end
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.join(File.dirname(__FILE__), 'test_helper')
4
+ require 'action_view'
5
+ require 'action_view/test_case'
6
+
7
+ # A simple model-like struct to back the form builder, mimicking an AR model.
8
+ Message = Struct.new(:name, :email, :body, :active, :country)
9
+
10
+ class FormBuilderMutationTest < ActionView::TestCase
11
+ include Spamtrap::Crypto
12
+
13
+ # Build a minimal form builder instance backed by a Message object.
14
+ def build_form_builder(object)
15
+ ActionView::Helpers::FormBuilder.new(:message, object, self, {})
16
+ end
17
+
18
+ # --- text-like inputs ---
19
+
20
+ def test_text_field_does_not_raise_when_mutate_is_true
21
+ msg = Message.new('Alice', 'alice@example.com', 'Hello')
22
+ f = build_form_builder(msg)
23
+ f.spamtrap(:trap, mutate: true)
24
+
25
+ assert_nothing_raised { f.text_field(:name) }
26
+ assert_nothing_raised { f.email_field(:email) }
27
+ assert_nothing_raised { f.text_area(:body) }
28
+ end
29
+
30
+ def test_model_value_is_preserved_in_encrypted_field
31
+ msg = Message.new('Alice', 'alice@example.com', 'Hello')
32
+ f = build_form_builder(msg)
33
+ f.spamtrap(:trap, mutate: true)
34
+
35
+ assert_includes f.text_field(:name), 'Alice'
36
+ assert_includes f.email_field(:email), 'alice@example.com'
37
+ assert_includes f.text_area(:body), 'Hello'
38
+ end
39
+
40
+ def test_encrypted_field_name_is_used_in_html
41
+ msg = Message.new('Alice', 'alice@example.com', 'Hello')
42
+ f = build_form_builder(msg)
43
+ f.spamtrap(:trap, mutate: true)
44
+
45
+ html = f.text_field(:name)
46
+
47
+ # The original unencrypted name must NOT appear as the input name attribute
48
+ refute_match(/name="message\[name\]"/, html)
49
+ end
50
+
51
+ def test_nil_model_value_does_not_raise
52
+ msg = Message.new(nil, nil, nil)
53
+ f = build_form_builder(msg)
54
+ f.spamtrap(:trap, mutate: true)
55
+
56
+ assert_nothing_raised { f.text_field(:name) }
57
+ end
58
+
59
+ def test_virtual_field_without_model_method_does_not_raise
60
+ msg = Message.new('Alice', 'alice@example.com', 'Hello')
61
+ f = build_form_builder(msg)
62
+ f.spamtrap(:trap, mutate: true)
63
+
64
+ # :nonexistent is not a method on Message; should render with empty value, not crash
65
+ assert_nothing_raised { f.text_field(:nonexistent) }
66
+ end
67
+
68
+ def test_explicit_value_option_is_preserved
69
+ msg = Message.new('Alice', 'alice@example.com', 'Hello')
70
+ f = build_form_builder(msg)
71
+ f.spamtrap(:trap, mutate: true)
72
+
73
+ html = f.text_field(:name, value: 'Overridden')
74
+
75
+ assert_includes html, 'Overridden'
76
+ refute_includes html, 'Alice'
77
+ end
78
+
79
+ # --- no mutation ---
80
+
81
+ def test_no_salt_leaves_field_names_unencrypted
82
+ msg = Message.new('Alice', 'alice@example.com', 'Hello')
83
+ f = build_form_builder(msg)
84
+
85
+ html = f.text_field(:name)
86
+
87
+ assert_match(/name="message\[name\]"/, html)
88
+ end
89
+
90
+ # --- check_box ---
91
+
92
+ def test_check_box_does_not_raise_when_mutate_is_true
93
+ msg = Message.new(nil, nil, nil, true)
94
+ f = build_form_builder(msg)
95
+ f.spamtrap(:trap, mutate: true)
96
+
97
+ assert_nothing_raised { f.check_box(:active) }
98
+ end
99
+
100
+ def test_check_box_checked_when_model_value_is_true
101
+ msg = Message.new(nil, nil, nil, true)
102
+ f = build_form_builder(msg)
103
+ f.spamtrap(:trap, mutate: true)
104
+
105
+ assert_includes f.check_box(:active), 'checked'
106
+ end
107
+
108
+ def test_check_box_unchecked_when_model_value_is_false
109
+ msg = Message.new(nil, nil, nil, false)
110
+ f = build_form_builder(msg)
111
+ f.spamtrap(:trap, mutate: true)
112
+
113
+ refute_includes f.check_box(:active), 'checked'
114
+ end
115
+
116
+ # --- select ---
117
+
118
+ def test_select_does_not_raise_when_mutate_is_true
119
+ msg = Message.new(nil, nil, nil, nil, 'US')
120
+ f = build_form_builder(msg)
121
+ f.spamtrap(:trap, mutate: true)
122
+
123
+ assert_nothing_raised { f.select(:country, %w[US CA GB]) }
124
+ end
125
+
126
+ def test_select_preselects_model_value
127
+ msg = Message.new(nil, nil, nil, nil, 'CA')
128
+ f = build_form_builder(msg)
129
+ f.spamtrap(:trap, mutate: true)
130
+
131
+ html = f.select(:country, %w[US CA GB])
132
+
133
+ assert_match(/selected.*CA|CA.*selected/, html)
134
+ end
135
+
136
+ private
137
+
138
+ # ActionView::TestCase helpers expect a #request method; provide a stub.
139
+ def request
140
+ @request ||= ActionDispatch::TestRequest.create
141
+ end
142
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spamtrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cedric Howe
@@ -36,6 +36,7 @@ files:
36
36
  - lib/spamtrap/helper.rb
37
37
  - lib/spamtrap/version.rb
38
38
  - test/controller_test.rb
39
+ - test/form_builder_mutation_test.rb
39
40
  - test/test_helper.rb
40
41
  homepage: http://github.com/cedric/spamtrap/
41
42
  licenses:
@@ -60,4 +61,5 @@ specification_version: 4
60
61
  summary: Simple spamtrap for spambots.
61
62
  test_files:
62
63
  - test/controller_test.rb
64
+ - test/form_builder_mutation_test.rb
63
65
  - test/test_helper.rb