From 57f803cc957d4e5ffaf0b495411049b729984a01 Mon Sep 17 00:00:00 2001 From: James Lucas Date: Wed, 17 Jan 2024 16:22:13 +1100 Subject: [PATCH 1/4] refactor: wrap in else block to improve code coverage reporting --- src/js/customControls.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/js/customControls.js b/src/js/customControls.js index cde0625ca..41e07fd44 100644 --- a/src/js/customControls.js +++ b/src/js/customControls.js @@ -133,17 +133,17 @@ export default class customControls { const value = typeof i18n == 'object' ? i18n[lookupCamel] || i18n[type] : i18n if (value) { return value + } else { + // otherwise check the mi18n object - allow for mapping a lookup to a custom mi18n lookup + let mapped = def.mi18n + if (typeof mapped === 'object') { + mapped = mapped[lookupCamel] || mapped[type] + } + if (!mapped) { + mapped = lookupCamel + } + return mi18n.get(mapped) } - - // otherwise check the mi18n object - allow for mapping a lookup to a custom mi18n lookup - let mapped = def.mi18n - if (typeof mapped === 'object') { - mapped = mapped[lookupCamel] || mapped[type] - } - if (!mapped) { - mapped = lookupCamel - } - return mi18n.get(mapped) } get definition() { From 76c52e1a34ff8cb9653ac2e2a958f1190080d066 Mon Sep 17 00:00:00 2001 From: James Lucas Date: Wed, 17 Jan 2024 16:22:35 +1100 Subject: [PATCH 2/4] test: ignore index.js file from code coverage --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 833787d6f..cc1d85fb9 100644 --- a/package.json +++ b/package.json @@ -186,7 +186,8 @@ "collectCoverage": true, "coverageDirectory": ".jest/coverage", "coveragePathIgnorePatterns": [ - "tests/" + "tests/", + "/src/js/control/index.js" ], "testEnvironment": "jsdom", "testEnvironmentOptions": { From 65ed213e2a9e773a6d039833a9427558e21d4c4d Mon Sep 17 00:00:00 2001 From: James Lucas Date: Wed, 17 Jan 2024 16:23:13 +1100 Subject: [PATCH 3/4] test: ignore lines from code coverage report --- src/js/control/custom.js | 2 +- src/js/events.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/js/control/custom.js b/src/js/control/custom.js index 265fbe494..e31d76feb 100644 --- a/src/js/control/custom.js +++ b/src/js/control/custom.js @@ -18,8 +18,8 @@ export default class controlCustom extends control { */ build() { let custom = this.template + /* istanbul ignore next */ if (!custom) { - /* istanbul ignore next */ return control.error( `Invalid custom control type '${this.type}'. Please ensure you have registered it correctly as a template option.`, ) diff --git a/src/js/events.js b/src/js/events.js index 36744fcbf..7730482eb 100644 --- a/src/js/events.js +++ b/src/js/events.js @@ -10,6 +10,7 @@ */ function createNewEvent(eventName) { let event + /* istanbul ignore else - historical InternetExplorer only */ if (typeof Event === 'function') { event = new Event(eventName) } else { From 81739768878655ce718c9cf036702a86c0bcfe91 Mon Sep 17 00:00:00 2001 From: James Lucas Date: Wed, 17 Jan 2024 16:23:59 +1100 Subject: [PATCH 4/4] test: improve test coverage for tinymce, quill, select, and custom controls --- tests/control/custom.test.js | 38 ++++++++++++++++++++++++++++++++++ tests/control/select.test.js | 34 ++++++++++++++++++++++++++++++ tests/control/textarea.test.js | 35 +++++++++++++++++++++++++++++-- 3 files changed, 105 insertions(+), 2 deletions(-) diff --git a/tests/control/custom.test.js b/tests/control/custom.test.js index 7e97faa9c..48b2caf7a 100644 --- a/tests/control/custom.test.js +++ b/tests/control/custom.test.js @@ -366,4 +366,42 @@ describe('Test Custom Control', () => { fbWrap.formRender({formData, templates}) expect(fbWrap.find('span')[0].textContent).toBe('not preview') }) + + test('test loading js/css from custom template', async () => { + const fbWrap = $('
') + const cbOnRender = jest.fn() + + const formData = [ + { + 'type': 'starRating', + 'required': false, + 'label': 'Star Rating', + 'name': 'starRating-1697591966052-0' + }, + ] + const templates = { + starRating: function(fieldData) { + const control = this + control.field = `` + return { + field: control.field, + onRender: () => { + $(control.field).rateYo( {rating: 2} ) + cbOnRender() + }, + js: 'https://cdnjs.cloudflare.com/ajax/libs/rateYo/2.3.2/jquery.rateyo.min.js', + css: 'https://cdnjs.cloudflare.com/ajax/libs/rateYo/2.3.2/jquery.rateyo.min.css' + } + } + } + + fbWrap.formRender({formData, templates}) + + await new Promise(resolve => setTimeout(resolve, 2000)) + + expect(cbOnRender.mock.calls).toHaveLength(1) + + expect(fbWrap.find('#starRating-1697591966052-0')[0].outerHTML).toBe('') + + }) }) \ No newline at end of file diff --git a/tests/control/select.test.js b/tests/control/select.test.js index 1d76ee7e3..1433f20a7 100644 --- a/tests/control/select.test.js +++ b/tests/control/select.test.js @@ -78,4 +78,38 @@ describe('Test Text Control', () => { element.value = 'option-1' expect(element.validity.valid).toBeTruthy() }) + + test('userData overrides default selections', async () => { + const controlInstance = new controlSelect({ + 'type': 'select', + 'required': true, + 'label': 'Select', + 'className': 'form-control', + 'placeholder': 'Select an option...', + 'name': 'test-select', + 'multiple': false, + 'values': [ + { + 'label': 'Option 1', + 'value': 'option-1', + 'selected': true + }, + { + 'label': 'Option 2', + 'value': 'option-2', + 'selected': false + }, + { + 'label': 'Option 3', + 'value': 'option-3', + 'selected': false + } + ], + userData: ['option-2'] + }, false) + + const element = controlInstance.build() + controlInstance.onRender() + expect(element.value).toBe('option-2') + }) }) \ No newline at end of file diff --git a/tests/control/textarea.test.js b/tests/control/textarea.test.js index 7eea3e276..9dfe8ae47 100644 --- a/tests/control/textarea.test.js +++ b/tests/control/textarea.test.js @@ -1,6 +1,21 @@ import controlTextarea from '../../src/js/control/textarea.js' import controlTinymce from '../../src/js/control/textarea.tinymce' import controlQuill from '../../src/js/control/textarea.quill' +import { getScripts, getStyles, isCached } from '../../src/js/utils' + +const sleep = milliseconds => { + return new Promise(resolve => setTimeout(resolve, milliseconds)) +} + +const loadResources = async (js, css) => { + if (css) { + getStyles(css) + } + if (js && !isCached(js)) { + await getScripts(js) + } +} + describe('Test Text Control', () => { test('test building control element', async () => { const controlInstance = new controlTextarea({ @@ -35,7 +50,7 @@ describe('Test Text Control', () => { }) describe('Test building text variations and subtypes', () => { - test('can render TinyMCE', () => { + test('can render TinyMCE', async () => { const controlInstance = new controlTinymce({ 'type': 'textarea', 'required': false, @@ -45,12 +60,22 @@ describe('Test building text variations and subtypes', () => { 'access': false, 'subtype': 'tinymce', }, false) + controlInstance.configure() const element = controlInstance.build() expect(element.constructor.name).toBe('HTMLTextAreaElement') expect(element.type).toBe('textarea') + + window.document.body.appendChild(element) //Element must be attached to dom for tinymce theme to work otherwise exception thrown + + await loadResources(controlInstance.js, controlInstance.css) + + expect(window.tinymce).not.toBeUndefined() + controlInstance.onRender() + await sleep(2000) + expect(window.tinymce.get('tinymce-elem')).not.toBeNull() }) - test('can render Quill', () => { + test('can render Quill', async () => { const controlInstance = new controlQuill({ 'type': 'textarea', 'required': false, @@ -60,7 +85,13 @@ describe('Test building text variations and subtypes', () => { 'access': false, 'subtype': 'quill', }, false) + controlInstance.configure() const element = controlInstance.build() expect(element.constructor.name).toBe('HTMLDivElement') + + window.document.body.appendChild(element) //Element must be attached to dom for quill to work otherwise exception thrown + + await loadResources(controlInstance.js, controlInstance.css) + controlInstance.onRender() }) }) \ No newline at end of file