@@ -152,6 +152,133 @@ def setup
152
152
assert_not_equal set_two , @importmap . preloaded_module_paths ( resolver : ApplicationController . helpers , cache_key : "2" ) . to_s
153
153
end
154
154
155
+ test "preloaded_module_packages returns hash of resolved paths to packages when no entry_point specified" do
156
+ packages = @importmap . preloaded_module_packages ( resolver : ApplicationController . helpers )
157
+
158
+ md5 = packages [ "https://cdn.skypack.dev/md5" ]
159
+ assert md5 , "Should include md5 package"
160
+ assert_equal "md5" , md5 . name
161
+ assert_equal "https://cdn.skypack.dev/md5" , md5 . path
162
+ assert_equal true , md5 . preload
163
+
164
+ goodbye_controller_path = packages . keys . find { |path | path . include? ( "goodbye_controller" ) }
165
+ assert goodbye_controller_path , "Should include goodbye_controller package"
166
+ assert_equal "controllers/goodbye_controller" , packages [ goodbye_controller_path ] . name
167
+ assert_equal true , packages [ goodbye_controller_path ] . preload
168
+
169
+ leaflet = packages [ "https://cdn.skypack.dev/leaflet" ]
170
+ assert leaflet , "Should include leaflet package"
171
+ assert_equal "leaflet" , leaflet . name
172
+ assert_equal "https://cdn.skypack.dev/leaflet" , leaflet . path
173
+ assert_equal 'application' , leaflet . preload
174
+
175
+ chartkick = packages [ "https://cdn.skypack.dev/chartkick" ]
176
+ assert chartkick , "Should include chartkick package"
177
+ assert_equal "chartkick" , chartkick . name
178
+ assert_equal [ 'application' , 'alternate' ] , chartkick . preload
179
+
180
+ application_path = packages . keys . find { |path | path . include? ( "application" ) }
181
+ assert_nil application_path , "Should not include application package (preload: false)"
182
+
183
+ tinymce_path = packages . keys . find { |path | path . include? ( "tinymce" ) }
184
+ assert_nil tinymce_path , "Should not include tinymce package (preload: 'alternate')"
185
+ end
186
+
187
+ test "preloaded_module_packages returns hash based on single entry_point provided" do
188
+ packages = @importmap . preloaded_module_packages ( resolver : ApplicationController . helpers , entry_point : "alternate" )
189
+
190
+ tinymce = packages [ "https://cdn.skypack.dev/tinymce" ]
191
+ assert tinymce , "Should include tinymce package for alternate entry point"
192
+ assert_equal "tinyMCE" , tinymce . name
193
+ assert_equal "https://cdn.skypack.dev/tinymce" , tinymce . path
194
+ assert_equal 'alternate' , tinymce . preload
195
+
196
+ # Should include packages for multiple entry points (chartkick preloads for both 'application' and 'alternate')
197
+ chartkick = packages [ "https://cdn.skypack.dev/chartkick" ]
198
+ assert chartkick , "Should include chartkick package"
199
+ assert_equal "chartkick" , chartkick . name
200
+ assert_equal [ 'application' , 'alternate' ] , chartkick . preload
201
+
202
+ # Should include always-preloaded packages
203
+ md5 = packages [ "https://cdn.skypack.dev/md5" ]
204
+ assert md5 , "Should include md5 package (always preloaded)"
205
+
206
+ leaflet_path = packages . keys . find { |path | path . include? ( "leaflet" ) }
207
+ assert_nil leaflet_path , "Should not include leaflet package (preload: 'application' only)"
208
+ end
209
+
210
+ test "preloaded_module_packages returns hash based on multiple entry_points provided" do
211
+ packages = @importmap . preloaded_module_packages ( resolver : ApplicationController . helpers , entry_point : [ "application" , "alternate" ] )
212
+
213
+ leaflet = packages [ "https://cdn.skypack.dev/leaflet" ]
214
+ assert leaflet , "Should include leaflet package for application entry point"
215
+
216
+ # Should include packages for 'alternate' entry point
217
+ tinymce = packages [ "https://cdn.skypack.dev/tinymce" ]
218
+ assert tinymce , "Should include tinymce package for alternate entry point"
219
+
220
+ # Should include packages for multiple entry points
221
+ chartkick = packages [ "https://cdn.skypack.dev/chartkick" ]
222
+ assert chartkick , "Should include chartkick package for both entry points"
223
+
224
+ # Should include always-preloaded packages
225
+ md5 = packages [ "https://cdn.skypack.dev/md5" ]
226
+ assert md5 , "Should include md5 package (always preloaded)"
227
+
228
+ application_path = packages . keys . find { |path | path . include? ( "application" ) }
229
+ assert_nil application_path , "Should not include application package (preload: false)"
230
+ end
231
+
232
+ test "preloaded_module_packages includes package integrity when present" do
233
+ # Create a new importmap with a preloaded package that has integrity
234
+ importmap = Importmap ::Map . new . tap do |map |
235
+ map . pin "editor" , to : "rich_text.js" , preload : true , integrity : "sha384-OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb"
236
+ end
237
+
238
+ packages = importmap . preloaded_module_packages ( resolver : ApplicationController . helpers )
239
+
240
+ editor_path = packages . keys . find { |path | path . include? ( "rich_text" ) }
241
+ assert editor_path , "Should include editor package"
242
+ assert_equal "editor" , packages [ editor_path ] . name
243
+ assert_equal "sha384-OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb" , packages [ editor_path ] . integrity
244
+ end
245
+
246
+ test "preloaded_module_packages uses custom cache_key" do
247
+ set_one = @importmap . preloaded_module_packages ( resolver : ApplicationController . helpers , cache_key : "1" ) . to_s
248
+
249
+ ActionController ::Base . asset_host = "http://assets.example.com"
250
+
251
+ set_two = @importmap . preloaded_module_packages ( resolver : ActionController ::Base . helpers , cache_key : "2" ) . to_s
252
+
253
+ assert_not_equal set_one , set_two
254
+ ensure
255
+ ActionController ::Base . asset_host = nil
256
+ end
257
+
258
+ test "preloaded_module_packages caches reset" do
259
+ set_one = @importmap . preloaded_module_packages ( resolver : ApplicationController . helpers , cache_key : "1" ) . to_s
260
+ set_two = @importmap . preloaded_module_packages ( resolver : ApplicationController . helpers , cache_key : "2" ) . to_s
261
+
262
+ @importmap . pin "something" , to : "https://cdn.example.com/somewhere.js" , preload : true
263
+
264
+ assert_not_equal set_one , @importmap . preloaded_module_packages ( resolver : ApplicationController . helpers , cache_key : "1" ) . to_s
265
+ assert_not_equal set_two , @importmap . preloaded_module_packages ( resolver : ApplicationController . helpers , cache_key : "2" ) . to_s
266
+ end
267
+
268
+ test "preloaded_module_packages handles missing assets gracefully" do
269
+ importmap = Importmap ::Map . new . tap do |map |
270
+ map . pin "existing" , to : "application.js" , preload : true
271
+ map . pin "missing" , to : "nonexistent.js" , preload : true
272
+ end
273
+
274
+ packages = importmap . preloaded_module_packages ( resolver : ApplicationController . helpers )
275
+
276
+ assert_equal 1 , packages . size
277
+
278
+ existing_path = packages . keys . find { |path | path &.include? ( "application" ) }
279
+ assert existing_path , "Should include existing asset"
280
+ end
281
+
155
282
private
156
283
def generate_importmap_json
157
284
@generate_importmap_json ||= JSON . parse @importmap . to_json ( resolver : ApplicationController . helpers )
0 commit comments