+ Start a Discussion
finalistfinalist 

CampaignMember: Status in Trigger Unit Test <> UI behaviour

I have a after trigger on CampaignMember with a goal to calculate a Lead score based on Campaign participation.  Each Campaign has a set of scores associated to Campaign Member status values, and the trigger rolls these values up to the Lead.

 

Campaign #1- Webinar: Registered - 5pts, Attended - 8pts

Campaign #2- Seminar: Registered - 7pts, Attended - 10pts

 

Joe Lead - attended Webinar (+8), registered for Seminar (+7) for a total of 15 rolled up to the Lead.

 

This appears to be working in the UI, but the Unit Tests are failing because the Campaign Member: Status that I set when I create is changed to 'Sent' when it is inserted in the database.  This happens even if 'Sent' isn't one of the available labels/values for Campaign Member: Status.

 

I checked for Workflow rules that might be setting Status, but there are none.

 

Here's the Unit Test code:

 

 

Lead TestLead1 = new Lead(LastName='TestLead 1', Company='Test Company', Status='Qualified'); insert TestLead1; Campaign TestCampaign1 = new Campaign(Name='Test-Webinar Campaign I', Response_1__c='Responded', Response_1_Score__c=0, Response_2__c='Registered', Response_2_Score__c=4, Response_3__c='Attended', Response_3_Score__c=7); insert TestCampaign1; // Create CampaignMembers, associating the new Leads to their associated Campaigns CampaignMember member1 = new CampaignMember(CampaignId=TestCampaign1.Id, LeadId=TestLead1.Id, Status='Registered'); system.debug('===== InsertSingleCampaignMember:' + TestCampaign1.Name + ', member1(pre-insert)=' + member1.Status + ' ====='); insert member1;

The debug code is confirming that the initial CampaignMember status = 'Registered'

 

Once inside the After trigger, the status appears as 'Sent' (and I changed 'Sent' in the sandbox to 'Solicited'; it still says 'Sent')

 

Again, no workflow.  Here is my Trigger code: 

 

 

Set<Id> setLeadIds = new Set<Id>(); Set<Id> setMemberIds = new Set<Id>(); List<CampaignMember> lstCampaignMembers = new List<CampaignMember>(); List<Lead> lstLeads = new List<Lead>(); // Add the Lead, CampaignMember and Campaign Ids in the trigger to our sets for (CampaignMember member :trigger.new) { if (member.LeadId <> null) { setLeadIds.add(member.LeadId); setCampaignIds.add(member.CampaignId); system.debug('===== processing campaign member ' + member.Status + '...'); ...

At this point ^, when I'm capturing the details of the CampaignMembers in my After trigger, the member Status is 'Sent'.

 

Does this make sense to anybody?!?

 

For overkill' sake, this is what appears when I run my test:

 

 

Class.UnitTests_updateCampaignMembers.test_Insert_SingleLead_SingleCampaign: line 33, column 4: ===== InsertSingleCampaignMember:Test-Webinar Campaign I, member1(pre-insert)=Registered ===== ** so far, so good ** Class.UnitTests_updateCampaignMembers.test_Insert_SingleLead_SingleCampaign: line 35, column 4: Insert: SOBJECT:CampaignMember *** Beginning updateCampaignMembers on CampaignMember trigger event AfterInsert for 00vQ000000077Ry Trigger.updateCampaignMembers: line 24, column 3: SelectLoop:LIST:SOBJECT:CampaignMember 20100109142457.212:Trigger.updateCampaignMembers: line 28, column 5: ===== processing campaign member Sent... ** nope, not so good after all **

 

 

 

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
finalistfinalist

jkucera, has anyone told you that you're beautiful?

 

SortOrder is also a required field when you're creating a new CampaignMemberStatus, and I changed the syntax somewhat, but this worked:

 

 

CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId=TestCampaign1.Id, HasResponded=true, Label='Responded', SortOrder=2); CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId=TestCampaign1.Id, HasResponded=True, Label='Registered', SortOrder=3); CampaignMemberStatus cms3 = new CampaignMemberStatus(CampaignId=TestCampaign1.Id, HasResponded=True, Label='Attended', SortOrder=4);

 

