You need to sign in to do that
Don't have an account?
KatherineC
Code Coverage is 71% in Sandbox, but when deployed it says only 19%?
We recently upgraded from trial to paid production environment, tried to remove unwanted triggers and start from scratch. I noticed that Chatter has a trigger only has 35% coverage, it affects my overall coverage, what can I do with that? It's also confusing that we have 71% overall code coverage in Sandbox, but when deployed it said only 19%, how come? Attached are screenshots:
Sandbox Overall Coverage
Production Overall Coverage
Error Msg
Sandbox Overall Coverage
Production Overall Coverage
Error Msg
As Chatter_Answer_Question have 17 line so if able to improve code coverage between 85%-90% then it will improve the overall code coverage for you production. So improve code coverage for Chatter_Answer_Question in Sandbox and then deploy it with other components.
@isTest
private class ChatterAnswersEscalationTriggerTest {
static testMethod void validateQuestionEscalation() {
String questionTitle = 'questionTitle';
String questionBody = 'questionBody';
Community[] c = [SELECT Id from Community];
// We cannot create a question without a community
if (c.size() == 0) { return; }
String communityId = c[0].Id;
Question q = new Question();
q.Title = questionTitle;
q.Body = questionBody;
q.CommunityId = communityId;
insert(q);
q.Priority = 'high';
update(q);
Case ca = [SELECT Origin, CommunityId, Subject, Description from Case where QuestionId =: q.Id];
// Test that escaltion trigger correctly escalate the question to a case
System.assertEquals(questionTitle, ca.Subject);
System.assertEquals(questionBody, ca.Description);
System.assertEquals('Chatter Answers', ca.Origin);
System.assertEquals(communityId, ca.CommunityId);
}
}
TRIGGER
trigger chatter_answers_question_escalation_to_case_trigger on Question (after update) {
for (Question q: Trigger.new) {
try {
if (q.Priority == 'high' && (q.Cases == null || q.Cases.size() == 0) && Trigger.oldMap.get(q.id).Priority != 'high') {
q = [select Id, Title, Body, CommunityId, createdById, createdBy.AccountId, createdBy.ContactId from Question where Id = :q.Id];
Case newCase = new Case(Origin='Chatter Answers', OwnerId=q.CreatedById, QuestionId=q.Id, CommunityId=q.CommunityId, Subject=q.Title, Description=q.Body, AccountId=q.CreatedBy.AccountId, ContactId=q.CreatedBy.ContactId);
insert newCase;
}
} catch (Exception e) {
String subjectText = 'Case Escalation exception in site ' + Site.getName();
String bodyText = 'Case Escalation on Question having ID: ' + q.Id + ' has failed with the following message: ' + e.getMessage() +
'\n\nStacktrace: ' + e.getStacktraceString();
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] { Site.getAdminEmail() };
mail.setReplyTo('no-reply@salesforce.com');
mail.setSenderDisplayName('Salesforce Chatter Answers User');
// The default sender is the portal user causing this trigger to run, to change this, set an organization-wide address for
// the portal user profile, and set the ID in the following line.
// mail.setOrgWideEmailAddressId(orgWideEmailAddressId);
mail.setToAddresses(toAddresses);
mail.setSubject(subjectText);
mail.setPlainTextBody(bodyText);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}
}
}
APEX CLASS - TOTAL 4
public class ChatterAnswers {
public String createAccount(String firstname, String lastname, Id siteAdminId) {
Account a = new Account(name = firstname + ' ' + lastname, ownerId = siteAdminId);
insert a;
return a.Id;
}
}
-------------------------------------------------------------------------------
@isTest
private class ChatterAnswersEscalationTriggerTest {
static testMethod void validateQuestionEscalation() {
String questionTitle = 'questionTitle';
String questionBody = 'questionBody';
Community[] c = [SELECT Id from Community];
// We cannot create a question without a community
if (c.size() == 0) { return; }
String communityId = c[0].Id;
Question q = new Question();
q.Title = questionTitle;
q.Body = questionBody;
q.CommunityId = communityId;
insert(q);
q.Priority = 'high';
update(q);
Case ca = [SELECT Origin, CommunityId, Subject, Description from Case where QuestionId =: q.Id];
// Test that escaltion trigger correctly escalate the question to a case
System.assertEquals(questionTitle, ca.Subject);
System.assertEquals(questionBody, ca.Description);
System.assertEquals('Chatter Answers', ca.Origin);
System.assertEquals(communityId, ca.CommunityId);
}
}
---------------------------------------------------------------------------------------------
public class TrialCustomerPortalHomePageController {
User loggedInUser = [Select id,contactId,Contact.AccountId from User where id = :UserInfo.getUserId()];
public List<Asset> MyRegisteredProducts {get; set;}
public List<Case> MyRecentCases {get; set;}
public List<Solution> TopSolutions {get; set;}
public List<Idea> PopularIdeas {get; set;}
public String sortField1 {get; set;}
public String previousSortField1 {get; set;}
public String sortField2 {get; set;}
public String previousSortField2 {get; set;}
public String sortField3 {get; set;}
public String previousSortField3 {get; set;}
public String sortField4 {get; set;}
public String previousSortField4 {get; set;}
public TrialCustomerPortalHomePageController() {
MyRegisteredProducts = [select id,Name,SerialNumber,InstallDate,UsageEndDate,Status
from Asset
where ContactId = :loggedInUser.ContactId
order by SerialNumber desc limit 3];
MyRecentCases = [select id,CaseNumber,Subject,Status,LastModifiedDate
from Case
where ContactId = :loggedInUser.ContactId
order by LastModifiedDate desc limit 3];
TopSolutions = [select id,SolutionName,TimesUsed,LastModifiedDate
from Solution
order by TimesUsed desc limit 3];
PopularIdeas = [select id,Title,Categories,VoteTotal
from Idea
order by VoteTotal desc limit 3];
}
public void SortProducts(){
String order = 'asc';
if(previousSortField1 == sortField1){
order = 'desc';
previousSortField1 = null;
}else{
previousSortField1 = sortField1;
}
superSort.sortList(MyRegisteredProducts,sortField1,order);
}
public void SortCases(){
String order = 'asc';
if(previousSortField2 == sortField2){
order = 'desc';
previousSortField2 = null;
}else{
previousSortField2 = sortField2;
}
superSort.sortList(MyRecentCases,sortField2,order);
}
public void SortSolutions(){
String order = 'asc';
if(previousSortField3 == sortField3){
order = 'desc';
previousSortField3 = null;
}else{
previousSortField3 = sortField3;
}
superSort.sortList(TopSolutions,sortField3,order);
}
public void SortIdeas(){
String order = 'asc';
if(previousSortField4 == sortField4){
order = 'desc';
previousSortField4 = null;
}else{
previousSortField4 = sortField4;
}
superSort.sortList(PopularIdeas,sortField4,order);
}
}
----------------------------------------NOT SURE THIS ONE IS CHATTER RELATED OR NOT-------------
public class superSort {
/*This method takes 3 arguments, the List of objects to sort, the field to sort,
and the order, asc or desc*/
public static void sortList(List<sObject> items, String sortField, String order){
/*I must give credit where it is due as the sorting algorithm I am using is the
one supplied by Andrew Waite here: http://blog.sforce.com/sforce/2008/09/sorting-collect.html */
Boolean isSortFieldReference = false;
Map<Id,String> referenceName;
/*Determine the type of the field that needs to be sorted, if it is a
reference we will want sort by the name of the related object, not the
ID itself*/
if(items[0].getSObjectType().getDescribe().fields.getMap().get(sortField).getDescribe().getType().Name() == 'REFERENCE'){
isSortFieldReference = true;
referenceName = new Map<Id,String>();
/*Determine the type of this object and populate the Id to Name map*/
Set<Id> referenceIds = new Set<Id>();
for(sObject s : items){
referenceIds.add((Id)s.get(sortField));
}
String objectID = (String)items[0].get(sortField);
String prefix = objectID.substring(0,3);
String objectType;
Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
for(Schema.SObjectType s : gd.values()){
if(prefix == s.getDescribe().getKeyPrefix()){
objectType = s.getDescribe().Name;
}
}
//Query the related objects for the name and populate the Id -> Name map
String queryString = 'select Id, Name from ' + objectType + ' where ID IN :referenceIDs';
for(sObject s : Database.query(queryString )){
referenceName.put((Id)s.get('Id'),(String)s.get('Name'));
}
}
/*Declare a list that will contain the sorted results. I think this is one of the
coolest parts of this method as the system will not let you declare a list of
sObjects (List<sObject> objects = new List<sObjects>();) but using a
wrapper class you can bypass this system limitation to create this type of list */
List<cObject> resultList = new List<cObject>();
//Create a map that can be used for sorting
Map<object, List<cObject>> objectMap = new Map<object, List<cObject>>();
for(sObject ob : items){
if(isSortFieldReference == false){
if(objectMap.get(ob.get(sortField)) == null){
objectMap.put(ob.get(sortField), new List<cObject>());
}
cObject o = new cObject(ob);
objectMap.get(ob.get(sortField)).add(o);
}else{
if(objectMap.get(referenceName.get((Id)ob.get(sortField))) == null){
objectMap.put(referenceName.get((Id)ob.get(sortField)), new List<cObject>());
}
cObject o = new cObject(ob);
objectMap.get(referenceName.get((Id)ob.get(sortField))).add(o);
}
}
//Sort the keys
List<object> keys = new List<object>(objectMap.keySet());
keys.sort();
for(object key : keys){
resultList.addAll(objectMap.get(key));
}
//Apply the sorted values to the source list
items.clear();
if(order.toLowerCase() == 'asc'){
for(cObject ob : resultList){
items.add(ob.obj);
}
}else if(order.toLowerCase() == 'desc'){
for(integer i = resultList.size()-1; i >= 0; i--){
items.add(resultList[i].obj);
}
}
}
public class cObject{
sObject obj {get; set;}
public cObject(sObject obj){
this.obj = obj;
}
}
/*Some test methods that provide 100% coverage
public static testMethod void sortAscendingTest(){
List<Opportunity> opps = new List<Opportunity>();
for(integer i = 0; i<1000; i++){
opps.add(new Opportunity(Name = 'test' + i, Amount = 1000 * Math.random()));
}
Test.startTest();
Long start = system.currentTimeMillis();
sortList(opps,'Amount','asc');
system.debug(system.currentTimeMillis() - start);
Test.stopTest();
//Assert the list was sorted correctly
Decimal assertValue = -1;
for(Opportunity o : opps) {
System.debug('Opp value: ' + o.amount);
System.assert(assertValue <= o.amount);
assertValue = o.amount;
}
}
public static testMethod void sortDescendingTest(){
List<Opportunity> opps = new List<Opportunity>();
for(integer i = 0; i<1000; i++){
opps.add(new Opportunity(Name = 'test' + i, Amount = 1000 * Math.random()));
}
Test.startTest();
sortList(opps,'Amount','desc');
Test.stopTest();
//Assert the list was sorted correctly
Decimal assertValue = 1001;
for(Opportunity o : opps) {
System.debug('Opp value: ' + o.amount);
System.assert(assertValue >= o.amount);
assertValue = o.amount;
}
}*/
}