Skip to content

Commit 056502a

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 <noreply@anthropic.com>
1 parent 3de5cb5 commit 056502a

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
@@ -514,63 +514,6 @@ def execute_stream_view_containing_react_components
514514
end
515515
end
516516

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

576519
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)