const { expect } = require('chai')
const SandboxedModule = require('sandboxed-module')
const MODULE_PATH = require('path').join(
__dirname,
'../../../../app/src/Features/Helpers/SafeHTMLSubstitution.js'
)
describe('SafeHTMLSubstitution', function() {
let SafeHTMLSubstitution
before(function() {
SafeHTMLSubstitution = SandboxedModule.require(MODULE_PATH)
})
describe('SPLIT_REGEX', function() {
const CASES = {
'PRE<0>INNER0>POST': ['PRE', '0', 'INNER', 'POST'],
'<0>INNER0>': ['', '0', 'INNER', ''],
'<0>0>': ['', '0', '', ''],
'<0>INNER0><0>INNER20>': ['', '0', 'INNER', '', '0', 'INNER2', ''],
'<0><1>INNER1>0>': ['', '0', '<1>INNER1>', ''],
'PLAIN TEXT': ['PLAIN TEXT']
}
Object.entries(CASES).forEach(([input, output]) => {
it(`should parse "${input}" as expected`, function() {
expect(input.split(SafeHTMLSubstitution.SPLIT_REGEX)).to.deep.equal(
output
)
})
})
})
describe('render', function() {
describe('substitution', function() {
it('should substitute a single component', function() {
expect(
SafeHTMLSubstitution.render('<0>good0>', [{ name: 'b' }])
).to.equal('good')
})
it('should substitute a single component as string', function() {
expect(SafeHTMLSubstitution.render('<0>good0>', ['b'])).to.equal(
'good'
)
})
it('should substitute a single component twice', function() {
expect(
SafeHTMLSubstitution.render('<0>one0><0>two0>', [{ name: 'b' }])
).to.equal('onetwo')
})
it('should substitute two components', function() {
expect(
SafeHTMLSubstitution.render('<0>one0><1>two1>', [
{ name: 'b' },
{ name: 'i' }
])
).to.equal('onetwo')
})
it('should substitute a single component with a class', function() {
expect(
SafeHTMLSubstitution.render('<0>text0>', [
{
name: 'b',
attrs: {
class: 'magic'
}
}
])
).to.equal('text')
})
it('should substitute two nested components', function() {
expect(
SafeHTMLSubstitution.render('<0><1>nested1>0>', [
{ name: 'b' },
{ name: 'i' }
])
).to.equal('nested')
})
it('should handle links', function() {
expect(
SafeHTMLSubstitution.render('<0>Go to Login0>', [
{ name: 'a', attrs: { href: 'https://www.overleaf.com/login' } }
])
).to.equal('Go to Login')
})
it('should not complain about too many components', function() {
expect(
SafeHTMLSubstitution.render('<0>good0>', [
{ name: 'b' },
{ name: 'i' },
{ name: 'u' }
])
).to.equal('good')
})
})
describe('pug.escape', function() {
it('should handle plain text', function() {
expect(SafeHTMLSubstitution.render('plain text')).to.equal('plain text')
})
it('should keep a simple string delimiter', function() {
expect(SafeHTMLSubstitution.render("'")).to.equal(`'`)
})
it('should escape double quotes', function() {
expect(SafeHTMLSubstitution.render('"')).to.equal(`"`)
})
it('should escape &', function() {
expect(SafeHTMLSubstitution.render('&')).to.equal(`&`)
})
it('should escape <', function() {
expect(SafeHTMLSubstitution.render('<')).to.equal(`<`)
})
it('should escape >', function() {
expect(SafeHTMLSubstitution.render('>')).to.equal(`>`)
})
it('should escape html', function() {
expect(SafeHTMLSubstitution.render('bad')).to.equal(
'<b>bad</b>'
)
})
})
describe('escape around substitutions', function() {
it('should escape text inside a component', function() {
expect(
SafeHTMLSubstitution.render('<0>inner0>', [{ name: 'b' }])
).to.equal('<i>inner</i>')
})
it('should escape text in front of a component', function() {
expect(
SafeHTMLSubstitution.render('PRE<0>inner0>', [{ name: 'b' }])
).to.equal('<i>PRE</i>inner')
})
it('should escape text after of a component', function() {
expect(
SafeHTMLSubstitution.render('<0>inner0>POST', [
{ name: 'b' }
])
).to.equal('inner<i>POST</i>')
})
})
})
})