Skip to content

Commit 81ad323

Browse files
committed
Clean up select specs: remove redundant assertions
Consolidate duplicate tests that assert both granular attributes and full HTML strings for the same behavior. 37 examples → 14.
1 parent f7fd471 commit 81ad323

2 files changed

Lines changed: 54 additions & 340 deletions

File tree

Lines changed: 24 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
# frozen_string_literal: true
2-
31
RSpec.describe "Select in Collection Integration", type: :view do
4-
# Set up test database for collection models
52
before(:all) do
63
ActiveRecord::Schema.define do
74
create_table :orders, force: true do |t|
@@ -17,196 +14,74 @@
1714
end
1815
end
1916

20-
# Test model for collection (array of objects)
2117
class Order < ActiveRecord::Base
22-
# Serialize tag_ids as JSON array for multiple select testing
2318
serialize :tag_ids, coder: JSON
2419
end
2520

26-
describe "single select in collection" do
27-
let(:initial_orders) do
28-
[
29-
Order.new(item_id: 1),
30-
Order.new(item_id: 2)
31-
]
32-
end
33-
let(:model) do
34-
User.new(first_name: "Test", email: "test@example.com").tap do |user|
35-
orders_list = initial_orders
36-
user.define_singleton_method(:orders) { @orders ||= orders_list }
37-
user.define_singleton_method(:orders=) { |val| @orders = val }
38-
end
21+
let(:item_options) { [[1, "Coffee"], [2, "Tea"], [3, "Juice"]] }
22+
let(:tag_options) { [[1, "Ruby"], [2, "Rails"], [3, "Phlex"]] }
23+
24+
def build_model(orders)
25+
User.new(first_name: "Test", email: "test@example.com").tap do |user|
26+
orders_list = orders
27+
user.define_singleton_method(:orders) { @orders ||= orders_list }
28+
user.define_singleton_method(:orders=) { |val| @orders = val }
3929
end
30+
end
31+
32+
describe "single select in collection" do
33+
let(:model) { build_model([Order.new(item_id: 1), Order.new(item_id: 2)]) }
4034
let(:form) { Superform::Rails::Form.new(model, action: "/users") }
41-
let(:item_options) { [[1, "Coffee"], [2, "Tea"], [3, "Juice"]] }
4235

43-
it "renders select with collection notation" do
36+
it "renders selects with collection notation and pre-selects values" do
4437
html = render(form) do |f|
45-
orders_collection = f.collection(:orders)
46-
orders_collection.each do |order_namespace|
38+
f.collection(:orders).each do |order_namespace|
4739
f.render order_namespace.field(:item_id).select(*item_options)
4840
end
4941
end
5042

51-
# Collection uses model_name[collection_name][index][field_name] notation
5243
expect(html).to include('name="user[orders][0][item_id]"')
5344
expect(html).to include('name="user[orders][1][item_id]"')
54-
end
55-
56-
it "pre-selects options based on collection values" do
57-
html = render(form) do |f|
58-
orders_collection = f.collection(:orders)
59-
orders_collection.each do |order_namespace|
60-
f.render order_namespace.field(:item_id).select(*item_options)
61-
end
62-
end
6345

64-
# First order should have item_id=1 (Coffee) selected
6546
first_select = html.match(/<select[^>]*id="user_orders_0_item_id"[^>]*>.*?<\/select>/m)[0]
6647
expect(first_select).to include('<option selected value="1">Coffee</option>')
6748

68-
# Second order should have item_id=2 (Tea) selected
6949
second_select = html.match(/<select[^>]*id="user_orders_1_item_id"[^>]*>.*?<\/select>/m)[0]
7050
expect(second_select).to include('<option selected value="2">Tea</option>')
7151
end
72-
73-
it "works with submitted params from collection" do
74-
# Simulate Rails params after form submission
75-
submitted_model = User.new(first_name: "Test", email: "test@example.com").tap do |user|
76-
user.define_singleton_method(:orders) do
77-
[
78-
Order.new(item_id: 3), # Changed to Juice
79-
Order.new(item_id: 1) # Changed to Coffee
80-
]
81-
end
82-
end
83-
submitted_form = Superform::Rails::Form.new(submitted_model, action: "/users")
84-
85-
html = render(submitted_form) do |f|
86-
orders_collection = f.collection(:orders)
87-
orders_collection.each do |order_namespace|
88-
f.render order_namespace.field(:item_id).select(*item_options)
89-
end
90-
end
91-
92-
# First order should now have item_id=3 (Juice) selected
93-
first_select = html.match(/<select[^>]*id="user_orders_0_item_id"[^>]*>.*?<\/select>/m)[0]
94-
expect(first_select).to include('<option selected value="3">Juice</option>')
95-
96-
# Second order should now have item_id=1 (Coffee) selected
97-
second_select = html.match(/<select[^>]*id="user_orders_1_item_id"[^>]*>.*?<\/select>/m)[0]
98-
expect(second_select).to include('<option selected value="1">Coffee</option>')
99-
end
10052
end
10153

