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>INNERPOST': ['PRE', '0', 'INNER', 'POST'], '<0>INNER': ['', '0', 'INNER', ''], '<0>': ['', '0', '', ''], '<0>INNER<0>INNER2': ['', '0', 'INNER', '', '0', 'INNER2', ''], '<0><1>INNER': ['', '0', '<1>INNER', ''], '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>good', [{ name: 'b' }]) ).to.equal('good') }) it('should substitute a single component as string', function() { expect(SafeHTMLSubstitution.render('<0>good', ['b'])).to.equal( 'good' ) }) it('should substitute a single component twice', function() { expect( SafeHTMLSubstitution.render('<0>one<0>two', [{ name: 'b' }]) ).to.equal('onetwo') }) it('should substitute two components', function() { expect( SafeHTMLSubstitution.render('<0>one<1>two', [ { name: 'b' }, { name: 'i' } ]) ).to.equal('onetwo') }) it('should substitute a single component with a class', function() { expect( SafeHTMLSubstitution.render('<0>text', [ { name: 'b', attrs: { class: 'magic' } } ]) ).to.equal('text') }) it('should substitute two nested components', function() { expect( SafeHTMLSubstitution.render('<0><1>nested', [ { name: 'b' }, { name: 'i' } ]) ).to.equal('nested') }) it('should handle links', function() { expect( SafeHTMLSubstitution.render('<0>Go to Login', [ { 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>good', [ { 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>inner', [{ name: 'b' }]) ).to.equal('<i>inner</i>') }) it('should escape text in front of a component', function() { expect( SafeHTMLSubstitution.render('PRE<0>inner', [{ name: 'b' }]) ).to.equal('<i>PRE</i>inner') }) it('should escape text after of a component', function() { expect( SafeHTMLSubstitution.render('<0>innerPOST', [ { name: 'b' } ]) ).to.equal('inner<i>POST</i>') }) }) }) })