diff --git a/TODO.txt b/TODO.txt
index 92f1e14e79d..bfabbd1bbcc 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -4,6 +4,13 @@ Licenses that are needed with the source code and binary:
* Amoss - https://github.com/bobalicious/amoss/blob/main/LICENSE
* SObject Fabricator - https://github.com/bobalicious/SObjectFabricator/blob/master/LICENSE
+* Docs at the top level about the ortoo Id
+
+Remove need for data-name - reference the id info
+
+Add library for getting LWC elements by their generated Ortoo Id
+ Add docs for the retrieval of elements
+
Look at the use of 'MockDatabase' in fflib
Look at:
SobjectUtils.getSobjectName
@@ -19,8 +26,6 @@ Look at:
* Try parent and datatable referencing a DML Service
* Standards
- * data-name to identify elements in a test
- * e.g. [data-name="cancel"]
* Labels should be:
* Imported into a static named _LABEL
* Referenced in an object named 'labels'.
diff --git a/framework/default/ortoo-core/default/lwc/confirmationDialog/__tests__/confirmationDialog.test.js b/framework/default/ortoo-core/default/lwc/confirmationDialog/__tests__/confirmationDialog.test.js
index 7e2dc8fb7f7..1bf01488460 100644
--- a/framework/default/ortoo-core/default/lwc/confirmationDialog/__tests__/confirmationDialog.test.js
+++ b/framework/default/ortoo-core/default/lwc/confirmationDialog/__tests__/confirmationDialog.test.js
@@ -45,10 +45,10 @@ describe('c-confirmation-dialog', () => {
const expectedElement = element.shadowRoot.querySelector( 'c-modal div[slot="footer"]' );
expect( expectedElement ).not.toBe( null );
- expect( expectedElement.querySelector( '[data-name="confirm"]' ).title ).not.toBe( null );
- expect( expectedElement.querySelector( '[data-name="confirm"]' ).label ).not.toBe( null );
- expect( expectedElement.querySelector( '[data-name="cancel"]' ).title ).not.toBe( null );
- expect( expectedElement.querySelector( '[data-name="cancel"]' ).label ).not.toBe( null );
+ expect( expectedElement.querySelector( '[data-ortoo-elem-id="confirmation-confirm"]' ).title ).not.toBe( null );
+ expect( expectedElement.querySelector( '[data-ortoo-elem-id="confirmation-confirm"]' ).label ).not.toBe( null );
+ expect( expectedElement.querySelector( '[data-ortoo-elem-id="confirmation-cancel"]' ).title ).not.toBe( null );
+ expect( expectedElement.querySelector( '[data-ortoo-elem-id="confirmation-cancel"]' ).label ).not.toBe( null );
});
it('When set to visible, contains a div containing cancel and confirm buttons with the specified labels, directing them to the modal footer slot', () => {
@@ -64,10 +64,10 @@ describe('c-confirmation-dialog', () => {
const expectedElement = element.shadowRoot.querySelector( 'c-modal div[slot="footer"]' );
expect( expectedElement ).not.toBe( null );
- expect( expectedElement.querySelector( '[data-name="confirm"]' ).title ).toBe( 'Confirm thing' );
- expect( expectedElement.querySelector( '[data-name="confirm"]' ).label ).toBe( 'Confirm thing' );
- expect( expectedElement.querySelector( '[data-name="cancel"]' ).title ).toBe( 'Cancel thing' );
- expect( expectedElement.querySelector( '[data-name="cancel"]' ).label ).toBe( 'Cancel thing' );
+ expect( expectedElement.querySelector( '[data-ortoo-elem-id="confirmation-confirm"]' ).title ).toBe( 'Confirm thing' );
+ expect( expectedElement.querySelector( '[data-ortoo-elem-id="confirmation-confirm"]' ).label ).toBe( 'Confirm thing' );
+ expect( expectedElement.querySelector( '[data-ortoo-elem-id="confirmation-cancel"]' ).title ).toBe( 'Cancel thing' );
+ expect( expectedElement.querySelector( '[data-ortoo-elem-id="confirmation-cancel"]' ).label ).toBe( 'Cancel thing' );
});
it('When set to visible and passed a valid type, contains a div containing cancel and confirm buttons with the specified labels, directing them to the modal footer slot', () => {
@@ -81,8 +81,8 @@ describe('c-confirmation-dialog', () => {
const expectedElement = element.shadowRoot.querySelector( 'c-modal div[slot="footer"]' );
expect( expectedElement ).not.toBe( null );
- expect( expectedElement.querySelector( '[data-name="confirm"]' ).label ).not.toBe( null );
- expect( expectedElement.querySelector( '[data-name="cancel"]' ).label ).not.toBe( null );
+ expect( expectedElement.querySelector( '[data-ortoo-elem-id="confirmation-confirm"]' ).label ).not.toBe( null );
+ expect( expectedElement.querySelector( '[data-ortoo-elem-id="confirmation-cancel"]' ).label ).not.toBe( null );
});
it('When set to an invalid type, will throw an error', () => {
@@ -113,7 +113,7 @@ describe('c-confirmation-dialog', () => {
const cancelHandler = jest.fn();
element.addEventListener( 'cancel', cancelHandler ) ;
- element.shadowRoot.querySelector( '[data-name="confirm"]' ).click();
+ element.shadowRoot.querySelector( '[data-ortoo-elem-id="confirmation-confirm"]' ).click();
expect( confirmHandler ).toHaveBeenCalled();
expect( confirmHandler.mock.calls[0][0].detail ).toBe( CONFIRM_MESSAGE );
@@ -142,7 +142,7 @@ describe('c-confirmation-dialog', () => {
const cancelHandler = jest.fn();
element.addEventListener( 'cancel', cancelHandler ) ;
- element.shadowRoot.querySelector( '[data-name="cancel"]' ).click();
+ element.shadowRoot.querySelector( '[data-ortoo-elem-id="confirmation-cancel"]' ).click();
expect( cancelHandler ).toHaveBeenCalled();
expect( cancelHandler.mock.calls[0][0].detail ).toBe( CANCEL_MESSAGE );
diff --git a/framework/default/ortoo-core/default/lwc/confirmationDialog/confirmationDialog.html b/framework/default/ortoo-core/default/lwc/confirmationDialog/confirmationDialog.html
index 82b302d2ca7..f015c91338f 100644
--- a/framework/default/ortoo-core/default/lwc/confirmationDialog/confirmationDialog.html
+++ b/framework/default/ortoo-core/default/lwc/confirmationDialog/confirmationDialog.html
@@ -2,6 +2,7 @@
@@ -13,24 +14,25 @@
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/framework/default/ortoo-core/default/lwc/confirmationDialog/confirmationDialog.js b/framework/default/ortoo-core/default/lwc/confirmationDialog/confirmationDialog.js
index d7007326da3..8bd4f37dbb7 100644
--- a/framework/default/ortoo-core/default/lwc/confirmationDialog/confirmationDialog.js
+++ b/framework/default/ortoo-core/default/lwc/confirmationDialog/confirmationDialog.js
@@ -1,4 +1,5 @@
import { LightningElement, api } from 'lwc';
+import configureElementIdGenerator from 'c/elementIdGenerator';
import CONFIRM_LABEL from '@salesforce/label/c.ortoo_core_confirm';
import CANCEL_LABEL from '@salesforce/label/c.ortoo_core_cancel';
@@ -70,7 +71,16 @@ export default class ConfirmationDialog extends LightningElement {
@api visible;
+ @api ortooElemIdPrefix = 'confirmation';
+
+ ortooIdConfiguration = {
+ modalId: '',
+ cancelId: 'cancel',
+ confirmId: 'confirm',
+ }
+
connectedCallback() {
+ configureElementIdGenerator( this );
this.confirmLabel = this.confirmLabel ? this.confirmLabel : buttonLabels[ this.type ].confirm;
this.cancelLabel = this.cancelLabel ? this.cancelLabel : buttonLabels[ this.type ].cancel;
}
diff --git a/framework/default/ortoo-core/default/lwc/elementFinder/__tests__/elementFinder.test.js b/framework/default/ortoo-core/default/lwc/elementFinder/__tests__/elementFinder.test.js
new file mode 100644
index 00000000000..4db42853b60
--- /dev/null
+++ b/framework/default/ortoo-core/default/lwc/elementFinder/__tests__/elementFinder.test.js
@@ -0,0 +1,33 @@
+import configureFindElement from 'c/elementFinder';
+
+describe( 'configureFindElement', () => {
+ it( 'will add a "findElement" function against the passed object', () => {
+
+ const objectToRunAgainst = {};
+
+ configureFindElement( objectToRunAgainst );
+
+ expect( objectToRunAgainst.findElement ).toBeDefined();
+ });
+});
+
+describe( 'findElement', () => {
+ it( 'will ask the bound object for the element with the specified data-ortoo-elem-id', () => {
+
+ const mockQuerySelector = jest.fn();
+
+ const objectToRunAgainst = {
+ template: {
+ querySelector: mockQuerySelector
+ }
+ };
+ mockQuerySelector.mockReturnValueOnce( 'the element' );
+
+ configureFindElement( objectToRunAgainst );
+
+ const response = objectToRunAgainst.findElement( 'test-element' );
+
+ expect( response ).toBe( 'the element' );
+ expect( mockQuerySelector ).toBeCalledWith( '[data-ortoo-elem-id="test-element"]' );
+ });
+});
\ No newline at end of file
diff --git a/framework/default/ortoo-core/default/lwc/elementFinder/elementFinder.js b/framework/default/ortoo-core/default/lwc/elementFinder/elementFinder.js
new file mode 100644
index 00000000000..eb1f3d8eab7
--- /dev/null
+++ b/framework/default/ortoo-core/default/lwc/elementFinder/elementFinder.js
@@ -0,0 +1,18 @@
+/**
+ * Will bind a function that will allow the bound LWC to 'findElement' passing an Ortoo Element Id.
+ *
+ * Should be bound in the connectedCallback of the LWC. E.g.
+ *
+ * connectedCallback() {
+ * configureFindElement( this );
+ * }
+ *
+ * @param bindTo The LWC to bind this function to
+ */
+const configureFindElement = bindTo => {
+ bindTo.findElement = function( ortooElemId ) {
+ return this.template.querySelector( `[data-ortoo-elem-id="${ortooElemId}"]` );
+ }.bind( bindTo );
+};
+
+export default configureFindElement;
\ No newline at end of file
diff --git a/framework/default/ortoo-core/default/lwc/elementFinder/elementFinder.js-meta.xml b/framework/default/ortoo-core/default/lwc/elementFinder/elementFinder.js-meta.xml
new file mode 100644
index 00000000000..884004a97fa
--- /dev/null
+++ b/framework/default/ortoo-core/default/lwc/elementFinder/elementFinder.js-meta.xml
@@ -0,0 +1,5 @@
+
+
+ 52.0
+ false
+
\ No newline at end of file
diff --git a/framework/default/ortoo-core/default/lwc/elementIdGenerator/__tests__/elementIdGenerator.test.js b/framework/default/ortoo-core/default/lwc/elementIdGenerator/__tests__/elementIdGenerator.test.js
new file mode 100644
index 00000000000..96ac16533a2
--- /dev/null
+++ b/framework/default/ortoo-core/default/lwc/elementIdGenerator/__tests__/elementIdGenerator.test.js
@@ -0,0 +1,93 @@
+import configureElementIdGenerator from 'c/elementIdGenerator';
+
+describe('configureElementIdGenerator', () => {
+ afterEach(() => {
+ });
+
+ it( 'will add properties to the passed object based on the ortooIdConfiguration property names with values built from the combination of the ortooIdConfiguration property values and the ortooElemIdPrefix', () => {
+
+ const objectToRunAgainst = {
+ ortooElemIdPrefix: 'theprefix',
+ ortooIdConfiguration: {
+ field1: 'thefield1',
+ field2: 'thefield2'
+ }
+ };
+
+ configureElementIdGenerator( objectToRunAgainst );
+
+ expect( objectToRunAgainst.field1 ).toBe( 'theprefix-thefield1' );
+ expect( objectToRunAgainst.field2 ).toBe( 'theprefix-thefield2' );
+ });
+
+ it( 'will skip the value if it is not specified', () => {
+
+ const objectToRunAgainst = {
+ ortooElemIdPrefix: 'theprefix',
+ ortooIdConfiguration: {
+ field1: '',
+ field2: 'thefield2'
+ }
+ };
+
+ configureElementIdGenerator( objectToRunAgainst );
+
+ expect( objectToRunAgainst.field1 ).toBe( 'theprefix' );
+ expect( objectToRunAgainst.field2 ).toBe( 'theprefix-thefield2' );
+ });
+
+ it( 'will throw an error if given an object with no ortooElemIdPrefix property', () => {
+
+ const objectToRunAgainst = {
+ ortooIdConfiguration: {
+ field1: '',
+ field2: 'thefield2'
+ }
+ };
+
+ expect( () => configureElementIdGenerator( objectToRunAgainst ) ).toThrow();
+ });
+ it( 'will throw an error if given an object with an empty ortooElemIdPrefix property', () => {
+
+ const objectToRunAgainst = {
+ ortooElemIdPrefix: '',
+ ortooIdConfiguration: {
+ field1: '',
+ field2: 'thefield2'
+ }
+ };
+
+ expect( () => configureElementIdGenerator( objectToRunAgainst ) ).toThrow();
+ });
+ it( 'will throw an error if given an object with a null ortooElemIdPrefix property', () => {
+
+ const objectToRunAgainst = {
+ ortooElemIdPrefix: null,
+ ortooIdConfiguration: {
+ field1: '',
+ field2: 'thefield2'
+ }
+ };
+
+ expect( () => configureElementIdGenerator( objectToRunAgainst ) ).toThrow();
+ });
+
+ it( 'will throw an error if given an object with no ortooIdConfiguration property', () => {
+
+ const objectToRunAgainst = {
+ ortooElemIdPrefix: 'theprefix'
+ };
+
+ expect( () => configureElementIdGenerator( objectToRunAgainst ) ).toThrow();
+ });
+
+ it( 'will not throw an error if given an object with an empty object for the ortooIdConfiguration property', () => {
+
+ const objectToRunAgainst = {
+ ortooElemIdPrefix: 'theprefix',
+ ortooIdConfiguration: {}
+ };
+
+ expect( () => configureElementIdGenerator( objectToRunAgainst ) ).not.toThrow();
+ });
+});
\ No newline at end of file
diff --git a/framework/default/ortoo-core/default/lwc/elementIdGenerator/elementIdGenerator.js b/framework/default/ortoo-core/default/lwc/elementIdGenerator/elementIdGenerator.js
new file mode 100644
index 00000000000..ab4aec4dceb
--- /dev/null
+++ b/framework/default/ortoo-core/default/lwc/elementIdGenerator/elementIdGenerator.js
@@ -0,0 +1,25 @@
+const generateId = function( suffix ) {
+ return suffix ? this.ortooElemIdPrefix + '-' + suffix : this.ortooElemIdPrefix;;
+}
+
+const configureElementIdGenerator = function( bindTo ) {
+
+ if ( ! bindTo.ortooIdConfiguration ) {
+ throw 'configureGenerator called against an object with no ortooIdConfiguration member variable - this should contain the mapping of properties to their suffixes: ' + bindTo;
+ }
+
+ if ( ! bindTo.ortooElemIdPrefix ) {
+ throw new 'configureGenerator called against an object with no ortooElemIdPrefix member variable - this should contain the Id prefix' + bindTo;
+ }
+
+ for ( const idName in bindTo.ortooIdConfiguration ) {
+
+ Object.defineProperty( bindTo, idName, {
+ get: function() {
+ return generateId.call( bindTo, bindTo.ortooIdConfiguration[ idName ] );
+ }
+ });
+ }
+}
+
+export default configureElementIdGenerator;
\ No newline at end of file
diff --git a/framework/default/ortoo-core/default/lwc/elementIdGenerator/elementIdGenerator.js-meta.xml b/framework/default/ortoo-core/default/lwc/elementIdGenerator/elementIdGenerator.js-meta.xml
new file mode 100644
index 00000000000..884004a97fa
--- /dev/null
+++ b/framework/default/ortoo-core/default/lwc/elementIdGenerator/elementIdGenerator.js-meta.xml
@@ -0,0 +1,5 @@
+
+
+ 52.0
+ false
+
\ No newline at end of file
diff --git a/framework/default/ortoo-core/default/lwc/errorRenderer/__tests__/errorRenderer.test.js b/framework/default/ortoo-core/default/lwc/errorRenderer/__tests__/errorRenderer.test.js
index 73c62b38b27..3a3ec6b4cb0 100644
--- a/framework/default/ortoo-core/default/lwc/errorRenderer/__tests__/errorRenderer.test.js
+++ b/framework/default/ortoo-core/default/lwc/errorRenderer/__tests__/errorRenderer.test.js
@@ -1,6 +1,6 @@
import displayError from 'c/errorRenderer';
-let showToastEvent = function ShowToastEvent( details ) {
+const showToastEvent = function ShowToastEvent( details ) {
this.detail = details
};
@@ -8,7 +8,7 @@ jest.mock('lightning/platformShowToastEvent', () => ({
ShowToastEvent: showToastEvent
}));
-describe('c-error-renderer', () => {
+describe('displayError', () => {
afterEach(() => {
});
@@ -16,24 +16,52 @@ describe('c-error-renderer', () => {
console.error = jest.fn();
- let objectToRunAgainst = {
+ const objectToRunAgainst = {
dispatchEvent: jest.fn()
};
- let error = 'An error string';
+ const error = 'An error string';
displayError.call( objectToRunAgainst, error );
expect( objectToRunAgainst.dispatchEvent ).toBeCalled();
- let dispatchedEvent = objectToRunAgainst.dispatchEvent.mock.calls[0][0];
+ const dispatchedEvent = objectToRunAgainst.dispatchEvent.mock.calls[0][0];
expect( dispatchedEvent.detail.title ).toBe( 'c.ortoo_core_error_title' );
expect( dispatchedEvent.detail.message ).toBe( error );
expect( dispatchedEvent.detail.variant ).toBe( 'error' );
expect( console.error ).toHaveBeenCalledTimes( 1 );
- let reportedError = console.error.mock.calls[0][0];
+ const reportedError = console.error.mock.calls[0][0];
+
+ expect( reportedError ).toBe( error );
+ });
+
+ it( 'When the passed javascript error is a string, will raise a toast with the message as the error message', () => {
+
+ console.error = jest.fn();
+
+ const objectToRunAgainst = {
+ dispatchEvent: jest.fn()
+ };
+
+ const error = {
+ message: 'javascript error format'
+ };
+
+ displayError.call( objectToRunAgainst, error );
+
+ expect( objectToRunAgainst.dispatchEvent ).toBeCalled();
+
+ const dispatchedEvent = objectToRunAgainst.dispatchEvent.mock.calls[0][0];
+
+ expect( dispatchedEvent.detail.title ).toBe( 'c.ortoo_core_error_title' );
+ expect( dispatchedEvent.detail.message ).toBe( 'javascript error format' );
+ expect( dispatchedEvent.detail.variant ).toBe( 'error' );
+
+ expect( console.error ).toHaveBeenCalledTimes( 1 );
+ const reportedError = console.error.mock.calls[0][0];
expect( reportedError ).toBe( error );
});
@@ -42,11 +70,11 @@ describe('c-error-renderer', () => {
console.error = jest.fn();
- let objectToRunAgainst = {
+ const objectToRunAgainst = {
dispatchEvent: jest.fn()
};
- let error = {
+ const error = {
body: {
message: 'An error message in the body'
}
@@ -56,14 +84,14 @@ describe('c-error-renderer', () => {
expect( objectToRunAgainst.dispatchEvent ).toBeCalled();
- let dispatchedEvent = objectToRunAgainst.dispatchEvent.mock.calls[0][0];
+ const dispatchedEvent = objectToRunAgainst.dispatchEvent.mock.calls[0][0];
expect( dispatchedEvent.detail.title ).toBe( 'c.ortoo_core_error_title' );
expect( dispatchedEvent.detail.message ).toBe( 'An error message in the body' );
expect( dispatchedEvent.detail.variant ).toBe( 'error' );
expect( console.error ).toHaveBeenCalledTimes( 1 );
- let reportedError = console.error.mock.calls[0][0];
+ const reportedError = console.error.mock.calls[0][0];
expect( reportedError ).toBe( error );
});
diff --git a/framework/default/ortoo-core/default/lwc/errorRenderer/errorRenderer.js b/framework/default/ortoo-core/default/lwc/errorRenderer/errorRenderer.js
index b3720e88680..43ed94e408c 100644
--- a/framework/default/ortoo-core/default/lwc/errorRenderer/errorRenderer.js
+++ b/framework/default/ortoo-core/default/lwc/errorRenderer/errorRenderer.js
@@ -1,5 +1,4 @@
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
-
import ERROR_TITLE from '@salesforce/label/c.ortoo_core_error_title';
/**
@@ -7,11 +6,19 @@ import ERROR_TITLE from '@salesforce/label/c.ortoo_core_error_title';
*/
const displayError = function( error ) {
- let title = ERROR_TITLE;
+ let title = ERROR_TITLE; // should be a label
+
+ // By default we assume we have a string for the error
let message = error;
console.error( error );
+ // Javascript Errors will have message set
+ if ( error.message ) {
+ message = error.message;
+ }
+
+ // Apex Exceptions will have body.message set
if ( error.body ) {
message = error.body.message;
}
diff --git a/framework/default/ortoo-core/default/lwc/formValidator/__tests__/formValidator.test.js b/framework/default/ortoo-core/default/lwc/formValidator/__tests__/formValidator.test.js
index deee97d110e..53ba3e6d961 100644
--- a/framework/default/ortoo-core/default/lwc/formValidator/__tests__/formValidator.test.js
+++ b/framework/default/ortoo-core/default/lwc/formValidator/__tests__/formValidator.test.js
@@ -1,6 +1,6 @@
import reportValidity from 'c/formValidator';
-let showToastEvent = function ShowToastEvent( details ) {
+const showToastEvent = function ShowToastEvent( details ) {
this.detail = details
};
@@ -8,16 +8,16 @@ jest.mock('lightning/platformShowToastEvent', () => ({
ShowToastEvent: showToastEvent
}));
-describe('c-form-validator', () => {
+describe('reportValidity', () => {
afterEach(() => {
});
it( 'When called against an object, will ask it for all the data-validateable elements and then call reportValidity against each one. If all are true, returns true', () => {
- let mockQuerySelector = jest.fn();
- let mockDispatchEvent = jest.fn();
+ const mockQuerySelector = jest.fn();
+ const mockDispatchEvent = jest.fn();
- let objectToRunAgainst = {
+ const objectToRunAgainst = {
dispatchEvent: mockDispatchEvent,
template: {
querySelectorAll: mockQuerySelector
@@ -31,7 +31,7 @@ describe('c-form-validator', () => {
]
);
- let response = reportValidity.call( objectToRunAgainst );
+ const response = reportValidity.call( objectToRunAgainst );
expect( response ).toBe( true );
@@ -43,10 +43,10 @@ describe('c-form-validator', () => {
it( 'When an element reportValidity returns false, will return false and raise a toast', () => {
- let mockQuerySelector = jest.fn();
- let mockDispatchEvent = jest.fn();
+ const mockQuerySelector = jest.fn();
+ const mockDispatchEvent = jest.fn();
- let objectToRunAgainst = {
+ const objectToRunAgainst = {
dispatchEvent: mockDispatchEvent,
template: {
querySelectorAll: mockQuerySelector
@@ -60,13 +60,13 @@ describe('c-form-validator', () => {
]
);
- let response = reportValidity.call( objectToRunAgainst );
+ const response = reportValidity.call( objectToRunAgainst );
expect( response ).toBe( false );
expect( mockDispatchEvent ).toHaveBeenCalledTimes( 1 );
- let dispatchedEvent = mockDispatchEvent.mock.calls[0][0];
+ const dispatchedEvent = mockDispatchEvent.mock.calls[0][0];
expect( dispatchedEvent.detail.title ).toBe( 'c.ortoo_core_error_title' );
expect( dispatchedEvent.detail.message ).toBe( 'c.ortoo_core_validation_errors_occurred' );
@@ -76,17 +76,17 @@ describe('c-form-validator', () => {
it( 'When an element reportValidity returns false, will still call against all the others', () => {
// this ensures that every object is checked - otherwise not all errors will be reported properly
- let mockQuerySelector = jest.fn();
- let mockDispatchEvent = jest.fn();
+ const mockQuerySelector = jest.fn();
+ const mockDispatchEvent = jest.fn();
- let objectToRunAgainst = {
+ const objectToRunAgainst = {
dispatchEvent: mockDispatchEvent,
template: {
querySelectorAll: mockQuerySelector
}
};
- let mockSelectorReturn = [
+ const mockSelectorReturn = [
{ reportValidity: jest.fn().mockReturnValueOnce( true ) },
{ reportValidity: jest.fn().mockReturnValueOnce( false ) },
{ reportValidity: jest.fn().mockReturnValueOnce( false ) },
@@ -96,9 +96,92 @@ describe('c-form-validator', () => {
mockQuerySelector.mockReturnValueOnce( mockSelectorReturn );
- let response = reportValidity.call( objectToRunAgainst );
+ const response = reportValidity.call( objectToRunAgainst );
expect( response ).toBe( false );
mockSelectorReturn.forEach( thisElement => expect( thisElement.reportValidity ).toHaveBeenCalledTimes( 1 ) );
});
+
+ it( 'When an element reportValidity returns false, but options say to not show a toast, will not show a toast', () => {
+
+ const mockQuerySelector = jest.fn();
+ const mockDispatchEvent = jest.fn();
+
+ const objectToRunAgainst = {
+ dispatchEvent: mockDispatchEvent,
+ template: {
+ querySelectorAll: mockQuerySelector
+ }
+ };
+
+ mockQuerySelector.mockReturnValueOnce(
+ [
+ { reportValidity: () => true },
+ { reportValidity: () => false }
+ ]
+ );
+
+ reportValidity.call( objectToRunAgainst, { showToast: false } );
+ expect( mockDispatchEvent ).toHaveBeenCalledTimes( 0 );
+
+ });
+
+ it( 'When an element reportValidity returns false, and options say to show a toast, will show a toast', () => {
+
+ const mockQuerySelector = jest.fn();
+ const mockDispatchEvent = jest.fn();
+
+ const objectToRunAgainst = {
+ dispatchEvent: mockDispatchEvent,
+ template: {
+ querySelectorAll: mockQuerySelector
+ }
+ };
+
+ mockQuerySelector.mockReturnValueOnce(
+ [
+ { reportValidity: () => true },
+ { reportValidity: () => false }
+ ]
+ );
+
+ reportValidity.call( objectToRunAgainst, { showToast: true } );
+ expect( mockDispatchEvent ).toHaveBeenCalledTimes( 1 );
+
+ });
+ it( 'When an element reportValidity returns false, and given alternative error title and message, will show a toast with the specified text', () => {
+
+ const mockQuerySelector = jest.fn();
+ const mockDispatchEvent = jest.fn();
+
+ const objectToRunAgainst = {
+ dispatchEvent: mockDispatchEvent,
+ template: {
+ querySelectorAll: mockQuerySelector
+ }
+ };
+
+ mockQuerySelector.mockReturnValueOnce(
+ [
+ { reportValidity: () => true },
+ { reportValidity: () => false }
+ ]
+ );
+
+ const customTitle = 'custom title';
+ const customMessage = 'custom message';
+ const customVariant = 'warning';
+
+ const response = reportValidity.call( objectToRunAgainst, { validationErrorTitle: customTitle, validationErrorMessage: customMessage, toastVariant: customVariant } );
+
+ expect( response ).toBe( false );
+
+ expect( mockDispatchEvent ).toHaveBeenCalledTimes( 1 );
+
+ const dispatchedEvent = mockDispatchEvent.mock.calls[0][0];
+
+ expect( dispatchedEvent.detail.title ).toBe( customTitle );
+ expect( dispatchedEvent.detail.message ).toBe( customMessage );
+ expect( dispatchedEvent.detail.variant ).toBe( customVariant );
+ });
});
\ No newline at end of file
diff --git a/framework/default/ortoo-core/default/lwc/formValidator/formValidator.html b/framework/default/ortoo-core/default/lwc/formValidator/formValidator.html
deleted file mode 100644
index 27e0f69560f..00000000000
--- a/framework/default/ortoo-core/default/lwc/formValidator/formValidator.html
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/framework/default/ortoo-core/default/lwc/formValidator/formValidator.js b/framework/default/ortoo-core/default/lwc/formValidator/formValidator.js
index bcc3924b91e..02ff3ad1df8 100644
--- a/framework/default/ortoo-core/default/lwc/formValidator/formValidator.js
+++ b/framework/default/ortoo-core/default/lwc/formValidator/formValidator.js
@@ -13,10 +13,22 @@ import VALIDATION_MESSAGE from '@salesforce/label/c.ortoo_core_validation_errors
*
* @returns Boolean States if the bound LWC is regarded as valid.
*/
-const reportValidity = function() {
+const reportValidity = function( options ) {
+
+ !options && ( options = {} );
+
+ !options.hasOwnProperty( 'showToast' ) && ( options.showToast = true );
+ !options.hasOwnProperty( 'toastVariant' ) && ( options.toastVariant = 'error' );
+
+ !options.validationErrorTitle && ( options.validationErrorTitle = ERROR_TITLE );
+ !options.validationErrorMessage && ( options.validationErrorMessage = VALIDATION_MESSAGE );
const validateableElements = this.template.querySelectorAll( '[data-validateable]' );
+ if ( !validateableElements ) {
+ return true;
+ }
+
let hasValidationError = false;
validateableElements.forEach( thisElement => {
if ( ! thisElement.reportValidity() ) {
@@ -24,11 +36,11 @@ const reportValidity = function() {
}
});
- if ( hasValidationError ) {
+ if ( hasValidationError && options.showToast ) {
const toastEvent = new ShowToastEvent({
- title: ERROR_TITLE,
- message: VALIDATION_MESSAGE,
- variant: 'error',
+ title: options.validationErrorTitle,
+ message: options.validationErrorMessage,
+ variant: options.toastVariant,
});
this.dispatchEvent( toastEvent );
}
diff --git a/framework/default/ortoo-core/default/lwc/modal/__tests__/modal.test.js b/framework/default/ortoo-core/default/lwc/modal/__tests__/modal.test.js
index 888d00c5c98..ce6e25cd9b2 100644
--- a/framework/default/ortoo-core/default/lwc/modal/__tests__/modal.test.js
+++ b/framework/default/ortoo-core/default/lwc/modal/__tests__/modal.test.js
@@ -117,12 +117,26 @@ describe('c-modal', () => {
return Promise.resolve()
.then( () => {
const clickEvent = new CustomEvent( 'click', {} );
- return element.shadowRoot.querySelector( 'button[data-name="cancel-cross"]' ).dispatchEvent( clickEvent );
+ return element.shadowRoot.querySelector( '[data-ortoo-elem-id="modal-closecross"]' ).dispatchEvent( clickEvent );
})
.then( () => {
expect( cancelHandler ).toHaveBeenCalled();
});
});
+ it( 'Will use the passed prefix to define the element ids', () => {
+ const element = createElement('c-modal', {
+ is: Modal
+ });
+ element.visible = true;
+ element.ortooElemIdPrefix = 'definedmodel'
+
+ document.body.appendChild( element );
+
+ return Promise.resolve()
+ .then( () => {
+ expect( element.shadowRoot.querySelector( '[data-ortoo-elem-id="definedmodel-closecross"]' ) ).not.toBe( null );
+ })
+ });
});
\ No newline at end of file
diff --git a/framework/default/ortoo-core/default/lwc/modal/modal.html b/framework/default/ortoo-core/default/lwc/modal/modal.html
index a2b3f208f6a..650722d99be 100644
--- a/framework/default/ortoo-core/default/lwc/modal/modal.html
+++ b/framework/default/ortoo-core/default/lwc/modal/modal.html
@@ -13,10 +13,10 @@