10254
describe "multiple select in collection" do
103-
let(:initial_orders) do
104-
[
105-
Order.new(tag_ids: [1, 3]),
106-
Order.new(tag_ids: [2])
107-
]
108-
end
109-
let(:model) do
110-
User.new(first_name: "Test", email: "test@example.com").tap do |user|
111-
orders_list = initial_orders
112-
user.define_singleton_method(:orders) { @orders ||= orders_list }
113-
user.define_singleton_method(:orders=) { |val| @orders = val }
114-
end
115-
end
55+
let(:model) { build_model([Order.new(tag_ids: [1, 3]), Order.new(tag_ids: [2])]) }
11656
let(:form) { Superform::Rails::Form.new(model, action: "/users") }
117-
let(:tag_options) { [[1, "Ruby"], [2, "Rails"], [3, "Phlex"]] }
11857

119-
it "renders multiple select with correct field names" do
120-
html = render(form) do |f|
121-
orders_collection = f.collection(:orders)
122-
orders_collection.each do |order_namespace|
123-
f.render order_namespace.field(:tag_ids).select(
124-
*tag_options,
125-
multiple: true
126-
)
58+
def render_multiple_select(form)
59+
render(form) do |f|
60+
f.collection(:orders).each do |order_namespace|
61+
f.render order_namespace.field(:tag_ids).select(*tag_options, multiple: true)
12762
end
12863
end
129-
130-
# Multiple select in collection should use [index][field_name][] notation
131-
expect(html).to include('name="user[orders][0][tag_ids][]"')
132-
expect(html).to include('name="user[orders][1][tag_ids][]"')
133-
# Should include multiple attribute
134-
expect(html.scan(/multiple/).count).to eq(2)
13564
end
13665

137-
it "renders hidden inputs for empty submissions" do
138-
html = render(form) do |f|
139-
orders_collection = f.collection(:orders)
140-
orders_collection.each do |order_namespace|
141-
f.render order_namespace.field(:tag_ids).select(
142-
*tag_options,
143-
multiple: true
144-
)
145-
end
146-
end
66+
it "renders with correct field names and hidden inputs" do
67+
html = render_multiple_select(form)
14768

148-
# Should have hidden inputs before each select
69+
expect(html).to include('name="user[orders][0][tag_ids][]"')
70+
expect(html).to include('name="user[orders][1][tag_ids][]"')
14971
expect(html).to include('<input type="hidden" name="user[orders][0][tag_ids][]" value="">')
15072
expect(html).to include('<input type="hidden" name="user[orders][1][tag_ids][]" value="">')
15173
end
15274

15375
it "pre-selects multiple options based on array values" do
154-
html = render(form) do |f|
155-
orders_collection = f.collection(:orders)
156-
orders_collection.each do |order_namespace|
157-
f.render order_namespace.field(:tag_ids).select(
158-
*tag_options,
159-
multiple: true
160-
)
161-
end
162-
end
76+
html = render_multiple_select(form)
16377

164-
# First order should have Ruby (1) and Phlex (3) selected
165-
# Extract just the first select element for testing
16678
first_select = html.match(/<select[^>]*id="user_orders_0_tag_ids"[^>]*>.*?<\/select>/m)[0]
16779
expect(first_select).to include('<option selected value="1">Ruby</option>')
16880
expect(first_select).to include('<option selected value="3">Phlex</option>')
169-
# First order should NOT have Rails (2) selected
170-
expect(first_select).to include('<option value="2">Rails</option>')
17181
expect(first_select).not_to include('<option selected value="2">Rails</option>')
17282

173-
# Second order should have Rails (2) selected
174-
second_select = html.match(/<select[^>]*id="user_orders_1_tag_ids"[^>]*>.*?<\/select>/m)[0]
175-
expect(second_select).to include('<option selected value="2">Rails</option>')
176-
end
177-
178-
it "works with submitted params for multiple select" do
179-
# Simulate Rails params after form submission
180-
submitted_model = User.new(first_name: "Test", email: "test@example.com").tap do |user|
181-
user.define_singleton_method(:orders) do
182-
[
183-
Order.new(tag_ids: [2, 3]), # Changed to Rails + Phlex
184-
Order.new(tag_ids: [1, 2, 3]) # Changed to all three
185-
]
186-
end
187-
end
188-
submitted_form = Superform::Rails::Form.new(submitted_model, action: "/users")
189-
190-
html = render(submitted_form) do |f|
191-
orders_collection = f.collection(:orders)
192-
orders_collection.each do |order_namespace|
193-
f.render order_namespace.field(:tag_ids).select(
194-
*tag_options,
195-
multiple: true
196-
)
197-
end
198-
end
199-
200-
# First order should now have Rails (2) and Phlex (3) selected
201-
first_select = html.match(/<select[^>]*id="user_orders_0_tag_ids"[^>]*>.*?<\/select>/m)[0]
202-
expect(first_select).to include('<option selected value="2">Rails</option>')
203-
expect(first_select).to include('<option selected value="3">Phlex</option>')
204-
205-
# Second order should have all three selected
20683
second_select = html.match(/<select[^>]*id="user_orders_1_tag_ids"[^>]*>.*?<\/select>/m)[0]
207-
expect(second_select).to include('<option selected value="1">Ruby</option>')
20884
expect(second_select).to include('<option selected value="2">Rails</option>')
209-
expect(second_select).to include('<option selected value="3">Phlex</option>')
21085
end
21186
end
21287
end

0 commit comments

Comments
 (0)