+ Start a Discussion
Tom DawsonTom Dawson 

Trigger test class to stop chatter group members leaving the group

Hi All

I have wirrten a small Apex trigger to stop chatter group members from leaving a group, based on the permissions of the gorup which are set in a record in the custom object Chatter_Groups__c. Whenever a new chatter group is created, a record is automatically created in this custom object with the necessary fields. 

My trigger is working as intended:
trigger disableChatterDelete on CollaborationGroupMember (before delete) {
    
    List<Chatter__c> chatterGroups = [SELECT Id,
                                      Name, 
                                      Chatter_Group_Id__c,
                                      Allowed_to_leave__c
                                      FROM Chatter__c];
    
    Id userProfileId = userinfo.getProfileId();
    String userProfileName = [SELECT ID, Name from Profile Where Id = : userProfileId].Name;
    
    for(CollaborationGroupMember collab : Trigger.Old){
        
        integer index;
        for(integer i = 0; i < chatterGroups.size();i++){
            if(collab.CollaborationGroupId == chatterGroups[i].Chatter_Group_Id__c) index = i;
        }
        
        if(chatterGroups[index].Allowed_to_leave__c == false){
            
            if(chatterGroups[index].Chatter_Group_Id__c == collab.CollaborationGroupId){
                
                if(userProfileName != 'System Administrator'){
                    
                    if(Trigger.isBefore){
                        
                        if(Trigger.isDelete){
                            
                            collab.adderror('This Group is mandatory for all staff');
                        }
                    }
                }
            }
        }
    }
}
This is my test class:
@isTest
public class disableChatterDeleteTest {
    
    static testMethod void testDisableChatterDeleter(){
        
        // Create a unique UserName
        String uniqueUserName = 'salesuser' + DateTime.now().getTime() + '@testorg.com';
        // This code runs as the system user
        Profile p = [SELECT Id FROM Profile WHERE Name='SADC Employee'];
        
        Test.startTest(); 
        User usr = new User(Alias = 'suser', Email='user@testorg.com',
                            EmailEncodingKey='UTF-8', LastName='SalesTesting', LanguageLocaleKey='en_US',
                            LocaleSidKey='en_US', ProfileId = p.Id,
                            TimeZoneSidKey='America/New_York',
                            UserName=uniqueUserName);
        
        // Create new Chatter Group
        CollaborationGroup grp = new CollaborationGroup();
        grp.Name = 'Test Group';
        grp.CollaborationType = 'Public';
        insert grp;
        
        //Create new Chatter Group record
        Chatter__c grpRec = new Chatter__c();
        grpRec.Name = 'Test Group Record';
        grpRec.Chatter_Group_Id__c = grp.Id;
        grpRec.Allowed_to_leave__c = false;
        
        // Create new group member
        CollaborationGroupMember grpMem = new CollaborationGroupMember();
        grpMem.MemberId = usr.Id;
        grpMem.CollaborationGroupId = grp.Id;
        
        System.runAs(usr){
            
            try{
                delete grpMem;
            }catch(Exception ex){
                system.debug('Exception');
            }
            Test.stopTest(); 
            
            List<CollaborationGroup> groupList = [SELECT Id, MemberCount
                                                  FROM CollaborationGroup 
                                                 Where Id = : grp.Id];
            System.assertEquals(groupList[0].MemberCount, 1 );
        }
    }
}

Running this test class does not result in an error, but i have 0 code coverage. If anyone could tell me where i am going wrong it would be much appreciated!

Thanks

Tom 
 
Best Answer chosen by Tom Dawson
Andrew GAndrew G
Hi Tom

I may be wrong but i think the issue is that you don't insert the test data before trying to invoke the delete method.  In your example, you would be trying to delete a record that is held in memory, not in the database.  And I suspect you get no error as the exception does a write to the debug log, not throw something, or cause the test to fail.  Try something like:
@IsTest
public class disableChatterDeleteTest {
    
