Monday, July 15, 2019

Tips and Tricks : How to hide other feature in Chatter Feed in Visualforce page WITHOUT using JQuery ?

Business Requirement

To only enable Post features in Chatter Feed in Visualforce. Other features such as Poll, Upload File etc should be invisible to user  so that user only able to Post in Chatter Feed.

This is just to give idea that you can hide some of standard css element using style css with !IMPORTANT tag if it 's still not update as you want to or you can hide it using javascript during onload.

Example to hide some standard elements using style .


1
2
3
4
5
6
7
8
/**code to hide file upload in chatter comment section **/
.cxcontentcommentactiontext {
display:none;
}

.cxcontentcommentactionimg {
display:none;
}

Example to hide some of element in Chatter Feed using Javascript
1
2
3
4
5
6
7
window.onload = function() {
//this is to hide File upload and any feature except post in Chatter feed.
   const chatterList = document.querySelectorAll('.publisherFeedItemTypeChoices li');
   chatterList[1].style.display='none';
   chatterList[2].style.display='none';
   chatterList[3].style.display='none';
}

Basically if you can see which Element you want to hide. End result should be like below.


Monday, July 01, 2019

Tips and Tricks : Test class for Invocable method


Issue :

I got 100% coverage in my sandbox but when run validation for deployment it returns 0% coverage

It turn out that in my sandbox, I am depending on Process Builder to Invocable Apex class, as long I manipulate test data that fire Process Builder it will call Invocable class. This is not useful when deploying it to Production although it gets deployed together with Process Builder.

The correct way is to direct call Invocable method inside test class itself.

Example of class :


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
global class MyCustomObject_StatusUpdate_Util{
 @InvocableMethod(label='Update Quote Status')
  public static void updateQuote(Request[] requests) {
        Set<Id> setOppId = new Set<Id>();
        List<SBQQ__Quote__c> listQuoteToUpdate = new List<SBQQ__Quote__c>();

        for(Request request : requests) {
           setOppId.add(request.recordId);
        }
       
        if(setOppId.size()>0){
            List<SBQQ__Quote__c> listQuote =[Select Id,BypassValidationRule__c,SBQQ__Status__c from SBQQ__Quote__c where SBQQ__Opportunity2__c IN :setOppId  ];

             for(SBQQ__Quote__c quote : listQuote)  {
                 quote.BypassValidationRule__c = quote.BypassValidationRule__c?false:true;
                 quote.SBQQ__Status__c =requests[0].quoteStatus;
                 listQuoteToUpdate.add(quote);
             } 
            if(listQuoteToUpdate.size()>0){
                 Database.SaveResult [] updateResult = Database.update(listQuoteToUpdate, false);
            }
         }
     }

 global class Request{
        @InvocableVariable(label='Opportunity ID' required=true)
        public Id recordId;

        @InvocableVariable(label='Quote Status' required=true)
        public String quoteStatus;
      
    }
}

Example of test class :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static testMethod void testCallInvocableClass() {
        
     Test.startTest();
     My_Custom_Object__c myObject =[Select Id,Approval_Status__c FROM My_Custom_Object__c WHere Opportunity__c =:quote.SBQQ__Opportunity2__c];

    myObject.Approval_Status__c ='Approved';
    //this will work only in sandbox, not in deployment.Logically this will fire process builder
    update myObject;

 //to makesure test class is cover, need to call invocable class directly, which in this scenario I need to instantiate
 // inner class 
    List<MyCustomObject_StatusUpdate_Util.Request> listRequest =new List<MyCustomObject_StatusUpdate_Util.Request>();
    MyCustomObject_StatusUpdate_Util.Request req = new MyCustomObject_StatusUpdate_Util.Request();
    req.recordId=quote.SBQQ__Opportunity2__c;
    req.quoteStatus='In Progress';
    listRequest.add(req);
    
    //the call the method directly - here my method is updateQuote
    MyCustomObject_StatusUpdate_Util.updateQuote(listRequest);
   
    listQuote =[select id,SBQQ__Status__c  from SBQQ__Quote__c where SBQQ__Opportunity2__c=:listOpp[0].Id ];
    system.assertEquals('In Progress', listQuote[0].SBQQ__Status__c)
  
    Test.stopTest();
  
  }