Files
opportunities-extension/tests/dialogDrag.test.cjs

77 lines
3.7 KiB
JavaScript

const { test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const vm = require('node:vm');
const factory = vm.runInNewContext(fs.readFileSync('src/content/dialog-drag.js', 'utf8') + '\ncreateDialogDrag');
function setup({ header = false, interactive = false, unrelated = false } = {}) {
const events = {}, winEvents = {}, attrs = {}, style = {};
const panel = { style, isConnected: true, full: false,
closest: selector => selector.includes('modal') ? {} : null,
querySelector: () => title,
setAttribute: (key, value) => attrs[key] = value,
removeAttribute: key => delete attrs[key],
getClientRects: () => [1],
getBoundingClientRect() {
const left = 200 + (parseFloat(style.left) || 0), top = 150 + (parseFloat(style.top) || 0);
return { left, top, width: this.full ? 1000 : 400, height: this.full ? 800 : 300 };
}
};
const title = { closest: () => panel, setPointerCapture() {}, hasPointerCapture: () => true, releasePointerCapture() {} };
const bar = { ...title, contains: node => !unrelated && node === title };
const target = { closest: selector => selector === 'header, h2, h3' ? (header ? bar : title) : interactive ? {} : null };
const document = { documentElement: { clientWidth: 1000, clientHeight: 800 },
addEventListener: (name, fn) => events[name] = fn, querySelectorAll: () => [panel] };
const window = { addEventListener: (name, fn) => winEvents[name] = fn };
factory({ environment: { document, window } }).install();
const event = (x, y) => ({ target, button: 0, pointerId: 1, clientX: x, clientY: y, preventDefault() {} });
return { panel, events, winEvents, attrs, style, document, event };
}
test('dragging permits 70 percent overflow in every direction and stops on release', () => {
const h = setup();
h.events.pointerdown(h.event(220, 160));
h.events.pointermove(h.event(2000, 2000));
assert.equal(h.panel.getBoundingClientRect().left, 880);
assert.equal(h.panel.getBoundingClientRect().top, 710);
h.events.pointermove(h.event(-2000, -2000));
assert.equal(h.panel.getBoundingClientRect().left, -280);
assert.equal(h.panel.getBoundingClientRect().top, -210);
h.events.pointerup(h.event(0, 0));
assert.equal(h.attrs['data-dialog-dragging'], undefined);
h.events.pointermove(h.event(400, 400));
assert.equal(h.panel.getBoundingClientRect().left, -280);
});
test('full-page panels do not drag', () => {
const h = setup(); h.panel.full = true;
h.events.pointerdown(h.event(220, 160));
h.events.pointermove(h.event(300, 200));
assert.equal(h.style.left, undefined);
});
test('resize keeps at least 30 percent of a moved panel inside each viewport axis', () => {
const h = setup();
h.events.pointerdown(h.event(220, 160));
h.events.pointermove(h.event(500, 400));
h.document.documentElement.clientWidth = 600;
h.document.documentElement.clientHeight = 500;
h.winEvents.resize();
assert.equal(h.panel.getBoundingClientRect().left, 480);
assert.equal(h.panel.getBoundingClientRect().top, 390);
assert.equal(h.attrs['data-dialog-dragging'], undefined);
});
test('empty title bar space starts dragging', () => {
const h = setup({ header: true });
h.events.pointerdown(h.event(220, 160));
h.events.pointermove(h.event(300, 200));
assert.equal(h.panel.getBoundingClientRect().left, 280);
assert.equal(h.panel.getBoundingClientRect().top, 190);
});
test('title bar controls and content headers do not start dragging', () => {
for (const options of [{ header: true, interactive: true }, { header: true, unrelated: true }]) {
const h = setup(options);
h.events.pointerdown(h.event(220, 160));
h.events.pointermove(h.event(300, 200));
assert.equal(h.style.left, undefined);
}
});