11# frozen_string_literal: true
22
3+ require "async"
4+ require "async/queue"
35require "rails_helper"
46require "support/script_tag_utils"
57
@@ -327,6 +329,7 @@ def response; end
327329 HTML
328330 end
329331
332+ # mock_chunks can be an Async::Queue or an Array
330333 def mock_request_and_response ( mock_chunks = chunks , count : 1 )
331334 # Reset connection instance variables to ensure clean state for tests
332335 ReactOnRailsPro ::Request . instance_variable_set ( :@connection , nil )
@@ -339,9 +342,16 @@ def mock_request_and_response(mock_chunks = chunks, count: 1)
339342 chunks_read . clear
340343 mock_streaming_response ( %r{http://localhost:3800/bundles/[a-f0-9]{32}-test/render/[a-f0-9]{32}} , 200 ,
341344 count : count ) do |yielder |
342- mock_chunks . each do |chunk |
343- chunks_read << chunk
344- yielder . call ( "#{ chunk . to_json } \n " )
345+ if mock_chunks . is_a? ( Async ::Queue )
346+ while ( chunk = mock_chunks . dequeue )
347+ chunks_read << chunk
348+ yielder . call ( "#{ chunk . to_json } \n " )
349+ end
350+ else
351+ mock_chunks . each do |chunk |
352+ chunks_read << chunk
353+ yielder . call ( "#{ chunk . to_json } \n " )
354+ end
345355 end
346356 end
347357 end
@@ -428,18 +438,35 @@ def mock_request_and_response(mock_chunks = chunks, count: 1)
428438
429439 allow ( mocked_stream ) . to receive ( :write ) do |chunk |
430440 written_chunks << chunk
431- # Ensures that any chunk received is written immediately to the stream
432- expect ( written_chunks . count ) . to eq ( chunks_read . count ) # rubocop:disable RSpec/ExpectInHook
433441 end
434442 allow ( mocked_stream ) . to receive ( :close )
435443 mocked_response = instance_double ( ActionDispatch ::Response )
436444 allow ( mocked_response ) . to receive ( :stream ) . and_return ( mocked_stream )
437445 allow ( self ) . to receive ( :response ) . and_return ( mocked_response )
438- mock_request_and_response
446+ end
447+
448+ def execute_stream_view_containing_react_components
449+ queue = Async ::Queue . new
450+ mock_request_and_response ( queue )
451+
452+ Sync do |parent |
453+ parent . async { stream_view_containing_react_components ( template : template_path ) }
454+
455+ chunks_to_write = chunks . dup
456+ while ( chunk = chunks_to_write . shift )
457+ queue . enqueue ( chunk )
458+ sleep 0.05
459+
460+ # Ensures that any chunk received is written immediately to the stream
461+ expect ( written_chunks . count ) . to eq ( chunks_read . count )
462+ end
463+ queue . close
464+ sleep 0.05
465+ end
439466 end
440467
441468 it "writes the chunk to stream as soon as it is received" do
442- stream_view_containing_react_components ( template : template_path )
469+ execute_stream_view_containing_react_components
443470 expect ( self ) . to have_received ( :render_to_string ) . once . with ( template : template_path )
444471 expect ( chunks_read . count ) . to eq ( chunks . count )
445472 expect ( written_chunks . count ) . to eq ( chunks . count )
@@ -448,7 +475,7 @@ def mock_request_and_response(mock_chunks = chunks, count: 1)
448475 end
449476
450477 it "prepends the rails context to the first chunk only" do
451- stream_view_containing_react_components ( template : template_path )
478+ execute_stream_view_containing_react_components
452479 initial_result = written_chunks . first
453480 expect ( initial_result ) . to script_tag_be_included ( rails_context_tag )
454481
@@ -464,7 +491,7 @@ def mock_request_and_response(mock_chunks = chunks, count: 1)
464491 end
465492
466493 it "prepends the component specification tag to the first chunk only" do
467- stream_view_containing_react_components ( template : template_path )
494+ execute_stream_view_containing_react_components
468495 initial_result = written_chunks . first
469496 expect ( initial_result ) . to script_tag_be_included ( react_component_specification_tag )
470497
@@ -475,7 +502,7 @@ def mock_request_and_response(mock_chunks = chunks, count: 1)
475502 end
476503
477504 it "renders the rails view content in the first chunk" do
478- stream_view_containing_react_components ( template : template_path )
505+ execute_stream_view_containing_react_components
479506 initial_result = written_chunks . first
480507 expect ( initial_result ) . to include ( "<h1>Header Rendered In View</h1>" )
481508 written_chunks [ 1 ..] . each do |chunk |
0 commit comments