# 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