insert new List<CampaignMemberStatus>{cms1, cms2, cms3};

 

 I added this between where I created my test Campaign, and where I created my test CampaignMembers.  Works like a charm!

 

Still need to update my other tests, but this looks better.

 

Thanks!   

 

Message Edited by finalist on 01-11-2010 11:12 AM

All Answers

jkucerajkucera

You need to create values in the CampaignMemberStatus table as otherwise new campaigns only have available statuses of Sent or Responded.  Status isn't a picklist like others in the app - it's driven by this table.

 

I didn't check this syntax, but would be something like:

 

 

List<CampaignMemberStatus> cms=new List<CampaignMemberStatus>(); cms.add(CampaignId=TestCampaign1.Id, HasResponded=True, Label='Webinar: Registered'); cms.add(CampaignId=TestCampaign1.Id, HasResponded=True, Label='Seminar: Registered'); insert cms;

 

btw-I'll be publishing a lead scoring app that makes things like this point & click and does the heavy lifting for you.  It uses asynch apex so it scales to at least 50 lead rules & 50 campaign member rules.  

 

Look for it in ~2 weeks on the AppExchange.

finalistfinalist

jkucera, has anyone told you that you're beautiful?

 

SortOrder is also a required field when you're creating a new CampaignMemberStatus, and I changed the syntax somewhat, but this worked:

 

 

CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId=TestCampaign1.Id, HasResponded=true, Label='Responded', SortOrder=2); CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId=TestCampaign1.Id, HasResponded=True, Label='Registered', SortOrder=3); CampaignMemberStatus cms3 = new CampaignMemberStatus(CampaignId=TestCampaign1.Id, HasResponded=True, Label='Attended', SortOrder=4);

 

insert new List<CampaignMemberStatus>{cms1, cms2, cms3};

 

 I added this between where I created my test Campaign, and where I created my test CampaignMembers.  Works like a charm!

 

Still need to update my other tests, but this looks better.

 

Thanks!   

 

Message Edited by finalist on 01-11-2010 11:12 AM
This was selected as the best answer
jkucerajkucera

Glad to hear! 

 

If you're interested in beta testing the Lead Scoring app, send me an email and I can give you the latest working copy to play with.  My last to do's are to put together better documentation & help for how to use it, and go through a final code review.

 

jkucera at salesforce . com

BCT AdminBCT Admin

I have the following problem as well with a test class that is not working for the following CampaignMemberStatus trigger :

 

the trigger works as expected in the sandbox but i can not deploy it to production because of coverage. For some reason, the following statement below (in the test class) returns 0 rows...

 

        List<CampaignMemberStatus> newStatusOne = [ select Id, Label, HasResponded, CampaignId from CampaignMemberStatus where CampaignId = :newCampaign.id AND Label = 'Assessed'];

 

Any ideas ?

 

Thank you,

 

Valentin

 

 

 

@isTest
private class TestClassAgain
{
    static testMethod void TestClassAgain()
    {

        RecordType rt1 = [select Id from RecordType where Name = 'Participant Assessment' and SobjectType = 'Campaign' limit 1];
        RecordType rt2 = [select Id from RecordType where Name = 'Program Cycle' and SobjectType = 'Campaign' limit 1];
        RecordType rt3 = [select Id from RecordType where Name = 'Participant Session' and SobjectType = 'Campaign' limit 1];
       
        // Insert a new campaign with VR Email type to test
        Campaign newCampaign = new Campaign (Name = 'New Campaign 1', Recordtypeid = rt1.id);
        insert newCampaign;
        //System.debug('testing campname and id' + newCampaign.Name+ ' ' + 'id=' + newCampaign.id);
        
        
        Campaign newCampaign2 = new Campaign (Name = 'New Campaign 2', Recordtypeid = rt2.id);
        insert newCampaign2;
        
        Campaign newCampaign3 = new Campaign (Name = 'New Campaign 3', Recordtypeid = rt3.id);
        insert newCampaign3;

        // Verify that the new Campaign Member Status 'Assessed' has been created
        List<CampaignMemberStatus> newStatusOne = [ select Id, Label, HasResponded, CampaignId from CampaignMemberStatus where CampaignId = :newCampaign.id AND Label = 'Assessed'];
       // [ select Id, Label, HasResponded, CampaignId from CampaignMemberStatus where CampaignId = :testCampaign.id AND Label = 'Unable to Reach'];
        //System.assertEquals(newStatusOne.size(),0);
        System.assertEquals('Assessed', newStatusOne[0].Label);

        // Verify that the new Campaign Member Status 'Not Assessed' has been created
        List<CampaignMemberStatus> newStatusTwo = [select id, Label from CampaignMemberStatus];
       // System.assertEquals('Not Assessed', newStatusTwo[0].Label);
    }
}



