chore: import maquina-comercial-pessoal history via subtree
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> git-subtree-dir: maquina-comercial-pessoal git-subtree-mainline:f5af038e19git-subtree-split:a9ef4d776d
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { DatabaseSync } from 'node:sqlite';
|
||||
import {
|
||||
canonicalKeySql,
|
||||
canonicalPhoneKey,
|
||||
canonicalPhoneVariants,
|
||||
canonicalVariantSql,
|
||||
equivalentPhoneNumbers,
|
||||
equivalentSql,
|
||||
normalizePhone,
|
||||
normalizedSql
|
||||
} from '../src/phone.mjs';
|
||||
|
||||
// A regra 8/9 digitos existe duas vezes: em JS (equivalentPhoneNumbers /
|
||||
// canonicalPhoneKey, usadas pelo envio manual e pela revalidacao de ultima
|
||||
// milha) e em SQL (equivalentSql / canonicalKeySql, usadas pela selecao de
|
||||
// candidatos da campanha e pela listagem de tratamento). Se alguem editar uma
|
||||
// sem a outra, o bloqueio automatico e o manual passam a discordar em silencio.
|
||||
// Estes testes rodam o mesmo conjunto de numeros pelos dois caminhos.
|
||||
const NUMBERS = [
|
||||
'5575999091780', // celular BR de 13 digitos com nono digito
|
||||
'557599091780', // mesma linha em 8 digitos (local comeca com 9)
|
||||
'5571993335451', // outro celular de 13 digitos
|
||||
'557193335451', // fixo/8 digitos que comeca com 9 -> tem par
|
||||
'557133334444', // fixo de 12 digitos, local comeca com 3 (sem par direto)
|
||||
'5575933334444', // par assimetrico do numero abaixo
|
||||
'557533334444', // 12 digitos, local '33334444' fora da faixa 6-9
|
||||
'551140028922', // 12 digitos, local comeca com 4
|
||||
'557561234567', // 12 digitos, local comeca com 6 (limite inferior da faixa)
|
||||
'557551234567', // 12 digitos, local comeca com 5 (logo abaixo da faixa)
|
||||
'557591234567', // 12 digitos, local comeca com 9 (limite superior da faixa)
|
||||
'5511987654321', // 13 digitos comum
|
||||
'11987654321', // sem DDI 55
|
||||
'5575', // curto demais
|
||||
'' // vazio
|
||||
];
|
||||
|
||||
function sqlDb() {
|
||||
const db = new DatabaseSync(':memory:');
|
||||
db.exec('CREATE TABLE amostra (bruto TEXT)');
|
||||
return db;
|
||||
}
|
||||
|
||||
function sqlValues(db, numero) {
|
||||
db.prepare('DELETE FROM amostra').run();
|
||||
db.prepare('INSERT INTO amostra (bruto) VALUES (?)').run(numero);
|
||||
return db.prepare(
|
||||
`SELECT ${normalizedSql('bruto')} AS normalizado,
|
||||
${equivalentSql('bruto')} AS equivalente,
|
||||
${canonicalKeySql('bruto')} AS canonico,
|
||||
${canonicalVariantSql('bruto')} AS variante
|
||||
FROM amostra`
|
||||
).get();
|
||||
}
|
||||
|
||||
test('normalizedSql concorda com normalizePhone', () => {
|
||||
const db = sqlDb();
|
||||
for (const numero of [...NUMBERS, '+55 (75) 99909-1780', '55 71 9333-5451']) {
|
||||
assert.equal(sqlValues(db, numero).normalizado, normalizePhone(numero), numero);
|
||||
}
|
||||
db.close();
|
||||
});
|
||||
|
||||
test('equivalentSql concorda com equivalentPhoneNumbers em todas as amostras', () => {
|
||||
const db = sqlDb();
|
||||
for (const numero of NUMBERS) {
|
||||
const equivalentes = equivalentPhoneNumbers(numero);
|
||||
// equivalentPhoneNumbers devolve [proprio, alternativo?]; equivalentSql
|
||||
// devolve apenas o "outro lado" (ou o proprio quando nao ha alternativa).
|
||||
const esperado = equivalentes.length > 1 ? equivalentes[1] : normalizePhone(numero);
|
||||
assert.equal(sqlValues(db, numero).equivalente, esperado, numero);
|
||||
}
|
||||
db.close();
|
||||
});
|
||||
|
||||
test('canonicalKeySql concorda com canonicalPhoneKey em todas as amostras', () => {
|
||||
const db = sqlDb();
|
||||
for (const numero of NUMBERS) {
|
||||
assert.equal(sqlValues(db, numero).canonico, canonicalPhoneKey(numero), numero);
|
||||
}
|
||||
db.close();
|
||||
});
|
||||
|
||||
test('canonicalKeySql + canonicalVariantSql cobrem o mesmo conjunto de canonicalPhoneVariants', () => {
|
||||
const db = sqlDb();
|
||||
for (const numero of NUMBERS) {
|
||||
const { canonico, variante } = sqlValues(db, numero);
|
||||
const sqlSet = [...new Set([canonico, variante].filter(Boolean))].sort();
|
||||
const jsSet = [...new Set(canonicalPhoneVariants(numero))].sort();
|
||||
assert.deepEqual(sqlSet, jsSet, numero);
|
||||
}
|
||||
db.close();
|
||||
});
|
||||
|
||||
test('a chave canonica e simetrica onde equivalentPhoneNumbers nao e', () => {
|
||||
// Caso concreto: A tem 12 digitos com local fora da faixa 6-9, B tem 13.
|
||||
assert.deepEqual(equivalentPhoneNumbers('557533334444'), ['557533334444']);
|
||||
assert.deepEqual(equivalentPhoneNumbers('5575933334444'), ['5575933334444', '557533334444']);
|
||||
assert.equal(canonicalPhoneKey('557533334444'), '557533334444');
|
||||
assert.equal(canonicalPhoneKey('5575933334444'), '557533334444');
|
||||
|
||||
// E os pares 8/9 digitos ja cobertos pela suite continuam batendo entre si.
|
||||
assert.equal(canonicalPhoneKey('5575999091780'), canonicalPhoneKey('557599091780'));
|
||||
assert.equal(canonicalPhoneKey('5571993335451'), canonicalPhoneKey('557193335451'));
|
||||
|
||||
// Simetria total do conjunto de casamento nas amostras brasileiras.
|
||||
for (const numero of NUMBERS) {
|
||||
for (const outro of canonicalPhoneVariants(numero)) {
|
||||
assert.ok(
|
||||
canonicalPhoneVariants(outro).includes(normalizePhone(numero)),
|
||||
`${numero} <-> ${outro}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Numeros de linhas diferentes nao podem colidir.
|
||||
assert.notEqual(canonicalPhoneKey('557533334444'), canonicalPhoneKey('557133334444'));
|
||||
assert.notEqual(canonicalPhoneKey('5511987654321'), canonicalPhoneKey('551140028922'));
|
||||
});
|
||||
Reference in New Issue
Block a user