function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Jessica RiffeJessica Riffe 

During Test, created user isActive is false when inserting object

I have created a class that runs on the before insert of a custom object.  The purpose is that, if the newly inserted recrod is one of the Integration Users, change the owner to the Agent custom field on the record.
 
public static void UpdateIntegrationOwnerToAgent(List<Productivity_Data__c> data)
    {
        Id profileId = userinfo.getProfileId();
        String ProfileName = [SELECT Name FROM Profile WHERE Id =: profileId LIMIT 1].Name;
        for(Productivity_Data__c d : data)
        {
            system.debug('### ' + d.OwnerId);
            if(ProfileName == 'Integration User')
            {
                system.debug('### Agent: ' + d.Agent__c);
                system.debug('### isActive: ' + d.Agent__r.IsActive);
                if(d.Agent__c != null && d.Agent__r.isActive)
                {
                    d.OwnerId = d.Agent__c;
                } 
            }
        }
    }

As I'm writing my test code, my assertion is failing because the user that I created for the agent field has isActive set to false.  It is my understanding that when you create a user in test methods, they are active.  And this is generally the case, however, my check on the agent__r.IsActive is returning false, therefore not hitting my code that changes the user.
 
public static User getAgent(Boolean xCommit)
    {
        Profile prof = [SELECT Id FROM Profile WHERE Name='AWD Sales'];
        
        User agent = new User();
        agent.Alias = 'standt';
        agent.Email = 'standarduser@testorg.com'; 
        agent.EmailEncodingKey = 'UTF-8';
        agent.LanguageLocaleKey = 'en_US'; 
        agent.LocaleSidKey='en_US';
        agent.TimeZoneSidKey='America/Los_Angeles';
        agent.UserName = 'TestProductivityData@Test.com';
		agent.FirstName = 'Test Agent';
		agent.LastName = 'Integration Test';
		agent.Agent_ID__c = '1234';
        agent.ProfileId = prof.Id;
        
        if(xCommit)
			insert agent;
        return agent;
    }
    
    public static testMethod void Test01TestIntegrationUserChangeToAgent()
    { 
        Profile prof = [SELECT Id FROM Profile WHERE Name = 'Integration User'];
        User intUser = [SELECT Id FROM User WHERE ProfileId =: prof.Id LIMIT 1];
        
        User a = getAgent(true);
        
        List<Productivity_Data__c> pData = generateTestData(5, false);
        
        for(Productivity_Data__c p : pData)
        {
            p.Agent__c = a.Id;
            //p.AgentId__c = a.Agent_ID__c;
            p.OwnerId = intUser.Id;
        }
        Test.startTest();
        system.runAs(intUser)
        {
        	insert pData;
        }
        Test.stopTest();
        
        List<Id> pDataIds = New List<Id>();
        for(Integer i = 0; i < pData.size(); i++)
        {
            pDataIds.add(pData[i].Id);
        }
        
        pData = [SELECT Id, OwnerId, Agent__c FROM Productivity_Data__c WHERE Id IN: pDataIds];
        
        system.assertEquals(a.Id, pData[0].OwnerId);
    }

Yes, I can get around this with adding an if statment to not check isActive when running the tests.  But I would prefer to not do that and have it be tested correctly.  This is coming from a trigger before insert method that takes in the trigger.new list.  Which means, I'm not querying this data, it is coming straight from the trigger, and I would assume.. the relationships should be available in the trigger information.

Thanks
Jessica RiffeJessica Riffe
Turns out, upon more testing and searching for the possibility of using a try catch for the inactive users.. I determined that you can't do a try catch in the trigger data as you aren't actually performing the DML.  And.. in my actual testing of the scenario, it didn't work because *surprise* it still didn't pick up that the user is active.  

So I changed my class code to this:
 
public static void UpdateIntegrationOwnerToAgent(List<Productivity_Data__c> data)
    {
        Map<Id, Boolean> userToActiveStatus = new Map<Id, Boolean>();
        List<Id> userIds = new List<Id>();
        Id profileId = userinfo.getProfileId();
        String ProfileName = [SELECT Name FROM Profile WHERE Id =: profileId LIMIT 1].Name;
        for(Productivity_Data__c d : data)
        {
            if(d.Agent__c != null)
            	userIds.add(d.Agent__c);
        }
        
        List<User> users = new List<User>([SELECT Id, isActive FROM User where Id IN: userIds]);
        
        for(User u : users)
        {
            userToActiveStatus.put(u.Id, u.isActive);
        }
        
        for(Productivity_Data__c d : data)
        {
            system.debug('### ' + d.OwnerId);
            if(ProfileName == 'Integration User')
            {
                system.debug('### UserToActiveStatus ' + string.valueOf(userToActiveStatus.get(d.Agent__c)));
                if(d.Agent__c != null && userToActiveStatus.get(d.Agent__c))
                {
                    d.OwnerId = d.Agent__c;
                } 
            }
        }
    }

Unfortunately, I have to do 2 loops through the trigger new data, and use another query on the user object.  Now, my data is accurate though.