trigger SetCampaignMemberStatus on Campaign (after insert) {
//change default member statuses (Sent and Responded) for select campaigns
    Set <Id> cmpns1 = new Set <Id>();
    Set <Id> cmpns2 = new Set <Id>();
    Set <Id> cmpns3 = new Set <Id>();
    
    RecordType rt1 = [Select Id, Name from RecordType where Name = 'Participant Assessment' limit 1];  
    RecordType rt2 = [Select Id, Name from RecordType where Name = 'Participant Session' limit 1];
    RecordType rt3 = [Select Id, Name from RecordType where Name = 'Program Cycle' limit 1];
    
    for (Campaign c: trigger.new){
            if (c.RecordTypeId == rt1.Id)          { cmpns1.add(c.Id);}
            else if (c.RecordTypeId == rt2.Id)     { cmpns2.add(c.Id);}
            else if (c.RecordTypeId == rt3.Id)     { cmpns3.add(c.Id);}
    }
    
    List<CampaignMemberStatus> cms2Delete = new List<CampaignMemberStatus>();
    List<CampaignMemberStatus> cms2Insert = new List<CampaignMemberStatus>();
    
    for (CampaignMemberStatus cm: [Select Id, Label, CampaignID  FROM CampaignMemberStatus WHERE CampaignID IN :cmpns1]){
      if(cm.Label == 'Sent'){           
            CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Assessed', HasResponded=True, IsDefault = True, SortOrder=3);
            cms2Insert.add(cms1);
            cms2Delete.add(cm);
      }
     else
      if(cm.Label == 'Responded' ){
            CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Not Assessed', HasResponded=false, IsDefault = false, SortOrder=4);
            cms2Insert.add(cms2);
            cms2Delete.add(cm);
         }
    }
    for (CampaignMemberStatus cm: [Select Id, Label, CampaignID  FROM CampaignMemberStatus WHERE CampaignID IN :cmpns2]){
      if(cm.Label == 'Sent'){           
            CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Present', HasResponded=true, IsDefault = True, SortOrder=3);
            cms2Insert.add(cms1);
            cms2Delete.add(cm);
      }
     else
      if(cm.Label == 'Responded' ){
            CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Present (Late)', HasResponded=true, IsDefault = false, SortOrder=4);
            CampaignMemberStatus cms3 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Absent', HasResponded=false, IsDefault = false, SortOrder=5);
            CampaignMemberStatus cms4 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Absent (Excused)', HasResponded=false, IsDefault = false, SortOrder=6);                
            cms2Insert.add(cms2);
            cms2Insert.add(cms3);
            cms2Insert.add(cms4);
            cms2Delete.add(cm);
         }
    }
    
    
    for (CampaignMemberStatus cm: [Select Id, Label, CampaignID  FROM CampaignMemberStatus WHERE CampaignID IN :cmpns3]){
      if(cm.Label == 'Sent'){           
            CampaignMemberStatus cms1 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Enrolled', HasResponded=true, IsDefault = True, SortOrder=3);
            cms2Insert.add(cms1);
            cms2Delete.add(cm);
      }
     else
      if(cm.Label == 'Responded' ){
            CampaignMemberStatus cms2 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Dropped Out', HasResponded=false, IsDefault = false, SortOrder=4);
            CampaignMemberStatus cms3 = new CampaignMemberStatus(CampaignId=cm.CampaignID, Label='Expelled', HasResponded=false, IsDefault = false, SortOrder=5);
            cms2Insert.add(cms2);
            cms2Insert.add(cms3);
            cms2Delete.add(cm);
         }
    }
    
    //perform insert before delete because system requires at least one CMS for a Campaign
    insert cms2Insert;
    
    delete cms2Delete;
    

    
}