Friday, December 20, 2013

Testing Apex @future Methods in Salesforce

To write functional Apex unit tests for methods having the future annotation, all you need to do is use Test.startTest() and Test.stopTest(). The general structure of your testMethod will look like the following.

Whether it's scheduled Apex or @future Apex, calling Test.stopTest() will cause those methods to run in sequence in your test method. Test.stopTest() then allows you to validate the results of @future Apex using normal means.

Wednesday, December 4, 2013

Mark Read Checkbox in Field Permissions for Salesforce Profile with Bookmarklet

Below is a functional bookmarklet that you can use to mark the Read checkbox for every single field in the Field Permissions section of an object's settings within a Salesforce Profile.


To use the bookmarklet:
  1. Drag the link ("bookmarklet") on to your browser's bookmarks bar
  2. Open an object settings page within a Salesforce Profile
  3. Click the bookmarklet in your browser's bookmarks bar

Note: This was tested with Chrome on Windows 8 in Salesforce Winter '14.

Tuesday, December 3, 2013

Deploying Destructive Changes Using Workbench

Sometimes, especially in the case of custom Apex or Visualforce, a Salesforce admin or developer needs to delete components from an org. However, Salesforce's user-friendly change sets feature does not allow admins to propagate component deletions. The only semi-automated alternative to performing these deletions, especially in production orgs, is to leverage the metadata API.

Fortunately, with the availability of Workbench on Developer Force, the steps required for deploying destructive changes (that delete components) are pretty simple:

  1. Create a package.xml file
  2. Create a destructiveChanges.xml file
  3. Bundle the two files together in a .zip file
  4. Deploy the .zip package using Workbench

As you can see from this sample .zip package, the files are fairly simple and straightforward. Multiple types of metadata can be removed with a single package.

The exact steps for deploying using Workbench 29.0.1 are:
  1. Open the migration menu, then click Deploy
  2. Click Browse... and select the .zip package file
  3. Mark the "Rollback On Error" checkbox
  4. Mark the "Single Package" checkbox
  5. Mark the "Run All Tests" checkbox
  6. Click Next
  7. Review the deployment options, then click Deploy

The results, successful or otherwise, will be displayed in Workbench for you to review once the deployment process is complete.


Friday, October 4, 2013

Contact Age (Years) Formula Field In Salesforce

Due to complications in the human calendar, with leap years and different numbers of days in different months, it's not always easy to calculate the exact human age of a person for CRM purposes. In Salesforce, a more reliable method of calculating the age is through a formula field with the following formula:

( YEAR( TODAY() ) - YEAR( Birthdate ) )

+ IF(
    MONTH( TODAY() ) * 31 + DAY( TODAY() ) >= 
    MONTH( Birthdate ) * 31 + DAY( Birthdate ) , 
    0 , -1 )

The components of this seemingly complex formula are broken down below.

YEAR( TODAY() ) - YEAR( Birthdate )


This gives us the expected age. If a Johnny was born in 2000, and it's now 2013, we would expect the (max) age of Johnny to be 13 once his birthday arrives in 2013.

IF( ... , 0 , -1 )


By assuming that there is a max of 31 days in any given month, treating the month-day relationship as two "digits" in a base-31 number allows us to do a simple arithmetic comparison to see whether the birthday has come and gone in the current year. This works even for the rare February 29 birthdays.

So, if the birthday has passed, then the expected age is fine and we don't need to make any adjustments. If the birthday has not passed, then we subtract one from the max expected age to arrive at the correct current age.

Force.com #Tested, Standard Pattern for Apex Unit Tests

The first step to writing an Apex unit test is... just to lay down the framework. The boring stuff, really. Declare the class, add the isTest annotation, declare a testMethod-qualified method, etc. And to make boring matters worse, in practice Apex unit testing is pretty important to get right.

