Skip to content

Commit

Permalink
Merge pull request salesforce#80 from dbreese/create_missing_qas
Browse files Browse the repository at this point in the history
Creating missing LWCs and QAs
  • Loading branch information
dbreese authored Nov 14, 2023
2 parents 9af31a1 + 0f677c3 commit dadcb8d
Show file tree
Hide file tree
Showing 18 changed files with 495 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
.localdevserver
.DS_Store
node_modules
__lwr_cache__
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"fields": {
"Name": {
"value": "Name Mock"
},
"Phone": {
"value": "123-456-7890"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { createElement } from "lwc";
import EditContactRecord from "c/editContactRecord";
import { getRecord } from "lightning/uiRecordApi";

import CONTACT_NAME_FIELD from "@salesforce/schema/Contact.Name";
import CONTACT_TITLE_FIELD from "@salesforce/schema/Contact.Title";
import CONTACT_ACCOUNT_FIELD from "@salesforce/schema/Contact.AccountId";
import CONTACT_PHONE_FIELD from "@salesforce/schema/Contact.Phone";
import CONTACT_EMAIL_FIELD from "@salesforce/schema/Contact.Email";
import CONTACT_MOBILE_FIELD from "@salesforce/schema/Contact.MobilePhone";

const mockRecord = require("./data/getRecord.json");

describe("c-edit-contact-record", () => {
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);
}
});

it("should correctly populate form and name field", () => {
const RECORD_ID = "003abcdefghijklmno";
const OBJECT_API_NAME = "Contact";

const element = createElement("c-edit-contact-record", {
is: EditContactRecord,
});
element.recordId = RECORD_ID;
element.objectApiName = OBJECT_API_NAME;
document.body.appendChild(element);

// Emit mock record into the wired field - we have to do this after inserting into DOM
// for the component to receive updates. We will need to use a promise next to wait for
// DOM to re-render
// eslint-disable-next-line @lwc/lwc/no-unexpected-wire-adapter-usages
getRecord.emit(mockRecord);

// let's ensure that the form is as expected
const INPUT_FIELDS = [
CONTACT_NAME_FIELD,
CONTACT_TITLE_FIELD,
CONTACT_ACCOUNT_FIELD,
CONTACT_PHONE_FIELD,
CONTACT_EMAIL_FIELD,
CONTACT_MOBILE_FIELD,
];

const form = element.shadowRoot.querySelector("lightning-record-edit-form");
expect(form.recordId).toBe(RECORD_ID);
expect(form.objectApiName).toBe(OBJECT_API_NAME);

const submitButton = element.shadowRoot.querySelector(
'lightning-button[data-id="submit"]',
);
expect(submitButton.type).toBe("submit");

const cancelButton = element.shadowRoot.querySelector(
'lightning-button[data-id="cancel"]',
);
expect(cancelButton.type).toBe("button");

const message = element.shadowRoot.querySelector("lightning-messages");
expect(message).not.toBeNull();

// get the input fields and ensure they are in the correct order
const outputFieldNames = Array.from(
element.shadowRoot.querySelectorAll("lightning-input-field"),
).map((outputField) => outputField.fieldName);
expect(outputFieldNames).toEqual(INPUT_FIELDS);

// Resolve a promise to wait for a re-render of the new content to include the name value
// that is built after the @wire executes.
return Promise.resolve().then(() => {
const displayName = element.shadowRoot.querySelector(
'lightning-layout-item[data-id="name"]',
);

const mockedName = mockRecord.fields.Name.value;

// eslint-disable-next-line @lwc/lwc/no-inner-html
expect(displayName.innerHTML).toContain(mockedName);
});
});

it("should go back when clicking cancel button", () => {
const element = createElement("c-edit-contact-record", {
is: EditContactRecord,
});
document.body.appendChild(element);

// use a spy to ensure we called back()
const backSpy = jest.spyOn(window.history, "back");

const cancelButton = element.shadowRoot.querySelector(
'lightning-button[data-id="cancel"]',
);
cancelButton.click();

expect(backSpy).toHaveBeenCalled();
});

