diff --git a/.gitignore b/.gitignore index 9f6dbbc..e129511 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ tmp/ .fleet/ example-app*/ base-*/ +test-*.json !starters/apps/base-*/ qr.svg package-lock.json diff --git a/__mocks__/env.js b/__mocks__/env.js index ff09721..c628a9e 100644 --- a/__mocks__/env.js +++ b/__mocks__/env.js @@ -1,4 +1,4 @@ -const MOCK_DB = require('../packages/database/src/mock') +const MOCK_DB = require('../packages/database/src/json') const PROVIDER_DB = require('../packages/provider/src/mock') class MOCK_FLOW { @@ -16,14 +16,25 @@ class MOCK_FLOW { findIndexByRef = () => 0 } +const cleaName = (name) => { + name = name.toLowerCase() + name = name.replaceAll(' ', '-') + name = name.replaceAll(':', '-') + name = name.replaceAll('"', '-') + return name +} + /** * Preparar env para el test * @param {*} context */ const setup = async (context) => { + const name = cleaName(`${context.__suite__}-${context.__test__}`) + const filename = `test-${name}.json` context.provider = new PROVIDER_DB() - context.database = new MOCK_DB() + context.database = new MOCK_DB({ filename }) context.flow = new MOCK_FLOW() + await delay(10) } const clear = async (context) => { diff --git a/__test__/0.0.0-case.test.js b/__test__/0.0.0-case.test.js index eea982a..b234eb8 100644 --- a/__test__/0.0.0-case.test.js +++ b/__test__/0.0.0-case.test.js @@ -22,8 +22,7 @@ suiteCase(`Responder a "hola"`, async ({ database, provider }) => { body: 'hola', }) - await delay(0) - + await delay(10) assert.is('Buenas!', database.listHistory[0].answer) assert.is('Como vamos!', database.listHistory[1].answer) assert.is(undefined, database.listHistory[2]) @@ -43,7 +42,7 @@ suiteCase(`NO reponder a "pepe"`, async ({ database, provider }) => { body: 'pepe', }) - await delay(0) + await delay(100) assert.is(undefined, database.listHistory[0]) assert.is(undefined, database.listHistory[1]) diff --git a/__test__/0.0.1-case.test.js b/__test__/0.0.1-case.test.js new file mode 100644 index 0000000..1f71435 --- /dev/null +++ b/__test__/0.0.1-case.test.js @@ -0,0 +1,31 @@ +const { suite } = require('uvu') +const assert = require('uvu/assert') +const { addKeyword, createBot, createFlow } = require('../packages/bot/index') +const { setup, clear, delay } = require('../__mocks__/env') + +const suiteCase = suite('Flujo: Provider envia un location') + +suiteCase.before.each(setup) +suiteCase.after.each(clear) + +suiteCase(`Responder a "CURRENT_LOCATION"`, async ({ database, provider }) => { + const flow = addKeyword('#CURRENT_LOCATION#').addAnswer('Gracias por tu location') + + createBot({ + database, + provider, + flow: createFlow([flow]), + }) + + await provider.delaySendMessage(0, 'message', { + from: '000', + body: '#CURRENT_LOCATION#', + }) + + await delay(200) + const getHistory = database.listHistory.map((i) => i.answer) + assert.is('Gracias por tu location', getHistory[0]) + assert.is(undefined, getHistory[1]) +}) + +suiteCase.run() diff --git a/__test__/0.1.0-case.test.js b/__test__/0.1.0-case.test.js index 7bca259..2380ede 100644 --- a/__test__/0.1.0-case.test.js +++ b/__test__/0.1.0-case.test.js @@ -22,7 +22,7 @@ suiteCase(`Responder a "ole" en minuscula`, async ({ database, provider }) => { body: 'ole', }) - await delay(0) + await delay(100) assert.is('Bienvenido a la OLA', database.listHistory[0].answer) assert.is(undefined, database.listHistory[1]) @@ -42,7 +42,7 @@ suiteCase(`NO Responder a "ole" en minuscula`, async ({ database, provider }) => body: 'OLE', }) - await delay(0) + await delay(100) assert.is(undefined, database.listHistory[0]) assert.is(undefined, database.listHistory[1]) diff --git a/__test__/0.1.1-case.test.js b/__test__/0.1.1-case.test.js index dd49d5c..499d2ec 100644 --- a/__test__/0.1.1-case.test.js +++ b/__test__/0.1.1-case.test.js @@ -51,22 +51,22 @@ suiteCase(`Debe continuar el flujo del hijo`, async ({ database, provider }) => body: 'hola', }) - await provider.delaySendMessage(10, 'message', { + await provider.delaySendMessage(30, 'message', { from: '000', body: 'test@test.com', }) - await provider.delaySendMessage(15, 'message', { + await provider.delaySendMessage(60, 'message', { from: '000', body: 'paypal', }) - await provider.delaySendMessage(20, 'message', { + await provider.delaySendMessage(90, 'message', { from: '000', body: 'continue!', }) - await delay(500) + await delay(800) const getHistory = database.listHistory.map((i) => i.answer) assert.is('¿Como estas todo bien?', getHistory[0]) diff --git a/__test__/0.1.2-case.test.js b/__test__/0.1.2-case.test.js index b421955..cd0dbcd 100644 --- a/__test__/0.1.2-case.test.js +++ b/__test__/0.1.2-case.test.js @@ -26,7 +26,7 @@ suiteCase(`Responder a una expresion regular`, async ({ database, provider }) => body: '374245455400126', }) - await delay(10) + await delay(100) assert.is('Gracias por proporcionar un numero de tarjeta valido', database.listHistory[0].answer) assert.is('Fin!', database.listHistory[1].answer) @@ -50,7 +50,7 @@ suiteCase(`NO Responder a una expresion regular`, async ({ database, provider }) body: 'hola', }) - await delay(10) + await delay(100) assert.is(undefined, database.listHistory[0]) assert.is(undefined, database.listHistory[1]) diff --git a/__test__/0.1.3-case.test.js b/__test__/0.1.3-case.test.js index 1d4c28d..1893583 100644 --- a/__test__/0.1.3-case.test.js +++ b/__test__/0.1.3-case.test.js @@ -29,7 +29,7 @@ suiteCase(`Responder a "pregunta"`, async ({ database, provider }) => { body: '90', }) - await delay(20) + await delay(100) assert.is(['Hola como estas?', '¿Cual es tu edad?'].join('\n'), database.listHistory[0].answer) assert.is('90', database.listHistory[1].answer) diff --git a/__test__/0.1.4-case.test.js b/__test__/0.1.4-case.test.js index 6b9f7e8..c741c2c 100644 --- a/__test__/0.1.4-case.test.js +++ b/__test__/0.1.4-case.test.js @@ -50,7 +50,7 @@ suiteCase(`Responder con mensajes asyncronos`, async ({ database, provider }) => body: 'hola', }) - await delay(1200) + await delay(1500) const getHistory = database.listHistory.map((i) => i.answer) assert.is(MOCK_VALUES[0], getHistory[0]) @@ -98,7 +98,7 @@ suiteCase(`Responder con un "string"`, async ({ database, provider }) => { body: 'hola', }) - await delay(10) + await delay(100) const getHistory = database.listHistory.map((i) => i.answer) assert.is('Como vas?', getHistory[0]) assert.is('Todo bien!', getHistory[1]) @@ -124,7 +124,7 @@ suiteCase(`Responder con un "array"`, async ({ database, provider }) => { body: 'hola', }) - await delay(10) + await delay(100) const getHistory = database.listHistory.map((i) => i.answer) assert.is('Como vas?', getHistory[0]) assert.is('Todo bien!', getHistory[1]) @@ -151,7 +151,7 @@ suiteCase(`Responder con un "object"`, async ({ database, provider }) => { body: 'hola', }) - await delay(10) + await delay(100) const getHistory = database.listHistory.map((i) => i.answer) assert.is('Como vas?', getHistory[0]) assert.is('Todo bien!', getHistory[1]) diff --git a/__test__/0.1.5-case.test.js b/__test__/0.1.5-case.test.js index f2280bb..8b9e310 100644 --- a/__test__/0.1.5-case.test.js +++ b/__test__/0.1.5-case.test.js @@ -46,7 +46,7 @@ suiteCase(`Detener el flujo`, async ({ database, provider }) => { body: 'hola', }) - await delay(500) + await delay(900) const getHistory = database.listHistory.map((i) => i.answer) assert.is(MOCK_VALUES[0], getHistory[0]) @@ -81,7 +81,7 @@ suiteCase(`Detener el flujo flowDynamic`, async ({ database, provider }) => { body: 'hola', }) - await delay(10) + await delay(100) const getHistory = database.listHistory.map((i) => i.answer) assert.is('Buenas!', getHistory[0]) assert.is('Continuamos...', getHistory[1]) @@ -148,7 +148,7 @@ suiteCase(`flowDynamic con capture`, async ({ database, provider }) => { body: '18', }) - await delay(500) + await delay(900) const getHistory = database.listHistory.map((i) => i.answer) assert.is(MOCK_VALUES[0], getHistory[0]) assert.is('this is not email value', getHistory[1]) diff --git a/__test__/0.1.6-case.test.js b/__test__/0.1.6-case.test.js index 4a56dd0..3473aab 100644 --- a/__test__/0.1.6-case.test.js +++ b/__test__/0.1.6-case.test.js @@ -76,7 +76,7 @@ suiteCase(`Debe retornar un mensaje resumen`, async ({ database, provider }) => body: '100', }) - await delay(500) + await delay(1000) const getHistory = database.listHistory.map((i) => i.answer) assert.is(MOCK_VALUES[0], getHistory[0]) assert.is('¿Cual es tu nombre?', getHistory[1]) diff --git a/packages/bot/core/core.class.js b/packages/bot/core/core.class.js index 3c2b752..09e926d 100644 --- a/packages/bot/core/core.class.js +++ b/packages/bot/core/core.class.js @@ -84,7 +84,7 @@ class CoreClass { from, prevRef: prevMsg.refSerialize, }) - this.databaseClass.save(ctxByNumber) + await this.databaseClass.save(ctxByNumber) } // 📄 Crar CTX de mensaje (uso private) diff --git a/packages/database/src/json/index.js b/packages/database/src/json/index.js index 83450d5..edecd18 100644 --- a/packages/database/src/json/index.js +++ b/packages/database/src/json/index.js @@ -1,63 +1,79 @@ const { join } = require('path') -const { existsSync, writeFileSync, readFileSync } = require('fs') +const { existsSync } = require('fs') +const { writeFile, readFile } = require('fs').promises class JsonFileAdapter { db pathFile listHistory = [] + options = { filename: 'db.json' } - constructor() { - this.pathFile = join(process.cwd(), 'db.json') + constructor(options = {}) { + this.options = { ...this.options, ...options } + this.pathFile = join(process.cwd(), this.options.filename) this.init().then() } - databaseExists() { - return existsSync(this.pathFile) - } - - async init() { - const dbExists = await this.databaseExists() - - if (!dbExists) { - const data = { - history: [], - } - await this.saveData(data) + /** + * Revisamos si existe o no el json file + * @returns + */ + init = async () => { + if (existsSync(this.pathFile)) { + return Promise.resolve() + } + try { + const parseData = JSON.stringify([], null, 2) + return writeFile(this.pathFile, parseData, 'utf-8') + } catch (e) { + return Promise.reject(e.message) } } - readDatabase() { - const db = readFileSync(this.pathFile) - return JSON.parse(db) + validateJson = (raw) => { + try { + return JSON.parse(raw) + } catch (e) { + return {} + } } - saveData(data) { - writeFileSync(this.pathFile, JSON.stringify(data, null, 2)) + /** + * Leer archivo y parsear + * @returns + */ + readFileAndParse = async () => { + const data = await readFile(this.pathFile, 'utf-8') + const parseData = this.validateJson(data) + return parseData } + /** + * Buscamos el ultimo mensaje por numero + * @param {*} from + * @returns + */ getPrevByNumber = async (from) => { - const { history } = await this.readDatabase() - + const history = await this.readFileAndParse() if (!history.length) { - return null + return [] } - const result = history.filter((res) => res.from === from).pop() - - return { - ...result, - } + const result = history + .slice() + .reverse() + .filter((i) => !!i.keyword) + return result.find((a) => a.from === from) } + /** + * Guardar dato + * @param {*} ctx + */ save = async (ctx) => { - this.db = await this.readDatabase() - - this.db.history.push(ctx) - - await this.saveData(this.db) - this.listHistory.push(ctx) - console.log('Guardado en DB...', ctx) + const parseData = JSON.stringify(this.listHistory, null, 2) + await writeFile(this.pathFile, parseData, 'utf-8') } } diff --git a/packages/provider/src/baileys/index.js b/packages/provider/src/baileys/index.js index a2d88ae..eaa6adb 100644 --- a/packages/provider/src/baileys/index.js +++ b/packages/provider/src/baileys/index.js @@ -125,7 +125,7 @@ class BaileysProvider extends ProviderClass { if (messageCtx.message.locationMessage) { const { degreesLatitude, degreesLongitude } = messageCtx.message.locationMessage if (typeof degreesLatitude === 'number' && typeof degreesLongitude === 'number') { - payload = { ...payload, body: `📍` } + payload = { ...payload, body: `#CURRENT_LOCATION#` } } } diff --git a/packages/provider/src/venom/index.js b/packages/provider/src/venom/index.js index 6776033..2ab185e 100644 --- a/packages/provider/src/venom/index.js +++ b/packages/provider/src/venom/index.js @@ -93,7 +93,7 @@ class VenomProvider extends ProviderClass { const lat = payload.lat const lng = payload.lng if (lat !== '' && lng !== '') { - payload = { ...payload, body: `📍` } + payload = { ...payload, body: `#CURRENT_LOCATION#` } } } this.emit('message', payload) diff --git a/packages/provider/src/web-whatsapp/index.js b/packages/provider/src/web-whatsapp/index.js index 2e87938..71c1bc4 100644 --- a/packages/provider/src/web-whatsapp/index.js +++ b/packages/provider/src/web-whatsapp/index.js @@ -91,7 +91,7 @@ class WebWhatsappProvider extends ProviderClass { } payload.from = wwebCleanNumber(payload.from, true) if (payload._data.lat && payload._data.lng) { - payload = { ...payload, body: `📍` } + payload = { ...payload, body: `#CURRENT_LOCATION#` } } this.emit('message', payload) },