The reason is simple: In addition to deploying your own customizations, Salesforce will upgrade your org 3 times a year with 100+ new features per release. Whether you like it or not. Assuming CRM is fairly important to your organization, who's going to run tests for your org every time a new release happens, to make sure the business can continue to operate?

  • Code coverage and test methods are intended to make sure that customizations work correctly, release after release, with minimal human effort
  • Good tests help to make sure your code works not only for one-off record edits but also for batch inserts, updates and deletes
  • With good intent, Salesforce requires you to have at least 75% code coverage to deploy new code. So, if you have to write tests anyway, let's just do it right the first time. Build the tests to add value as regression tests, instead of just time drains.


Understanding the significance of these tests, a new developer may find writing good tests to be quite daunting, second-guessing himself and worrying about whether he followed best practices. Then, in frustration, he could decide to just "screw it" and hack something out to achieve the minimum amount of code coverage required to just push a risky feature into production. Bad outcome.

To help a developer avoid this sub-optimal decision, he can adopt a standard test class structure that is easily adapted for all Apex unit tests. Below is one such self-documenting template for Apex unit tests, using a contrived example of trying to roll-up all activities related to a particular contact record.


There are lots of comments and little code in the above block, which is intentional to leave material for the rest of this series. :-) Subsequent posts will dive into each step above in more detail, walking through sample implementations by building out this example trigger test class.

But regardless of whether you're testing triggers, controllers, extensions, Schedulables or anything else in Apex, the general steps above should remain the same for your test methods. This way, Apex unit tests transform from time-and-materials liabilities in a Salesforce org to valuable assets that shine every time anyone goes to release a new feature.

Wednesday, September 25, 2013

Force.com #Tested, Way Beyond Code Coverage

Force.com gives developers a quick and easy way to not only deploy business automation but also to set up unit tests for acceptance testing and regression testing. The value of such testing cannot be underestimated, especially in large orgs with multiple admins, developers and outsourced partners.

While the ideals are good, there are many challenges preventing an organization from reaching these goals. Managers may not fully understand the benefits of unit testing, and as a result have little or no buy-in for the practice. Without buy-in from managers, there is no enforcement of consistent methodologies for internal and external developers. Frustrated developers who don't have management support, training or knowledge on unit tests only see the code coverage portion of unit testing and feel that the practice is a big pain with little gain.

But actually, proper and disciplined use of unit tests on Force.com allows a company to:
  • More reliably implement new features by explicitly testing for expected functionality using Apex
  • Simplify regression testing by allowing the system to automatically perform acceptance tests that were used when deploying previous features to production
  • More confidently allow developers to simultaneously tackle multiple work streams for different features, knowing that both each other's functionality and previous functionality will be validated together before new features goes live
  • Define functional specifications for external parties through unit tests, in addition to written requirements

This blog mini-series aims to address the challenges above by sequentially tackling the following topics, with new posts every 3 business days:
  1. Standard pattern for Apex unit tests
  2. Common database of test data for all Apex unit tests
  3. Using System.assert() and related methods to verify expected conditions for the test
  4. Using Test.startTest(), Test.stopTest() and other Test methods
  5. Using System.assert() and related methods for validating test results
  6. Apex unit tests for workflow rules, validation rules and system configurations
  7. How this standard pattern affects code coverage

Monday, September 9, 2013

Adding a Live Agent Chat Side Tab to All Pages in a Community

Chatter Communities gives administrators and web developers a method to implement more advanced customization of the UI, without resorting to fully custom pages or sites through Force.com Sites or Site.com. The means to achieve this customization is through an HTML header or footer, uploaded as a Document in Salesforce. The ability to customize the entire site with HTML gives web developers an easy way to add a Web 2.0 feature to an entire community: live chat side tab via Live Agent.


Similar to the Contact Us side tab shown on salesforce.com (screenshot above), the intent behind the live chat side tab is to enable the following functionality, no matter where a user is in a community:

  • Chat with a customer service agent live, if one available
  • If an agent is unavailable, quickly open a page to log a new case

