Fanu2's picture
Deploy full app to HF Space
b456468
import { fabric } from 'fabric';
import ImageEditor from '@/imageEditor';
import '@/command/loadImage';
describe('UI', () => {
let actions, imageEditorMock, mockImage;
beforeEach(() => {
imageEditorMock = new ImageEditor(document.createElement('div'), {
includeUI: {
loadImage: false,
initMenu: 'flip',
menuBarPosition: 'bottom',
applyCropSelectionStyle: true,
},
});
actions = imageEditorMock.getActions();
mockImage = new fabric.Image();
imageEditorMock._graphics.setCanvasImage('mockImage', mockImage);
});
describe('mainAction', () => {
let mainAction;
beforeEach(() => {
mainAction = actions.main;
});
it('should be executed When the initLoadImage action occurs', async () => {
const loadImageFromURLSpy = jest
.spyOn(imageEditorMock, 'loadImageFromURL')
.mockReturnValue(Promise.resolve(300));
const clearUndoStackSpy = jest.spyOn(imageEditorMock, 'clearUndoStack');
const resizeEditorSpy = jest.spyOn(imageEditorMock.ui, 'resizeEditor');
await mainAction.initLoadImage('path', 'imageName');
expect(loadImageFromURLSpy).toHaveBeenCalled();
expect(clearUndoStackSpy).toHaveBeenCalled();
expect(resizeEditorSpy).toHaveBeenCalled();
});
it('should be executed When the undo action occurs', () => {
jest.spyOn(imageEditorMock, 'isEmptyUndoStack').mockReturnValue(false);
const undoSpy = jest.spyOn(imageEditorMock, 'undo').mockReturnValue({ then: () => {} });
mainAction.undo();
expect(undoSpy).toHaveBeenCalled();
});
it('should be executed When the redo action occurs', () => {
jest.spyOn(imageEditorMock, 'isEmptyRedoStack').mockReturnValue(false);
const redoSpy = jest.spyOn(imageEditorMock, 'redo').mockReturnValue({ then: () => {} });
mainAction.redo();
expect(redoSpy).toHaveBeenCalled();
});
it('should be executed When the delete action occurs', () => {
imageEditorMock.activeObjectId = 10;
imageEditorMock.removeActiveObject = jest.fn();
mainAction.delete();
expect(imageEditorMock.removeActiveObject).toHaveBeenCalled();
expect(imageEditorMock.activeObjectId).toBeNull();
});
it('should be run and the enabled state should be changed When the deleteAll action occurs', () => {
imageEditorMock.clearObjects = jest.fn();
const changeHelpButtonEnabledSpy = jest.spyOn(imageEditorMock.ui, 'changeHelpButtonEnabled');
mainAction.deleteAll();
expect(imageEditorMock.clearObjects).toHaveBeenCalled();
expect(changeHelpButtonEnabledSpy).toHaveBeenNthCalledWith(1, 'delete', false);
expect(changeHelpButtonEnabledSpy).toHaveBeenNthCalledWith(2, 'deleteAll', false);
});
it('should be executed When the load action occurs', async () => {
const loadImageFromFileSpy = jest
.spyOn(imageEditorMock, 'loadImageFromFile')
.mockReturnValue(Promise.resolve());
const clearUndoStackSpy = jest.spyOn(imageEditorMock, 'clearUndoStack');
const resizeEditorSpy = jest.spyOn(imageEditorMock.ui, 'resizeEditor');
global.URL.createObjectURL = jest.fn();
await mainAction.load();
expect(loadImageFromFileSpy).toHaveBeenCalled();
expect(clearUndoStackSpy).toHaveBeenCalled();
expect(resizeEditorSpy).toHaveBeenCalled();
});
});
describe('shapeAction', () => {
let shapeAction;
beforeEach(() => {
shapeAction = actions.shape;
});
it('should be executed When the changeShape action occurs', () => {
imageEditorMock.activeObjectId = 10;
imageEditorMock.changeShape = jest.fn();
shapeAction.changeShape({ strokeWidth: '#000000' });
expect(imageEditorMock.changeShape).toHaveBeenCalledWith(
10,
{ strokeWidth: '#000000' },
undefined
);
});
it('should be executed When the setDrawingShape action occurs', () => {
imageEditorMock.setDrawingShape = jest.fn();
shapeAction.setDrawingShape();
expect(imageEditorMock.setDrawingShape).toHaveBeenCalled();
});
});
describe('cropAction', () => {
let cropAction;
beforeEach(() => {
cropAction = actions.crop;
});
it('should be executed when the crop action occurs', async () => {
const getCropzoneRectSpy = jest
.spyOn(imageEditorMock, 'getCropzoneRect')
.mockReturnValue(true);
const cropSpy = jest.spyOn(imageEditorMock, 'crop').mockReturnValue(Promise.resolve());
const stopDrawingModeSpy = jest.spyOn(imageEditorMock, 'stopDrawingMode');
imageEditorMock.ui.changeMenu = jest.fn();
await cropAction.crop();
expect(getCropzoneRectSpy).toHaveBeenCalled();
expect(cropSpy).toHaveBeenCalled();
expect(stopDrawingModeSpy).toHaveBeenCalled();
});
it('should be executed When the cancel action occurs', () => {
const stopDrawingModeSpy = jest.spyOn(imageEditorMock, 'stopDrawingMode');
imageEditorMock.ui.changeMenu = jest.fn();
cropAction.cancel();
expect(stopDrawingModeSpy).toHaveBeenCalled();
expect(imageEditorMock.ui.changeMenu).toHaveBeenCalled();
});
});
describe('flipAction', () => {
let flipAction;
beforeEach(() => {
flipAction = actions.flip;
});
it('should be executed When the flip(flipType) action occurs', () => {
imageEditorMock.flipX = jest.fn();
imageEditorMock.flipY = jest.fn();
flipAction.flip('flipX');
expect(imageEditorMock.flipX).toHaveBeenCalled();
flipAction.flip('flipY');
expect(imageEditorMock.flipY).toHaveBeenCalled();
});
});
describe('rotateAction', () => {
let rotateAction;
beforeEach(() => {
rotateAction = actions.rotate;
});
it('should be executed When the rotate action occurs', () => {
const resizeEditorSpy = jest.spyOn(imageEditorMock.ui, 'resizeEditor');
imageEditorMock.rotate = jest.fn();
rotateAction.rotate(30);
expect(imageEditorMock.rotate).toHaveBeenCalledWith(30, undefined);
expect(resizeEditorSpy).toHaveBeenCalled();
});
it('should be executed When the setAngle action occurs', () => {
const resizeEditorSpy = jest.spyOn(imageEditorMock.ui, 'resizeEditor');
imageEditorMock.setAngle = jest.fn();
rotateAction.setAngle(30);
expect(imageEditorMock.setAngle).toHaveBeenCalledWith(30, undefined);
expect(resizeEditorSpy).toHaveBeenCalled();
});
});
describe('textAction', () => {
let textAction;
beforeEach(() => {
textAction = actions.text;
});
it('should be executed When the changeTextStyle action occurs', () => {
imageEditorMock.activeObjectId = 10;
imageEditorMock.changeTextStyle = jest.fn();
textAction.changeTextStyle({ fontSize: 10 });
expect(imageEditorMock.changeTextStyle).toHaveBeenCalledWith(10, { fontSize: 10 }, undefined);
});
});
describe('maskAction', () => {
let maskAction;
beforeEach(() => {
maskAction = actions.mask;
});
it('should be executed When the applyFilter action occurs', () => {
imageEditorMock.activeObjectId = 10;
imageEditorMock.applyFilter = jest.fn();
jest.spyOn(imageEditorMock, 'applyFilter');
maskAction.applyFilter();
expect(imageEditorMock.applyFilter).toHaveBeenCalledWith('mask', { maskObjId: 10 });
});
});
describe('drawAction', () => {
let drawAction;
beforeEach(() => {
drawAction = actions.draw;
});
it('should be executed When the setDrawMode("free") action occurs', () => {
imageEditorMock.startDrawingMode = jest.fn();
drawAction.setDrawMode('free');
expect(imageEditorMock.startDrawingMode).toHaveBeenCalledWith('FREE_DRAWING', undefined);
});
it('should be executed When the setColor() action occurs', () => {
imageEditorMock.setBrush = jest.fn();
drawAction.setColor('#000000');
expect(imageEditorMock.setBrush).toBeCalledWith({ color: '#000000' });
});
});
describe('iconAction', () => {
let iconAction;
beforeEach(() => {
iconAction = actions.icon;
});
it('should run drawing mode when the add icon occurs', () => {
const startDrawingModeSpy = jest.spyOn(imageEditorMock, 'startDrawingMode');
const setDrawingIconSpy = jest.spyOn(imageEditorMock, 'setDrawingIcon');
iconAction.addIcon('iconTypeA', '#fff');
expect(startDrawingModeSpy).toHaveBeenCalledWith('ICON');
expect(setDrawingIconSpy).toHaveBeenCalledWith('iconTypeA', '#fff');
});
});
describe('filterAction', () => {
let filterAction;
beforeEach(() => {
filterAction = actions.filter;
});
it('should be executed When the type of applyFilter is false', () => {
imageEditorMock.removeFilter = jest.fn();
jest.spyOn(imageEditorMock, 'hasFilter').mockReturnValue(true);
filterAction.applyFilter(false, {});
expect(imageEditorMock.removeFilter).toHaveBeenCalled();
});
it('should be executed When the type of applyFilter is true', () => {
imageEditorMock.applyFilter = jest.fn();
filterAction.applyFilter(true, {});
expect(imageEditorMock.applyFilter).toHaveBeenCalled();
});
});
describe('commonAction', () => {
it('should return to the getActions method must contain commonAction.', () => {
['shape', 'crop', 'flip', 'rotate', 'text', 'mask', 'draw', 'icon', 'filter'].forEach(
(submenu) => {
expect(actions[submenu].modeChange).toBeDefined();
expect(actions[submenu].deactivateAll).toBeDefined();
expect(actions[submenu].changeSelectableAll).toBeDefined();
expect(actions[submenu].discardSelection).toBeDefined();
expect(actions[submenu].stopDrawingMode).toBeDefined();
}
);
});
describe('modeChange()', () => {
let commonAction;
beforeEach(() => {
commonAction = actions.main;
});
it('should be executed When the modeChange("text") action occurs', () => {
const changeActivateModeSpy = jest.spyOn(imageEditorMock, '_changeActivateMode');
commonAction.modeChange('text');
expect(changeActivateModeSpy).toHaveBeenCalledWith('TEXT');
});
it('should be executed When the modeChange("crop") action occurs', () => {
const startDrawingModeSpy = jest.spyOn(imageEditorMock, 'startDrawingMode');
commonAction.modeChange('crop');
expect(startDrawingModeSpy).toHaveBeenCalledWith('CROPPER');
});
it('should be executed When the modeChange("shape") action occurs', () => {
const setDrawingShapeSpy = jest.spyOn(imageEditorMock, 'setDrawingShape');
const changeActivateModeSpy = jest.spyOn(imageEditorMock, '_changeActivateMode');
commonAction.modeChange('shape');
expect(setDrawingShapeSpy).toHaveBeenCalled();
expect(changeActivateModeSpy).toHaveBeenCalledWith('SHAPE');
});
});
});
describe('reAction', () => {
let changeHelpButtonEnabledSpy;
beforeEach(() => {
imageEditorMock.setReAction();
changeHelpButtonEnabledSpy = jest.spyOn(imageEditorMock.ui, 'changeHelpButtonEnabled');
});
describe('undoStackChanged', () => {
it('should be true if the undo stack has a length greater than zero', () => {
imageEditorMock.fire('undoStackChanged', 1);
expect(changeHelpButtonEnabledSpy).toHaveBeenNthCalledWith(1, 'undo', true);
expect(changeHelpButtonEnabledSpy).toHaveBeenNthCalledWith(2, 'reset', true);
});
it('should be false if the undo stack has a length of 0', () => {
imageEditorMock.fire('undoStackChanged', 0);
expect(changeHelpButtonEnabledSpy).toHaveBeenNthCalledWith(1, 'undo', false);
expect(changeHelpButtonEnabledSpy).toHaveBeenNthCalledWith(2, 'reset', false);
});
});
describe('redoStackChanged', () => {
it('should be true if the redo stack is greater than 0 length', () => {
imageEditorMock.fire('redoStackChanged', 1);
expect(changeHelpButtonEnabledSpy).toHaveBeenNthCalledWith(1, 'redo', true);
});
it('should be false if the redo stack has a length of 0', () => {
imageEditorMock.fire('redoStackChanged', 0);
expect(changeHelpButtonEnabledSpy).toHaveBeenNthCalledWith(1, 'redo', false);
});
});
describe('objectActivated', () => {
it('should be enabled when objectActivated occurs', () => {
imageEditorMock.fire('objectActivated', { id: 1 });
expect(changeHelpButtonEnabledSpy).toHaveBeenNthCalledWith(1, 'delete', true);
expect(changeHelpButtonEnabledSpy).toHaveBeenNthCalledWith(2, 'deleteAll', true);
});
it('should be enabled when objectActivated target is cropzone', () => {
const changeApplyButtonStatusSpy = jest.spyOn(
imageEditorMock.ui.crop,
'changeApplyButtonStatus'
);
imageEditorMock.fire('objectActivated', { id: 1, type: 'cropzone' });
expect(changeApplyButtonStatusSpy).toHaveBeenCalledWith(true);
});
it('should be changed to shape if the target of objectActivated is shape and the existing menu is not shape', () => {
imageEditorMock.ui.submenu = 'crop';
imageEditorMock.ui.changeMenu = jest.fn();
imageEditorMock.ui.shape.setShapeStatus = jest.fn();
const setMaxStrokeValueSpy = jest.spyOn(imageEditorMock.ui.shape, 'setMaxStrokeValue');
imageEditorMock.fire('objectActivated', { id: 1, type: 'circle' });
expect(imageEditorMock.ui.changeMenu).toHaveBeenCalledWith('shape', false, false);
expect(setMaxStrokeValueSpy).toHaveBeenCalled();
});
it('should be changed to text if the target of objectActivated is text and the existing menu is not text', () => {
imageEditorMock.ui.submenu = 'crop';
imageEditorMock.ui.changeMenu = jest.fn();
imageEditorMock.fire('objectActivated', { id: 1, type: 'i-text' });
expect(imageEditorMock.ui.changeMenu).toHaveBeenCalledWith('text', false, false);
});
it('should be changed to icon if the target of objectActivated is icon and the existing menu is not icon', () => {
imageEditorMock.ui.submenu = 'crop';
imageEditorMock.ui.changeMenu = jest.fn();
const setIconPickerColorSpy = jest.spyOn(imageEditorMock.ui.icon, 'setIconPickerColor');
imageEditorMock.fire('objectActivated', { id: 1, type: 'icon' });
expect(imageEditorMock.ui.changeMenu).toHaveBeenCalledWith('icon', false, false);
expect(setIconPickerColorSpy).toHaveBeenCalled();
});
});
describe('addObjectAfter', () => {
it('should be changed to match the size of the added object when addObjectAfter occurs', () => {
const setMaxStrokeValueSpy = jest.spyOn(imageEditorMock.ui.shape, 'setMaxStrokeValue');
imageEditorMock.ui.shape.changeStandbyMode = jest.fn();
imageEditorMock.fire('addObjectAfter', { type: 'circle', width: 100, height: 200 });
expect(setMaxStrokeValueSpy).toHaveBeenCalledWith(100);
expect(imageEditorMock.ui.shape.changeStandbyMode).toHaveBeenCalled();
});
});
describe('objectScaled', () => {
it('should be changed if objectScaled occurs on an object of type text', () => {
imageEditorMock.ui.text.fontSize = 0;
imageEditorMock.fire('objectScaled', { type: 'i-text', fontSize: 20 });
expect(imageEditorMock.ui.text.fontSize).toBe(20);
});
it('should be changed if objectScaled is for a shape type object and strokeValue is greater than the size of the object', () => {
jest.spyOn(imageEditorMock.ui.shape, 'getStrokeValue').mockReturnValue(20);
const setStrokeValueSpy = jest.spyOn(imageEditorMock.ui.shape, 'setStrokeValue');
imageEditorMock.fire('objectScaled', { type: 'rect', width: 10, height: 10 });
expect(setStrokeValueSpy).toHaveBeenCalledWith(10);
});
});
describe('selectionCleared', () => {
it('should be closed if selectionCleared occurs in the text menu state', () => {
imageEditorMock.ui.submenu = 'text';
const changeCursorSpy = jest.spyOn(imageEditorMock, 'changeCursor');
imageEditorMock.fire('selectionCleared');
expect(changeCursorSpy).toHaveBeenCalledWith('text');
});
});
});
});