const assert = require('assert/strict'); const linkReplacer = require('../lib/link-replacer'); const html5parser = require('html5parser'); const sinon = require('sinon'); describe('LinkReplacementService', function () { afterEach(function () { sinon.restore(); }); it('exported', function () { assert.equal(require('../index'), linkReplacer); }); describe('replace', function () { it('Can replace to URL', async function () { const html = 'link'; const expected = 'link'; const replaced = await linkReplacer.replace(html, () => new URL('https://google.com/test-dir?test-query')); assert.equal(replaced, expected); }); it('Can replace relative URLs', async function () { const html = 'link'; const expected = 'link'; const replaced = await linkReplacer.replace(html, u => u, {base: 'https://google.com/test-dir/'}); assert.equal(replaced, expected); }); it('Can replace relative URLs relative to root domain', async function () { const html = 'link'; const expected = 'link'; const replaced = await linkReplacer.replace(html, u => u, {base: 'https://google.com/test-dir/'}); assert.equal(replaced, expected); }); it('Can replace fragments relative to base', async function () { const html = 'link'; const expected = 'link'; const replaced = await linkReplacer.replace(html, u => u, {base: 'https://google.com/test-dir/'}); assert.equal(replaced, expected); }); it('Doesn\'t break weird &map', async function () { // Refs https://github.com/TryGhost/Team/issues/2666: somehow this gets replaced with https://example.com/test.jpg?test=true↦id=de76 if decoding entities is enabled const html = ''; const expected = ''; const replaced = await linkReplacer.replace(html, () => new URL('https://google.com/test-dir?test-query')); assert.equal(replaced, expected); }); it('Does not escape HTML characters', async function () { const html = 'This is a test & this \'should\' not "be" escaped'; const replaced = await linkReplacer.replace(html, () => new URL('https://google.com/test-dir?test-query')); assert.equal(replaced, html); }); it('Does escape HTML characters within a link\'s href', async function () { const html = 'link'; const expected = 'link'; const replaced = await linkReplacer.replace(html, url => new URL(url)); assert.equal(replaced, expected); }); it('Can replace to string', async function () { const html = 'link'; const expected = 'link'; const replaced = await linkReplacer.replace(html, () => '#valid-string'); assert.equal(replaced, expected); }); it('Ignores invalid links', async function () { const html = 'link'; const expected = 'link'; const replaced = await linkReplacer.replace(html, () => 'valid'); assert.equal(replaced, expected); }); it('Ignores parse errors', async function () { sinon.stub(html5parser, 'tokenize').throws(new Error('test')); const html = 'link'; const replaced = await linkReplacer.replace(html, () => 'valid'); assert.equal(replaced, html); }); it('Doesn\'t replace single-quote attributes with double-quote', async function () { const html = '