0

In short: my Test Setup Method Creates Accounts/Contacts/Leads/Campaign/etc I connect all of this data in my Test Setup method. I update the data in my Test Method.

I query the Contacts and Leads, both queries have Owner.IsActive field included. but I cannot see the Owner Data on the Leads. and based on the OwnerId returned in both queries they are owned by the same user so the lead owner is active (i created it, and run the test, and no other running user). All Profiles have all access to the Owner field on Lead

Senior SF Developer please tell me I am not going crazy and that this is a bug or something???

Here are the basics of my Trigger that is not returning the result I expect:

trigger CampaignMemberBeforeAfterInsertUpdate on CampaignMember (before insert, before update, after insert, after update) {
    Set<Id> contactId_Set = new Set<Id>();
    Set<Id> leadId_Set = new Set<Id>();
    if(Trigger.isBefore){
        if(generalTriggerHandler.runCampaignMemberOnce()){
            System.debug('CampaignMemberBeforeAfterInsertUpdate before runOnce');
            for(CampaignMember cm : Trigger.new) {
                if(String.isNotBlank(cm.ContactId)){
                    contactId_Set.add(cm.ContactId);
                }else if(String.isNotBlank(cm.LeadId)){
                    leadId_Set.add(cm.LeadId);
                }
            }

            Map<Id, Contact> idContact_Map  = new Map<Id,Contact>([SELECT Id, FirstName, OwnerId, Owner.IsActive, Account.Name
                FROM Contact WHERE Id IN :contactId_Set]);
            Map<Id, Lead> idLead_Map        = new Map<Id,Lead>([SELECT Id, FirstName, OwnerId, Owner.IsActive
                FROM Lead WHERE Id IN :leadId_Set]);
            for(Lead l : idLead_Map.Values()){
                system.debug('Lead.Owner.IsActive : ...'+l.Owner.IsActive);
                system.debug('Lead.Owner : ...'+l.OwnerId);
            }
            for(Contact c : idContact_Map.Values()){ 
                system.debug('Contact.Owner.IsActive : ...'+c.Owner.IsActive);
                system.debug('Contact.Owner : ...'+c.OwnerId);
            }
            system.debug('idLead_Map : ...'+idLead_Map);

            for(CampaignMember cm : Trigger.new){
                if(idContact_Map.containsKey(cm.ContactId) && idContact_Map.get(cm.ContactId).Owner.IsActive){
                    system.debug(idContact_Map.get(cm.ContactId));
                }else if(idLead_Map.containsKey(cm.LeadId) && idLead_Map.get(cm.LeadId).Owner.IsActive){
                    system.debug(idLead_Map.get(cm.LeadId));
                    //DOES NOT LAND HERE WHEN TESTING, NOT SURE ABOUT LIVE RUN
                }
            }
        }
    }
}

Test Class Code:

@testSetup
static void setupTestData(){

    Campaign cp = new Campaign(Name='Campaign',Status='Planned',
        StartDate=System.today(),EndDate=System.today());
    Insert cp;

    List<Account> accountList = new List<Account>();
    for(Integer i = 0; i <5; i++){
        Account acc = new Account();
        acc.Name = 'company' + i;
        accountList.add(acc);
    }
    Insert accountList;

    List<Contact> contactList = new List<Contact>();
    for(Integer i = 0; i <5; i++){
        Contact con = new Contact();
        con.FirstName = 'firstName' + i;
        con.LastName = 'lastName' + i;
        con.AccountId = accountList[i].id;
        contactList.add(con);
    }
    Insert contactList;

    List<Lead> leadList = new List<Lead>();
    for(Integer i = 0; i <5; i++){
        Lead lead = new Lead();
        lead.FirstName = 'firstName' + i;
        lead.LastName = 'lastName' + i;
        lead.Company = 'leadCompany' + i;
        leadList.add(lead);
    }
    Insert leadList;

    List<CampaignMember> cms = new List<CampaignMember>();
    for(Integer i = 0; i < 3; i++){
        Contact con = contactList[i];
        System.debug(con);
        cms.add(new CampaignMember(ContactId = con.Id, CampaignId = cp.id, Status='Added'));
    }
    for(Integer i = 0; i < 3; i++){
        Lead lead = leadList[i];
        System.debug(lead);
        cms.add(new CampaignMember(LeadId = lead.Id, CampaignId = cp.id, Status='Added'));
    }
    Insert cms;
}
static testMethod void test_UpdateCampM(){
    Test.startTest();
    List<Contact> contactList = [SELECT id FROM Contact];
    List<Lead> leadList=[SELECT id FROM Lead];
    List<CampaignMember> updatedCMs = [SELECT Id, ContactId, LeadId
        FROM CampaignMember
        WHERE ContactId in: contactList OR LeadId in: leadList];
    for(CampaignMember cm : updatedCMs){
        cm.status = 'Sent';
    }
    update updatedCMs;
    ...
}

