# frozen_string_literal: true require 'spec_helper' RSpec.describe CKEditor5::Rails::Hooks::Importmap::ImportmapTagsHelper do let(:test_class) do Class.new do include ActionView::Helpers::TagHelper include CKEditor5::Rails::Hooks::Importmap::ImportmapTagsHelper def javascript_importmap_module_preload_tags(*) '' end def javascript_import_module_tag(*) '' end def javascript_inline_importmap_tag(json) "" end end end let(:helper) { test_class.new } let(:importmap) { double('Importmap', to_json: '{"imports":{}}') } before do allow(Rails.application).to receive(:importmap).and_return(importmap) end describe '#javascript_importmap_tags' do context 'without CKEditor context' do it 'generates basic importmap tags' do result = helper.javascript_importmap_tags expect(result).to include('modulepreload') expect(result).to include('module') expect(helper).to be_importmap_rendered end end context 'with CKEditor context' do let(:bundle) do CKEditor5::Rails::Assets::AssetsBundle.new( scripts: [ CKEditor5::Rails::Assets::JSUrlImportMeta.new( 'https://cdn.com/script.js', import_name: '@ckeditor/module' ) ] ) end let(:html_tags) { '' } before do helper.instance_variable_set(:@__ckeditor_context, { bundle: bundle, html_tags: html_tags }) end it 'merges CKEditor importmap with base importmap' do result = CGI.unescapeHTML(helper.javascript_importmap_tags) expect(result).to include('@ckeditor/module') expect(result).to include('https://cdn.com/script.js') expect(result).to include(html_tags) end it 'handles invalid JSON gracefully' do allow(importmap).to receive(:to_json).and_return('invalid json') expect(Rails.logger).to receive(:error).with(/Failed to merge import maps/) helper.javascript_importmap_tags end it 'processes importmap in correct order when context is present' do html = CGI.unescapeHTML(helper.javascript_importmap_tags) doc = Nokogiri::HTML::DocumentFragment.parse(html) scripts = doc.css('script') expect(scripts[0]['type']).to eq('importmap') expect(scripts[1]['type']).to eq('modulepreload') expect(scripts[2]['type']).to eq('module') expect(scripts[3]['src']).to eq('ckeditor.js') end it 'adds inline importmap when context is missing' do helper.instance_variable_set(:@__ckeditor_context, nil) html = CGI.unescapeHTML(helper.javascript_importmap_tags) doc = Nokogiri::HTML::DocumentFragment.parse(html) scripts = doc.css('script') expect(scripts[0]['type']).to eq('importmap') expect(doc.css('script[src="ckeditor.js"]')).to be_empty end end end describe '#importmap_rendered?' do it 'returns false by default' do expect(helper).not_to be_importmap_rendered end it 'returns true after rendering importmap' do helper.javascript_importmap_tags expect(helper).to be_importmap_rendered end end describe '#merge_import_maps_json (private)' do it 'correctly merges two valid import maps' do map_a = '{"imports":{"a":"1"}}' map_b = '{"imports":{"b":"2"}}' result = JSON.parse(helper.send(:merge_import_maps_json, map_a, map_b)) expect(result['imports']).to eq('a' => '1', 'b' => '2') end it 'returns second map when first is invalid' do map_a = 'invalid json' map_b = '{"imports":{"b":"2"}}' expect(Rails.logger).to receive(:error).with(/Failed to merge import maps/) result = helper.send(:merge_import_maps_json, map_a, map_b) expect(result).to eq(map_b) end end end