Skip to content

Commit b5715a9

Browse files
ihabadhamclaude
andcommitted
Refactor: Move disconnect test to stream_spec.rb for better organization
Moved the "stops producing when client disconnects" test from react_on_rails_pro_helper_spec.rb to stream_spec.rb to follow the established architectural pattern. Why: - stream_spec.rb contains all streaming behavior/concurrency tests - helper_spec.rb is for Rails integration tests, not streaming behavior - stream_spec.rb uses cleaner setup (setup_stream_test) without Rails mocking Changes: - Removed test from helper_spec.rb (Rails integration test file) - Added test to stream_spec.rb in "Component streaming concurrency" block - Simplified test to use existing setup_stream_test helper - Updated test to account for TEMPLATE being first write - Test now expects ["TEMPLATE", "A1"] instead of just counting chunks Benefits: - Consistent with existing architecture (all concurrency tests in one place) - Simpler test setup (no Rails mocking complexity) - Easier to find (streaming behavior tests are in stream_spec.rb) - Net -16 lines of code Verified: All 21 tests in stream_spec.rb pass, including the new test. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent e0987ee commit b5715a9

File tree

2 files changed

+41
-57
lines changed

2 files changed

+41
-57
lines changed

react_on_rails_pro/spec/dummy/spec/helpers/react_on_rails_pro_helper_spec.rb

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -515,63 +515,6 @@ def execute_stream_view_containing_react_components
515515
end
516516
end
517517

518-
it "stops producing when client disconnects" do
519-
queue = Async::Queue.new
520-
mock_request_and_response(queue)
521-
522-
# Simulate client disconnect by making stream.write raise IOError
523-
call_count = 0
524-
stream_closed = false
525-
allow(mocked_stream).to receive(:write) do |chunk|
526-
call_count += 1
527-
if call_count == 2
528-
stream_closed = true
529-
raise IOError, "client disconnected"
530-
end
531-
written_chunks << chunk
532-
end
533-
534-
# Update the closed? stub to check the stream_closed flag
535-
allow(mocked_stream).to receive(:closed?) { stream_closed }
536-
537-
# Configure render_to_string to call stream_react_component
538-
allow(self).to receive(:render_to_string) do
539-
render_result = stream_react_component(component_name, props: props, **component_options)
540-
<<-HTML
541-
<div>
542-
<h1>Header Rendered In View</h1>
543-
#{render_result}
544-
</div>
545-
HTML
546-
end
547-
548-
Sync do |parent|
549-
parent.async do
550-
stream_view_containing_react_components(template: template_path)
551-
rescue IOError
552-
# Expected - client disconnected
553-
end
554-
555-
# Enqueue first chunk - should be written successfully
556-
queue.enqueue(chunks[0])
557-
sleep 0.05
558-
559-
# Enqueue second chunk - should trigger disconnect
560-
queue.enqueue(chunks[1])
561-
sleep 0.05
562-
563-
# Enqueue third chunk - should not be written (producer stopped)
564-
queue.enqueue(chunks[2])
565-
sleep 0.05
566-
567-
queue.close
568-
sleep 0.05
569-
end
570-
571-
# Should only have written the first chunk before disconnect
572-
expect(written_chunks.count).to eq(1)
573-
expect(mocked_stream).to have_received(:write).at_most(2).times
574-
end
575518
end
576519

577520
describe "#cached_stream_react_component", :caching do # rubocop:disable RSpec/MultipleMemoizedHelpers

react_on_rails_pro/spec/react_on_rails_pro/stream_spec.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,5 +486,46 @@ def setup_stream_test(component_count: 2)
486486
gaps = write_timestamps.each_cons(2).map { |a, b| b - a }
487487
expect(gaps.all? { |gap| gap >= 0.04 }).to be true
488488
end
489+
490+
it "stops producing when client disconnects" do
491+
queues, controller, stream = setup_stream_test(component_count: 2)
492+
493+
written_chunks = []
494+
stream_closed = false
495+
496+
# Simulate client disconnect on third write (after TEMPLATE and first component chunk)
497+
allow(stream).to receive(:write) do |chunk|
498+
if written_chunks.length == 2
499+
stream_closed = true
500+
raise IOError, "client disconnected"
501+
end
502+
written_chunks << chunk
503+
end
504+
505+
# Make closed? return the stream_closed flag
506+
allow(stream).to receive(:closed?) { stream_closed }
507+
508+
run_stream(controller) do |_parent|
509+
# First write will be "TEMPLATE" (automatic)
510+
sleep 0.05
511+
512+
# Enqueue chunks from both components
513+
queues[0].enqueue("A1") # Second write
514+
sleep 0.05
515+
516+
queues[1].enqueue("B1") # Third write - this should trigger disconnect
517+
sleep 0.05
518+
519+
queues[0].enqueue("A2") # Should not be written (producer stopped)
520+
queues[1].enqueue("B2") # Should not be written (producer stopped)
521+
sleep 0.05
522+
523+
queues.each(&:close)
524+
end
525+
526+
# Should have written TEMPLATE and first component chunk before disconnect
527+
expect(written_chunks.length).to eq(2)
528+
expect(written_chunks).to eq(["TEMPLATE", "A1"])
529+
end
489530
end
490531
end

0 commit comments

Comments
 (0)