ckeditor5 1.15.8 → 1.15.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -5
  3. data/README.md +3 -0
  4. data/lib/ckeditor5/rails/cdn/ckbox_bundle.rb +2 -2
  5. data/lib/ckeditor5/rails/cdn/helpers.rb +6 -0
  6. data/lib/ckeditor5/rails/context/helpers.rb +1 -1
  7. data/lib/ckeditor5/rails/editor/editable_height_normalizer.rb +50 -0
  8. data/lib/ckeditor5/rails/editor/helpers/config_helpers.rb +3 -3
  9. data/lib/ckeditor5/rails/editor/helpers/editor_helpers.rb +5 -4
  10. data/lib/ckeditor5/rails/editor/props.rb +3 -20
  11. data/lib/ckeditor5/rails/engine.rb +3 -2
  12. data/lib/ckeditor5/rails/plugins/simple_upload_adapter.rb +1 -1
  13. data/lib/ckeditor5/rails/presets/plugins_builder.rb +9 -9
  14. data/lib/ckeditor5/rails/presets/preset_builder.rb +6 -9
  15. data/lib/ckeditor5/rails/version.rb +1 -1
  16. data/lib/ckeditor5/rails/version_detector.rb +6 -0
  17. data/spec/lib/ckeditor5/rails/assets/asset_bundle_hml_serializer_spec.rb +111 -0
  18. data/spec/lib/ckeditor5/rails/assets/assets_bundle_spec.rb +191 -0
  19. data/spec/lib/ckeditor5/rails/cdn/ckbox_bundle_spec.rb +69 -0
  20. data/spec/lib/ckeditor5/rails/cdn/ckeditor_bundle_spec.rb +72 -0
  21. data/spec/lib/ckeditor5/rails/cdn/helpers_spec.rb +235 -0
  22. data/spec/lib/ckeditor5/rails/context/helpers_spec.rb +67 -0
  23. data/spec/lib/ckeditor5/rails/context/props_spec.rb +70 -0
  24. data/spec/lib/ckeditor5/rails/editor/editable_height_normalizer_spec.rb +50 -0
  25. data/spec/lib/ckeditor5/rails/editor/helpers/config_helpers_spec.rb +52 -0
  26. data/spec/lib/ckeditor5/rails/editor/helpers/editor_helpers_spec.rb +192 -0
  27. data/spec/lib/ckeditor5/rails/editor/props_inline_plugin_spec.rb +43 -0
  28. data/spec/lib/ckeditor5/rails/editor/props_plugin_spec.rb +66 -0
  29. data/spec/lib/ckeditor5/rails/editor/props_spec.rb +104 -0
  30. data/spec/lib/ckeditor5/rails/engine_spec.rb +88 -0
  31. data/spec/lib/ckeditor5/rails/hooks/form_spec.rb +203 -0
  32. data/spec/lib/ckeditor5/rails/hooks/simple_form_spec.rb +100 -0
  33. data/spec/lib/ckeditor5/rails/presets/manager_spec.rb +100 -0
  34. data/spec/lib/ckeditor5/rails/presets/plugins_builder_spec.rb +98 -0
  35. data/spec/lib/ckeditor5/rails/presets/preset_builder_spec.rb +347 -0
  36. data/spec/lib/ckeditor5/rails/presets/toolbar_builder_spec.rb +70 -0
  37. data/spec/lib/ckeditor5/rails/semver_spec.rb +58 -0
  38. data/spec/lib/ckeditor5/rails/version_detector_spec.rb +131 -0
  39. data/spec/lib/ckeditor5/rails/version_spec.rb +25 -0
  40. data/spec/spec_helper.rb +8 -2
  41. data/spec/support/test_models.rb +6 -0
  42. metadata +49 -2
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe CKEditor5::Rails::Editor::EditableHeightNormalizer do
6
+ subject(:normalizer) { described_class.new(editor_type) }
7
+
8
+ describe '#normalize' do
9
+ context 'when editor type is classic' do
10
+ let(:editor_type) { :classic }
11
+
12
+ it 'returns nil when value is nil' do
13
+ expect(normalizer.normalize(nil)).to be_nil
14
+ end
15
+
16
+ it 'converts integer to pixel string' do
17
+ expect(normalizer.normalize(500)).to eq('500px')
18
+ end
19
+
20
+ it 'accepts valid pixel string' do
21
+ expect(normalizer.normalize('300px')).to eq('300px')
22
+ end
23
+
24
+ it 'raises error for invalid string format' do
25
+ expect { normalizer.normalize('500') }.to raise_error(
26
+ CKEditor5::Rails::Editor::InvalidEditableHeightError,
27
+ /editable_height must be an integer representing pixels or string ending with 'px'/
28
+ )
29
+ end
30
+
31
+ it 'raises error for invalid value type' do
32
+ expect { normalizer.normalize([]) }.to raise_error(
33
+ CKEditor5::Rails::Editor::InvalidEditableHeightError,
34
+ /editable_height must be an integer representing pixels or string ending with 'px'/
35
+ )
36
+ end
37
+ end
38
+
39
+ context 'when editor type is not classic' do
40
+ let(:editor_type) { :inline }
41
+
42
+ it 'raises error' do
43
+ expect { normalizer.normalize(500) }.to raise_error(
44
+ CKEditor5::Rails::Editor::InvalidEditableHeightError,
45
+ 'editable_height can be used only with ClassicEditor'
46
+ )
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe CKEditor5::Rails::Editor::Helpers::Config do
6
+ let(:test_class) { Class.new { include CKEditor5::Rails::Editor::Helpers::Config } }
7
+ let(:helper) { test_class.new }
8
+
9
+ describe '#ckeditor5_element_ref' do
10
+ it 'returns a hash with $element key' do
11
+ expect(helper.ckeditor5_element_ref('#editor')).to eq({ '$element': '#editor' })
12
+ end
13
+
14
+ it 'accepts any selector string' do
15
+ expect(helper.ckeditor5_element_ref('.custom-editor')).to eq({ '$element': '.custom-editor' })
16
+ end
17
+ end
18
+
19
+ describe '#ckeditor5_preset' do
20
+ let(:preset_builder) { instance_double(CKEditor5::Rails::Presets::PresetBuilder) }
21
+
22
+ context 'when name is provided' do
23
+ before do
24
+ allow(CKEditor5::Rails::Engine).to receive(:find_preset).with(:default).and_return(preset_builder)
25
+ end
26
+
27
+ it 'returns preset from engine' do
28
+ expect(helper.ckeditor5_preset(:default)).to eq(preset_builder)
29
+ end
30
+ end
31
+
32
+ context 'when block is provided' do
33
+ it 'returns new PresetBuilder instance' do
34
+ expect(CKEditor5::Rails::Presets::PresetBuilder).to receive(:new)
35
+ helper.ckeditor5_preset {}
36
+ end
37
+
38
+ it 'yields the block to PresetBuilder' do
39
+ expect { |b| helper.ckeditor5_preset(&b) }.to yield_control
40
+ end
41
+ end
42
+
43
+ context 'when neither name nor block is provided' do
44
+ it 'raises ArgumentError' do
45
+ expect { helper.ckeditor5_preset }.to raise_error(
46
+ ArgumentError,
47
+ 'Configuration block is required for preset definition'
48
+ )
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,192 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'action_view'
5
+
6
+ RSpec.describe CKEditor5::Rails::Editor::Helpers::Editor do
7
+ let(:test_class) do
8
+ Class.new do
9
+ include ActionView::Helpers::TagHelper
10
+ include CKEditor5::Rails::Editor::Helpers::Editor
11
+ end
12
+ end
13
+
14
+ let(:helper) { test_class.new }
15
+ let(:preset) { instance_double(CKEditor5::Rails::Presets::PresetBuilder) }
16
+ let(:context) { { preset: :default, cdn: :jsdelivr } }
17
+
18
+ before do
19
+ helper.instance_variable_set(:@__ckeditor_context, context)
20
+ allow(preset).to receive(:type).and_return(:classic)
21
+ allow(preset).to receive(:config).and_return({})
22
+ allow(preset).to receive(:automatic_upgrades?).and_return(false)
23
+ end
24
+
25
+ describe '#ckeditor5_editor' do
26
+ before do
27
+ allow(helper).to receive(:find_preset).and_return(preset)
28
+ end
29
+
30
+ it 'raises error when context is not defined' do
31
+ helper.remove_instance_variable(:@__ckeditor_context)
32
+ expect { helper.ckeditor5_editor }.to raise_error(
33
+ described_class::EditorContextError,
34
+ /CKEditor installation context is not defined/
35
+ )
36
+ end
37
+
38
+ it 'raises error when preset is not found' do
39
+ allow(helper).to receive(:find_preset).and_raise(described_class::PresetNotFoundError)
40
+ expect do
41
+ helper.ckeditor5_editor(preset: :unknown)
42
+ end.to raise_error(described_class::PresetNotFoundError)
43
+ end
44
+
45
+ it 'merges extra configuration with preset config' do
46
+ extra_config = { toolbar: { items: ['bold'] } }
47
+ expect(helper).to receive(:build_editor_config)
48
+ .with(preset, nil, extra_config, nil)
49
+ .and_return(extra_config)
50
+
51
+ helper.ckeditor5_editor(extra_config: extra_config)
52
+ end
53
+
54
+ it 'sets initial data in config when provided' do
55
+ expect(helper).to receive(:build_editor_config)
56
+ .with(preset, nil, {}, 'initial content')
57
+ .and_call_original
58
+
59
+ helper.ckeditor5_editor(initial_data: 'initial content')
60
+ end
61
+
62
+ it 'cannot have both initial_data and block content' do
63
+ expect do
64
+ helper.ckeditor5_editor(initial_data: 'content') { 'block content' }
65
+ end.to raise_error(ArgumentError, /Cannot pass initial data and block/)
66
+ end
67
+
68
+ context 'when automatic upgrades are enabled' do
69
+ before do
70
+ allow(preset).to receive(:automatic_upgrades?).and_return(true)
71
+ end
72
+
73
+ it 'updates version when detector finds newer safe version' do
74
+ extra_config = { version: '35.1.0' }
75
+ allow(CKEditor5::Rails::VersionDetector).to receive(:latest_safe_version)
76
+ .with('35.1.0')
77
+ .and_return('35.3.0')
78
+
79
+ result = helper.ckeditor5_editor(extra_config: extra_config)
80
+ expect(result).to include('35.3.0')
81
+ end
82
+
83
+ it 'keeps original version when no safe upgrade is available' do
84
+ extra_config = { version: '35.1.0' }
85
+ allow(CKEditor5::Rails::VersionDetector).to receive(:latest_safe_version)
86
+ .with('35.1.0')
87
+ .and_return(nil)
88
+
89
+ result = helper.ckeditor5_editor(extra_config: extra_config)
90
+ expect(result).to include('35.1.0')
91
+ end
92
+
93
+ it 'skips version detection when version is not specified' do
94
+ expect(CKEditor5::Rails::VersionDetector).not_to receive(:latest_safe_version)
95
+ helper.ckeditor5_editor
96
+ end
97
+ end
98
+
99
+ context 'when automatic upgrades are disabled' do
100
+ before do
101
+ allow(preset).to receive(:automatic_upgrades?).and_return(false)
102
+ end
103
+
104
+ it 'does not modify version even when newer version is available' do
105
+ extra_config = { version: '35.1.0' }
106
+ expect(CKEditor5::Rails::VersionDetector).not_to receive(:latest_safe_version)
107
+
108
+ result = helper.ckeditor5_editor(extra_config: extra_config)
109
+ expect(result).to include('35.1.0')
110
+ end
111
+ end
112
+
113
+ context 'when using preset lookup' do
114
+ before do
115
+ RSpec::Mocks.space.proxy_for(helper).remove_stub(:find_preset)
116
+ end
117
+
118
+ it 'uses default preset when none specified' do
119
+ expect(CKEditor5::Rails::Engine).to receive(:find_preset)
120
+ .with(:default)
121
+ .and_return(preset)
122
+
123
+ helper.ckeditor5_editor
124
+ end
125
+
126
+ it 'uses preset from context when available' do
127
+ helper.instance_variable_set(:@__ckeditor_context, { preset: :custom })
128
+ expect(CKEditor5::Rails::Engine).to receive(:find_preset)
129
+ .with(:custom)
130
+ .and_return(preset)
131
+
132
+ helper.ckeditor5_editor
133
+ end
134
+
135
+ it 'prefers explicitly passed preset over context preset' do
136
+ helper.instance_variable_set(:@__ckeditor_context, { preset: :from_context })
137
+ expect(CKEditor5::Rails::Engine).to receive(:find_preset)
138
+ .with(:explicit)
139
+ .and_return(preset)
140
+
141
+ helper.ckeditor5_editor(preset: :explicit)
142
+ end
143
+
144
+ it 'raises error when preset cannot be found' do
145
+ allow(CKEditor5::Rails::Engine).to receive(:find_preset)
146
+ .with(:unknown)
147
+ .and_return(nil)
148
+
149
+ expect { helper.ckeditor5_editor(preset: :unknown) }.to raise_error(
150
+ described_class::PresetNotFoundError,
151
+ 'Preset unknown is not defined.'
152
+ )
153
+ end
154
+ end
155
+ end
156
+
157
+ describe '#ckeditor5_editable' do
158
+ it 'creates editable component with name' do
159
+ expect(helper.ckeditor5_editable('content')).to have_tag(
160
+ 'ckeditor-editable-component',
161
+ with: { name: 'content' }
162
+ )
163
+ end
164
+ end
165
+
166
+ describe '#ckeditor5_ui_part' do
167
+ it 'creates ui part component with name' do
168
+ expect(helper.ckeditor5_ui_part('toolbar')).to have_tag(
169
+ 'ckeditor-ui-part-component',
170
+ with: { name: 'toolbar' }
171
+ )
172
+ end
173
+ end
174
+
175
+ describe '#ckeditor5_toolbar' do
176
+ it 'creates toolbar ui part' do
177
+ expect(helper.ckeditor5_toolbar).to have_tag(
178
+ 'ckeditor-ui-part-component',
179
+ with: { name: 'toolbar' }
180
+ )
181
+ end
182
+ end
183
+
184
+ describe '#ckeditor5_menubar' do
185
+ it 'creates menubar ui part' do
186
+ expect(helper.ckeditor5_menubar).to have_tag(
187
+ 'ckeditor-ui-part-component',
188
+ with: { name: 'menuBarView' }
189
+ )
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe CKEditor5::Rails::Editor::PropsInlinePlugin do
6
+ let(:valid_code) do
7
+ <<~JAVASCRIPT
8
+ import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
9
+ export default class CustomPlugin extends Plugin {
10
+ init() {
11
+ console.log('Custom plugin initialized');
12
+ }
13
+ }
14
+ JAVASCRIPT
15
+ end
16
+
17
+ describe '#initialize' do
18
+ it 'accepts valid plugin code' do
19
+ expect { described_class.new(:CustomPlugin, valid_code) }.not_to raise_error
20
+ end
21
+
22
+ it 'raises error when code is not a string' do
23
+ expect { described_class.new(:CustomPlugin, nil) }
24
+ .to raise_error(ArgumentError, 'Code must be a String')
25
+ end
26
+
27
+ it 'raises error when code lacks export default' do
28
+ expect { described_class.new(:CustomPlugin, 'class CustomPlugin {}') }
29
+ .to raise_error(ArgumentError, /must include `export default`/)
30
+ end
31
+ end
32
+
33
+ describe '#to_h' do
34
+ it 'returns correct hash representation' do
35
+ plugin = described_class.new(:CustomPlugin, valid_code)
36
+ expect(plugin.to_h).to eq({
37
+ type: :inline,
38
+ name: :CustomPlugin,
39
+ code: valid_code
40
+ })
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe CKEditor5::Rails::Editor::PropsPlugin do
6
+ describe '.normalize' do
7
+ it 'converts string to plugin instance' do
8
+ plugin = described_class.normalize('Bold')
9
+ expect(plugin).to be_a(described_class)
10
+ expect(plugin.name).to eq('Bold')
11
+ end
12
+
13
+ it 'converts symbol to plugin instance' do
14
+ plugin = described_class.normalize(:Bold)
15
+ expect(plugin).to be_a(described_class)
16
+ expect(plugin.name).to eq(:Bold)
17
+ end
18
+
19
+ it 'returns existing plugin instances unchanged' do
20
+ original = described_class.new(:Bold)
21
+ plugin = described_class.normalize(original)
22
+ expect(plugin).to be(original)
23
+ end
24
+
25
+ it 'returns inline plugin instances unchanged' do
26
+ inline = CKEditor5::Rails::Editor::PropsInlinePlugin.new(:Custom, 'export default class {}')
27
+ plugin = described_class.normalize(inline)
28
+ expect(plugin).to be(inline)
29
+ end
30
+
31
+ it 'raises error for invalid input' do
32
+ expect { described_class.normalize({}) }.to raise_error(ArgumentError)
33
+ end
34
+ end
35
+
36
+ describe '#to_h' do
37
+ it 'generates hash for standard plugin' do
38
+ plugin = described_class.new(:Bold)
39
+ expect(plugin.to_h).to include(
40
+ type: :external,
41
+ import_name: 'ckeditor5',
42
+ import_as: :Bold
43
+ )
44
+ end
45
+
46
+ it 'generates hash for premium plugin' do
47
+ plugin = described_class.new(:Bold, premium: true)
48
+ expect(plugin.to_h).to include(
49
+ type: :external,
50
+ import_name: 'ckeditor5-premium-features',
51
+ import_as: :Bold
52
+ )
53
+ end
54
+
55
+ it 'handles custom import metadata' do
56
+ plugin = described_class.new(:Custom,
57
+ import_name: 'custom-module',
58
+ window_name: 'CustomPlugin')
59
+ expect(plugin.to_h).to include(
60
+ type: :external,
61
+ import_name: 'custom-module',
62
+ window_name: 'CustomPlugin'
63
+ )
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe CKEditor5::Rails::Editor::Props do
6
+ let(:controller_context) do
7
+ {
8
+ bundle: double('Bundle', translations_scripts: [{ path: 'translations/en.js' }]),
9
+ license_key: nil
10
+ }
11
+ end
12
+ let(:type) { :classic }
13
+ let(:config) { { plugins: [], toolbar: { items: [] } } }
14
+
15
+ describe '#initialize' do
16
+ it 'accepts valid editor type' do
17
+ expect { described_class.new(controller_context, :classic, {}) }.not_to raise_error
18
+ end
19
+
20
+ it 'raises error for invalid editor type' do
21
+ expect { described_class.new(controller_context, :invalid, {}) }
22
+ .to raise_error(ArgumentError, 'Invalid editor type: invalid')
23
+ end
24
+ end
25
+
26
+ describe '#to_attributes' do
27
+ subject(:props) { described_class.new(controller_context, type, config) }
28
+
29
+ it 'includes required attributes' do
30
+ attributes = props.to_attributes
31
+ expect(attributes).to include(
32
+ type: 'ClassicEditor',
33
+ translations: String,
34
+ plugins: String,
35
+ config: String,
36
+ watchdog: true
37
+ )
38
+ end
39
+
40
+ context 'with editable height' do
41
+ subject(:props) { described_class.new(controller_context, type, config, editable_height: '500px') }
42
+
43
+ it 'includes editable-height attribute' do
44
+ expect(props.to_attributes['editable-height']).to eq('500px')
45
+ end
46
+ end
47
+
48
+ context 'with license key' do
49
+ let(:controller_context) do
50
+ { bundle: double('Bundle', translations_scripts: []), license_key: 'ABC123' }
51
+ end
52
+
53
+ it 'includes license key in config' do
54
+ config_json = props.to_attributes[:config]
55
+ expect(config_json).to include('licenseKey')
56
+ expect(JSON.parse(config_json)['licenseKey']).to eq('ABC123')
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '.valid_editor_type?' do
62
+ it 'returns true for valid types' do
63
+ %i[classic inline balloon decoupled multiroot].each do |type|
64
+ expect(described_class.valid_editor_type?(type)).to be true
65
+ end
66
+ end
67
+
68
+ it 'returns false for invalid types' do
69
+ expect(described_class.valid_editor_type?(:invalid)).to be false
70
+ end
71
+ end
72
+
73
+ describe 'editable height validation' do
74
+ context 'with non-classic editor' do
75
+ let(:type) { :inline }
76
+
77
+ it 'raises error when editable height is set' do
78
+ expect do
79
+ described_class.new(controller_context, type, config, editable_height: '500px')
80
+ end.to raise_error(CKEditor5::Rails::Editor::InvalidEditableHeightError)
81
+ end
82
+ end
83
+
84
+ context 'with classic editor' do
85
+ let(:type) { :classic }
86
+
87
+ it 'accepts integer values' do
88
+ props = described_class.new(controller_context, type, config, editable_height: 500)
89
+ expect(props.to_attributes['editable-height']).to eq('500px')
90
+ end
91
+
92
+ it 'accepts pixel string values' do
93
+ props = described_class.new(controller_context, type, config, editable_height: '500px')
94
+ expect(props.to_attributes['editable-height']).to eq('500px')
95
+ end
96
+
97
+ it 'raises error for invalid values' do
98
+ expect do
99
+ described_class.new(controller_context, type, config, editable_height: '500em')
100
+ end.to raise_error(CKEditor5::Rails::Editor::InvalidEditableHeightError)
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe CKEditor5::Rails::Engine do
6
+ describe 'configuration' do
7
+ let(:preset) { instance_double(CKEditor5::Rails::Presets::PresetBuilder) }
8
+ let(:preset_manager) { instance_double(CKEditor5::Rails::Presets::Manager) }
9
+
10
+ before do
11
+ allow(described_class).to receive(:base).and_return(ActiveSupport::OrderedOptions.new)
12
+ allow(described_class.base).to receive(:presets).and_return(preset_manager)
13
+ allow(preset_manager).to receive(:default).and_return(preset)
14
+ end
15
+
16
+ it 'has default configuration' do
17
+ expect(described_class.base).to be_a(ActiveSupport::OrderedOptions)
18
+
19
+ default_preset = described_class.default_preset
20
+
21
+ expect(default_preset.type).to eq(:classic)
22
+ expect(default_preset.toolbar.items).to include(:undo, :redo, :'|', :heading)
23
+ expect(default_preset.plugins.items.map(&:name)).to include(:Essentials, :Paragraph, :Heading)
24
+ end
25
+
26
+ describe '.configure' do
27
+ it 'yields configuration proxy' do
28
+ yielded_config = nil
29
+ described_class.configure do |config|
30
+ yielded_config = config
31
+ end
32
+ expect(yielded_config).to be_a(described_class::ConfigurationProxy)
33
+ end
34
+
35
+ it 'allows configuring default preset' do
36
+ described_class.configure do
37
+ automatic_upgrades enabled: false
38
+ version '35.0.0'
39
+ license_key '1234567'
40
+ end
41
+
42
+ expect(described_class.default_preset.version).to eq('35.0.0')
43
+ expect(described_class.default_preset.license_key).to eq('1234567')
44
+ end
45
+ end
46
+
47
+ describe '.find_preset' do
48
+ before do
49
+ allow(preset_manager).to receive(:[]).with(:custom).and_return(preset)
50
+ allow(preset_manager).to receive(:[]).with(
51
+ kind_of(CKEditor5::Rails::Presets::PresetBuilder)
52
+ ).and_return(preset)
53
+ end
54
+
55
+ it 'returns preset instance if provided' do
56
+ test_preset = CKEditor5::Rails::Presets::PresetBuilder.new
57
+ expect(described_class.find_preset(test_preset)).to eq(test_preset)
58
+ end
59
+
60
+ it 'looks up preset by name' do
61
+ expect(described_class.find_preset(:custom)).to eq(preset)
62
+ end
63
+ end
64
+ end
65
+
66
+ describe 'initializers' do
67
+ describe 'helper initializer' do
68
+ it 'includes helpers in ActionView and ActionController' do
69
+ expect(ActionView::Base.included_modules).to include(CKEditor5::Rails::Helpers)
70
+ expect(ActionController::Base.included_modules).to include(CKEditor5::Rails::Helpers)
71
+ end
72
+ end
73
+
74
+ describe 'form_builder initializer' do
75
+ it 'includes FormBuilderExtension in ActionView::Helpers::FormBuilder' do
76
+ expect(ActionView::Helpers::FormBuilder.included_modules)
77
+ .to include(CKEditor5::Rails::Hooks::Form::FormBuilderExtension)
78
+ end
79
+ end
80
+
81
+ describe 'simple_form initializer', if: defined?(SimpleForm) do
82
+ it 'registers ckeditor5 input type' do
83
+ expect(SimpleForm::FormBuilder.mappings[:ckeditor5])
84
+ .to eq(CKEditor5::Rails::Hooks::SimpleForm::CKEditor5Input)
85
+ end
86
+ end
87
+ end
88
+ end