feat: Support image resize in message signature (#8042)

This commit is contained in:
Sivin Varghese
2023-10-09 13:20:12 +05:30
committed by GitHub
parent 26e8877cd9
commit 86ca90aa15
9 changed files with 371 additions and 183 deletions

View File

@@ -6,6 +6,8 @@ import {
cleanSignature,
extractTextFromMarkdown,
insertAtCursor,
findNodeToInsertImage,
setURLWithQueryAndSize,
} from '../editorHelper';
import { EditorState } from 'prosemirror-state';
import { EditorView } from 'prosemirror-view';
@@ -273,3 +275,167 @@ describe('insertAtCursor', () => {
expect(editorView.state.doc.firstChild.firstChild.text).toBe('Hello Me');
});
});
describe('findNodeToInsertImage', () => {
let mockEditorState;
beforeEach(() => {
mockEditorState = {
selection: {
$from: {
node: jest.fn(() => ({})),
},
from: 0,
},
schema: {
nodes: {
image: {
create: jest.fn(attrs => ({ type: { name: 'image' }, attrs })),
},
paragraph: {
create: jest.fn((_, node) => ({
type: { name: 'paragraph' },
content: [node],
})),
},
},
},
};
});
it('should insert image directly into an empty paragraph', () => {
const mockNode = {
type: { name: 'paragraph' },
content: { size: 0, content: [] },
};
mockEditorState.selection.$from.node.mockReturnValueOnce(mockNode);
const result = findNodeToInsertImage(mockEditorState, 'image-url');
expect(result).toEqual({
node: { type: { name: 'image' }, attrs: { src: 'image-url' } },
pos: 0,
});
});
it('should insert image directly into a paragraph without an image but with other content', () => {
const mockNode = {
type: { name: 'paragraph' },
content: {
size: 1,
content: [
{
type: { name: 'text' },
},
],
},
};
mockEditorState.selection.$from.node.mockReturnValueOnce(mockNode);
mockEditorState.selection.from = 1;
const result = findNodeToInsertImage(mockEditorState, 'image-url');
expect(result).toEqual({
node: { type: { name: 'image' }, attrs: { src: 'image-url' } },
pos: 2, // Because it should insert after the text, on a new line.
});
});
it("should wrap image in a new paragraph when the current node isn't a paragraph", () => {
const mockNode = {
type: { name: 'not-a-paragraph' },
content: { size: 0, content: [] },
};
mockEditorState.selection.$from.node.mockReturnValueOnce(mockNode);
const result = findNodeToInsertImage(mockEditorState, 'image-url');
expect(result.node.type.name).toBe('paragraph');
expect(result.node.content[0].type.name).toBe('image');
expect(result.node.content[0].attrs.src).toBe('image-url');
expect(result.pos).toBe(0);
});
it('should insert a new image directly into the paragraph that already contains an image', () => {
const mockNode = {
type: { name: 'paragraph' },
content: {
size: 1,
content: [
{
type: { name: 'image', attrs: { src: 'existing-image-url' } },
},
],
},
};
mockEditorState.selection.$from.node.mockReturnValueOnce(mockNode);
mockEditorState.selection.from = 1;
const result = findNodeToInsertImage(mockEditorState, 'image-url');
expect(result.node.type.name).toBe('image');
expect(result.node.attrs.src).toBe('image-url');
expect(result.pos).toBe(1);
});
});
describe('setURLWithQueryAndSize', () => {
let selectedNode;
let editorView;
beforeEach(() => {
selectedNode = {
setAttribute: jest.fn(),
};
const tr = {
setNodeMarkup: jest.fn().mockReturnValue({
docChanged: true,
}),
};
const state = {
selection: { from: 0 },
tr,
};
editorView = {
state,
dispatch: jest.fn(),
};
});
it('updates the URL with the given size and updates the editor view', () => {
const size = { height: '20px' };
setURLWithQueryAndSize(selectedNode, size, editorView);
// Check if the editor view is updated
expect(editorView.dispatch).toHaveBeenCalledTimes(1);
});
it('updates the URL with the given size and updates the editor view with original size', () => {
const size = { height: 'auto' };
setURLWithQueryAndSize(selectedNode, size, editorView);
// Check if the editor view is updated
expect(editorView.dispatch).toHaveBeenCalledTimes(1);
});
it('does not update the editor view if the document has not changed', () => {
editorView.state.tr.setNodeMarkup = jest.fn().mockReturnValue({
docChanged: false,
});
const size = { height: '20px' };
setURLWithQueryAndSize(selectedNode, size, editorView);
// Check if the editor view dispatch was not called
expect(editorView.dispatch).not.toHaveBeenCalled();
});
it('does not perform any operations if selectedNode is not provided', () => {
setURLWithQueryAndSize(null, { height: '20px' }, editorView);
// Ensure the dispatch method wasn't called
expect(editorView.dispatch).not.toHaveBeenCalled();
});
});