summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_shared/components/rich_content_editor/editor_service_spec.js
blob: 16f60b5ff2154f2a2d410276ea4c77f1dea74e03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import {
  generateToolbarItem,
  addCustomEventListener,
  removeCustomEventListener,
  registerHTMLToMarkdownRenderer,
  addImage,
  getMarkdown,
  getEditorOptions,
} from '~/vue_shared/components/rich_content_editor/services/editor_service';
import buildHTMLToMarkdownRenderer from '~/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer';
import buildCustomRenderer from '~/vue_shared/components/rich_content_editor/services/build_custom_renderer';

jest.mock('~/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer');
jest.mock('~/vue_shared/components/rich_content_editor/services/build_custom_renderer');

describe('Editor Service', () => {
  let mockInstance;
  let event;
  let handler;

  beforeEach(() => {
    mockInstance = {
      eventManager: { addEventType: jest.fn(), removeEventHandler: jest.fn(), listen: jest.fn() },
      editor: { exec: jest.fn() },
      invoke: jest.fn(),
      toMarkOptions: {
        renderer: {
          constructor: {
            factory: jest.fn(),
          },
        },
      },
    };
    event = 'someCustomEvent';
    handler = jest.fn();
  });

  describe('generateToolbarItem', () => {
    const config = {
      icon: 'bold',
      command: 'some-command',
      tooltip: 'Some Tooltip',
      event: 'some-event',
    };

    const generatedItem = generateToolbarItem(config);

    it('generates the correct command', () => {
      expect(generatedItem.options.command).toBe(config.command);
    });

    it('generates the correct event', () => {
      expect(generatedItem.options.event).toBe(config.event);
    });

    it('generates a divider when isDivider is set to true', () => {
      const isDivider = true;

      expect(generateToolbarItem({ isDivider })).toBe('divider');
    });
  });

  describe('addCustomEventListener', () => {
    it('registers an event type on the instance and adds an event handler', () => {
      addCustomEventListener(mockInstance, event, handler);

      expect(mockInstance.eventManager.addEventType).toHaveBeenCalledWith(event);
      expect(mockInstance.eventManager.listen).toHaveBeenCalledWith(event, handler);
    });
  });

  describe('removeCustomEventListener', () => {
    it('removes an event handler from the instance', () => {
      removeCustomEventListener(mockInstance, event, handler);

      expect(mockInstance.eventManager.removeEventHandler).toHaveBeenCalledWith(event, handler);
    });
  });

  describe('addImage', () => {
    it('calls the exec method on the instance', () => {
      const mockImage = { imageUrl: 'some/url.png', description: 'some description' };

      addImage(mockInstance, mockImage);

      expect(mockInstance.editor.exec).toHaveBeenCalledWith('AddImage', mockImage);
    });
  });

  describe('getMarkdown', () => {
    it('calls the invoke method on the instance', () => {
      getMarkdown(mockInstance);

      expect(mockInstance.invoke).toHaveBeenCalledWith('getMarkdown');
    });
  });

  describe('registerHTMLToMarkdownRenderer', () => {
    let baseRenderer;
    const htmlToMarkdownRenderer = {};
    const extendedRenderer = {};

    beforeEach(() => {
      baseRenderer = mockInstance.toMarkOptions.renderer;
      buildHTMLToMarkdownRenderer.mockReturnValueOnce(htmlToMarkdownRenderer);
      baseRenderer.constructor.factory.mockReturnValueOnce(extendedRenderer);

      registerHTMLToMarkdownRenderer(mockInstance);
    });

    it('builds a new instance of the HTML to Markdown renderer', () => {
      expect(buildHTMLToMarkdownRenderer).toHaveBeenCalledWith(baseRenderer);
    });

    it('extends base renderer with the HTML to Markdown renderer', () => {
      expect(baseRenderer.constructor.factory).toHaveBeenCalledWith(
        baseRenderer,
        htmlToMarkdownRenderer,
      );
    });

    it('replaces the default renderer with extended renderer', () => {
      expect(mockInstance.toMarkOptions.renderer).toBe(extendedRenderer);
    });
  });

  describe('getEditorOptions', () => {
    const externalOptions = {
      customRenderers: {},
    };
    const renderer = {};

    beforeEach(() => {
      buildCustomRenderer.mockReturnValueOnce(renderer);
    });

    it('generates a configuration object with a custom HTML renderer and toolbarItems', () => {
      expect(getEditorOptions()).toHaveProp('customHTMLRenderer', renderer);
      expect(getEditorOptions()).toHaveProp('toolbarItems');
    });

    it('passes external renderers to the buildCustomRenderers function', () => {
      getEditorOptions(externalOptions);
      expect(buildCustomRenderer).toHaveBeenCalledWith(externalOptions.customRenderers);
    });
  });
});