function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
CypherCypher 

Test Class for Visual Force Standard Controller Extension

All-

I have created a visual force page that uses a standard controller extension.  The page esentially looks up the NAME of the record and then performs a search on all chatter posts for that string.  Here is the Page:

<apex:page standardController="Asset_cust__c" extensions="ChatterUpdatesController" >

<style type="text/css">
.boldlink {color:#015ba7;font-weight:bold;text-decoration:none;vertical-align:top;}
.link {color:#015ba7;text-decoration:none;vertical-align:top;}
.addComment {color:#015ba7;text-decoration:none;font-size:0.92em;padding-left:5px;}
.feedimage {width:45px;height:45px;}
.groupimage {width:20px;height:20px;}
.commentimage {width:30px;height:30px;}
.dateTime {color:#7D7D84;font-size:0.92em;padding-right:5px;padding-bottom:4px;}
.feedbackground {vertical-align: top;padding-top:8px;padding-bottom:8px;padding-right:8px;border-bottom:#dee4e9 1px solid;}
.commentbackground {vertical-align: top;padding:4px;background-color: #eff7fa;border-top:#dee4e9 1px solid;}
.line {line-height:15px;white-space:normal;}
.bodytext {vertical-align:top;margin-left:2px;}
</style>

<apex:outputText rendered="{!feeds.size == 0}">No records found.</apex:outputText>

<apex:outputpanel layout="block" style="overflow:auto;width:750px;height:500px">
<apex:dataTable value="{!feeds}" var="f" id="theTable" border="0" rendered="{!feeds.size > 0}">

<apex:column styleClass="feedbackground" > <apex:image id="profileImage" url="{!f.image}" styleClass="feedimage" /> </apex:column>

<apex:column styleClass="feedbackground" >
<apex:image id="groupImage" url="{!f.groupImage}" styleClass="groupimage" rendered="{!f.groupName!=null}" />
<apex:outputLink styleClass="boldlink" value="/{!f.groupId}" target="_parent" rendered="{!f.groupName!=null}"> {!f.groupName} </apex:outputLink>
<apex:outputText styleClass="line" rendered="{!f.groupName!=null}"> </apex:outputText>
<apex:outputLink styleClass="link" value="/{!f.createdById}" target="_parent" rendered="{!f.groupName!=null}"> {!f.createdByName} </apex:outputLink>
<apex:outputLink styleClass="boldlink" value="/{!f.createdById}" target="_parent" rendered="{!f.groupName==null}"> {!f.createdByName} </apex:outputLink>
<apex:outputText styleClass="bodytext" value="{!f.body}" />

<apex:panelGrid columns="3" cellpadding="0" cellspacing="0" style="padding-top:4px;padding-bottom:4px;">
<apex:outputLink styleClass="link" value="/{!f.feedId}" target="_parent">
<!-- apex:outputText styleClass="dateTime" value="{0,date,MMMM dd, yyyy 'at' hh:mm a}" > <apex:param value="{!f.feedDate}" />
/apex:outputText -->
<apex:outputText styleClass="dateTime" value="{!f.formattedFeedDate}" />
</apex:outputLink>
<!-- apex:outputText > </apex:outputText>
<apex:outputLink styleClass="addComment" value="/"> Comment </apex:outputLink-->
</apex:panelGrid>

<apex:dataTable value="{!f.comments}" var="c" border="0" >

<apex:column styleClass="commentbackground" > <apex:image id="profileImage" url="{!c.image}" styleClass="commentimage" /></apex:column>

<apex:column styleClass="commentbackground">
<apex:outputLink styleClass="boldlink" value="!c.createdById}" target="_parent"> {!c.createdByName} </apex:outputLink>
<apex:outputText styleClass="bodytext" value="{!c.body}" />

<apex:panelGrid columns="1" cellpadding="0" cellspacing="0" style="padding-top:4px;padding-bottom:4px;" >
<!-- apex:outputText styleClass="dateTime" value="{0,date,MMMM dd, yyyy 'at' hh:mm a}" ><apex:param value="{!c.feedDate}" /> </apex:outputText -->
<apex:outputText styleClass="dateTime" value="{!c.formattedFeedDate}" />
</apex:panelGrid>
</apex:column>

</apex:dataTable>

</apex:column>

</apex:dataTable>
</apex:outputpanel>
</apex:page>

 Here is the controller:

/*
* ClassName: ChatterUpdatesController
* CreatedBy: Richard D. Grubb II
* LastModifiedBy: Richard D. Grubb II
* LastModifiedOn: 24 Apr 2012
* CalledFrom: Asset_VF_Page.page VisualForce Page
* Description: This class looks up the current Asset Object and performs a
* Search through Chatter to return all instances of the Asset Name in a VF page.
* ---------------------------------------
* Revision History
* 24 Apr 2012 – Initial Creation (Richard D. Grubb II)
*/

public with sharing class ChatterUpdatesController {

private final Asset_cust__c c;
public List<Feed> feeds;
public Map<Id,User> uls;
String AssetId = '';

// Constructor with one parameter
public ChatterUpdatesController(ApexPages.StandardController stdController) {
Id cid = stdController.getId();

//lookup asset name
c = [select Name from Asset_cust__c where Id =: cid];

feeds = new List<Feed>();
uls = new Map<Id,User>();

}

public List<Feed> getFeeds() {
feeds = new List<Feed>();
//search by asset name
//serch by row id and any child objects
String curId = c.Name;
String srchString = '(\" *' +curId+'\") or (\"'+curId+'* \")';
System.debug(srchString);


Set<Id> userIdSet = new Set<Id>();
Set<Id> groupIdSet = new Set<Id>();

Set<Id> feedId = new Set<Id>();

Map<Id,List<Feed>> feedCommentsMap = new Map<Id,List<Feed>>();
String keyPrefix = CollaborationGroup.sObjectType.getDescribe().getKeyPrefix();

Integer i=0;
System.debug('id ' + curId);

//sosl search on feeditem and feedcomment to get all feeds and comments that match the search string
for (List<SObject> ls : [FIND :srchString IN ALL FIELDS RETURNING FeedItem(Type, Title, ParentId, LinkUrl,
Id, CreatedDate, CreatedById, CreatedBy.Name, Body
order by CreatedDate desc limit 50),
FeedComment (Id, FeedItemId, ParentId, CreatedById, CreatedBy.Name, CreatedDate, CommentBody
order by FeedItemId,CreatedDate asc limit 50) ]) {

System.debug('results ' + ls);

Integer sortId = 0;
for (SObject lsitem : ls) {
if (i==0) {
FeedItem item = (FeedItem) lsitem;
feedId.add(item.Id);
}
if (i==1) {
FeedComment item = (FeedComment) lsitem;
feedId.add(item.FeedItemId);
}
}
i++;
}

//query to fetch feeditems for comments that matched the search string
for (FeedItem item : [select Id,ParentId,CreatedById,CreatedBy.Name,Body,CreatedDate,
(select Id,CreatedById,CreatedBy.Name,CommentBody,CreatedDate,FeedItemId from FeedComments
order by CreatedDate asc)
from FeedItem where Id in: feedId order by LastModifiedDate desc]) {

Feed f = new Feed(item.CreatedById, item.CreatedBy.Name, item.Body, item.CreatedDate);
f.setFeedId(item.Id);
f.parentId = item.ParentId;
feeds.add(f);

userIdSet.add(item.CreatedById);
if (('' + item.Parentid).substring(0,3) == keyPrefix) {
groupIdSet.add(item.ParentId);
f.groupId = item.ParentId;
}


if (item.FeedComments != null) {
for (FeedComment fc : item.FeedComments) {
Feed fi = new Feed(fc.CreatedById, fc.CreatedBy.Name, fc.CommentBody, fc.CreatedDate);
fi.setFeedId(fc.FeedItemId);
if (feedCommentsMap.containsKey(fc.FeedItemId)) {
List<Feed> cfeeds = feedCommentsMap.get(fc.FeedItemId);
cfeeds.add(fi);
} else {
List<Feed> cfeeds = new List<Feed>();
cfeeds.add(fi);
feedCommentsMap.put(fc.FeedItemId, cfeeds);
}

userIdSet.add(fc.CreatedById);
}
}
}

uls = new Map<Id, User>([select Id,SmallPhotoUrl from User where Id in: userIdSet]);
Map<Id,CollaborationGroup> cgMap = new Map<Id,CollaborationGroup>([select Id, name, SmallPhotoUrl from CollaborationGroup
where Id in: groupIdSet]);

//set the image and group name
for (Feed f : feeds) {
if (f != null) {
Id createdById = f.createdById;
User u = uls.get(createdById);
if (u != null) {
f.image = u.SmallPhotoUrl;
}
Id parentId = f.ParentId;
CollaborationGroup g = cgMap.get(parentId);
if (g != null) {
f.groupImage = g.SmallPhotoUrl;
f.groupName = g.Name;
}
List<Feed> cfeeds = feedCommentsMap.get(f.FeedId);
if (cfeeds != null) {
for (Feed cf : cfeeds) {
Id cfCreatedById = cf.createdById;
User cu = uls.get(cfCreatedById);
if (cu != null) {
cf.image = cu.SmallPhotoUrl;
}
}
}
f.setComments(cfeeds);
}
}

return feeds;
}

public class Feed {
public Id feedId {get;set;}
public String createdByName {get;set;}
public String body {get;set;}
public DateTime feedDate {get;set;}
public String formattedFeedDate {get;set;}
public String image {get;set;}
public Id createdById {get;set;}
public String groupName {get;set;}
public String groupImage {get;set;}
public Id groupId {get;set;}
public String parentId;

public List<Feed> comments {get;set;}

public Feed(Id createdById, String createdByName, String body, DateTime feedDate) {
this.createdById = createdById;
this.createdByName = createdByName;
this.body = body;
this.feedDate = feedDate;
this.formattedFeedDate = feedDate.format('MMMMM dd, yyyy \'at\' hh:mm a');

comments = new List<Feed>();
}

public String getImage() {
return image;
}

public String getGroupName() {
return groupName;
}

public void setComments(List<Feed> comments) {
this.comments = comments;
}

public void setFeedId(Id fid) {
this.feedId = fid;
}
}
}

 I have noticed that when I enter a new chatter post with the information, it takes about 30 seconds before it will show up in the results of the Visual Force Page (this may or may not be relevant).

I began writing a test class, but it only covers 28% of the code.  I think the issue is, when the SOSL query runs, it is returning 0 rows...even though they are explicitly coded in the test class.  I thought maybe it was this 30 second delay so I wrote REAL chatter posts with the information I needed.  The test class cannot find those either.  Here is the test class:

@istest (SeeAllData=true)
public class Chatter_VF {
public static testMethod void Asset_VF_Test()
{
PageReference pg = Page.Asset_VF_Page;
Test.setCurrentPage(pg);

//Create Dummy Data for Test Purposes
Asset_cust__c Aircraft = new Asset_cust__c(Name = 'RDG123');
insert Aircraft;

CollaborationGroup grp = new CollaborationGroup();
grp.Name = 'Air India Teting Group XXXXYYYY';
grp.CollaborationType = 'Public';
insert grp;
FeedItem chat = new FeedItem();
FeedItem chat2 = new FeedItem();
FeedComment comm = new FeedComment();
FeedComment comm2 = new FeedComment();
chat.Body = 'This is a test for Engine ESN111 and Aircraft RDG123';
chat.ParentId = grp.Id;
insert chat;
comm.CommentBody = 'Aircraft RDG123';
comm.FeedItemId = chat.Id;
insert comm;
comm2.CommentBody = 'super test for Aircraft RDG123';
comm2.FeedItemId = chat.Id;
insert comm2;
chat2.Body = 'This is the second Feed Item for Aircraft RDG123';
chat2.ParentId = grp.Id;
insert chat2;

ApexPages.StandardController controller = new ApexPages.StandardController(Aircraft);
ChatterUpdatesController cont = new ChatterUpdatesController(controller);
cont.getFeeds();

}
}

Does anyone know what I am doing wrong?  Or, is it impossible to query Chatter results in test classes because they aren't "real"?  Please, any help is most appreciated. 

Rajesh SriramuluRajesh Sriramulu

Hi,

 

Try This

 

 

@istest (SeeAllData=true)
public class Chatter_VF {
public static testMethod void Asset_VF_Test()
{
PageReference pg = Page.Asset_VF_Page;
Test.setCurrentPage(pg);

//Create Dummy Data for Test Purposes
Asset_cust__c Aircraft = new Asset_cust__c(Name = 'RDG123');
insert Aircraft;

CollaborationGroup grp = new CollaborationGroup();
grp.Name = 'Air India Teting Group XXXXYYYY';
grp.CollaborationType = 'Public';
insert grp;
FeedItem chat = new FeedItem();
FeedItem chat2 = new FeedItem();
FeedComment comm = new FeedComment();
FeedComment comm2 = new FeedComment();
chat.Body = 'This is a test for Engine ESN111 and Aircraft RDG123';
chat.ParentId = grp.Id;
insert chat;
comm.CommentBody = 'Aircraft RDG123';
comm.FeedItemId = chat.Id;
insert comm;
comm2.CommentBody = 'super test for Aircraft RDG123';
comm2.FeedItemId = chat.Id;
insert comm2;
chat2.Body = 'This is the second Feed Item for Aircraft RDG123';
chat2.ParentId = grp.Id;
insert chat2;

ApexPages.StandardController controller = new ApexPages.StandardController(Aircraft);
ChatterUpdatesController cont = new ChatterUpdatesController(controller);
cont.getFeeds();

Id createdById=grp.Id;

 String createdByName='test';

String body='test1';

DateTime feedDate=DateTime feedDate=datetime.newinstance(2008,12,1);

 

ChatterUpdatesController.Feed cucf = new ChatterUpdatesController.Feed cucf(createdById,createdByName,body,feedDate);

String string1;

String string2;

 

string1=cucf.getImage();
string2=cucf.getGroupName();

List<Feed> comments1 = new List<Feed>();

cucf.setComments(comments1 );

cucf.setFeedId(createdById)
}
}

 

Regards,

Rajesh.

CypherCypher

Rajesh -

Thanks for your help.  Your code (slightly altered, below) got me to 56% coverage.  Here is my updated code, for those following along:

@istest (SeeAllData=true)
public class TestAirIndiaChatter_VF {
public static testMethod void Asset_VF_Test()
{
PageReference pg = Page.Asset_VF_Page;
Test.setCurrentPage(pg);

//Create Dummy Data for Test Purposes
Asset_cust__c Aircraft = new Asset_cust__c(Name = 'RDG123');
insert Aircraft;

CollaborationGroup grp = new CollaborationGroup();
grp.Name = 'Air India Teting Group XXXXYYYY';
grp.CollaborationType = 'Public';
insert grp;
FeedItem chat = new FeedItem();
FeedItem chat2 = new FeedItem();
FeedComment comm = new FeedComment();
FeedComment comm2 = new FeedComment();
chat.Body = 'This is a test for Engine ESN111 and Aircraft RDG123';
chat.ParentId = grp.Id;
insert chat;
comm.CommentBody = 'Aircraft RDG123';
comm.FeedItemId = chat.Id;
insert comm;
comm2.CommentBody = 'super test for Aircraft RDG123';
comm2.FeedItemId = chat.Id;
insert comm2;
chat2.Body = 'This is the second Feed Item for Aircraft RDG123';
chat2.ParentId = grp.Id;
insert chat2;

ApexPages.StandardController controller = new ApexPages.StandardController(Aircraft);
ChatterUpdatesController cont = new ChatterUpdatesController(controller);
cont.getFeeds();

Id createdById=grp.Id;
String createdByName='test';
String body='test1';
DateTime feedDate =datetime.newinstance(2008,12,1);

ChatterUpdatesController.Feed cucf = new ChatterUpdatesController.Feed(createdById,createdByName,body,feedDate);
String string1;
String string2;

string1=cucf.getImage();
string2=cucf.getGroupName();

List<ChatterUpdatesController.Feed> comments1 = new List<ChatterUpdatesController.Feed>();
//List<Feed> comments1 = new List<Feed>();
cucf.setComments(comments1);
cucf.setFeedId(createdById);


}
}

 I am now facing 2 issues:

First, the Force.com IDE says that this is 100% covered, but the Admin tool in SFDC says it is only 56% covered.  I've seen some threads about this, but don't know which is correct.  I've flushed all previous tests, and it is stil sowing 56%.  Here is the screen shot of the uncovered code.

The bold and italicized rows are the untested/uncovered code according to the SFDC Admin Screen (64-70, 82-107, 118-140)  Any thoughts?


CypherCypher
  
 61  
 62   Integer sortId = 0;
 63   for (SObject lsitem : ls) {
 64   if (i==0) {
 65   FeedItem item = (FeedItem) lsitem;
 66   feedId.add(item.Id);
 67   }
 68   if (i==1) {
 69   FeedComment item = (FeedComment) lsitem;
 70   feedId.add(item.FeedItemId);
  
 80   from FeedItem where Id in: feedId order by LastModifiedDate desc]) {
 81  
 82   Feed f = new Feed(item.CreatedById, item.CreatedBy.Name, item.Body, item.CreatedDate);
 83   f.setFeedId(item.Id);
 84   f.parentId = item.ParentId;
 85   feeds.add(f);
 86  
 87   userIdSet.add(item.CreatedById);
 88   if (('' + item.Parentid).substring(0,3) == keyPrefix) {
 89   groupIdSet.add(item.ParentId);
 90   f.groupId = item.ParentId;
 91   }
 92  
 93  
 94   if (item.FeedComments != null) {
 95   for (FeedComment fc : item.FeedComments) {
 96   Feed fi = new Feed(fc.CreatedById, fc.CreatedBy.Name, fc.CommentBody, fc.CreatedDate);
 97   fi.setFeedId(fc.FeedItemId);
 98   if (feedCommentsMap.containsKey(fc.FeedItemId)) {
 99   List<Feed> cfeeds = feedCommentsMap.get(fc.FeedItemId);
 100   cfeeds.add(fi);
 101   } else {
 102   List<Feed> cfeeds = new List<Feed>();
 103   cfeeds.add(fi);
 104   feedCommentsMap.put(fc.FeedItemId, cfeeds);
 105   }
 106  
 107   userIdSet.add(fc.CreatedById);
  
 116   //set the image and group name
 117   for (Feed f : feeds) {
 118   if (f != null) {
 119   Id createdById = f.createdById;
 120   User u = uls.get(createdById);
 121   if (u != null) {
 122   f.image = u.SmallPhotoUrl;
 123   }
 124   Id parentId = f.ParentId;
 125   CollaborationGroup g = cgMap.get(parentId);
 126   if (g != null) {
 127   f.groupImage = g.SmallPhotoUrl;
 128   f.groupName = g.Name;
 129   }
 130   List<Feed> cfeeds = feedCommentsMap.get(f.FeedId);
 131   if (cfeeds != null) {
 132   for (Feed cf : cfeeds) {
 133   Id cfCreatedById = cf.createdById;
 134   User cu = uls.get(cfCreatedById);
 135   if (cu != null) {
 136   cf.image = cu.SmallPhotoUrl;
 137   }
 138   }
 139   }
 140   f.setComments(cfeeds);
  
CypherCypher

I now think it may have to do with the SOSL queries in the controller - they always return 0 rows.  However, the use of the Test.setFixedSearchResults method is not adding anything to the coverage.  Although the IDE says I am 100% covered, the salesforce admin screen says only 56% covered.

CypherCypher

I added this code, and still getting the same 56% coverage:

 

Id[] fixedSearchResults = new Id[4];
fixedSearchResults[0] = chat.Id;
fixedSearchResults[1] = comm.Id;
fixedSearchResults[2] = comm2.Id;
fixedSearchResults[3] = chat2.Id;
Test.setFixedSearchResults(fixedSearchResults);
cont.getFeeds();

Rajesh SriramuluRajesh Sriramulu

Hi

 

 

Try to Run All test in UI their it will show exact code coverage.

 

Regards,

Rajesh.