@silexlabs/grapesjs-symbols
Version:
Symbols for GrapesJS
148 lines (130 loc) • 5.14 kB
text/typescript
import { jest } from '@jest/globals'
import {
_addSymbol,
_removeSymbol,
_unlinkSymbolInstance,
_createSymbolInstance,
displayError
} from './SymbolsCommands'
jest.mock('./utils', () => ({
allowDrop: jest.fn(() => true),
createSymbol: jest.fn((_, comp) => ({ instances: [comp, { id: 'inst2' }] })),
deleteSymbol: jest.fn(),
unbindSymbolInstance: jest.fn()
}))
jest.mock('lit-html', () => ({
html: (...args: any[]) => args,
render: jest.fn(),
}))
jest.mock('lit-html/directives/unsafe-html.js', () => ({
unsafeHTML: (x: any) => x,
}))
describe('SymbolsCommands', () => {
let editor: any
let component: any
let symbol: any
beforeEach(() => {
component = {
setName: jest.fn(),
set: jest.fn(),
getName: jest.fn(() => 'compName'),
getId: jest.fn(() => 'compId'),
append: jest.fn((inst, _) => [inst]),
}
symbol = {
getId: jest.fn(() => 'symbolId'),
append: jest.fn((inst, _) => [inst]),
}
editor = {
getSelected: jest.fn(() => component),
Components: {
getSymbols: jest.fn(() => [symbol]),
allById: jest.fn(() => ({ parentId: symbol })),
},
Modal: {
open: jest.fn(),
close: jest.fn(),
},
select: jest.fn(),
}
})
describe('_addSymbol', () => {
it('creates a symbol with label and icon', () => {
const result = _addSymbol(editor, null, { component, label: 'lbl', icon: 'ico' })
expect(component.setName).toHaveBeenCalledWith('lbl')
expect(component.set).toHaveBeenCalledWith('icon', 'ico')
expect(result).toEqual({ instances: [component, { id: 'inst2' }] })
})
it('uses selected component if no component provided', () => {
editor.getSelected.mockReturnValue(component)
const result = _addSymbol(editor, null, { label: 'lbl', icon: 'ico' })
expect(component.setName).toHaveBeenCalledWith('lbl')
expect(component.set).toHaveBeenCalledWith('icon', 'ico')
expect(result).toEqual({ instances: [component, { id: 'inst2' }] })
})
it('usees selected component and its name if no label provided', () => {
editor.getSelected.mockReturnValue(component)
const result = _addSymbol(editor, null, {})
expect(component.setName).toHaveBeenCalledWith('compName')
expect(result).toEqual({ instances: [component, { id: 'inst2' }] })
})
it('throws if missing component', () => {
editor.getSelected.mockReturnValue(null)
expect(() => _addSymbol(editor, null, { component: undefined })).toThrow()
})
})
describe('_removeSymbol', () => {
it('removes symbol by id', async () => {
symbol.getId.mockReturnValue('symbolId')
expect(() => _removeSymbol(editor, null, { symbolId: 'symbolId' })).not.toThrow()
// deleteSymbol is called by the command
const { deleteSymbol } = await import('./utils')
expect(deleteSymbol).toHaveBeenCalledWith(editor, symbol)
})
it('throws if missing symbolId', () => {
expect(() => _removeSymbol(editor, null, { symbolId: '' })).toThrow()
})
it('throws if symbol not found', () => {
editor.Components.getSymbols.mockReturnValue([])
expect(() => _removeSymbol(editor, null, { symbolId: 'notfound' })).toThrow()
})
})
describe('_unlinkSymbolInstance', () => {
it('calls unbindSymbolInstance', async () => {
const { unbindSymbolInstance } = await import('./utils')
expect(() => _unlinkSymbolInstance(editor, null, { component })).not.toThrow()
expect(unbindSymbolInstance).toHaveBeenCalledWith(editor, component)
})
it('throws if missing component', () => {
expect(() => _unlinkSymbolInstance(editor, null, { component: null as any })).toThrow()
})
})
describe('_createSymbolInstance', () => {
beforeEach(() => {
// allowDrop returns true by default
editor.Components.allById.mockReturnValue({ parentId: symbol })
})
it('creates a symbol instance and appends it', () => {
const pos = { placement: 'after', index: 0 }
const result = _createSymbolInstance(editor, null, { symbol, pos, target: symbol })
expect(result).toEqual({ id: 'inst2' })
})
it('throws if missing params', () => {
expect(() => _createSymbolInstance(editor, null, { symbol: null as any, pos: {}, target: symbol })).toThrow()
expect(() => _createSymbolInstance(editor, null, { symbol, pos: null, target: symbol })).toThrow()
expect(() => _createSymbolInstance(editor, null, { symbol, pos: {}, target: null as any })).toThrow()
})
it('throws if parent not found', () => {
editor.Components.allById.mockReturnValue({})
expect(() => _createSymbolInstance(editor, null, { symbol, pos: {}, target: { getAttribute: () => 'parentId' } as any as HTMLElement })).toThrow()
})
})
describe('displayError', () => {
it('opens modal with error', () => {
const content = document.createElement('div')
document.body.appendChild(content)
displayError(editor, 'Title', 'Message')
expect(editor.Modal.open).toHaveBeenCalled()
})
})
})