From a331450acd6334baa1c5f07668865894f3432430 Mon Sep 17 00:00:00 2001 From: Christian Schwabe Date: Wed, 23 Dec 2020 10:07:26 +0100 Subject: [PATCH] Try to implement test round abount empApi. --- .../__tests__/data/prefix.json | 1 + .../formulaShareRulesListViewEmpApi.test.js | 60 ++++++++++++++++ .../formulaShareRulesListView.js | 69 ++++++++++++++----- fs-core/test/jest-mocks/lightning/empApi.js | 33 +++++++++ jest.config.js | 4 +- 5 files changed, 150 insertions(+), 17 deletions(-) create mode 100644 fs-core/main/default/lwc/formulaShareRulesListView/__tests__/data/prefix.json create mode 100644 fs-core/main/default/lwc/formulaShareRulesListView/__tests__/formulaShareRulesListViewEmpApi.test.js create mode 100644 fs-core/test/jest-mocks/lightning/empApi.js diff --git a/fs-core/main/default/lwc/formulaShareRulesListView/__tests__/data/prefix.json b/fs-core/main/default/lwc/formulaShareRulesListView/__tests__/data/prefix.json new file mode 100644 index 0000000..3cc762b --- /dev/null +++ b/fs-core/main/default/lwc/formulaShareRulesListView/__tests__/data/prefix.json @@ -0,0 +1 @@ +"" \ No newline at end of file diff --git a/fs-core/main/default/lwc/formulaShareRulesListView/__tests__/formulaShareRulesListViewEmpApi.test.js b/fs-core/main/default/lwc/formulaShareRulesListView/__tests__/formulaShareRulesListViewEmpApi.test.js new file mode 100644 index 0000000..9ef70c6 --- /dev/null +++ b/fs-core/main/default/lwc/formulaShareRulesListView/__tests__/formulaShareRulesListViewEmpApi.test.js @@ -0,0 +1,60 @@ +import { createElement } from 'lwc'; +import FormulaShareRulesListView from 'c/formulaShareRulesListView'; +import { registerLdsTestWireAdapter } from '@salesforce/sfdx-lwc-jest'; +import { getTreeGridData } from '@salesforce/apex/FormulaShareRulesListViewController.getTreeGridData'; +import getNamespacePrefix from '@salesforce/apex/FormulaShareUtilities.getNamespacePrefix'; + +import { jestMockPublish } from 'lightning/empApi'; + +// Register a test wire adapter. +const getTreeGridDataWireAdapter = registerLdsTestWireAdapter(getTreeGridData); +const getPrefixWireAdapter = registerLdsTestWireAdapter(getNamespacePrefix); + +// Import mock data to send through the wire adapter. +const mockExampleTreeGridData = require('./data/exampleTreeGridData.json'); +const mockPrefixData = require('./data/prefix.json'); + +// eslint-disable-next-line no-undef +const flushPromises = () => new Promise(setImmediate); + +describe('c-formula-share-rules-list-view', () => { + afterEach(() => { + // The jsdom instance is shared across test cases in a single file so reset the DOM + while (document.body.firstChild) { + document.body.removeChild(document.body.firstChild); + } + + // Prevent data saved on mocks from leaking between tests + jest.clearAllMocks(); + }); + + it('Test activate events (Positive).', async () => { + // Create initial lwc element and attach to virtual DOM. + const element = createElement('c-formula-share-rules-list-view', { + is: FormulaShareRulesListView + }); + document.body.appendChild(element); + + getPrefixWireAdapter.emit(mockPrefixData); + getTreeGridDataWireAdapter.emit(mockExampleTreeGridData); + + // Make sure async subscribe call in connectedCallback completes + await flushPromises(); + + // connectedCallback is now complete, but no Platform Events have + // been published yet. Make assertions here about the state of your + // component prior to receiving the Platform Events. + + // Mock-publish a Platform Event and await the promise + await jestMockPublish('/event/FormulaShare_List_Update__e', { + data: { + payload: { + Object_Label__c: 'Account', + Type__c: 'activate' + } + } + }); + // Now any DOM updates that depend on the Platform Event should + // have rendered; assert about them here. + }); +}); \ No newline at end of file diff --git a/fs-core/main/default/lwc/formulaShareRulesListView/formulaShareRulesListView.js b/fs-core/main/default/lwc/formulaShareRulesListView/formulaShareRulesListView.js index 86014a5..cc467c6 100644 --- a/fs-core/main/default/lwc/formulaShareRulesListView/formulaShareRulesListView.js +++ b/fs-core/main/default/lwc/formulaShareRulesListView/formulaShareRulesListView.js @@ -7,6 +7,7 @@ import getTreeGridData from '@salesforce/apex/FormulaShareRulesListViewControlle import recalculateSharing from '@salesforce/apex/FormulaShareRulesListViewController.recalculateSharing'; import activateDeactivate from '@salesforce/apex/FormulaShareRulesListViewController.activateDeactivate'; import getNamespacePrefix from '@salesforce/apex/FormulaShareUtilities.getNamespacePrefix'; +import isContactSharingControlledByAccount from '@salesforce/apex/FormulaShareUtilities.isContactSharingControlledByAccount'; export default class TreeGrid extends NavigationMixin(LightningElement) { @@ -142,7 +143,7 @@ export default class TreeGrid extends NavigationMixin(LightningElement) { } else if(error) { - //console.log('Error fetching data from Salesforce'); + console.log('Error fetching data from Salesforce'); this.showError(error, 'Error fetching data from Salesforce'); } } @@ -187,43 +188,70 @@ export default class TreeGrid extends NavigationMixin(LightningElement) { } } + prefix; + @wire(getNamespacePrefix) + wiredNamespacePrefix({ error, data }) + { + if (data) { + console.log('>>>data: ' + JSON.stringify(data, null, '\t')); + + this.prefix = data; + } else if (error) { + console.error('>>>error: ' + error); + this.prefix = undefined; + console.log('Error getting namespace prefix'); + this.showError(error, 'Error getting namespace prefix'); + } + } // Subcribes to list platform event, and refresh treegrid each time event is received createOrUpdate = false; manageRefreshEvents() { + console.log('>>>manageRefreshEvents.'); // Get namespace prefix - getNamespacePrefix() - .then((prefix) => { - //console.log('Got namespace: '+prefix); + /*getNamespacePrefix() + .then((prefix) => {*/ + try { + console.log('Got namespace: '+ JSON.stringify(this.prefix, null, '\t')); // Subscribe to list update events (raised by batch job and on rule activate/deactivate) const listUpdateCallback = (response) => { - //console.log('Received Refresh Event'); + console.log('Received Refresh Event'); this.refreshView(); }; - subscribe('/event/'+prefix+'FormulaShare_List_Update__e', -1, listUpdateCallback).then(response => { - //console.log('Successfully subscribed to : ', JSON.stringify(response.channel)); + console.log('#1'); + subscribe('/event/'+this.prefix+'FormulaShare_List_Update__e', -1, listUpdateCallback) + .then(response => { + console.log('Successfully subscribed to : ', JSON.stringify(response.channel)); + }) + .catch(error => { + console.error('>>>error 2: ', JSON.stringify(error)); }); - + console.log('#2'); // Scubscribe to dml events (raised by on rule create/edit) const dmlUpdateCallback = (response) => { if(response.data.payload.Successful__c || response.data.payload.sdfs__Successful__c) { - //console.log('Received FormulaShare_Rule_DML__e'); + console.log('Received FormulaShare_Rule_DML__e'); this.createOrUpdate = true; this.refreshView(); } }; + console.log('#3'); subscribe('/event/'+prefix+'FormulaShare_Rule_DML__e', -1, dmlUpdateCallback).then(response => { - //console.log('List component subscribed to : ', JSON.stringify(response.channel)); + console.log('List component subscribed to : ', JSON.stringify(response.channel)); }); - - }) - .catch(error => { - //console.log('Error getting namespace prefix'); + console.log('#4'); + } catch (error) { + console.error('>>>error: ', JSON.stringify(error)); + } + + } + /*.catch(error => { + console.log('Error getting namespace prefix'); this.showError(error, 'Error getting namespace prefix'); }); - } + }*/ // Set available drop-down actions for each grid row @@ -376,9 +404,14 @@ export default class TreeGrid extends NavigationMixin(LightningElement) { // Action method to update a rule to active/inactive spinnerClasses; activateDeactivate(row, actionName) { + console.log('>>>activateDeactivate.'); + console.log('>>>row: ' + JSON.stringify(row, null, '\t')); + console.log('>>>actionName: ' + JSON.stringify(actionName, null, '\t')); + const rowDeveloperName = row['developerName']; activateDeactivate({ ruleName : rowDeveloperName, type : actionName }) .then(() => { + console.log('then()'); this.processingLoad = true; this.spinnerClasses = 'processingMessage'; @@ -386,9 +419,10 @@ export default class TreeGrid extends NavigationMixin(LightningElement) { setTimeout(() => { this.spinnerClasses = 'processingMessage afterProcessingMessage'; }, 5000); + console.log('#1') }) .catch(error => { - //console.log('Error changing activation status'); + console.log('Error changing activation status'); this.showError(error, 'Error changing activation status') }); } @@ -423,6 +457,9 @@ export default class TreeGrid extends NavigationMixin(LightningElement) { // Called to trigger a toast message including a system error showError(error, toastTitle) { + console.log('>>>error: ' + JSON.stringify(error, null, '\t')); + console.log('>>>toastTitle: ' + JSON.stringify(toastTitle, null, '\t')); + let errorMessage = 'Unknown error'; if (Array.isArray(error.body)) { errorMessage = error.body.map(e => e.message).join(', '); diff --git a/fs-core/test/jest-mocks/lightning/empApi.js b/fs-core/test/jest-mocks/lightning/empApi.js new file mode 100644 index 0000000..c4bd9b6 --- /dev/null +++ b/fs-core/test/jest-mocks/lightning/empApi.js @@ -0,0 +1,33 @@ + +// https://salesforce.stackexchange.com/questions/297563/test-lightning-emp-api +// An object to store callbacks +const _channels = {}; + +// On subscribe, store the callback function and resolve the promise +export const subscribe = jest.fn((channel, replayId, onMessageCallback) => { + _channels[channel] = { onMessageCallback }; + Promise.resolve({ + id: "_" + Date.now(), + channel: channel, + replayId: replayId + }); +}); + +// I'm using isEmpEnabled in my component, so I have it set to return true +export const isEmpEnabled = jest.fn().mockResolvedValue(true); + +// A Jest-specific function for "publishing" your Platform Event +export const jestMockPublish = jest.fn((channel, message) => { + if ( + _channels[channel] && + _channels[channel].onMessageCallback instanceof Function + ) { + _channels[channel].onMessageCallback(message); + } + Promise.resolve(true); +}); + +// I just copied these from the standard lightning/empApi stub +export const unsubscribe = jest.fn().mockResolvedValue({}); +export const onError = jest.fn().mockResolvedValue(jest.fn()); +export const setDebugFlag = jest.fn().mockResolvedValue(); \ No newline at end of file diff --git a/jest.config.js b/jest.config.js index 50b8d39..9fc0914 100644 --- a/jest.config.js +++ b/jest.config.js @@ -13,7 +13,9 @@ module.exports = { '^lightning/uiRecordApi$': '/fs-core/test/jest-mocks/lightning/uiRecordApi', '^lightning/messageService$': - '/fs-core/test/jest-mocks/lightning/messageService' + '/fs-core/test/jest-mocks/lightning/messageService', + "^lightning/empApi$": + "/fs-core/test/jest-mocks/lightning/empApi" }, //setupFiles: ['jest-canvas-mock'], setupFilesAfterEnv,