('input[name="url"]')! }
}
describe('J3 rel checkboxes', () => {
it('enable for an absolute http(s) URL and disable again for an internal one', () => {
const { box, url } = openLink('Partner')
for (const token of ['nofollow', 'sponsored', 'ugc']) expect(box(token).disabled, token).toBe(true)
fill(url, 'https://partner.test')
for (const token of ['nofollow', 'sponsored', 'ugc']) expect(box(token).disabled, token).toBe(false)
box('ugc').checked = true
fill(url, '/blog/partner')
expect(box('ugc').disabled).toBe(true)
})
it('writes only the checked tokens, in order, for an external link', () => {
const { el, box, url, linkForm } = openLink('Partner')
fill(url, 'https://partner.test/x')
box('ugc').checked = true
box('nofollow').checked = true
click(linkForm.querySelector('[data-action="apply"]'))
expect(el.value).toMatch(/^Partner<\/a><\/p>$/)
})
it('writes no rel for an internal link even when a box was checked', () => {
const { el, box, url, linkForm } = openLink('Partner')
fill(url, 'https://partner.test')
box('sponsored').checked = true
fill(url, '/oferta')
click(linkForm.querySelector('[data-action="apply"]'))
expect(el.value).toBe('Partner
')
})
})
describe('J3 generic link text', () => {
it('warns for a listed text in any case or punctuation and stays quiet otherwise', () => {
const generic = openLink('Czytaj więcej…')
expect(generic.linkForm.querySelector('[data-warning]')!.hidden).toBe(false)
fill(generic.url, '/blog/a')
click(generic.linkForm.querySelector('[data-action="apply"]'))
expect(generic.el.value).toBe('Czytaj więcej…
')
document.body.replaceChildren()
const specific = openLink('Badania nad chagą')
expect(specific.linkForm.querySelector('[data-warning]')!.hidden).toBe(true)
})
it('reads external URLs by scheme only', () => {
for (const [u, want] of [
['https://a.test/x?y=1', true],
['http://a.test', true],
['/kontakt', false],
['./a', false],
['ftp://a.test', false],
['javascript:alert(1)', false],
['', false],
] as const) {
expect(isExternalUrl(u), u).toBe(want)
}
})
})
describe('J4 file names', () => {
it('follows the slug rule examples', () => {
for (const [name, want] of [
['Chaga – zdjęcie 1.JPEG', 'chaga-zdjecie-1.jpeg'],
[' Kurki w koszyku .png', 'kurki-w-koszyku.png'],
['IMG_2024.06.01.webp', 'img-2024-06-01.webp'],
['___.gif', 'image.gif'],
['bez-rozszerzenia', 'bez-rozszerzenia'],
] as const) {
expect(mediaFileName(name), name).toBe(want)
}
expect(slugFileStem('Łódź & Kraków')).toBe('lodz-krakow')
expect(slugFileStem('--a--b--')).toBe('a-b')
})
it('clears and locks the alt of a decorative image and frees it again', () => {
const { el } = mount('', { options: ON })
const input = el.querySelector('input[type="file"]')!
Object.defineProperty(input, 'files', { value: [new File([new Uint8Array([137, 80, 78, 71])], 'linia.png', { type: 'image/png' })], configurable: true })
input.dispatchEvent(new Event('change'))
const imageForm = form(el, 'image')!
const alt = imageForm.querySelector('input[name="alt"]')!
const decorative = imageForm.querySelector('input[name="decorative"]')!
fill(alt, 'Linia')
decorative.checked = true
decorative.dispatchEvent(new Event('change'))
expect(alt.value).toBe('')
expect(alt.disabled).toBe(true)
decorative.checked = false
decorative.dispatchEvent(new Event('change'))
expect(alt.disabled).toBe(false)
chooseImage(el, { alt: 'Linia' })
})
})