Monday, October 7, 2013

Writing Apex Test method for insert attachment





Salesforce.com makes it extremely easy to add attachments to any record either programmatically or from the UI. Writing a test case for the insert attachment is little tricky. Below are the quick apex code snippets for inserting an attachment for use in a Apex Text method. This would be useful for ensuring sufficient code coverage for the Apex classes that depend on insert attachment functionality. 

Version 1: with 1 argument (object Id of an object to which the attachment is added or the parentId of the attachment)

    /**
     * test method for add attachment to any object by passing the object Id
     */
    private static void testAddAttachmentToObject(Id objectId) {
    Blob b = Blob.valueOf('Test Data');
   
    Attachment attachment = new Attachment();
    attachment.ParentId = objectId;
    attachment.Name = 'Test Attachment for Parent';
    attachment.Body = b;
   
    insert(attachment);

     List<Attachment> attachments=[select id, name from Attachment where parent.id=: objectId];
     System.assertEquals(1, attachments.size());
    }

Version 2: without any arguments

    /**
     * test method for add attachment to any object by creating an object 
     */
    private static void testAddAttachmentToObject() {

        Account acct = new Account(Name='Test Account'); 
       /*
            you should supply values for all mandatory fields 
            same way, you can create any other object
      */
        insert acct;

     Blob b = Blob.valueOf('Test Data');
      
     Attachment attachment = new Attachment();
     attachment.ParentId = acct.Id;
     attachment.Name = 'Test Attachment for Parent';
     attachment.Body = b;
    
     insert(attachment);

     List<Attachment> attachments=[select id, name from Attachment where parent.id=: acct.Id];
     System.assertEquals(1, attachments.size());
    }

Hope this is helpful.

Thursday, August 22, 2013

Display Chatter in Visualforce pages

               Display Chatter Widget in VisualForce Pages

Chatter is a very useful widget available to collaborate with other users or a group of users in your Salesforce Org. It is visible (at the bottom corner of the window on right hand side) in all standard Salesforce views. But it will not be visible on custom developed VisualForce pages by default. 

To enable it on VisualForce Pages you need to follow 2 steps.

1) change the default settings. 
    Go to Your Name-->Setup-->Customize-->Chatter-->Chat Settings
       You can see there two options
          1. Chat Settings.
          2. Visualforce Settings.
       Click on Edit & Check the box next to "Allow" under VisualForce Settings.  Click on Save.

2) Set Correct attributes to Visualforce Page <apex:page> tag. 

       You need to add "Showheader=ture" attrubute on the <apex:page> tag.
       If you don't want to show header but chatter widget must be shown, then you have to use two attributes.
           showheader=false
           showchat=true


Example 1:

  <apex:page standardController="Account" showHeader="true">
    <apex:form>
        <apex:pageBlock title="My Content" mode="edit">
            <apex:pageBlockButtons>
                <apex:commandButton action="{!save}" value="Save"/>
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="My Content Section" columns="2">
                <apex:inputField value="{!account.name}"/>
                <apex:inputField value="{!account.site}"/>
                <apex:inputField value="{!account.type}"/>
                <apex:inputField value="{!account.accountNumber}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Output of this page with chatter widget displaying @ the bottom right hand side corner of the window



Example 2:

<apex:page standardController="Account" showHeader="false" showChat="true">
    <apex:form>
        <apex:pageBlock title="My Content" mode="edit">
            <apex:pageBlockButtons>
                <apex:commandButton action="{!save}" value="Save"/>
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="My Content Section" columns="2">
                <apex:inputField value="{!account.name}"/>
                <apex:inputField value="{!account.site}"/>
                <apex:inputField value="{!account.type}"/>
                <apex:inputField value="{!account.accountNumber}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Output of this page with chatter widget displaying @ the bottom right hand side corner of the window



To prevent the chat widget from displaying on a specific Visualforce page, do any of the following:
  • Turn off the Salesforce tab header on your page by setting <apex:page showHeader=”false”>.
  • Set the page contentType to something other than text/html, for example, <apex:page contentType="text/plain">.


Monday, July 8, 2013

Apex Compile Error: Test methods must be in test classes

         Apex Compile Error: Test methods must be in test classes


            Have you ever got an error "Error: Compile Error: Test methods must be in test classes at line 37 column 28" while saving an Apex Class? and wondered why is it an error? It used to work without any error & now, it is not working! Nothing to worry, this is an update starting from Summer '13 release. Here is an excerpt from the release notes:

Test Methods Defined in Test Classes:


Starting in Summer ‘13, test methods can be defined only in test classes (classes annotated with @isTest). You can no longer add a test method in a non-test class. This change applies to new Apex code saved using Salesforce.com API version 28.0 and later. Apex code saved using earlier API versions isn’t affected. 

This change is in line with the Apex coding best practice of including test methods in test classes. Test classes don’t count toward your organization’s code size limit, so separating the test code from the product code enables you to write more Apex code. Also, Apex testing will be enhanced in future releases and this is a prerequisite for those planned enhancements.

Lets take an example TestController class (Prior to Salesforce.com API Version 28.0) it was allowed to have the test methods also in the same class as shown bellow. 


