ckeditor5 1.15.8 → 1.15.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +6 -5
- data/README.md +3 -0
- data/lib/ckeditor5/rails/cdn/ckbox_bundle.rb +2 -2
- data/lib/ckeditor5/rails/cdn/helpers.rb +6 -0
- data/lib/ckeditor5/rails/context/helpers.rb +1 -1
- data/lib/ckeditor5/rails/editor/editable_height_normalizer.rb +50 -0
- data/lib/ckeditor5/rails/editor/helpers/config_helpers.rb +3 -3
- data/lib/ckeditor5/rails/editor/helpers/editor_helpers.rb +5 -4
- data/lib/ckeditor5/rails/editor/props.rb +3 -20
- data/lib/ckeditor5/rails/engine.rb +3 -2
- data/lib/ckeditor5/rails/plugins/simple_upload_adapter.rb +1 -1
- data/lib/ckeditor5/rails/presets/plugins_builder.rb +9 -9
- data/lib/ckeditor5/rails/presets/preset_builder.rb +6 -9
- data/lib/ckeditor5/rails/version.rb +1 -1
- data/lib/ckeditor5/rails/version_detector.rb +6 -0
- data/spec/lib/ckeditor5/rails/assets/asset_bundle_hml_serializer_spec.rb +111 -0
- data/spec/lib/ckeditor5/rails/assets/assets_bundle_spec.rb +191 -0
- data/spec/lib/ckeditor5/rails/cdn/ckbox_bundle_spec.rb +69 -0
- data/spec/lib/ckeditor5/rails/cdn/ckeditor_bundle_spec.rb +72 -0
- data/spec/lib/ckeditor5/rails/cdn/helpers_spec.rb +235 -0
- data/spec/lib/ckeditor5/rails/context/helpers_spec.rb +67 -0
- data/spec/lib/ckeditor5/rails/context/props_spec.rb +70 -0
- data/spec/lib/ckeditor5/rails/editor/editable_height_normalizer_spec.rb +50 -0
- data/spec/lib/ckeditor5/rails/editor/helpers/config_helpers_spec.rb +52 -0
- data/spec/lib/ckeditor5/rails/editor/helpers/editor_helpers_spec.rb +192 -0
- data/spec/lib/ckeditor5/rails/editor/props_inline_plugin_spec.rb +43 -0
- data/spec/lib/ckeditor5/rails/editor/props_plugin_spec.rb +66 -0
- data/spec/lib/ckeditor5/rails/editor/props_spec.rb +104 -0
- data/spec/lib/ckeditor5/rails/engine_spec.rb +88 -0
- data/spec/lib/ckeditor5/rails/hooks/form_spec.rb +203 -0
- data/spec/lib/ckeditor5/rails/hooks/simple_form_spec.rb +100 -0
- data/spec/lib/ckeditor5/rails/presets/manager_spec.rb +100 -0
- data/spec/lib/ckeditor5/rails/presets/plugins_builder_spec.rb +98 -0
- data/spec/lib/ckeditor5/rails/presets/preset_builder_spec.rb +347 -0
- data/spec/lib/ckeditor5/rails/presets/toolbar_builder_spec.rb +70 -0
- data/spec/lib/ckeditor5/rails/semver_spec.rb +58 -0
- data/spec/lib/ckeditor5/rails/version_detector_spec.rb +131 -0
- data/spec/lib/ckeditor5/rails/version_spec.rb +25 -0
- data/spec/spec_helper.rb +8 -2
- data/spec/support/test_models.rb +6 -0
- 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
|