文件
mynode/packages/renderer/MdToHtml/createEventHandlingAttrs.test.ts
chen 301194963b
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
feat: Initial clean release of CHM
2026-11-04 11:29:39 +08:00

113 行
3.4 KiB
TypeScript

/**
* @jest-environment jsdom
*/
import createEventHandlingAttrs, { createEventHandlingListeners, Options } from './createEventHandlingAttrs';
import { describe, beforeAll, it, jest, expect, test } from '@jest/globals';
describe('createEventHandlingAttrs', () => {
let lastMessage: string|undefined = undefined;
const postMessageFn = (message: string) => {
lastMessage = message;
};
beforeAll(() => {
lastMessage = undefined;
jest.useFakeTimers();
});
it('should not create listeners to handle long-press when long press is disabled', () => {
const options: Options = {
enableLongPress: false,
postMessageSyntax: 'postMessageFn',
enableEditPopup: false,
};
const listeners = createEventHandlingListeners('someresourceid', options, 'postMessage("click")');
// Should not add touchstart/mouseenter/leave listeners when not creating
// an edit popup or long-pressing.
expect(listeners.onmouseenter).toBe('');
expect(listeners.onmouseleave).toBe('');
expect(listeners.ontouchstart).toBe('');
expect(listeners.ontouchmove).toBe('');
expect(listeners.ontouchend).toBe('');
expect(listeners.ontouchcancel).toBe('');
});
it('should create click listener for given click action', () => {
const options: Options = {
enableLongPress: false,
postMessageSyntax: 'postMessageFn',
enableEditPopup: false,
};
const clickAction = 'postMessageFn("click")';
const listeners = createEventHandlingListeners('someresourceid', options, clickAction);
expect(listeners.onclick).toContain(clickAction);
postMessageFn('test');
eval(listeners.onclick);
expect(lastMessage).toBe('click');
});
it('should create ontouch listeners for long press', () => {
const options: Options = {
enableLongPress: true,
postMessageSyntax: 'postMessageFn',
enableEditPopup: false,
};
const clickAction: null|string = null;
const listeners = createEventHandlingListeners('resourceidhere', options, clickAction);
expect(listeners.onclick).toBe('');
expect(listeners.ontouchstart).not.toBe('');
// Clear lastMessage
postMessageFn('test');
eval(listeners.ontouchstart);
jest.advanceTimersByTime(1000 * 4);
expect(lastMessage).toBe('longclick:resourceidhere');
});
it('motion during a long press should cancel the timeout', () => {
const options: Options = {
enableLongPress: true,
postMessageSyntax: 'postMessageFn',
enableEditPopup: false,
};
const listeners = createEventHandlingListeners('id', options, null);
lastMessage = '';
eval(listeners.ontouchstart);
jest.advanceTimersByTime(100);
eval(listeners.ontouchmove);
jest.advanceTimersByTime(1000 * 100);
// Message handler should not have been called.
expect(lastMessage).toBe('');
});
test.each([
'"',
'"',
'"',
])('should not allow an entity sequence in the click action to break out of the attribute (case %#)', (entity) => {
const options: Options = {
enableLongPress: true,
postMessageSyntax: 'postMessageFn',
enableEditPopup: false,
};
const clickAction = `postMessageFn("joplin://resourceid#${entity});canary=1;//")`;
const attrs = createEventHandlingAttrs('resourceid', options, clickAction);
const container = document.createElement('div');
container.innerHTML = `<a ${attrs}>link</a>`;
const onclick = container.querySelector('a').getAttribute('onclick');
expect(onclick).not.toContain('");canary=1');
expect(onclick).toContain(entity);
});
});