//This class will give Compilation error "Test methods must be in test classes at line 25 column 28"  
public class TestController { //Declarations private Integer inventoryCount = 100; // Instance method public String DisplayStatus() { String status = 'Current inventory status: ' + inventoryCount + ' records.'; System.debug(LoggingLevel.INFO, status); return status; } // Static method public static Id InsertAccount(String aName, String bCity) { Account a = new Account(Name=aName, BillingCity=bCity); insert a; return a.Id; } /* *Unit test methods **/ static testmethod void testDisplayStatus() { // To call the instance method, you must first create an instance of the class. TestController m = new TestController(); String s = m.DisplayStatus(); // Verify status message System.assertNotEquals(null, s); } static testmethod void testInsertRecord() { // Call the static method Id accountID = TestController.InsertRecord('Acme','New York'); // Verify record got inserted System.assert(accountID != null); Account a = [SELECT Name,BillingCity FROM Account WHERE Id=:accountID]; System.assertEquals('Acme',a.Name); System.assertEquals('New York',a.BillingCity); } }

We can resolve this compilation error by moving all the test methods to new Test class "TestContollerTest.cls"

1. Create a new (test) class & name it "TestContollerTest". This class should have @isTest annotation to indicate this is a test class
2. Remove all methods from the Original class and add (Cut & Paste) them in the new Test class. (Note: if you have used keywords like "this" to reference the static variables and/or methods you should remove those references. For e.g.: this.<methodName> to <className>.<methodName> etc.)

The following example shows how to add test methods in a separate test class, TestControllerTest for the main class TestController.

public class TestController { //Declarations private Integer inventoryCount = 100; // Instance method public String DisplayStatus() { String status = 'Current inventory status: ' + inventoryCount + ' records.'; System.debug(LoggingLevel.INFO, status); return status; } // Static method public static Id InsertAccount(String aName, String bCity) { Account a = new Account(Name=aName, BillingCity=bCity); insert a; return a.Id; } }

@isTest private class TestControllerTest { static testmethod void testDisplayStatus() { // To call the instance method, you must first create an instance of the class. TestController m = new TestController(); String s = m.DisplayStatus(); // Verify status message System.assertNotEquals(null, s); } static testmethod void testInsertAccount() { // Call the static method Id accountID = TestController.InsertAccount('Acme','New York'); // Verify record got inserted System.assert(accountID != null); Account a = [SELECT Name,BillingCity FROM Account WHERE Id=:accountID]; System.assertEquals('Acme',a.Name); System.assertEquals('New York',a.BillingCity); } }

Friday, June 28, 2013

Introduction to new Visualforce tag



Introduction to new VisualForce Tag support:clickToDial

Summer ’13 introduced a new computer-telephony integration (CTI) Visualforce component—support:clickToDial. The support:clickToDial component lets you add a phone field to custom Visualforce detail and edit pages. When users in organizations with Open CTI or Salesforce CRM Call Center click on the phone field, the phone number is dialed automatically and connects to the SoftPhone. Use this to, for example, specify which phone fields on custom pages users can click to automatically call customers.

The following examples will guide you through the usage of the new CTI tag.

Example1: Using it in the pageblocktable with in <apex:column> tag:


<apex:page standardController="Account">

    <apex:includeScript value="/support/console/24.0/integration.js"/> <!-- you need to include this in your page for the new tag to work -->
    <apex:pageBlock title="My Content">

        <apex:pageBlockTable value="{!account.Contacts}" var="item">

            <apex:column value="{!item.name}"/> 
            <apex:column value="{!item.Title}" />
            <apex:column value="{!item.Email}" />
            <apex:column headerValue="Phone"> <support:clickToDial number="{!item.Phone}" entityId="{!item.Id}" /> </apex:column>
            <apex:column value="{!item.Phone}" /> <!-- this field is added only to show the difference -->

        </apex:pageBlockTable> 

    </apex:pageBlock> 

</apex:page>

How to run the code:

This page uses Account Standard Controller & shows the list of contacts of the account in the pageBlock Table. Copy & paste the above code into a VisualForce page named Test1. You can test the page by opening it in a browser as https://c.<na1>.visual.force.com/apex/Test1?Id=<AccountId>

Example2: Using it in a details page :

I have tried using it with <apex:outputField>, but was not successful.


<apex:page standardController="Account" tabStyle="Account">

    <apex:includeScript value="/support/console/24.0/integration.js"/><!-- you need to include this in your page for the new tag to work -->
    
    <apex:pageBlock >
        <apex:pageBlockSection title="Account Information">
            <apex:outputField value="{!account.name}"/>             
            <apex:outputField value="{!account.industry}"/>
            <!-- may be we need to apply CSS to align this properly -->
            Phone: <support:clickToDial number="{!account.phone}" entityId="{!account.Id}" />
            <apex:outputLabel value="Phone"><support:clickToDial number="{!account.phone}" entityId="{!account.Id}" /> </apex:outputLabel>
        </apex:pageBlockSection>
    </apex:pageBlock>

</apex:page>


How to run the code:

This page uses Account Standard Controller & shows the details the account in the pageBlock. Copy & paste the above code into a VisualForce page named Test2. You can test the page by opening it in a browser as https://c.<na1>.visual.force.com/apex/Test2?Id=<AccountId>

Hope this helps. Happy experimenting with support:clickToDial. I'll keep posting if I find any other successful usage of support:clickToDial.