Here is the system debug Output:

enter image description here

Here are the outputs of the system debug of the 2 Trigger Queries above teh system debug for loops:

01:37:39:736 VARIABLE_ASSIGNMENT [23]|idContact_Map|{"003...6r1IAD":{"Id":"003...6r1IAD","FirstName":"firstName0","OwnerId":"005...oZlQAL","AccountId":"001...CIzIAM","Owner":{"Id":"005...oZlQAL","IsActive":true},"Account":{"Id":"001...CIzIAM","Name":"company0"}},"003...6r2IAD":{"Id":"003...

NB: the Owner and Account objects are returned in the Contact query but the Lead query has no Owner object only the Id

01:37:39:748 VARIABLE_ASSIGNMENT [27]|idLead_Map|{"00Q...5UvMAJ":{"Id":"00Q...5UvMAJ","FirstName":"firstName0","OwnerId":"005...oZlQAL"},"00Q...5UwMAJ":{"Id":"00Q...5UwMAJ","FirstName":"firstName1","OwnerId":"005...oZlQAL"},"00Q...5UxMAJ":{"Id":"00Q...5UxMAJ","FirstName":"firstName2","OwnerId":...

Search Words: Cannot query User fields through the lead owner field Can only get the OwnerId field when querying lead

4
  • 1
    You are still putting your trigger logic in your trigger body?
    – Adrian Larson
    Commented Jan 3, 2022 at 14:28
  • @Adrian, Not sure how to answer that. Just wondering what tone you are using with that question. Do know it comes across as combative, and not sure how it would help answer the question. For this question, ... yes I have? Commented Jan 3, 2022 at 22:06
  • It's just normally the first thing I would suggest to fix.
    – Adrian Larson
    Commented Jan 4, 2022 at 3:29
  • but that is not a fix, that is an adjustment to the code towards best practice for easily manageable code. not towards answering the question being asked. hmmmm.... I found it easier to write/read my question with linear code. Also very weird how my comments were removed that aided the question, and how this question got down voted, when it is a perfectly acceptable question, with a lot of detail. Commented Jan 6, 2022 at 0:32

2 Answers 2

1

You could adapt this to work with a list/map and a for loop, but this is the way to query polymorphic relationships and use the results. This way will ensure your code sees the Owner.IsActive field even when called from a TestMethod.

Contact c = [SELECT Id, FirstName, OwnerId, Account.Name,
                    TYPEOF Owner
                      WHEN User
                           THEN IsActive, FirstName
                      WHEN Group
                           THEN Name
                    END
             FROM Contact
             WHERE Id = :contactId];

Boolean isActive;
if (c.Owner instanceof User) {
    User u = c.Owner;
    isActive = u.IsActive;
}
0

So I believe it is because of the polymorphic Field.

I have added an additional query of the users.Isactive from lead.ownerId's:

        Map<Id, Contact> idContact_Map  = new Map<Id,Contact>([SELECT Id, FirstName, OwnerId, Owner.IsActive, Account.Name
            FROM Contact WHERE Id IN :contactId_Set]);
        Map<Id, Lead> idLead_Map        = new Map<Id,Lead>([SELECT Id, FirstName, OwnerId, Owner.IsActive
            FROM Lead WHERE Id IN :leadId_Set]);
        for(Lead l : idLead_Map.Values()){
            userId_Set.add(l.OwnerId);
        }
        Map<Id, User> idUser_Map    = new Map<Id,User>([SELECT Id, IsActive
            FROM User WHERE Id IN :userId_Set]);

        for(CampaignMember cm : Trigger.new){
            if(idContact_Map.containsKey(cm.ContactId) && idContact_Map.get(cm.ContactId).Owner.IsActive){
                system.debug(idContact_Map.get(cm.ContactId));
            }else if(idLead_Map.containsKey(cm.LeadId) && idUser_Map.get(idLead_Map.get(cm.LeadId).OwnerId).IsActive){
                //DOES LAND HERE Due the id in the new user map
            }
        }

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .