From 6369617e6fcb97456137700d656b8d401fe88edf Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Sat, 8 Jan 2022 00:11:40 +0100 Subject: [PATCH] [JS] Fix few errors around AFSpecial_Keystroke - @cincodenada found some errors which are fixed in this patch; - it partially fixes issue #14306; - add some tests. --- src/scripting_api/aform.js | 18 +--- src/scripting_api/event.js | 4 +- test/unit/scripting_spec.js | 179 ++++++++++++++++++++++++++++++++++++ 3 files changed, 185 insertions(+), 16 deletions(-) diff --git a/src/scripting_api/aform.js b/src/scripting_api/aform.js index c91d72786..664e3807d 100644 --- a/src/scripting_api/aform.js +++ b/src/scripting_api/aform.js @@ -433,11 +433,8 @@ class AForm { } psf = this.AFMakeNumber(psf); - if (psf === null) { - throw new Error("Invalid psf in AFSpecial_Format"); - } - let formatStr = ""; + let formatStr; switch (psf) { case 0: formatStr = "99999"; @@ -486,7 +483,7 @@ class AForm { ]); function _checkValidity(_value, _cMask) { - for (let i = 0, ii = value.length; i < ii; i++) { + for (let i = 0, ii = _value.length; i < ii; i++) { const mask = _cMask.charAt(i); const char = _value.charAt(i); const checker = checkers.get(mask); @@ -546,9 +543,6 @@ class AForm { } psf = this.AFMakeNumber(psf); - if (psf === null) { - throw new Error("Invalid psf in AFSpecial_Keystroke"); - } let formatStr; switch (psf) { @@ -559,12 +553,8 @@ class AForm { formatStr = "99999-9999"; break; case 2: - const finalLen = - event.value.length + - event.change.length + - event.selStart - - event.selEnd; - if (finalLen >= 8) { + const value = this.AFMergeChange(event); + if (value.length > 8 || value.startsWith("(")) { formatStr = "(999) 999-9999"; } else { formatStr = "999-9999"; diff --git a/src/scripting_api/event.js b/src/scripting_api/event.js index a06fb0220..16ddfb3db 100644 --- a/src/scripting_api/event.js +++ b/src/scripting_api/event.js @@ -26,8 +26,8 @@ class Event { this.richChange = data.richChange || []; this.richChangeEx = data.richChangeEx || []; this.richValue = data.richValue || []; - this.selEnd = data.selEnd || -1; - this.selStart = data.selStart || -1; + this.selEnd = data.selEnd ?? -1; + this.selStart = data.selStart ?? -1; this.shift = data.shift || false; this.source = data.source || null; this.target = data.target || null; diff --git a/test/unit/scripting_spec.js b/test/unit/scripting_spec.js index c6236761b..0b5cd6490 100644 --- a/test/unit/scripting_spec.js +++ b/test/unit/scripting_spec.js @@ -1176,6 +1176,185 @@ describe("Scripting", function () { }); }); + describe("AFSpecial_Keystroke", function () { + it("should validate a zip code on a keystroke event", async () => { + const refId = getId(); + const data = { + objects: { + field: [ + { + id: refId, + value: "", + actions: { + Keystroke: [`AFSpecial_Keystroke(0);`], + }, + type: "text", + }, + ], + }, + appInfo: { language: "en-US", platform: "Linux x86_64" }, + calculationOrder: [], + dispatchEventName: "_dispatchMe", + }; + sandbox.createSandbox(data); + + let value = ""; + const changes = "12345"; + let i = 0; + + for (; i < changes.length; i++) { + const change = changes.charAt(i); + await sandbox.dispatchEventInSandbox({ + id: refId, + value, + change, + name: "Keystroke", + willCommit: false, + selStart: i, + selEnd: i, + }); + expect(send_queue.has(refId)).toEqual(false); + value += change; + } + + await sandbox.dispatchEventInSandbox({ + id: refId, + value, + change: "A", + name: "Keystroke", + willCommit: false, + selStart: i, + selEnd: i, + }); + expect(send_queue.has(refId)).toEqual(true); + expect(send_queue.get(refId)).toEqual({ + id: refId, + value, + selRange: [i, i], + }); + + send_queue.delete(refId); + }); + + it("should validate a US phone number (long) on a keystroke event", async () => { + const refId = getId(); + const data = { + objects: { + field: [ + { + id: refId, + value: "", + actions: { + Keystroke: [`AFSpecial_Keystroke(2);`], + }, + type: "text", + }, + ], + }, + appInfo: { language: "en-US", platform: "Linux x86_64" }, + calculationOrder: [], + dispatchEventName: "_dispatchMe", + }; + sandbox.createSandbox(data); + + let value = ""; + const changes = "(123) 456-7890"; + let i = 0; + + for (; i < changes.length; i++) { + const change = changes.charAt(i); + await sandbox.dispatchEventInSandbox({ + id: refId, + value, + change, + name: "Keystroke", + willCommit: false, + selStart: i, + selEnd: i, + }); + expect(send_queue.has(refId)).toEqual(false); + value += change; + } + + await sandbox.dispatchEventInSandbox({ + id: refId, + value, + change: "A", + name: "Keystroke", + willCommit: false, + selStart: i, + selEnd: i, + }); + expect(send_queue.has(refId)).toEqual(true); + expect(send_queue.get(refId)).toEqual({ + id: refId, + value, + selRange: [i, i], + }); + + send_queue.delete(refId); + }); + + it("should validate a US phone number (short) on a keystroke event", async () => { + const refId = getId(); + const data = { + objects: { + field: [ + { + id: refId, + value: "", + actions: { + Keystroke: [`AFSpecial_Keystroke(2);`], + }, + type: "text", + }, + ], + }, + appInfo: { language: "en-US", platform: "Linux x86_64" }, + calculationOrder: [], + dispatchEventName: "_dispatchMe", + }; + sandbox.createSandbox(data); + + let value = ""; + const changes = "123-4567"; + let i = 0; + + for (; i < changes.length; i++) { + const change = changes.charAt(i); + await sandbox.dispatchEventInSandbox({ + id: refId, + value, + change, + name: "Keystroke", + willCommit: false, + selStart: i, + selEnd: i, + }); + expect(send_queue.has(refId)).toEqual(false); + value += change; + } + + await sandbox.dispatchEventInSandbox({ + id: refId, + value, + change: "A", + name: "Keystroke", + willCommit: false, + selStart: i, + selEnd: i, + }); + expect(send_queue.has(refId)).toEqual(true); + expect(send_queue.get(refId)).toEqual({ + id: refId, + value, + selRange: [i, i], + }); + + send_queue.delete(refId); + }); + }); + describe("eMailValidate", function () { it("should validate an e-mail address", async () => { let value = await myeval(`eMailValidate(123)`);