@@ -146,8 +146,9 @@ def mock_dev_server_running
146146 context "with server bundle (SSR/RSC) file not in manifest" do
147147 let ( :server_bundle_name ) { "server-bundle.js" }
148148 let ( :ssr_generated_path ) { File . expand_path ( File . join ( "ssr-generated" , server_bundle_name ) ) }
149+ let ( :public_path ) { File . expand_path ( File . join ( packer_public_output_path , server_bundle_name ) ) }
149150
150- context "with server_bundle_output_path configured" do
151+ context "with server_bundle_output_path configured and enforce_private_server_bundles=false " do
151152 before do
152153 mock_missing_manifest_entry ( server_bundle_name )
153154 allow ( ReactOnRails ) . to receive_message_chain ( "configuration.server_bundle_js_file" )
@@ -158,10 +159,23 @@ def mock_dev_server_running
158159 . and_return ( false )
159160 end
160161
161- it "returns configured path directly without checking existence" do
162- # When enforce_private_server_bundles is false, it will check File.exist?
163- # for both private and public paths, but should still return the configured path
164- public_path = File . expand_path ( File . join ( packer_public_output_path , server_bundle_name ) )
162+ it "returns private path when it exists even if public path also exists" do
163+ allow ( File ) . to receive ( :exist? ) . with ( ssr_generated_path ) . and_return ( true )
164+ allow ( File ) . to receive ( :exist? ) . with ( public_path ) . and_return ( true )
165+
166+ result = described_class . bundle_js_file_path ( server_bundle_name )
167+ expect ( result ) . to eq ( ssr_generated_path )
168+ end
169+
170+ it "returns public path when private path does not exist and public path exists" do
171+ allow ( File ) . to receive ( :exist? ) . with ( ssr_generated_path ) . and_return ( false )
172+ allow ( File ) . to receive ( :exist? ) . with ( public_path ) . and_return ( true )
173+
174+ result = described_class . bundle_js_file_path ( server_bundle_name )
175+ expect ( result ) . to eq ( public_path )
176+ end
177+
178+ it "returns configured path if both private and public paths do not exist" do
165179 allow ( File ) . to receive ( :exist? ) . with ( ssr_generated_path ) . and_return ( false )
166180 allow ( File ) . to receive ( :exist? ) . with ( public_path ) . and_return ( false )
167181
@@ -170,6 +184,41 @@ def mock_dev_server_running
170184 end
171185 end
172186
187+ context "with server_bundle_output_path configured and enforce_private_server_bundles=true" do
188+ before do
189+ mock_missing_manifest_entry ( server_bundle_name )
190+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.server_bundle_js_file" )
191+ . and_return ( server_bundle_name )
192+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.server_bundle_output_path" )
193+ . and_return ( "ssr-generated" )
194+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.enforce_private_server_bundles" )
195+ . and_return ( true )
196+ end
197+
198+ # It should always return the ssr_generated_path, regardless of which files exist
199+ file_states_combinations = [
200+ { ssr_exists : true , public_exists : true } ,
201+ { ssr_exists : true , public_exists : false } ,
202+ { ssr_exists : false , public_exists : true } ,
203+ { ssr_exists : false , public_exists : false }
204+ ]
205+ file_states_combinations . each do |file_states |
206+ it "returns private path when enforce_private_server_bundles=true " \
207+ "(ssr_exists=#{ file_states [ :ssr_exists ] } , " \
208+ "public_exists=#{ file_states [ :public_exists ] } )" do
209+ allow ( File ) . to receive ( :exist? )
210+ . with ( ssr_generated_path )
211+ . and_return ( file_states [ :ssr_exists ] )
212+ allow ( File ) . to receive ( :exist? )
213+ . with ( public_path )
214+ . and_return ( file_states [ :public_exists ] )
215+
216+ result = described_class . bundle_js_file_path ( server_bundle_name )
217+ expect ( result ) . to eq ( ssr_generated_path )
218+ end
219+ end
220+ end
221+
173222 context "without server_bundle_output_path configured" do
174223 before do
175224 mock_missing_manifest_entry ( server_bundle_name )
@@ -190,27 +239,65 @@ def mock_dev_server_running
190239
191240 context "with RSC bundle file not in manifest" do
192241 let ( :rsc_bundle_name ) { "rsc-bundle.js" }
242+ let ( :public_path ) { File . expand_path ( File . join ( packer_public_output_path , rsc_bundle_name ) ) }
193243 let ( :ssr_generated_path ) { File . expand_path ( File . join ( "ssr-generated" , rsc_bundle_name ) ) }
194244
195- before do
196- mock_missing_manifest_entry ( rsc_bundle_name )
197- allow ( ReactOnRails ) . to receive_message_chain ( "configuration.rsc_bundle_js_file" )
198- . and_return ( rsc_bundle_name )
199- allow ( ReactOnRails ) . to receive_message_chain ( "configuration.server_bundle_output_path" )
200- . and_return ( "ssr-generated" )
201- allow ( ReactOnRails ) . to receive_message_chain ( "configuration.enforce_private_server_bundles" )
202- . and_return ( false )
245+ context "with enforce_private_server_bundles=false" do
246+ before do
247+ mock_missing_manifest_entry ( rsc_bundle_name )
248+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.rsc_bundle_js_file" )
249+ . and_return ( rsc_bundle_name )
250+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.server_bundle_output_path" )
251+ . and_return ( "ssr-generated" )
252+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.enforce_private_server_bundles" )
253+ . and_return ( false )
254+ end
255+
256+ it "returns private path when it exists even if public path also exists" do
257+ allow ( File ) . to receive ( :exist? ) . with ( ssr_generated_path ) . and_return ( true )
258+ expect ( File ) . not_to receive ( :exist? ) . with ( public_path )
259+
260+ result = described_class . bundle_js_file_path ( rsc_bundle_name )
261+ expect ( result ) . to eq ( ssr_generated_path )
262+ end
263+
264+ it "fallbacks to public path when private path does not exist and public path exists" do
265+ allow ( File ) . to receive ( :exist? ) . with ( ssr_generated_path ) . and_return ( false )
266+ allow ( File ) . to receive ( :exist? ) . with ( public_path ) . and_return ( true )
267+
268+ result = described_class . bundle_js_file_path ( rsc_bundle_name )
269+ expect ( result ) . to eq ( public_path )
270+ end
271+
272+ it "returns configured path if both private and public paths do not exist" do
273+ allow ( File ) . to receive ( :exist? ) . with ( ssr_generated_path ) . and_return ( false )
274+ allow ( File ) . to receive ( :exist? ) . with ( public_path ) . and_return ( false )
275+
276+ result = described_class . bundle_js_file_path ( rsc_bundle_name )
277+ expect ( result ) . to eq ( ssr_generated_path )
278+ end
203279 end
204280
205- it "treats RSC bundles as server bundles and returns configured path directly" do
206- # When enforce_private_server_bundles is false, it will check File.exist?
207- # for both private and public paths, but should still return the configured path
208- public_path = File . expand_path ( File . join ( packer_public_output_path , rsc_bundle_name ) )
209- allow ( File ) . to receive ( :exist? ) . with ( ssr_generated_path ) . and_return ( false )
210- allow ( File ) . to receive ( :exist? ) . with ( public_path ) . and_return ( false )
281+ context "with enforce_private_server_bundles=true" do
282+ before do
283+ mock_missing_manifest_entry ( rsc_bundle_name )
284+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.rsc_bundle_js_file" )
285+ . and_return ( rsc_bundle_name )
286+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.server_bundle_output_path" )
287+ . and_return ( "ssr-generated" )
288+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.enforce_private_server_bundles" )
289+ . and_return ( true )
290+ end
291+
292+ it "enforces private RSC bundles and never checks public directory" do
293+ public_path = File . expand_path ( File . join ( packer_public_output_path , rsc_bundle_name ) )
294+
295+ # Should not check public path when enforcement is enabled
296+ expect ( File ) . not_to receive ( :exist? ) . with ( public_path )
211297
212- result = described_class . bundle_js_file_path ( rsc_bundle_name )
213- expect ( result ) . to eq ( ssr_generated_path )
298+ result = described_class . bundle_js_file_path ( rsc_bundle_name )
299+ expect ( result ) . to eq ( ssr_generated_path )
300+ end
214301 end
215302 end
216303 end
@@ -263,7 +350,7 @@ def mock_dev_server_running
263350 expect ( path ) . to end_with ( "ssr-generated/#{ server_bundle_name } " )
264351 end
265352
266- context "with server_bundle_output_path configured" do
353+ context "with server_bundle_output_path configured and enforce_private_server_bundles=false " do
267354 it "returns the configured path directly without checking file existence" do
268355 server_bundle_name = "server-bundle.js"
269356 mock_bundle_configs ( server_bundle_name : server_bundle_name )
@@ -283,6 +370,26 @@ def mock_dev_server_running
283370 expect ( path ) . to end_with ( "ssr-generated/#{ server_bundle_name } " )
284371 end
285372 end
373+
374+ context "with server_bundle_output_path configured and enforce_private_server_bundles=true" do
375+ it "returns the private path without checking public directories" do
376+ server_bundle_name = "server-bundle.js"
377+ mock_missing_manifest_entry ( server_bundle_name )
378+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.server_bundle_js_file" )
379+ . and_return ( server_bundle_name )
380+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.server_bundle_output_path" )
381+ . and_return ( "ssr-generated" )
382+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.enforce_private_server_bundles" )
383+ . and_return ( true )
384+
385+ # Should not check public paths when enforcement is enabled
386+ public_path = File . expand_path ( File . join ( packer_public_output_path , server_bundle_name ) )
387+ expect ( File ) . not_to receive ( :exist? ) . with ( public_path )
388+
389+ path = described_class . server_bundle_js_file_path
390+ expect ( path ) . to end_with ( "ssr-generated/#{ server_bundle_name } " )
391+ end
392+ end
286393 end
287394
288395 context "with server file in the manifest, used for client" , packer_type . to_sym do
@@ -346,14 +453,38 @@ def mock_dev_server_running
346453 include_context "with #{ packer_type } enabled"
347454
348455 context "with server file not in manifest" , packer_type . to_sym do
349- it "returns the private ssr-generated path for RSC bundles" do
350- server_bundle_name = "rsc-bundle.js"
351- mock_bundle_configs ( rsc_bundle_name : server_bundle_name )
352- mock_missing_manifest_entry ( server_bundle_name )
456+ context "with enforce_private_server_bundles=false" do
457+ it "returns the private ssr-generated path for RSC bundles" do
458+ server_bundle_name = "rsc-bundle.js"
459+ mock_bundle_configs ( rsc_bundle_name : server_bundle_name )
460+ mock_missing_manifest_entry ( server_bundle_name )
353461
354- path = described_class . rsc_bundle_js_file_path
462+ path = described_class . rsc_bundle_js_file_path
355463
356- expect ( path ) . to end_with ( "ssr-generated/#{ server_bundle_name } " )
464+ expect ( path ) . to end_with ( "ssr-generated/#{ server_bundle_name } " )
465+ end
466+ end
467+
468+ context "with enforce_private_server_bundles=true" do
469+ it "returns the private ssr-generated path for RSC bundles without checking public paths" do
470+ server_bundle_name = "rsc-bundle.js"
471+ mock_missing_manifest_entry ( server_bundle_name )
472+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.server_bundle_js_file" )
473+ . and_return ( "server-bundle.js" ) # Different from RSC bundle name
474+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.rsc_bundle_js_file" )
475+ . and_return ( server_bundle_name )
476+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.server_bundle_output_path" )
477+ . and_return ( "ssr-generated" )
478+ allow ( ReactOnRails ) . to receive_message_chain ( "configuration.enforce_private_server_bundles" )
479+ . and_return ( true )
480+
481+ # Should not check public paths when enforcement is enabled
482+ public_path = File . expand_path ( File . join ( packer_public_output_path , server_bundle_name ) )
483+ expect ( File ) . not_to receive ( :exist? ) . with ( public_path )
484+
485+ path = described_class . rsc_bundle_js_file_path
486+ expect ( path ) . to end_with ( "ssr-generated/#{ server_bundle_name } " )
487+ end
357488 end
358489 end
359490
0 commit comments