The steps to achieving this are actually surprisingly simple, and can be tested through a brief tutorial with a new Developer Edition org. The high-level steps are:
  1. Enable Live Agent
  2. Create a Live Agent Deployment, copying the HTML code and pasting it into the community's custom HTML footer
  3. In the HTML footer, add a div with an inline style attribute to become the side tab
  4. Create a Live Agent Chat Button, copying the HTML code and pasting it into the side tab div
  5. Configure a new community to use the custom HTML footer, after uploading it

Tuesday, September 3, 2013

Listing Required Fields for an Object in Salesforce Using Apex Code

Sometimes it's desirable or necessary to get a list of all required fields for a particular Salesforce object, especially for subsequent processing in Apex. Instead of hard-coding this list, which is not sustainable or maintainable long-term, a better approach is to use Salesforce field describe results and the isNillable() method.

Below is sample code that demonstrates this approach, code that can be adapted for any standard or custom object.

Monday, September 2, 2013

Custom CSS for Chatter Communities

Chatter Communities allows an organization using Salesforce to quickly deploy a functional, branded portal experience for partners and customers. Communities conveniently allows for a custom HTML header and footer to be added to a community, but it appears that in the Summer '13 release of Salesforce there is no support for using merge fields or to easily pull in custom CSS styles into a community. If you're used to using the URLFOR() function with the apex:stylesheet element in Visualforce, you may feel like something's missing.

Without too much hacking, there are two HTML5-compliant ways to approach this problem in Summer '13:

<style scoped>...</style>

This approach is simple, and any styles defined should be applied to the div id="contentWrapper" element into which the community's HTML header and footer are inserted. The parent div pretty much includes all of the visual content on the page, which makes this approach fairly comprehensive in the scope of its effects.

JavaScript script to insert link elements

Typically in Visualforce, styles are applied through dynamic links to CSS stylesheets stored as static resources. However, to build that dynamic URL in static HTML requires manual construction based on knowledge of Salesforce's URL conventions.

A relative URL to a CSS stylesheet stored within a .zip file loaded as a static resource has the following components:
  • CommunityName: The keyword appended after ServerName, if applicable. This may be blank for a particular community.
  • ResourceNumber: A unique number assigned to a static resource by Salesforce
  • ResourceName: The name (case-sensitive) of the static resource
  • InsidePath: The path inside the .zip file to the CSS stylesheet
The full URL is then constructed by concatenating the following: '/' + CommunityName + '/resource/' + ResourceNumber + '/' + ResourceName + '/' + InsidePath

A few sample URL's are shown below:
  • /cirruscommunity/resource/1378136101000/CirrusStaticResource/styles/layout.css
  • /slalomcommunity/resource/1379138201002/SlalomStaticResource/css/common.css
ResourceNumber can be ascertained by opening the static resource and looking for the string of numbers in the "View file" link's URL. Right-clicking the "View file" link and copying the link address should easily grab the ResourceNumber for you.

Lastly, the following JavaScript script can be edited to add all of the stylesheets you want to the community.

<script type="text/javascript">
  function appendLinkToHead(path) {
    var link = document.createElement("link");
    link.setAttribute("rel", "stylesheet");
    link.setAttribute("type", "text/css");
    link.setAttribute("href", path);
   
    var head = document.getElementsByTagName("head")[0];
    head.appendChild(link);
  } // function appendCommunityLink(String)

  var communityName = "community";
  var resourceNo = "1378136101000";
  var resourceName = "CommunityResource";
 
  var resourcePath = "/" + communityName + "/resource/"
      + resourceNo + "/" + resourceName + "/";
 
  var stylesheets = [
      "library/css/brand.css",
      "library/css/layout.css",
      "library/css/reset.css"];

  for (var i = 0; i < stylesheets.length; i++)
    appendLinkToHead(resourcePath + stylesheets[i]);
</script>