// The imported-post resave contract at the element layer (Phase 16.2 D-03,
// D-07; todo journal-imported-html-admin-resave): a value the administrator
// does not touch comes back as the exact served string, even after the
// Source tab and the preview were opened and closed, and the element
// announces nothing.
import { afterEach, describe, expect, it, vi } from 'vitest'
import fixture from './fixtures/imported-post.html?raw'
import { button, click, mount } from './helpers'
afterEach(() => {
vi.useRealTimers()
document.body.replaceChildren()
})
// What the server serves for a markdown post (D-07): its content_html, as
// goldmark rendered it at import, with the raw author footer and a trailing
// newline.
const markdownContentHTML =
'
Nagłówek
\n' +
'Tekst z kursywą i pogrubieniem.
\n' +
'\n' +
'\nCytat
\n
\n' +
'źródło
\n' +
'\n'
const samples: [string, string][] = [
['the imported HTML post', fixture],
['a markdown post served as content_html', markdownContentHTML],
['HTML with leading white space and a comment', '\n \na b
\n'],
['an empty value', ''],
]
function tab(el: HTMLElement, name: 'wysiwyg' | 'source'): HTMLButtonElement {
const found = el.querySelector(`button[data-tab="${name}"]`)
if (!found) throw new Error(`no ${name} tab`)
return found
}
describe('untouched value (D-03)', () => {
it.each(samples)('returns %s unchanged after a Source tab round trip', (_name, served) => {
const { el, changes } = mount(served)
expect(el.value).toBe(served)
el.showSource(true)
expect(el.querySelector('textarea')!.value).toBe(served)
expect(el.value).toBe(served)
el.showSource(false)
expect(el.value).toBe(served)
expect(changes).toEqual([])
})
it.each(samples)('returns %s unchanged after the tab buttons are clicked', (_name, served) => {
const { el, changes } = mount(served)
click(tab(el, 'source'))
expect(tab(el, 'source').getAttribute('aria-selected')).toBe('true')
click(tab(el, 'wysiwyg'))
click(tab(el, 'source'))
click(tab(el, 'wysiwyg'))
expect(tab(el, 'wysiwyg').getAttribute('aria-selected')).toBe('true')
expect(el.value).toBe(served)
expect(changes).toEqual([])
})
it.each(samples)('returns %s unchanged when the value is set after connect and echoed', (_name, served) => {
const { el, changes } = mount()
el.value = served
el.showSource(true)
el.showSource(false)
// The SPA writes the form value back only when it differs; an echo of
// the same string must change nothing.
el.value = el.value
expect(el.value).toBe(served)
expect(changes).toEqual([])
})
it('returns the imported post unchanged after the preview is opened and closed', () => {
vi.useFakeTimers()
const { el, changes } = mount(fixture)
click(button(el, 'preview'))
vi.advanceTimersByTime(1000)
click(button(el, 'preview'))
el.showSource(true)
el.showSource(false)
expect(el.value).toBe(fixture)
expect(changes).toEqual([])
})
it('returns the imported post unchanged after a detach and a new attach', () => {
const { el, changes } = mount(fixture)
el.remove()
expect(el.value).toBe(fixture)
document.body.append(el)
expect(el.value).toBe(fixture)
expect(changes).toEqual([])
})
it('reports an edit in the Source tab once and keeps the edited text exactly', () => {
const { el, changes } = mount(fixture)
el.showSource(true)
const textarea = el.querySelector('textarea')!
const edited = fixture.replace('', ' (edytowane)')
expect(edited).not.toBe(fixture)
textarea.value = edited
textarea.dispatchEvent(new Event('input'))
el.showSource(false)
expect(el.value).toBe(edited)
expect(changes).toEqual([edited])
})
})