[SalesForce] Trigger on Cases, trying to access predefined Case Teams

So I'm trying to create a simple trigger that pulls the list of Case Team Members anytime their updated and copies the list into a custom text field that can be accessed by an email template.

trigger Case_UpdateTeamMembers on Case (before insert, before update) {

    if(Trigger.size > 100) return; //Avoids SOQL query limit by skipping trigger if many cases are triggered at once. This code is only relevant to individually updated cases anyway (triggered by adding new team members)

    for(Case c :trigger.new){

        c.Team_Members__c = '';

        list<user> teamList = [SELECT Name FROM User WHERE ID IN (SELECT MemberID FROM CaseTeamMember Where ParentID = :c.ID)];

        system.debug(teamList);

        for(User u :teamList) c.Team_Members__c = c.Team_Members__c + u.Name +' \r\n';

        system.debug(c.Team_Members__c);

    }

}

I've run into an issue with my test code, because I can't get my 'teamList' variable to populate with any actual team members (even though that query works just fine on existing cases in production).

My first guess was that this has to do with it being a 'before' trigger, so the new case I create in my test code wouldn't have any team members assigned till after the trigger ran its code (I'm assuming that case assignment stuff happens after all triggers fire).

But when I modified by test code to delibarately insert a team member to the case, my trigger still didn't return any team members!

here's my test code for reference:

@isTest
private class Case_UpdateTeamMembers_Test {

    @isTest static void test_method_one() {
        Case c = new Case(Subject = 'testCase',
                          Case_Problem_Type__c = 'System Error',
                          Description = 'Test',
                          Desired_Date_of_Completion__c = Date.today());

        CaseTeamRole role = [Select ID from CaseTeamRole LIMIT 1];
        User u = [SELECT ID FROM User WHERE isActive = True LIMIT 1];



        Test.startTest();
        insert new CaseTeamMember(ParentID = c.ID, MemberID = u.ID, TeamRoleID = role.ID);
        Test.stopTest();    

        string teamMembers = [SELECT Team_Members__c FROM Case WHERE ID = :c.ID].Team_Members__c;

        system.debug(teamMembers);

        system.assert(teamMembers.length() > 0);
    }

}

Appreciate any help you all can provide!

Best Answer

You have a few different issues with your trigger and your test class.

  1. You have an order of execution issue with your unit test and trigger, essentially. When your case is first created, it will have no team members associated with it. Only when a Case is updated, will it run the Case Team Member logic that is part of your trigger. The reason is there needs to be a Case before a CaseTeamMember can be associated with it.

  2. You are using a SOQL query inside of a for loop. This is bad. You need to remove the before insert part of your trigger or switch to after insert (before insert does not have access to Ids), and instead of using Id = :c.Id, you should use Id in :Trigger.newMap.keySet(). Then move the SOQL outside of your for loop and refactor your code a bit to handle your bulk conditions better. This will allow you to remove the If(Trigger.size > 100) check as well.

  3. Your unit test creates a Case (which fires the trigger) and then inserts the CaseTeamMember record, but never updates the Case. Update your test class to update the Case record after inserting the CaseTeamMember, and you should be able to test your trigger then.

  4. Because your trigger relies on children data that is only available after the parent is updated, it might make better sense to create a batch job that populates the text field for you, or perhaps rethink your requirement a bit.

Related Topic