it("should go back after success", () => {
const element = createElement("c-edit-contact-record", {
is: EditContactRecord,
});
document.body.appendChild(element);

const backSpy = jest.spyOn(window.history, "back");
const form = element.shadowRoot.querySelector("lightning-record-edit-form");

form.dispatchEvent(new CustomEvent("success"));

return Promise.resolve().then(() => {
expect(backSpy).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@import 'c/commonStyles';

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<template>
<div class="component-background">
<lightning-record-edit-form object-api-name="Contact" record-id={recordId} onsuccess={onSuccess}>
<div class="header-slot">
<!-- cancel and submit buttons-->
<lightning-layout horizontal-align="spread" class="slds-var-p-horizontal_xx-small">
<lightning-layout-item>
<lightning-button variant="base" data-id="cancel" label="Cancel" type="button" onclick={dismiss}
class="button"></lightning-button>
</lightning-layout-item>

<lightning-layout-item data-id="name" class="record-name slds-align_absolute-center">
<p style="word-break: break-all;">{name}</p>
</lightning-layout-item>

<lightning-layout-item>
<lightning-button variant="base" data-id="submit" label="Save" type="submit"
class="button-primary"></lightning-button>
</lightning-layout-item>
</lightning-layout>
</div>

<div class="header-offset slds-var-p-horizontal_small slds-var-p-bottom_medium">

<!-- show any error messages or alerts -->
<lightning-messages></lightning-messages>

<!-- input fields -->
<lightning-input-field field-name={nameField}></lightning-input-field>
<lightning-input-field field-name={titleField}></lightning-input-field>
<lightning-input-field field-name={accountField}></lightning-input-field>
<lightning-input-field field-name={phoneField}></lightning-input-field>
<lightning-input-field field-name={emailField}></lightning-input-field>
<lightning-input-field field-name={mobileField}></lightning-input-field>
</div>

</lightning-record-edit-form>
</div>
</template>
46 changes: 46 additions & 0 deletions force-app/main/default/lwc/editContactRecord/editContactRecord.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { LightningElement, api, wire } from "lwc";
import { getRecord } from "lightning/uiRecordApi";

import CONTACT_NAME_FIELD from "@salesforce/schema/Contact.Name";
import CONTACT_TITLE_FIELD from "@salesforce/schema/Contact.Title";
import CONTACT_ACCOUNT_FIELD from "@salesforce/schema/Contact.AccountId";
import CONTACT_PHONE_FIELD from "@salesforce/schema/Contact.Phone";
import CONTACT_EMAIL_FIELD from "@salesforce/schema/Contact.Email";
import CONTACT_MOBILE_FIELD from "@salesforce/schema/Contact.MobilePhone";

export default class EditContactRecord extends LightningElement {
@api recordId;
@api objectApiName;

nameField = CONTACT_NAME_FIELD;
titleField = CONTACT_TITLE_FIELD;
accountField = CONTACT_ACCOUNT_FIELD;
phoneField = CONTACT_PHONE_FIELD;
emailField = CONTACT_EMAIL_FIELD;
mobileField = CONTACT_MOBILE_FIELD;

@wire(getRecord, { recordId: "$recordId", fields: [CONTACT_NAME_FIELD] })
record;

get name() {
return this.record &&
this.record.data &&
this.record.data.fields &&
this.record.data.fields.Name
? this.record.data.fields.Name.value
: "";
}

onSuccess(event) {
console.log("Updated contact", event.detail);
// Dismiss modal on success
this.dismiss(event);
}

dismiss(event) {
console.log("Dismissing modal", event.detail);
// TODO: Can we use window.history.back() here?
// eslint-disable-next-line no-restricted-globals
history.back();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>56.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__RecordPage</target>
<target>lightning__RecordAction</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__RecordAction">
<actionType>ScreenAction</actionType>
</targetConfig>
</targetConfigs>
</LightningComponentBundle>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"fields": {
"Name": {
"value": "Name Mock"
},
"Amount": {
"value": 123.45
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { createElement } from "lwc";
import EditOpportunityRecord from "c/editOpportunityRecord";
import { getRecord } from "lightning/uiRecordApi";

import OPPORTUNITY_NAME_FIELD from "@salesforce/schema/Opportunity.Name";
import OPPORTUNITY_ACCOUNT_FIELD from "@salesforce/schema/Opportunity.AccountId";
import OPPORTUNITY_CLOSE_DATE_FIELD from "@salesforce/schema/Opportunity.CloseDate";
import OPPORTUNITY_AMOUNT_FIELD from "@salesforce/schema/Opportunity.Amount";
import OPPORTUNITY_STAGENAME_FIELD from "@salesforce/schema/Opportunity.StageName";

const mockRecord = require("./data/getRecord.json");

describe("c-edit-opportunity-record", () => {
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);
}
});

it("should correctly populate form and name field", () => {
const RECORD_ID = "006abcdefghijklmno";
const OBJECT_API_NAME = "Opportunity";

const element = createElement("c-edit-opportunity-record", {
is: EditOpportunityRecord,
});
element.recordId = RECORD_ID;
element.objectApiName = OBJECT_API_NAME;
document.body.appendChild(element);

// Emit mock record into the wired field - we have to do this after inserting into DOM
// for the component to receive updates. We will need to use a promise next to wait for
// DOM to re-render
// eslint-disable-next-line @lwc/lwc/no-unexpected-wire-adapter-usages
getRecord.emit(mockRecord);

// let's ensure that the form is as expected
const INPUT_FIELDS = [
OPPORTUNITY_NAME_FIELD,
OPPORTUNITY_ACCOUNT_FIELD,
OPPORTUNITY_CLOSE_DATE_FIELD,
OPPORTUNITY_AMOUNT_FIELD,
OPPORTUNITY_STAGENAME_FIELD,
];

const form = element.shadowRoot.querySelector("lightning-record-edit-form");
expect(form.recordId).toBe(RECORD_ID);
expect(form.objectApiName).toBe(OBJECT_API_NAME);

const submitButton = element.shadowRoot.querySelector(
'lightning-button[data-id="submit"]',
);
expect(submitButton.type).toBe("submit");

const cancelButton = element.shadowRoot.querySelector(
'lightning-button[data-id="cancel"]',
);
expect(cancelButton.type).toBe("button");

const message = element.shadowRoot.querySelector("lightning-messages");
expect(message).not.toBeNull();

// get the input fields and ensure they are in the correct order
const outputFieldNames = Array.from(
element.shadowRoot.querySelectorAll("lightning-input-field"),
).map((outputField) => outputField.fieldName);
expect(outputFieldNames).toEqual(INPUT_FIELDS);

// Resolve a promise to wait for a re-render of the new content to include the name value
// that is built after the @wire executes.
return Promise.resolve().then(() => {
const displayName = element.shadowRoot.querySelector(
'lightning-layout-item[data-id="name"]',
);

const mockedName = mockRecord.fields.Name.value;

// eslint-disable-next-line @lwc/lwc/no-inner-html
expect(displayName.innerHTML).toContain(mockedName);
});
});

it("should go back when clicking cancel button", () => {
const element = createElement("c-edit-opportunity-record", {
is: EditOpportunityRecord,
});
document.body.appendChild(element);

// use a spy to ensure we called back()
const backSpy = jest.spyOn(window.history, "back");

const cancelButton = element.shadowRoot.querySelector(
'lightning-button[data-id="cancel"]',
);
cancelButton.click();

expect(backSpy).toHaveBeenCalled();
});

it("should go back after success", () => {
const element = createElement("c-edit-opportunity-record", {
is: EditOpportunityRecord,
});
document.body.appendChild(element);

const backSpy = jest.spyOn(window.history, "back");
const form = element.shadowRoot.querySelector("lightning-record-edit-form");

form.dispatchEvent(new CustomEvent("success"));

return Promise.resolve().then(() => {
expect(backSpy).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@import 'c/commonStyles';

Loading

0 comments on commit dadcb8d

Please sign in to comment.