    static testMethod void testDisableChatterDeleter(){
        
        // Create a unique UserName
        String uniqueUserName = 'salesuser' + DateTime.now().getTime() + '@testorg.com';
        // This code runs as the system user
        Profile p = [SELECT Id FROM Profile WHERE Name='SADC Employee'];
        
        User usr = new User(Alias = 'suser', Email='user@testorg.com',
                            EmailEncodingKey='UTF-8', LastName='SalesTesting', LanguageLocaleKey='en_US',
                            LocaleSidKey='en_US', ProfileId = p.Id,
                            TimeZoneSidKey='America/New_York',
                            UserName=uniqueUserName);
        
        // Create new Chatter Group
        CollaborationGroup grp = new CollaborationGroup();
        grp.Name = 'Test Group';
        grp.CollaborationType = 'Public';
        insert grp;
        
        //Create new Chatter Group record
        Chatter__c grpRec = new Chatter__c();
        grpRec.Name = 'Test Group Record';
        grpRec.Chatter_Group_Id__c = grp.Id;
        grpRec.Allowed_to_leave__c = false;
	insert grpRec;
        
        // Create new group member
        CollaborationGroupMember grpMem = new CollaborationGroupMember();
        grpMem.MemberId = usr.Id;
        grpMem.CollaborationGroupId = grp.Id;
	insert grpMem;
        
        System.runAs(usr){
            Test.startTest(); 

            try{
                delete grpMem;
            }catch(Exception ex){
                system.assert(false);  // throw a bad assert to stop to check if the test fails
            }
            Test.stopTest(); 
            
            List<CollaborationGroup> groupList = [SELECT Id, MemberCount
                                                  FROM CollaborationGroup 
                                                 Where Id = : grp.Id];
            System.assertEquals(groupList[0].MemberCount, 1 );
        }
    }
}

Regards
Andrew​​​​​​​

All Answers

Andrew GAndrew G
Hi Tom

I may be wrong but i think the issue is that you don't insert the test data before trying to invoke the delete method.  In your example, you would be trying to delete a record that is held in memory, not in the database.  And I suspect you get no error as the exception does a write to the debug log, not throw something, or cause the test to fail.  Try something like:
@IsTest
public class disableChatterDeleteTest {
    
    static testMethod void testDisableChatterDeleter(){
        
        // Create a unique UserName
        String uniqueUserName = 'salesuser' + DateTime.now().getTime() + '@testorg.com';
        // This code runs as the system user
        Profile p = [SELECT Id FROM Profile WHERE Name='SADC Employee'];
        
        User usr = new User(Alias = 'suser', Email='user@testorg.com',
                            EmailEncodingKey='UTF-8', LastName='SalesTesting', LanguageLocaleKey='en_US',
                            LocaleSidKey='en_US', ProfileId = p.Id,
                            TimeZoneSidKey='America/New_York',
                            UserName=uniqueUserName);
        
        // Create new Chatter Group
        CollaborationGroup grp = new CollaborationGroup();
        grp.Name = 'Test Group';
        grp.CollaborationType = 'Public';
        insert grp;
        
        //Create new Chatter Group record
        Chatter__c grpRec = new Chatter__c();
        grpRec.Name = 'Test Group Record';
        grpRec.Chatter_Group_Id__c = grp.Id;
        grpRec.Allowed_to_leave__c = false;
	insert grpRec;
        
        // Create new group member
        CollaborationGroupMember grpMem = new CollaborationGroupMember();
        grpMem.MemberId = usr.Id;
        grpMem.CollaborationGroupId = grp.Id;
	insert grpMem;
        
        System.runAs(usr){
            Test.startTest(); 

            try{
                delete grpMem;
            }catch(Exception ex){
                system.assert(false);  // throw a bad assert to stop to check if the test fails
            }
            Test.stopTest(); 
            
            List<CollaborationGroup> groupList = [SELECT Id, MemberCount
                                                  FROM CollaborationGroup 
                                                 Where Id = : grp.Id];
            System.assertEquals(groupList[0].MemberCount, 1 );
        }
    }
}

Regards
Andrew​​​​​​​
This was selected as the best answer
Tom DawsonTom Dawson
Hi Andrew

Thanks for the reply! Yes you are right - I figured it out late last night and felt pretty stupid for a while haha. I also had to do 'insert usr' as it wasnt picking that up either. That seems to be working.

Something else that i picked up is that 'System.assertEquals(groupList[0].MemberCount, 1 );' is actually evaluating to 2, instead of 1. Do you think that is because in making the group, it would already have an owner and then I am adding a group member to it?

Thanks for your help.

Tom 
 
Andrew GAndrew G
Hi Tom

If i understand the behaviours correctly, when a collaboration group is created, it is required to have an owner who is also a member of the group.  

If you want to double check, or highlight, this behaviour, in your test class put a SELECT statement and Assert after you create the group with a comment //one member who is owner. 

Then in your final assert say //2 members as not deleted.

Also you could assert the addError response
 
}catch(Exception ex){

    System.assert(ex.getMessage().contains('This Group is mandatory for all staff'));

}

And for full coverage, run a second test method using runAs(System Admin), which should allow the delete.

Regards
Andrew
Tom DawsonTom Dawson
That makes sense. Thanks for your help, Andrew. Working great. 

Tom