import assert from 'node:assert/strict';
import test from 'node:test';
import {
findDocumentWriteCallLines,
findInnerHtmlAssignmentLines,
findInsertAdjacentHtmlCallLines,
hasDocumentWriteCall,
hasInnerHtmlAssignment,
hasInsertAdjacentHtmlCall,
} from './index';
test('hasInnerHtmlAssignment detecta asignacion directa a innerHTML', () => {
const ast = {
type: 'Program',
body: [
{
type: 'ExpressionStatement',
expression: {
type: 'AssignmentExpression',
left: {
type: 'MemberExpression',
computed: false,
object: { type: 'Identifier', name: 'element' },
property: { type: 'Identifier', name: 'innerHTML' },
},
right: { type: 'StringLiteral', value: '
x
' },
},
},
],
};
assert.equal(hasInnerHtmlAssignment(ast), true);
});
test('hasInnerHtmlAssignment detecta acceso computed con StringLiteral', () => {
const ast = {
type: 'AssignmentExpression',
left: {
type: 'MemberExpression',
computed: true,
object: { type: 'Identifier', name: 'target' },
property: { type: 'StringLiteral', value: 'innerHTML' },
},
right: { type: 'Identifier', name: 'payload' },
};
assert.equal(hasInnerHtmlAssignment(ast), true);
});
test('hasInnerHtmlAssignment no detecta propiedades distintas', () => {
const ast = {
type: 'AssignmentExpression',
left: {
type: 'MemberExpression',
computed: false,
object: { type: 'Identifier', name: 'element' },
property: { type: 'Identifier', name: 'textContent' },
},
right: { type: 'StringLiteral', value: 'safe' },
};
assert.equal(hasInnerHtmlAssignment(ast), false);
});
test('hasDocumentWriteCall detecta document.write no computed', () => {
const ast = {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
computed: false,
object: { type: 'Identifier', name: 'document' },
property: { type: 'Identifier', name: 'write' },
},
arguments: [{ type: 'StringLiteral', value: '' }],
};
assert.equal(hasDocumentWriteCall(ast), true);
});
test('hasDocumentWriteCall ignora member expressions computed', () => {
const ast = {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
computed: true,
object: { type: 'Identifier', name: 'document' },
property: { type: 'StringLiteral', value: 'write' },
},
arguments: [],
};
assert.equal(hasDocumentWriteCall(ast), false);
});
test('hasInsertAdjacentHtmlCall detecta propiedad insertAdjacentHTML', () => {
const directAst = {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
computed: false,
object: { type: 'Identifier', name: 'node' },
property: { type: 'Identifier', name: 'insertAdjacentHTML' },
},
arguments: [],
};
const computedAst = {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
computed: true,
object: { type: 'Identifier', name: 'node' },
property: { type: 'StringLiteral', value: 'insertAdjacentHTML' },
},
arguments: [],
};
assert.equal(hasInsertAdjacentHtmlCall(directAst), true);
assert.equal(hasInsertAdjacentHtmlCall(computedAst), true);
});
test('hasInsertAdjacentHtmlCall no detecta metodos distintos', () => {
const ast = {
type: 'CallExpression',
callee: {
type: 'MemberExpression',
computed: false,
object: { type: 'Identifier', name: 'node' },
property: { type: 'Identifier', name: 'insertAdjacentText' },
},
arguments: [],
};
assert.equal(hasInsertAdjacentHtmlCall(ast), false);
});
test('find*Lines de browser retornan lineas de coincidencia', () => {
const ast = {
type: 'Program',
body: [
{
type: 'AssignmentExpression',
loc: { start: { line: 6 } },
left: {
type: 'MemberExpression',
computed: false,
object: { type: 'Identifier', name: 'element' },
property: { type: 'Identifier', name: 'innerHTML' },
},
right: { type: 'Identifier', name: 'payload' },
},
{
type: 'CallExpression',
loc: { start: { line: 10 } },
callee: {
type: 'MemberExpression',
computed: false,
object: { type: 'Identifier', name: 'document' },
property: { type: 'Identifier', name: 'write' },
},
arguments: [],
},
{
type: 'CallExpression',
loc: { start: { line: 14 } },
callee: {
type: 'MemberExpression',
computed: false,
object: { type: 'Identifier', name: 'target' },
property: { type: 'Identifier', name: 'insertAdjacentHTML' },
},
arguments: [],
},
],
};
assert.deepEqual(findInnerHtmlAssignmentLines(ast), [6]);
assert.deepEqual(findDocumentWriteCallLines(ast), [10]);
assert.deepEqual(findInsertAdjacentHtmlCallLines(ast), [14]);
});