Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand refresh view api recipes #922

Merged
merged 4 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions force-app/main/default/classes/AccountController.cls
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ public with sharing class AccountController {
return [SELECT Id, Name FROM Account WITH USER_MODE LIMIT 10];
}

@AuraEnabled(cacheable=true)
public static Integer getTotalNumber() {
return [SELECT COUNT() FROM Account WITH USER_MODE];
}

@AuraEnabled(cacheable=true)
public static Account getSingleAccount() {
return [
Expand Down
11 changes: 11 additions & 0 deletions force-app/main/default/classes/TestAccountController.cls
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ public class TestAccountController {
Assert.areEqual(10, accts.size());
}

@isTest
static void getTotalNumber_returnsCount() {
TestAccountController.createAccounts(10);

Test.startTest();
Integer accountNumber = AccountController.getTotalNumber();
Test.stopTest();

Assert.areEqual(10, accountNumber);
}

@isTest
static void getSingleAccount() {
TestAccountController.createAccounts(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@
<type>Region</type>
</flexiPageRegions>
<flexiPageRegions>
<itemInstances>
<componentInstance>
<componentName>viewToRefresh</componentName>
<identifier>c_viewToRefresh</identifier>
</componentInstance>
</itemInstances>
<name>region3</name>
<type>Region</type>
</flexiPageRegions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
</div>

<c-view-source source="lwc/dispatchRefreshEvent" slot="footer">
Refresh data in a view without reloading the page thanks to the
Create an account and refresh data in a view without reloading the
page thanks to the&nbsp;
<a
href="https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.data_refreshview"
target="_blank"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"apiName": "Contact",
"childRelationships": {},
"eTag": "846fdcd21a53214d447e578adbe263c6",
"fields": {
"Email": {
"displayValue": null,
"value": "amy@demo.net"
},
"Name": {
"displayValue": null,
"value": "Amy Taylor"
},
"Phone": {
"displayValue": null,
"value": "4152568563"
},
"Title": {
"displayValue": null,
"value": "VP of Engineering"
},
"Picture__c": {
"displayValue": null,
"value": "https://s3-us-west-2.amazonaws.com/dev-or-devrl-s3-bucket/sample-apps/people/amy_taylor.jpg"
}
},
"id": "0031700000pHcf8AAC",
"lastModifiedById": "00517000002fESIAA2",
"lastModifiedDate": "2019-02-15T10:33:07.000Z",
"recordTypeInfo": null,
"systemModstamp": "2019-02-15T10:33:07.000Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"apiName": "Contact",
"childRelationships": {},
"eTag": "846fdcd21a53214d447e578adbe263c6",
"fields": {
"Email": {
"displayValue": null,
"value": "amy@demo.net"
},
"Name": {
"displayValue": null,
"value": "Amy Taylor"
},
"Phone": {
"displayValue": null,
"value": "4152568563"
},
"Title": {
"displayValue": null,
"value": "VP of Engineering"
}
},
"id": "0031700000pHcf8AAC",
"lastModifiedById": "00517000002fESIAA2",
"lastModifiedDate": "2019-02-15T10:33:07.000Z",
"recordTypeInfo": null,
"systemModstamp": "2019-02-15T10:33:07.000Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { createElement } from 'lwc';
import ViewToRefresh from 'c/viewToRefresh';
import getTotalNumber from '@salesforce/apex/AccountController.getTotalNumber';
import {
registerRefreshHandler,
unregisterRefreshHandler,
RefreshEvent
} from 'lightning/refresh';
import { refreshApex } from '@salesforce/apex';

// Mock Apex wire adapter
jest.mock(
'@salesforce/apex/AccountController.getTotalNumber',
() => {
const {
createApexTestWireAdapter
} = require('@salesforce/sfdx-lwc-jest');
return {
default: createApexTestWireAdapter(jest.fn())
};
},
{ virtual: true }
);

// Mock refreshApex module
jest.mock(
'@salesforce/apex',
() => {
return {
refreshApex: jest.fn(() => Promise.resolve())
};
},
{ virtual: true }
);

describe('c-view-to-refresh', () => {
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();
});

// Helper function to wait until the microtask queue is empty. This is needed for promise
// timing when calling imperative Apex.
async function flushPromises() {
return Promise.resolve();
}

it('registers itself as refresh handler on connected callback', () => {
// Create component
const element = createElement('c-view-to-refresh', {
is: ViewToRefresh
});
document.body.appendChild(element);

// Validate if pubsub got registered after connected to the DOM
expect(registerRefreshHandler).toHaveBeenCalled();
});

it('invokes getTotalNumber onload', async () => {
// Create component
const element = createElement('c-view-to-refresh', {
is: ViewToRefresh
});
document.body.appendChild(element);

// Emit data from @wire
getTotalNumber.emit(10);

// Wait for any asynchronous DOM updates
await flushPromises();

// Check UI
const divEl = element.shadowRoot.querySelector('div.account-number');
expect(divEl.textContent).toBe('Number of accounts: 10');
});

it('invokes refreshApex when RefreshEvent is listened', async () => {
// Create component
const element = createElement('c-view-to-refresh', {
is: ViewToRefresh
});
document.body.appendChild(element);

// Emit data from @wire
getTotalNumber.emit(10);

// Fire a RefreshEvent
element.dispatchEvent(new RefreshEvent());

// Wait for any asynchronous DOM updates
await flushPromises();
await flushPromises();
albarivas marked this conversation as resolved.
Show resolved Hide resolved

// Check refreshApex has been called
expect(refreshApex).toHaveBeenCalled();
});

it('unregisters itself as refresh handler on disconnected callback', () => {
// Create component
const element = createElement('c-view-to-refresh', {
is: ViewToRefresh
});
document.body.appendChild(element);

document.body.removeChild(element);

// Validate if pubsub got registered after connected to the DOM
expect(unregisterRefreshHandler).toHaveBeenCalled();
});

it('is accessible', async () => {
// Create component
const element = createElement('c-view-to-refresh', {
is: ViewToRefresh
});
document.body.appendChild(element);

// Assign mock value for resolved Apex promise
getTotalNumber.mockResolvedValue(10);

// Wait for any asynchronous DOM updates
await flushPromises();

// Check accessibility
await expect(element).toBeAccessible();
});
});
18 changes: 18 additions & 0 deletions force-app/main/default/lwc/viewToRefresh/viewToRefresh.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<lightning-card title="ViewToRefresh" icon-name="standard:account">
<div class="slds-var-m-around_medium">
<template lwc:if={numOfAccounts.data}>
<div class="account-number">
Number of accounts: {numOfAccounts.data}
</div>
</template>
<template lwc:elseif={numOfAccounts.error}>
<c-error-panel errors={numOfAccounts.error}></c-error-panel>
</template>
</div>

<c-view-source source="lwc/viewToRefresh" slot="footer">
Refresh a custom component when a Refresh View event is listened.
</c-view-source>
</lightning-card>
</template>
29 changes: 29 additions & 0 deletions force-app/main/default/lwc/viewToRefresh/viewToRefresh.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { LightningElement, wire } from 'lwc';
import getTotalNumber from '@salesforce/apex/AccountController.getTotalNumber';
import {
registerRefreshHandler,
unregisterRefreshHandler
} from 'lightning/refresh';
import { refreshApex } from '@salesforce/apex';

export default class ViewToRefresh extends LightningElement {
refreshHandlerID;

@wire(getTotalNumber)
numOfAccounts;

connectedCallback() {
this.refreshHandlerID = registerRefreshHandler(
this,
this.refreshHandler
);
}

disconnectedCallback() {
unregisterRefreshHandler(this.refreshHandlerID);
}

refreshHandler() {
refreshApex(this.numOfAccounts);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>59.0</apiVersion>
albarivas marked this conversation as resolved.
Show resolved Hide resolved
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
</targets>
</LightningComponentBundle>
27 changes: 24 additions & 3 deletions force-app/test/jest-mocks/lightning/refresh.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
/**
* Refresh Event base class
*/
export const RefreshEventName = 'lightning__refreshevent';

export const RefreshEventName = 'lightning__refresh';
export class RefreshEvent extends CustomEvent {
constructor() {
super(RefreshEventName, { bubbles: true, composed: true });
super(RefreshEventName, {
composed: true,
cancelable: true,
bubbles: true
});
}
}

let eventHandler;
let elementToRefresh;
export const registerRefreshHandler = jest.fn((element, handler) => {
elementToRefresh = element;
eventHandler = handler;
window.addEventListener(
RefreshEventName,
eventHandler.bind(elementToRefresh)
);
});

export const unregisterRefreshHandler = jest.fn((id) => {
window.removeEventListener(
RefreshEventName,
eventHandler.bind(elementToRefresh)
);
});
Loading