import { fixture, expect } from '@open-wc/testing';
import { html } from 'lit';
import '../index';
import { TextSelection } from 'prosemirror-state';
import type { NileWysiwygEditor } from './nile-wysiwyg-editor';
async function editorFixture(template = html``) {
const el = await fixture(template);
await el.updateComplete;
return el;
}
/** A compact table-based email with cell padding and a 600px container. */
const EMAIL_FIXTURE =
'
' +
'
' +
'
' +
'
' +
'
Company Name
' +
'
' +
'
' +
'
Hello there.
' +
'
' +
'
';
/** A full standalone HTML document, the kind that lands in text/plain. */
const FULL_DOC =
'' +
'
Pasted cell
' +
'';
/** Fire a paste through the ProseMirror view's handlePaste prop. */
function firePaste(el: NileWysiwygEditor, data: Record) {
const view = el.pmView!;
const dt = new DataTransfer();
for (const [type, value] of Object.entries(data)) dt.setData(type, value);
const event = new ClipboardEvent('paste', { clipboardData: dt });
return view.someProp('handlePaste', f => f(view, event, view.state.tr.doc.slice(0)));
}
describe('nile-wysiwyg-editor email-fidelity: property reflection', () => {
it('1. defaults emailFidelity to false', async () => {
const el = await editorFixture();
expect(el.emailFidelity).to.equal(false);
expect(el.hasAttribute('email-fidelity')).to.equal(false);
});
it('2. reflects the property to the kebab attribute', async () => {
const el = await editorFixture();
el.emailFidelity = true;
await el.updateComplete;
expect(el.hasAttribute('email-fidelity')).to.equal(true);
});
it('3. reads the attribute into the property', async () => {
const el = await editorFixture(
html``
);
expect(el.emailFidelity).to.equal(true);
});
});
describe('nile-wysiwyg-editor email-fidelity: value parsing', () => {
it('4. keeps cell padding in value with the flag on', async () => {
const el = await editorFixture(
html``
);
el.value = EMAIL_FIXTURE;
await el.updateComplete;
const doc = new DOMParser().parseFromString(el.value, 'text/html');
const padded = Array.from(doc.querySelectorAll('td')).some(
td => td.style.padding !== '' || td.style.paddingTop !== ''
);
expect(padded, 'a td keeps padding').to.equal(true);
});
it('5. strips cell padding in value with the flag off', async () => {
const el = await editorFixture();
el.value = EMAIL_FIXTURE;
await el.updateComplete;
expect(el.value).to.not.include('padding');
});
it('6. re-parses value when the flag toggles on', async () => {
const el = await editorFixture();
el.value = EMAIL_FIXTURE;
await el.updateComplete;
expect(el.value).to.not.include('padding');
el.emailFidelity = true;
el.value = EMAIL_FIXTURE;
await el.updateComplete;
expect(el.value).to.match(/padding/);
});
});
describe('nile-wysiwyg-editor email-fidelity: paste', () => {
it('7. parses a text/plain-only HTML document when the flag is on', async () => {
const el = await editorFixture(
html``
);
const handled = firePaste(el, { 'text/plain': FULL_DOC });
expect(handled).to.equal(true);
await el.updateComplete;
expect(el.getHTML()).to.include('
{
const el = await editorFixture();
firePaste(el, { 'text/plain': FULL_DOC });
await el.updateComplete;
// No real table node — the markup is kept as literal text.
expect(el.getHTML()).to.not.include('