Professional Documents
Culture Documents
Table of Contents
1-1: Explore the Certification App (Instructor Demo) 4
1-2: Prepare Your Training Org and Environment 6
1-3: Create a Sandbox 10
3-1: See Apex in Action 11
3-2: Create and Use an Apex Class 14
3-3: Take a Quick Tour of Apex 16
3-4: Examine Implicit Operations 21
3-5: Profile Limits Using the Developer Console 23
3-6: Work with a Custom Object 24
4-1: Create and Run a Query in the Developer Console 25
4-2: Write a SOQL Query that Uses a WHERE Clause in VS Code 27
4-3: Write and Execute a SOQL Query in Apex 29
4-4: Write a Dynamic Query in Apex 30
4-5: Write and Test Child-to-Parent Relationship Queries 32
4-6: Write and Test Parent-to-Child Relationship Queries 33
4-7: Create a Simple SOSL Search 34
5-1: Execute DML Commands 36
5-2: Handle DML Errors and Exceptions 38
6-1: Deploy Code from Sandbox to Production (Optional) 39
7-1: Define a Trigger 42
7-2: Define the Trigger's Business Logic 43
8-1: Define an Apex Class 45
9-1: Explore the Implicit Firing of Triggers 46
9-2: View the Events that Occur During a Rollback 48
9-3: Use a Platform Event for Immediate Error Logging 50
10-1: Make Test Data Available to Test Methods 52
10-2: Write and Run an Apex Test 54
11-1: Refactor a Trigger to Avoid SOQL Limits 56
11-2: Refactor a Trigger to Avoid DML Limits 58
12-1: Create a Formula Field to Eliminate a Query 59
12-2: Create Fields for Counting Certification Elements 60
12-3: Create Collections to Filter the Query 62
Goal:
Familiarize yourself with the custom Certification app.
Tasks:
1. Locate the correct Service Vendor account.
2. Create a new technician record.
3. Sign your new technician up for training.
4. Add a certification attempt for your technician.
5. Document that your technician has earned the certification.
6. Discussion.
Time:
5 minutes
Instructions:
A. In the Certification app, open the record detail page for the Windy City Network
Solutions Account. Its record type is Service Vendor.
A. Open the record detail page for the [101] AWCA Server course.
B. Open its related delivery DELIVERY-00034.
C. Create a related Course Attendee as follows:
Student Jonas Whittier
Course Delivery DELIVERY-00034
Status Enrolled
A. Open the Certification Element detail page for the AWCA Server Multiple Choice
certification attempt you just created, and then open the AWCA Server Certification
record.
B. Create a related Certification Held as follows:
Certification AWCA Server
Certified Professional Jonas Whittier
Date Achieved (Enter Today's Date)
6. Discussion
Goal:
Prepare your org for classroom activities and access after class.
Tasks:
1. Update your user details in your training org.
2. Download your lab files from the Files tab.
3. Turn off Browser Caching.
4. Open the Project in VS Code.
5. Authorize the org using the Salesforce CLI.
6. Retrieve the Base metadata.
7. Update VS Code Settings.
8. Refresh SObject Definitions
9. (Optional) Enable Apex Code Formatting
Time:
60 minutes
Instructions:
Note: If you are using a Windows machine and your system administrator disabled compressed
folders, you may need to download third-party unzipping software such as 7-zip.
A. Open VS Code.
B. Open the folder selection dialog as follows, depending on your operating system:
Windows: File | Open Folder
Mac: File | Open.
Note: The -a flag sets the alias of the org to DEX450. The –s flag sets it as the default org.
C. In a few seconds, your default browser will open in a screen to log into Salesforce. Use
the credentials your instructor gave you.
D. Click Allow.
E. If you received an error related to port 1717, you may need to kill a process.
Windows: Ctrl+Alt+Delete -> Task Manager -> End process named Node.
(Node.js developers might have several running processes with this name)
Mac: lsof -i tcp:1717 and then kill -9 <the process ID>
Note: If you do not see the Retrieve Source command when you right click package.xml, make sure
that you have installed the Salesforce Extension Pack in VS Code.
A. From the Command Palette (View | Command Palette) enter the following:
> Preferences: Open Workspace Settings
Note: We set these options in your Workspace settings to avoid impacting any of your other projects.
You may wish to enable some or all of them in your User Settings instead.
A. From the Command Palette, run the following to enhance VS Code's autocomplete
abilities.
> SFDX: Refresh SObject Definitions
A. Install the LTS (Long Term Support) version of NodeJS from nodejs.org.
B. Use the VS Code Extensions Marketplace to install the Prettier - Code formatter
extension. There are many extensions with the word Prettier in the title. Make sure to
download the one titled Prettier - Code formatter which has millions of installs.
C. From a Terminal (View | Terminal) in VS Code, run the following command:
npm install
D. Restart VS Code.
E. In VS Code, open
force-app/main/default/classes/CourseAttendeeTriggerHandler.cls.
F. From the Command Palette (View | Command Palette) enter the following to format
the class:
> Format Document
G. Consider enabling the Editor: Format on Save option in your Workspace Settings.
Note: We have provided a sample .prettierrc file at the root of the project. You can customize
this file to your liking to configure Prettier.
Goal:
Create a sandbox to configure and test changes separate from the production environment.
Tasks:
1. Create a developer sandbox.
Time:
5 minutes
Instructions:
Goal:
Execute Apex to create a new Contact record in the database.
Tasks:
1. Configure the Debug Logs using Developer Console.
2. Review the User Trace Flags.
3. Open the Execute Anonymous window.
4. Enter the code to execute.
5. Examine the logs.
6. Examine the result in the user interface.
Time:
15 minutes
Instructions:
A. Click the Debug Only checkbox to filter the log and only display our debug statements.
The window will display a log entry with the ID of the inserted record.
B. Deselect Debug Only. The full log view will display again.
C. Enter DML into the Filter input box (case-sensitive).
D. Notice the limits usage for DML Statements and DML Rows.
E. Select File | Close All to close the log. If you don't do this, the same log will be open
the next time that you open Developer Console.
F. Close Developer console.
A. In the Salesforce UI, confirm that June Morgan, the record inserted using Apex,
appears in the Recent Contacts section.
Question: what would happen if you tried to insert a Contact named June Morgan again?
Goal:
Create an Apex class named ContactManager and define a method within the class to create a
Contact record in the database.
Tasks:
1. Create an Apex class.
2. Invoke the class method using Execute Anonymous.
3. Examine the output to see the invocation of the class.
Time:
10 minutes
Instructions:
Tip: Consult your cheat sheet as needed for instructions to perform common tasks like creating an
Apex Class.
A. In VS Code, create a new Apex class ContactManager, overwriting all of its contents
with ContactManagerClass.txt from the appropriate EXFiles folder.
B. Save ContactManager.cls. Because you enabled the deploy on save option in VS
Code, you should see something similar to this in the output pane (View | Output):
Note: Throughout the instructions we assume you have enabled deploy on save. If you decide not to
enable that option, you will need to manually deploy files after saving them.
A. In the Output tab (View | Output) search for the string USER_DEBUG and locate the two
debug statements. You can search either by going to Edit | Find or by using the
keyboard shortcut Ctrl + F. Note: Be sure the Salesforce CLI Is chosen from the
dropdown Menu.
B. Notice that the newly created record has an ID, which was returned by the method.
C. Search the output for the string ContactManager and observe the invocation of the
static addContact() method.
Note: This isn't the only way to see log info in VS Code. You'll learn more about logs later.
Goal:
Quickly learn some Apex fundamentals that will be familiar to you, and check out some simple
differences.
Tasks:
1. Enable Replay Debugger.
2. Set up the main class.
3. Set up and review the test class.
4. Run the test.
5. View code coverage.
6. Replay the code.
7. Use a Checkpoint.
Time:
45 minutes
Instructions:
In the VS Code status bar (bottom of the window) you should see "Recording detailed logs
until [30 minutes from now] "
"FIELD_INTEGRITY_EXCEPTION: This entity is already being traced by a trace flag with a start and
expiration date that overlap this trace flag's start and expiration date."
then in your org close the Developer Console (if open), navigate to the Debug Logs page in Setup
and delete the SFDC_DevConsole user trace flag. Re-run the command.
A. In VS Code, create a new Apex class CourseManager, overwriting all of its contents
with CourseManagerClass.txt.
B. Complete the TODOs.
i. The following two lines of code create two lists of records. There will be 3
overlapping records with names: course3, course4, and course5.
List<Course__c> oldCourses = createTestDataCourses(0, 5);
ii. The following line checks whether the code that will be moved to production actually
fulfills the business requirement. If the assertion fails, an exception will be caused,
which will fail the test.
System.assert(duplicateCourses.size()==3);
Note: If you do not see your test listed, move your mouse over the words "APEX TESTS" and click
the Refresh Tests button (a circular arrow).
Outcome Passed
Tests Ran 1
Note: If you receive a message that "No code coverage information was found for this file", enable
the Retrieve-test-code-coverage option as instructed in Exercise 1-2.
C. A list of one or more logs will display. Select the most recent log and it will download
and open in its own editor tab.
D. Go to View | Run to change the selected area in the sidebar.
E. Right-click anywhere inside of the log file and select the following option:
SFDX: Launch Apex Replay Debugger with Current File
F. Press F5 (or the Continue icon in Debugger tools) and it will stop at your breakpoint.
G. Observe that a string representation of newCourseList is visible as a local variable in
the sidebar. oldCourseList says List of size 6 too large to display.
H. Press F10 (or the Step Over icon in Debugger tools).
I. Expand the variable newCourse in the sidebar.
J. Press F10 repeatedly, watching the value of newCourse change, until you reach the
return statement.
K. A known limitation of Replay Debugger is that modifying a collection does not update
the collection variable in the sidebar when using standard breakpoints. Thus, the value
of courseDuplicatesSet will not be reflected.
L. Press Shift + F11 (or the Step Out icon in Debugger tools) when you reach the
return statement. You will return to the testFindDuplicates method in the test
class.
M. Observe the value of duplicateCourses.
N. Press F5 (or the Continue icon in Debugger tools) and your replay session will end.
7. Use a Checkpoint
return courseDuplicatesSet;
B. Run the following from the Command Palette to add a checkpoint to the line:
> SFDX: Toggle Checkpoint
C. Run the following from the Command Palette to ensure that a heap dump is collected
on the server when this checkpoint is reached:
> SFDX: Update Checkpoints in Org
D. Use the Apex Tests view in VS Code to execute the CourseManager_Test test again.
E. Use the Get Apex Debug Logs command again to download the Apex log you just
generated by running the test. The log's contents should automatically open in a VS
Code editor window.
F. In the newly opened VS Code editor window, search the log contents for the phrase
HEAP_DUMP to ensure the checkpoint functioned as expected.
G. Launch the Replay Debugger again, selecting the new log file.
H. Press the Continue button in the debugger tools until you reach the checkpoint that you
placed on the return statement.
I. Observe that the value of courseDuplicatesSet can now be observed because
we're using a checkpoint rather than a breakpoint.
J. Observe that the value of oldCourseList, which was previously too large to display,
can also now be observed. This is another example of a checkpoint making more
information available.
K. Run the SFDX: Toggle Checkpoint and SFDX: Update Checkpoints in Org
commands again to remove the checkpoint.
L. Run the following from the Command:
> SFDX: Turn Off Apex Debug Log for Replay Debugger
Tip: Checkpoints expire after 30 minutes and heap dumps expire after a day.
Goal:
Examine the operations implicitly occurring when you perform a DML operation.
Tasks:
1. Ensure a trace flag is running.
2. Create a Course Attendee record in the user interface.
3. View the logs to see operations implicitly invoked due to the DML operation.
Time:
10 minutes
Instructions:
A. Open Developer Console so that an active trace flag with Debug Level
SFDC_DevConsole is running. Keep it open until you complete Exercise 3-6.
Note: By default, the trace flags generated for Replay Debugger logs do not have Profiling FINEST
which is required for this specific log.
A. Open the detail page for the Course Delivery record named DELIVERY-00025.
B. Create a related Course Attendee as follows:
Course Delivery DELIVERY-00025
Student Clara Petit
Status Enrolled
3. View the logs to see operations implicitly invoked due to the DML operation.
B. A list of one or more logs will display. Select the most recent log and it will download
and open in its own editor tab.
C. Search the log file you just downloaded for the string AfterInsert. There should be
two results. What do the lines containing this phrase indicate?
D. Confirm that the provideAccessLMS method of the
CourseAttendeeTriggerHandler class was executed.
E. Search the log for the string WF and verify that the New Course Delivery Created
workflow rule is mentioned in the logs. It fires because a Roll Up Summary field exists
on Course Delivery that counts the number of attendees.
F. On the line that says WF_CRITERIA_BEGIN, observe that the end of the line says
ON_CREATE_ONLY|0, indicating that the Workflow rule did not meet the evaluation
criteria and thus did not execute.
Note: Even if the DML operation on an object does not meet a Workflow Rule's evaluation criteria,
you will still see a log entry that says WF_RULE_EVAL_BEGIN, but you will shortly after see
WF_RULE_NOT_EVALUATED to indicate that the Evaluation Criteria were not met.
Goal:
Investigate limits using the Developer Console.
Tasks:
1. Review the limit profiling information in the log.
Time:
5 minutes
Instructions
F. Click the Timeline tab in the Execution Overview panel. Notice the entries in the
Category, Millis, and % columns.
G. Switch to the Limits tab in the Execution Overview panel. Enter STATEMENT in the
Filter input box of the Execution Log panel (case-sensitive).
H. Click the first entry in the Execution Log panel. This resets the Used so far column in
the Limits tab. The Source panel jumps to the line of code that was executed at that
point in time.
I. Click the third-to-last entry in the Execution Log panel. The values for SOQL and
SOQL_ROWS Limits Used so far are updated. The Source panel jumps to the line of
code that was executed at that point in time.
J. Click the last entry in the Execution Log panel. All limits used now display.
Goal:
Work with the fields of the Course object.
Tasks:
1. Write code to insert a record for the Course object.
2. Check the Salesforce UI to ensure that the record was inserted successfully.
Time:
15 minutes
Instructions:
NOTE: Remember that you can use Ctrl + P (or Cmd + P) to easily find a file. Make sure to
pay attention to whether you're opening a file from EXFiles or EXFiles_solutions.
2. Check the Salesforce UI to ensure that the record was inserted successfully.
Goal:
Retrieve Cases using the Query Editor in the Developer Console.
Tasks:
1. Run a query in the Query Editor in the Developer Console.
2. Explore row-level options.
3. Delete Debug Logs.
Time:
5 minutes
Instructions:
C. Create a query.
i. Holding the CTRL key, select the following fields from the Case.obj tab:
CaseNumber IsClosed
ClosedDate Status
Id Subject
ii. Click Query at the bottom of the list. The focus will shift to the Query Editor tab in
the bottom panel.
A. From the Query Editor tab, run the following SOQL query.
SELECT Id, StartTime, LogUserId, LogLength, Location FROM ApexLog
Note: System debug logs such as those generated from Developer Console are retained for 24
hours. Monitoring debug logs are retained for seven days. You do not have to manually delete
logs, but if your org accumulates more than 1,000 MB of debug logs, users are prevented from
adding or editing trace flags. That is a scenario where you may wish to manually delete the logs
as you just did.
Goal:
Retrieve Cases that meet specific criteria.
Tasks:
1. Write and test queries with various WHERE clauses using the SOQL Builder extension in
VS Code.
Time:
20 minutes
Instructions:
1. Write and test a query using the SOQL Builder extension in VS Code.
B. Create a query that selects the Id, Subject, Status and IsClosed fields from the Case
sObject retrieving only "Closed" records.
C. Save your query as a file called Task1.soql in the /scripts/soql folder.
A. Create a query that selects the Id, Subject and Type fields from the Case sObject
retrieving only records that have no specified type (Type is a nullable field so a Case
without a type has a Null value). Save your query in a file called Task2.soql.
B. Create a query that selects the Id, Subject, Priority and Product_Category__c fields
from the Case sObject retrieving only "Printers" product category records that have a
"High" priority. Save your query in a file called Task3.soql.
C. Create a query that selects the Id and Subject fields from the Case sObject retrieving
only records that have the word "printers" somewhere in the subject. Save your query in
a file called Task4.soql.
Note: If you wish to re-run any of your saved queries using SOQL Builder open the soql file and click
the Switch Between SOQL Builder and Text Editor icon (top right):
Alternatively if you wish to remain in the text editor and run your query then simply highlight the
entire SOQL query before opening the Command Palette, and then run the following:
> SFDX: Execute SOQL Query with Currently Selected Text
Select REST API rather than Tooling API. The query result will be visible in the Output pane.
Goal:
Print cases into the debug log.
Tasks:
1. Print a single case into the debug log.
2. Print multiple cases into the debug log.
Time:
10 minutes
Instructions:
Goal:
Retrieve cases that meet criteria specified at run time.
Tasks:
1. Use a bound variable to specify filter criteria.
2. Use Database.query() to work around the problem from Task 1.
3. (Optional) Use a bound variable to query by record type.
Time:
10 minutes
Instructions:
A. Navigate to developer.salesforce.com and search for SOQL and SOSL Reference and
select it. Within that document search for Date Formats and Date Literals to
bring up an article with that name, and within that article, find the reference to
LAST_N_DAYS to see how it can be used in filter criteria for date values.
B. In VS Code, open SOQLDynamicQueryInApex-task1.apex and attempt to execute
the Apex. Observe that it returns an error because the bind variable is not supported
with LAST_N_DAYS in a bracketed SOQL query.
Goal:
Write child-to-parent relationship queries that explore relationships among sObjects in the
Certification application.
Tasks:
1. Select all Contacts and their related Accounts.
2. Move the query into Apex and output the results using a SOQL for Loop.
3. Select Courses that have related Certifications.
Time:
20 minutes
Instructions:
HINT: If needed, use Object Inspector in Developer Console to view field API names.
A. In VS Code, open SOQL-C2P-task1.soql and complete the task. You will write and
execute a SOQL query within VS Code.
2. Move the query into Apex and output the results using a SOQL for Loop.
A. In VS Code, open SOQL-C2P-task3.soq and complete the task. You will write and
execute a SOQL query within VS Code.
Goal:
Write parent-to-child relationship queries that explore relationships among sObjects in the
Certification application.
Tasks:
1. Select all Accounts and their related Contacts.
2. Select all Certifications that have a related Course.
Time:
10 minutes
Instructions:
NOTE: You can choose whether to run the SOQL queries for this exercise in VS Code or in the
Developer Console Query Editor – whichever you prefer.
A. In VS Code, open SOQL-P2C-task1.soql and complete the task. You will write and
execute a SOQL query within VS Code.
A. In VS Code, open SOQL-P2C-task2.soql and complete the task. You will write and
execute a SOQL query within VS Code.
Goal:
Search for text across multiple sObjects.
Tasks:
1. Construct a simple SOSL search.
2. Create a code block to cycle through the results.
Time:
15 minutes
Instructions:
A. Open Developer Console. We must use Developer Console for this exercise because
unlike SOQL, SOSL cannot be executed directly from the Salesforce CLI.
B. In the Query Editor tab, write and execute a SOSL search for a person named Frank.
This search should be made on the Contact and User objects, returning the found
person’s FirstName and LastName.
Note: The search string must be delimited by curly braces without any quotes in the Query Editor tab.
However, single quotes are required in an Anonymous block.
Tip: VS code allows you to maintain multiple terminal instances. If you only have one instance
running, killing it will close the Terminal panel. If you have multiple instances running, killing one
will automatically cause the panel to change to another instance.
F. Repeat steps B-E, but modify the tail command to filter for debug statements.
Windows CMD: sfdx force:apex:log:tail | findstr USER_DEBUG
Powershell: sfdx force:apex:log:tail | Select-String USER_DEBUG
Mac / Linux: sfdx force:apex:log:tail | grep USER_DEBUG
Goal:
Create and save Contacts.
Note: This exercise should be performed in the Sandbox if available. If your Sandbox is not yet available
then perform this exercise in your production org.
Tasks:
Time:
25 minutes
Instructions:
1. Log into the Sandbox if available. If your Sandbox is not yet available then skip this step.
It is usually a good idea to close any tabs you have open that reference your production
environment to avoid confusion.
A. In the Developer Console, create a new Apex class ContactsDML, overwriting its
contents with ContactsDML.txt.
A. Create another Apex Class ContactsDML_Test and overwrite its contents with
ContactsDMLTest.txt.
B. Complete the TODOs.
C. Click Run Test in the top right corner.
D. Click the Tests tab in the bottom panel.
E. Expand the collapsed folder by clicking on +.
F. Ensure that all your methods executed successfully. A green tick indicates success.
Goal:
Handle errors when inserting Contacts.
Note: If you performed the previous exercise in the Sandbox then continue to use the Sandbox for this
exercise - otherwise perform this exercise in your production org.
Tasks:
1. Print the list of reasons why Contacts could not be inserted into the database.
2. Test your code.
Time:
15 minutes
Instructions:
1. Continue working in the same org that you used for the previous exercise.
2. Print the list of reasons why Contacts could not be inserted into the database
A. In Developer Console, open the ContactsDML class and overwrite all of its contents
with ContactsDMLException.txt.
B. Complete the TODOs for the exceptionsDML method.
A. In Developer Console, open the ContactsDML_Test class and overwrite its contents
with ContactsDMLExceptionTest.txt.
B. Complete the TODOs for the exceptionsDMLTest method.
C. Run the test and verify it completed successfully.
Goal:
Deploy the two Apex classes previously created in the Sandbox to the Production org.
Tasks:
1. (Production) Change the deployment connection to allow inbound changes.
10. (Sandbox) Create and upload an outbound change set.
11. (Production) Validate and deploy the inbound change set.
12. (Production) Test changes to confirm that deployment was successful.
Time:
20 minutes
Instructions:
4. (Production) Validate and deploy the inbound change set called ContactsDML Classes.
Note: You may need to wait approximately 10 minutes before your inbound change set will be ready
for Production. It can take up to 30 minutes.
Note: In our Trial production system, selecting the Default validation will not run any Apex tests.
In a real production environment, it will.
In order to see the result of running Apex tests as part of this deployment process, we will select
the Run local tests option which will execute any tests found in the change set plus any tests
that you may already have deployed into the production environment.
Note: Notice that the page shows your two components deployed and a number of Apex tests
being executed. It may take several minutes for the tests to complete. You will see that several
Apex tests actually fail - this is to be expected in this training environment as we still have some
work to do in this org.
If this was a real production system, we would not be able to proceed with this deployment until
we address these problems. However, in our trial system, we can ignore these issues and
complete the deployment.
G. Return to the Inbound Change Sets page and click the Deploy link next to the
ContactsDML Classes change set.
H. Select the radio button for Default.
I. Click Deploy and then click OK.
J. In Setup, go to Custom Code | Apex Classes. Check that ContactsDML and
ContactsDML_Test are listed, indicating that the deployment completed successfully.
K. Click on the ContactsDML_Test class and then click the Run Test button shown near
the top of the page
L. Verify that the test runs successfully.
Goal:
Define a trigger on the Course_Delivery__c sObject.
Tasks:
1. Define a trigger.
Time:
5 minutes
Instructions:
1. Define a trigger.
Goal:
Define the business logic of a trigger that only allows a Course Delivery to be saved if is not
scheduled to start on a holiday.
Tasks:
1. Create a Holiday.
2. Update the trigger.
3. Attempt to create a delivery that begins on a holiday.
4. Create a delivery that begins on a day that is not a holiday.
5. Attempt to update a delivery to begin on a holiday.
Time:
15 minutes
Instructions:
1. Create a Holiday.
2. Update a trigger.
A. Attempt to create and save a new Course Delivery with a start date of December 31 of
the current year. The save should fail.
A. Create and save a new Course Delivery with a start date of January 1 of the
upcoming year. It should work.
A. Attempt to update the course delivery you just created so that its start date is on
December 31 of the current year. It should fail.
Question: Why do you need to test the behavior defined in both step 3 and step 5?
Goal:
Make a trigger easy to read and maintain by creating a handler class for it.
Tasks:
1. Create an Apex class.
2. Invoke the class from the trigger.
3. Test the trigger.
Time:
15 minutes
Instructions:
Goal:
Determine the actions that occur when a Course record is saved.
Tasks:
1. Open the Developer Console.
2. Update the status of a Course record to “Retired” in the UI.
3. Review the results in the Developer Console.
Time:
10 minutes
Instructions:
Note: If you do not have a working copy of CourseDeliveryTrigger, then create or replace it in your
org with the version EXFiles_solutions\7-2\CourseDeliveryTrigger.txt.
A. Open Developer Console now so that you are guaranteed to have an active trace flag
when you retire a course in the next step.
A. Leaving the Developer Console open, switch to the Salesforce UI in another window.
B. Open the record detail page for the Course named [401] Data Recovery.
C. Change its status to Retired and save the record.
E. The Save Order tab in the Execution Overview panel also shows the triggers firing, as
well as a workflow rule.
F. Click the Executed Units tab in the Execution Overview panel and click the entry for
the checkStatus method. Observe that it updated the Execution Log filter.
G. Notice the various operations called during the execution of this method in the
Execution Log panel.
Goal:
Determine the events that occur when an update action is rolled back.
Tasks:
1. Open the Developer Console.
2. Attempt to update the status of a Course record to “Retired” in the UI.
3. Review the results in the Developer Console.
4. Review the results in the UI.
Time:
10 minutes
Instructions:
E. In the tab that opens, search for the string "Status__c":"Retired". It occurs many
times, but you should examine the line that contains the first occurrence closely to see
that is part of a VARIABLE_ASSIGNMENT for triggerNew.
F. Note that this value of "Status__c" was never committed to the database.
G. Close the raw log and return to the regular log that has the All perspective open.
H. Click the Executed Units tab in the Execution Overview panel and click the entry for
the addError method. The entry in the log confirms that the addError method was
executed.
A. Return to the Salesforce UI, cancel your attempted edit and refresh the page.
B. Notice that the Status of each record in the Course Deliveries related list has not
changed and the Course Status is still Active, indicating that the save was rolled back.
Goal:
Create a custom error logging mechanism for the Course Delivery trigger using a custom object
and a Platform Event.
Tasks:
1. Define the schema of a Platform Event.
2. Publish the Event from an Apex class.
3. Subscribe to the Event from an Apex trigger.
4. Test the functionality of the event.
Time:
25 minutes
Instructions:
A. In VS Code, create a new Apex Trigger ErrorMessageTrigger, and replace all of its
contents with ErrorMessageTrigger.txt.
B. Complete the TODOs.
Note: You may find it helpful to refresh the sObject definitions to allow VS Code to recognize the
platform event definition.
Goal:
Create test data to test the Certification application.
Tasks:
1. Create test data using a Static Resource.
2. Create test data programmatically.
3. Run the test.
4. Retrieve the Static Resource.
Time:
10 minutes
Instructions:
A. In Setup, go to Custom Code | Static Resources and create a new Static Resource as
follows, uploading the file HolidaysForStaticResource.txt.
Name Test_Holidays
Cache Control Private
Note: You will not need to modify the Static Resource locally, but this example shows you one way to
download a file you created in Developer Console. You could have used the Wildcard Character
(*) to pull down all Static Resources, or you could have used the Org Browser.
Goal:
Determine if the Certification application allows a Course Delivery to be created if it does not fall
on a holiday.
Tasks:
1. Write a test that tests the business logic of a trigger and a class.
2. Run the Test.
3. Explore Code Coverage.
Time:
10 minutes
Instructions:
1. Write a test that tests the business logic of a trigger and a class.
Note: If you receive a message that "No code coverage information was found for this file", make
sure that you have enabled the Retrieve-test-code-coverage option as instructed in Exercise 1-
2. Also, make sure you are viewing coverage for the correct Apex class.
C. Notice that the code that was not covered by the test class (highlighted in red) is related
to ‘bad data’ – i.e. Course Deliveries that are scheduled on a Holiday.
D. Click the Highlight Apex Code Coverage button to turn coverage highlighting off.
E. Click on some other classes and experiment with viewing the Code Coverage. Keep in
mind that you need to run a class's corresponding tests to view its coverage
information.
Goal:
Refactor the code for the Course Trigger to avoid the “Too many SOQL queries” error when
running a test with several records.
Tasks:
1. Examine the current Course trigger.
2. Test the trigger with a single record in the Salesforce UI.
3. Test the trigger with several records using unit test code.
4. Refactor the code to avoid a SOQL error.
Time:
15 minutes
Instructions:
A. Open the record detail page for the Course named [101] AWCA Server.
B. Change the status to Retired and attempt to save the change.
i. If the Course does not have any enrolled Attendees, then it should allow you to
change the status.
ii. If it does have enrolled attendees, then you will get a message telling you that the
“Course has enrolled students.”
iii. Either outcome indicates that the trigger was able to complete execution.
3. Test the trigger with several records using unit test code.
Note: In the next exercise you will refactor the trigger to resolve this new error.
Goal:
Refactor the code for the Course Trigger to avoid the “Too many DML rows” error when running
a test with several records.
Tasks:
1. Examine the current Course trigger.
2. Refactor the code to avoid a DML error.
3. Re-test the trigger with several records using unit test code.
Time:
15 minutes
Instructions:
A. Copy and paste the contents of CourseTriggerHandler.txt into the window (make
sure to use the 11-2 directory), overwriting all existing text.
B. Complete the TODOs.
3. Re-test the trigger with several records using unit test code.
A. In VS Code, open CourseTrigger_Test.cls and run the test. It should pass now.
Goal:
Create a formula field so that the certification Id is available on the Certification Attempt object.
Tasks:
1. Create a hidden formula field on the Certification Attempt object.
Time:
5 minutes
Instructions:
A. In Object Manager, add the following Formula custom field to the Certification
Attempt object.
Goal:
Implement fields that will make the number of Certification Elements associated with a
Certification available on the Certification Attempt Element.
Tasks:
1. Create a roll-up summary field on the Certification object.
2. Create a hidden formula field on the Certification Attempt object.
Time:
5 minutes
Instructions:
A. From the Object Manager, add the following Roll-Up Summary field to the
Certification object.
Field Label Number of Certification Elements
Field Name Number_of_Certification_Elements
Summarized Object Certification Elements
Roll-Up Type COUNT
Field-level Security Leave as-is
Page layout Leave as-is
A. From the Object Manager, add the following Formula field to the Certification Attempt
object.
Goal:
Create the query that will bring back Certification Attempt records.
Tasks:
1. Write code to create a query filter then loop over the SOQL results.
2. Create a trigger for Certification Attempt that calls the new handler class.
3. Test your new trigger logic.
Time:
20 minutes
Instructions:
1. Write code to create a query filter then loop over the SOQL results.
2. Create a trigger for Certification Attempt that calls the new handler class.
A. Tail the Debug Logs in your terminal, being sure to filter for USER_DEBUG.
B. In the Salesforce UI, open the record detail page for the AWCA Network certification.
C. Open the related Certification Element AWCA Network Multiple Choice.
Goal:
Aggregate the results of the query for use in determining if a candidate has passed all elements
of a certification.
Tasks:
1. Construct and use a Map to aggregate query results.
2. Test your new trigger logic.
Time:
20 minutes
Instructions:
A. Tail the Debug Logs in your terminal, being sure to filter for USER_DEBUG.
B. In the Salesforce UI, open the record detail page for the AWCA Network certification.
C. In the Certification Elements related list, click the record named AWCA Network
Multiple Choice.
D. Create a new related Certification Attempt as follows:
Record Type Multiple Choice
Certification Candidate Arthur Franz
Status Complete/Pass
E. Click Save.
F. Return to the Terminal in VS Code where you are tailing the debug log.
G. Look for the following three entries, which indicate that the new trigger logic was fired
successfully:
i. One that indicates that the createCertificationHeld method was called.
ii. One that shows which Certification Attempt record was retrieved.
Goal:
Complete the solution to create Certification Held records for qualified candidates.
Tasks:
1. Create Certification Held records for qualified candidates.
2. Test your solution.
Time:
15 minutes
Instructions:
A. Tail the Debug Logs in your terminal, being sure to filter for USER_DEBUG.
B. In the Salesforce UI, view the Certification record named AWCA Network.
C. Open the related Certification Element AWCA Network Multiple Choice.
D. Create a related Certification Attempt as follows
Record Type Multiple Choice
Certification Candidate Clara Morales
Status Complete/Pass
E. Return to the Terminal in VS Code where you are tailing the debug log.
F. Look for the following entries, which indicate that the new trigger logic was fired
successfully.
i. One that indicates that the createCertificationHeld method was called.
ii. One that shows which Certification Attempt record was retrieved.
iii. One that shows that the size of passCounts equals one.
iv. One that says a certification held record was added.
Goal:
Create a workflow rule that will prevent duplicate Certification Held records from being created.
Tasks:
1. Create a new hidden text field.
2. Create a workflow rule to populate the new field.
3. Execute the workflow rule for all existing records.
4. Test your workflow rule.
Time:
10 minutes
Instructions:
A. In the Object Manager, add the following Text field to the Certification Held object.
Length 37
Formula true
A. In VS Code, run the following anonymous Apex to populate the hidden text field.
Database.update([ SELECT Id FROM Certification_Held__c ], false);
D. Click Save. You should see the error message, “duplicate value found.” This indicates
that the new workflow rule was fired successfully.
E. Click Cancel.
Goal:
Create a simple Visualforce page that displays your name and Course record data.
Tasks:
1. Create a Visualforce page using the inline editor.
2. Add static text to the page.
3. Add a reference to the global user variable to display your name.
4. Modify your page to use the standard controller for the Course object.
5. Create a tabbed interface for a Course record.
6. Modify the page to use the Lightning Design System styling.
Time:
10 minutes
Instructions:
A. Open a new browser tab to your org. Replace everything in the URL address bar after
force.com with /apex/HelloPage, then press ENTER. For example:
https://<instance>.lightning.force.com/apex/HelloPage
Note: A warning will be displayed that the page does not exist.
<b>Hello World</b>
C. Press CTRL + S to save the file. Note that the web page content changes.
B. Save the file. Note that the web page content changes.
4. Modify your page to use the standard controller for the Course object.
A. In the Salesforce UI, locate any Course record and copy its ID from the URL to the
clipboard.
B. Switch back to the tab hosting your Visualforce page and append to the end of the URL
?id=RecordId, replacing RecordId with the Course record ID you just copied, then
press ENTER.
C. Add the standard controller attribute to the page definition:
<apex:page standardController="Course__c">
A. Add the following markup for a tabbed interface to your Visualforce page:
<apex:page standardController="Course__c">
<b>Hello {!$User.FirstName}</b>
<apex:tabPanel >
<apex:tab label="Details">
<apex:detail relatedList="false"/>
</apex:tab>
<apex:tab label="Related Lists">
<apex:relatedList list="Course_Deliveries__r"/>
<apex:relatedList list="CombinedAttachments"/>
</apex:tab>
</apex:tabPanel>
</apex:page>
B. Save your page. Notice that the page is styled differently from what you may be used to
in the Lightning UI.
<apex:page standardController="Course__c"
lightningStylesheets="true">
Goal:
Create a simple technician status page to display technician name, account name, and courses
they’ve registered for. Launch the page with a custom button.
Tasks:
1. Locate a record to be used as context during development.
2. Create a Visualforce page to only display the necessary fields and navigational links.
3. Create a custom button on the Technician Page Layout to launch the page.
4. Test the new page.
Time:
15 minutes
Instructions:
NOTE: PowerShell users may need to remove the leading slash in front of /apex
3. Create a custom button on the Technician Contact Layout to launch the page.
A. From Object Manager, open the Contact object and add the following new Button:
Name Technician_Status
Content TechnicianStatusPage
B. In the Technician Contact page layout, open the Mobile & Lightning Actions
category of the palette and drag your new Technician Status button to the Salesforce
Mobile and Lightning Experience Actions section of the page, placing it to the left of
New Event.
Optional Challenge: After reviewing your work the business has decided that they no longer want the
Technician Status page accessible from a button but would rather have it visible on the Contact record
page immediately below the Related List Quick Links component. The Visualforce page should only be
visible for Technician Contact records.
2. In Setup edit the Visualforce page and make it Available for Lightning Experience.
3. Edit a Contact record page using Lightning App builder and add your Technician Status page using the
standard Visualforce component. Make sure the page is only visible when the Contact Record Type is
Technician.
Goal:
Use the provided controller extension to display all Certification Held records related to the
current account in a Visualforce page embedded on the account page layout.
Tasks:
1. Create an Apex controller extension that queries all Certification Held records.
2. Create a page to display all Certification Held records.
3. Create a section on the Account Page Layout to display the new page.
4. Test your new page.
Time:
15 minutes
Instructions:
1. Create an Apex controller extension that queries all Certification Held records.
3. Create a section on the Account page layout to display the new page.
A. In Object Manager, open the Service Vendor Account Layout page layout for the
Account object.
B. From the palette, click Visualforce Pages.
C. Drag and drop Section from the palette to below the Account Information section.
E. Click OK.
F. Drag and drop AccountDisplayCertsHeldPage from the palette to the new
Certifications Held section.
G. Click the Properties icon (wrench) in the top-right area of the
AccountDisplayCertsHeldPage element to open the Visualforce Page Properties.
H. Enter the following information:
Width (in pixels or %) 100%
Height (in pixels) 100
Show scrollbars Selected
Show label Deselected
I. Click OK.
J. Click Save.
A. Open the Account detail page for the record named Alveswood Technologies.
B. Verify that the new section appears and that you can scroll through all the records.
Goal:
Create a Visualforce page and custom controller to display a list of courses with corresponding
checkboxes. Utilize a wrapper class to render the checkbox property. Begin writing the action
method that will trigger the search.
Tasks:
1. Write the code necessary for the custom controller.
2. Create a page to display all courses.
3. Test your new page.
Time:
25 minutes
Instructions:
Goal:
You must redirect the user to show the results of the search they have set up.
Tasks:
1. Create a new results page.
2. Write the code necessary to redirect the user to a new page.
3. Add code to the new page to display the course deliveries.
4. Test your new page.
5. Test the basic error handling.
Time:
25 minutes
Instructions:
A. In VS Code, open SearchCourses_CC.cls and overwrite its contents with the 13-5
version of SearchCourses_CC.txt.
B. Complete the TODOs.
B. Select one or more of the checkboxes next to the courses listed, then click See
Upcoming Course Deliveries. The page will refresh and show you the search results.
C. Verify that the Upcoming Course Deliveries page displays course deliveries related to
the course(s) you selected.
D. Verify that you can click New Search and return to the original search page.
A. Select NONE of the checkboxes next to the courses listed, then click See Upcoming
Course Deliveries. The page will display a message to select at least one course.
Goal:
Create a Visualforce page that lets you paginate and filter Account records.
Tasks:
1. Create a page to display Account records.
2. Test your new page.
Time:
10 minutes
Instructions:
Goal:
Create a Visualforce page and custom controller to display a list of contacts based on the
results of a SOSL search.
Tasks:
1. Write the code necessary for the custom controller.
2. Create a page to search for contacts.
3. Test your new page.
Time:
15 minutes
Instructions:
Goal:
Modify the controller of a Visualforce page to defend against SOQL Injection.
Tasks:
1. Create a custom Visualforce Controller.
2. Create a Visualforce page.
3. Search for an existing record.
4. Sanitize the code to defend against SOQL Injection attacks.
Time:
10 minutes
Instructions:
A. In VS Code, create an Apex class SOQLController and overwrite its contents with
SOQLControllerClass.txt.
Goal:
Write an Apex test class to validate the navigation from the SearchCourses page to the
ListCourseDeliveries page.
Tasks:
1. Create the test class.
2. Run the test.
3. Verify the result.
Time:
20 minutes
Instructions:
Goal:
Using the Aura programming model, create a Lightning component that will display the number
of days that your trial org has left before expiration. Surface the component on the Certification
App’s Home page.
Tasks:
1. Create an Apex class to return the number of days left.
2. Create an Aura Component to display the data.
3. Surface the Aura Component.
Time:
20 minutes
Instructions:
Note: When developing Lightning Components, it is helpful to enable Debug mode so that your code
is not minified.
1. Create the Apex class with an @AuraEnabled method that will return the number of days
remaining to your trial org as an Integer data type.
2. Create the Aura component that will retrieve the number of days left from the Apex method
you just created and display the result.
3. Surface the Lightning Component on the Home tab of the Certification App.
A. Modify the homepage of the Certification App and surface the TrialExpirationAura
custom component above the Assistant standard component at the top right of the
canvas.
Goal:
Create a Lightning Web Component that will display the number of days that your trial org has
left before expiration. Surface the component on the Certification App’s Home page.
Tasks:
1. Create an Apex class to return the number of days left.
2. Create a Lightning Component to display the data.
3. Surface the Lightning Component.
Time:
30 minutes
Instructions:
Note: When developing Lightning Components, it is helpful to enable Debug mode so that your code
is not minified.
1. Create the Apex class with an @AuraEnabled method that will return the number of days
remaining to your trial org as an Integer data type.
A. If you completed 15-1, proceed to step 2 as you have already done this.
B. If you have not completed 15-1:
i. In VS Code, create an Apex class TrialExpirationController and overwrite
its contents with TrialExpirationControllerClass.txt.
ii. Complete the TODO.
trialExpirationLwc.js trialExpirationLwcJs.txt
trialExpirationLwc.js-meta.xml trialExpirationLwcMeta.txt
3. Surface the Lightning Component on the Home tab of the Certification App.
A. Modify the homepage of the Certification App and surface the TrialExpirationLwc
custom component above the Assistant standard component at the top right of the
canvas.