Skip to content

Commit

Permalink
feat: migrated from promises to async/await (#836)
Browse files Browse the repository at this point in the history
* feat: migrated from promises to async/await

* fix: clean test CSS selectors

* fix: removed duplicate lightning mocks
  • Loading branch information
pozil authored Aug 8, 2023
1 parent b959183 commit 22bd307
Show file tree
Hide file tree
Showing 28 changed files with 269 additions and 358 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ describe('c-apex-imperative-method', () => {

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

const detailEls = element.shadowRoot.querySelectorAll('p:not([class])');
expect(detailEls.length).toBe(APEX_CONTACTS_SUCCESS.length);
Expand All @@ -98,6 +99,7 @@ describe('c-apex-imperative-method', () => {

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

const errorPanelEl = element.shadowRoot.querySelector('c-error-panel');
expect(errorPanelEl).not.toBeNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ export default class ApexImperativeMethod extends LightningElement {
contacts;
error;

handleLoad() {
getContactList()
.then((result) => {
this.contacts = result;
this.error = undefined;
})
.catch((error) => {
this.error = error;
this.contacts = undefined;
});
async handleLoad() {
try {
this.contacts = await getContactList();
this.error = undefined;
} catch (error) {
this.contacts = undefined;
this.error = error;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,23 +66,18 @@ describe('c-apex-imperative-method-with-complex-params', () => {
document.body.appendChild(element);

// Select input field for simulating string user input
const inputStringEl = element.shadowRoot.querySelector(
'lightning-input[class="string-input"]'
);
const inputStringEl = element.shadowRoot.querySelector('.string-input');
inputStringEl.value = APEX_PARAMETER.someString;
inputStringEl.dispatchEvent(new CustomEvent('change'));

// Select input field for simulating number user input
const inputNumberEl = element.shadowRoot.querySelector(
'lightning-input[class="number-input"]'
);
const inputNumberEl = element.shadowRoot.querySelector('.number-input');
inputNumberEl.value = APEX_PARAMETER.someInteger;
inputNumberEl.dispatchEvent(new CustomEvent('change'));

// Select input field for simulating list item user input
const inputListItemEl = element.shadowRoot.querySelector(
'lightning-input[class="list-item-input"]'
);
const inputListItemEl =
element.shadowRoot.querySelector('.list-item-input');
inputListItemEl.value = APEX_PARAMETER.someList.length;
inputListItemEl.dispatchEvent(new CustomEvent('change'));

Expand Down Expand Up @@ -114,23 +109,18 @@ describe('c-apex-imperative-method-with-complex-params', () => {
document.body.appendChild(element);

// Select input field for simulating string user input
const inputStringEl = element.shadowRoot.querySelector(
'lightning-input[class="string-input"]'
);
const inputStringEl = element.shadowRoot.querySelector('.string-input');
inputStringEl.value = APEX_PARAMETER.someString;
inputStringEl.dispatchEvent(new CustomEvent('change'));

// Select input field for simulating number user input
const inputNumberEl = element.shadowRoot.querySelector(
'lightning-input[class="number-input"]'
);
const inputNumberEl = element.shadowRoot.querySelector('.number-input');
inputNumberEl.value = APEX_PARAMETER.someInteger;
inputNumberEl.dispatchEvent(new CustomEvent('change'));

// Select input field for simulating list item user input
const inputListItemEl = element.shadowRoot.querySelector(
'lightning-input[class="list-item-input"]'
);
const inputListItemEl =
element.shadowRoot.querySelector('.list-item-input');
inputListItemEl.value = APEX_PARAMETER.someList.length;
inputListItemEl.dispatchEvent(new CustomEvent('change'));

Expand All @@ -140,6 +130,7 @@ describe('c-apex-imperative-method-with-complex-params', () => {

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

// Select p for validating conditionally changed text content
const detailEl = element.shadowRoot.querySelector('p');
Expand All @@ -162,6 +153,7 @@ describe('c-apex-imperative-method-with-complex-params', () => {

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

const errorPanelEl = element.shadowRoot.querySelector('c-error-panel');
expect(errorPanelEl).not.toBeNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default class ApexImperativeMethodWithComplexParams extends LightningElem
this.listItemValue = event.target.value;
}

handleButtonClick() {
async handleButtonClick() {
// Creating the object that represents the shape
// of the Apex wrapper class.
let parameterObject = {
Expand All @@ -36,14 +36,12 @@ export default class ApexImperativeMethodWithComplexParams extends LightningElem

// Calling the imperative Apex method with the JSON
// object as parameter.
checkApexTypes({ wrapper: parameterObject })
.then((result) => {
this.message = result;
this.error = undefined;
})
.catch((error) => {
this.message = undefined;
this.error = error;
});
try {
this.message = await checkApexTypes({ wrapper: parameterObject });
this.error = undefined;
} catch (error) {
this.message = undefined;
this.error = error;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ describe('c-apex-imperative-method-with-params', () => {

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

// Select div for validating conditionally changed text content
const detailEls = element.shadowRoot.querySelectorAll('p');
Expand All @@ -125,6 +126,7 @@ describe('c-apex-imperative-method-with-params', () => {

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

const errorPanelEl = element.shadowRoot.querySelector('c-error-panel');
expect(errorPanelEl).not.toBeNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ export default class ApexImperativeMethodWithParams extends LightningElement {
this.searchKey = event.target.value;
}

handleSearch() {
findContacts({ searchKey: this.searchKey })
.then((result) => {
this.contacts = result;
this.error = undefined;
})
.catch((error) => {
this.error = error;
this.contacts = undefined;
});
async handleSearch() {
try {
this.contacts = await findContacts({ searchKey: this.searchKey });
this.error = undefined;
} catch (error) {
this.error = error;
this.contacts = undefined;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,20 @@ describe('c-apex-wire-method-with-complex-params', () => {
document.body.appendChild(element);

// Select input field for simulating string user input
const inputStringEl = element.shadowRoot.querySelector(
'lightning-input[class="string-input"]'
);
const inputStringEl =
element.shadowRoot.querySelector('.string-input');
inputStringEl.value = WIRE_INPUT.someString;
inputStringEl.dispatchEvent(new CustomEvent('change'));

// Select input field for simulating number user input
const inputNumberEl = element.shadowRoot.querySelector(
'lightning-input[class="number-input"]'
);
const inputNumberEl =
element.shadowRoot.querySelector('.number-input');
inputNumberEl.value = WIRE_INPUT.someInteger;
inputNumberEl.dispatchEvent(new CustomEvent('change'));

// Select input field for simulating list item user input
const inputListItemEl = element.shadowRoot.querySelector(
'lightning-input[class="list-item-input"]'
);
const inputListItemEl =
element.shadowRoot.querySelector('.list-item-input');
inputListItemEl.value = WIRE_INPUT.someList.length;
inputListItemEl.dispatchEvent(new CustomEvent('change'));

Expand All @@ -127,23 +124,20 @@ describe('c-apex-wire-method-with-complex-params', () => {
document.body.appendChild(element);

// Select input field for simulating string user input
const inputStringEl = element.shadowRoot.querySelector(
'lightning-input[class="string-input"]'
);
const inputStringEl =
element.shadowRoot.querySelector('.string-input');
inputStringEl.value = WIRE_INPUT.someString;
inputStringEl.dispatchEvent(new CustomEvent('change'));

// Select input field for simulating number user input
const inputNumberEl = element.shadowRoot.querySelector(
'lightning-input[class="number-input"]'
);
const inputNumberEl =
element.shadowRoot.querySelector('.number-input');
inputNumberEl.value = WIRE_INPUT.someInteger;
inputNumberEl.dispatchEvent(new CustomEvent('change'));

// Select input field for simulating list item user input
const inputListItemEl = element.shadowRoot.querySelector(
'lightning-input[class="list-item-input"]'
);
const inputListItemEl =
element.shadowRoot.querySelector('.list-item-input');
inputListItemEl.value = WIRE_INPUT.someList.length;
inputListItemEl.dispatchEvent(new CustomEvent('change'));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ describe('c-composition-contact-search', () => {

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

const contactTileEl =
element.shadowRoot.querySelector('c-contact-tile');
Expand Down Expand Up @@ -133,6 +134,7 @@ describe('c-composition-contact-search', () => {
// for the Promise chain to complete before ending the test and fail
// the test if the promise ends in the rejected state.
await flushPromises();
await flushPromises();

const errorPanelEl = element.shadowRoot.querySelector('c-error-panel');
expect(errorPanelEl).not.toBeNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,14 @@ export default class CompositionContactSearch extends LightningElement {
window.clearTimeout(this.delayTimeout);
const searchKey = event.target.value;
// eslint-disable-next-line @lwc/lwc/no-async-operation
this.delayTimeout = setTimeout(() => {
findContacts({ searchKey })
.then((result) => {
this.contacts = result;
this.error = undefined;
})
.catch((error) => {
this.error = error;
this.contacts = undefined;
});
this.delayTimeout = setTimeout(async () => {
try {
this.contacts = await findContacts({ searchKey });
this.error = undefined;
} catch (error) {
this.error = error;
this.contacts = undefined;
}
}, DELAY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,8 @@ describe('c-dispatch-refresh-event', () => {
// Wait for any asynchronous DOM updates.
await flushPromises();

// Validate dispatch refresh event on success
// Return a promise to wait for any asynchronous DOM updates.
return Promise.resolve().then(() => {
//Validate RefreshEvent is fired
expect(refreshHandler).toHaveBeenCalledTimes(1);
});
//Validate RefreshEvent is fired
expect(refreshHandler).toHaveBeenCalledTimes(1);
});

it('is accessible', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ describe('c-editRecordScreenAction', () => {
}
});

// 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('Test populates name from getRecord wire', async () => {
// Create initial element
const element = createElement('c-editRecordScreenAction', {
Expand All @@ -33,11 +39,12 @@ describe('c-editRecordScreenAction', () => {
// Emit data from @wire
await getRecord.emit(mockGetRecord);

// Return a promise to wait for any asynchronous DOM updates.
return Promise.resolve().then(() => {
expect(firstNameEl.value).toBe('User');
expect(lastNameEl.value).toBe('User');
});
// Wait for any asynchronous DOM updates.
await flushPromises();

// Check values
expect(firstNameEl.value).toBe('User');
expect(lastNameEl.value).toBe('User');
});

it('Test update record from updateRecord wire on save', async () => {
Expand All @@ -57,26 +64,23 @@ describe('c-editRecordScreenAction', () => {
const inputEl = element.shadowRoot.querySelectorAll('lightning-button');
inputEl[1].click();

// Return a promise to wait for any asynchronous DOM updates.
return Promise.resolve()
.then(() => {
const expectedFields = {
fields: {
Id: RECORD_ID,
FirstName: mockGetRecord.fields.FirstName.value,
LastName: mockGetRecord.fields.FirstName.value
}
};
expect(updateRecord).toHaveBeenCalledTimes(1);
expect(updateRecord).toHaveBeenCalledWith(expectedFields);
})
.then(() => {
// Check if toast event has been fired
expect(handler).toHaveBeenCalled();
expect(handler.mock.calls[0][0].detail.message).toBe(
TOAST_MESSAGE
);
});
// Wait for any asynchronous DOM updates.
await flushPromises();

// Check for record update
const expectedFields = {
fields: {
Id: RECORD_ID,
FirstName: mockGetRecord.fields.FirstName.value,
LastName: mockGetRecord.fields.FirstName.value
}
};
expect(updateRecord).toHaveBeenCalledTimes(1);
expect(updateRecord).toHaveBeenCalledWith(expectedFields);

// Check if toast event has been fired
expect(handler).toHaveBeenCalled();
expect(handler.mock.calls[0][0].detail.message).toBe(TOAST_MESSAGE);
});

it('Test close screen on Cancel', async () => {
Expand Down
Loading

0 comments on commit 22bd307

Please sign in to comment.