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
Eric BaniquedEric Baniqued 

Please help me in writing a test code for this

I'm no expert in writing apex codes and I've just got this code below to work in the sandbox environment. What this does is that it changes the case status to In Progress when an agent accepts a case from omni channel. I've tried to deploy it in production but its not letting me as I am getting an error for code coverage. I dont have any idea on how to write a test class for AgentWork as I can't find many detailed examples that I can relate my code and study to write it from scratch. 

trigger Omni_Work_Status on AgentWork (after update) {
    for ( AgentWork newAW : Trigger.new){

        AgentWork oldAW = Trigger.oldMap.get(newAW.Id);
        Boolean acceptedWork = oldAW.AcceptDatetime != newAW.AcceptDatetime;

        if ( acceptedWork ){

        String workitemId = newAW.WorkItemId;

        try{
            
            Case c = [SELECT Status FROM Case WHERE Id =: workitemId ];

            c.Status = 'In Progress';

            update c;

        } catch (exception e){

            //do nothing

            System.debug('error message: '+ e.getMessage());

            }
        }
    }
}
Devi ChandrikaDevi Chandrika (Salesforce Developers) 
Hi Eric,

Create a test class
1)Insert a case
2)Insert a  Omni_Work_Status by giving values in AcceptDatetime field and also WorkItemId field.Assign inserted case id to WorkItemId field.
3)update this Omni_Work_Status record by changing the value of AcceptDatetime.
4)Also cover exception by repating all the 3 steps and not assign any caseid to WorkItemId field ,So that exception block will be covered.

Hope this helps you
Let me know if this helps you. Kindly mark it as solved so that it may help others in future.

Thanks and Regards
Andrew GAndrew G
First, your trigger is not bulkified.  You have SELECT statement inside a for loop.  Just to bulkify, change to something like:
trigger Omni_Work_Status on AgentWork (after update) {
    Set<Id> awIds = new Set<Id>();

    for ( AgentWork newAW : Trigger.new){
        AgentWork oldAW = Trigger.oldMap.get(newAW.Id);
        if( oldAW.AcceptDatetime != newAW.AcceptDatetime){
            awIds.add(newAW.WorkItemId);
        }
    }

    List<Case> caseList = new List<Case>();
    caseList  = [SELECT Status FROM Case WHERE Id IN  :awIds ];
    for(Case c : caseList) {
        c.status = 'In Progress';
    }

    try{
        update caseList;
    } catch (exception e){
        //do nothing
         System.debug('error message: '+ e.getMessage());
    }
}
Then for Test class:

Let me get back to you.  Work calls. But Devi alludes to the basics.
Regards 
Andrew
 
ANUTEJANUTEJ (Salesforce Developers) 
Hi Eric,

I found the below trailhead link which explains you what to do in the sense you would be able to write with a test class for a trigger after having a read.

https://trailhead.salesforce.com/en/content/learn/modules/apex_testing/apex_testing_triggers

Also please have a look  at the below articles:

>> https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_qs_test.htm

>> https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_example.htm

Kindly let me know if this is useful and also please close the thread marking a best answer so that it would be useful and it would help keep the community clean.

Regards,
Anutej Poddaturi
Andrew GAndrew G
To cover the above trigger, something like:
@isTest
private class AgentWorkTriggerTest{
//by using @testSetup we can create the test data once and use it in multiple tests

	@testSetup static void setup() {
                DateTime dt = datetime.now().addmonth(-1);

		Case c = new Case(Status='New');
		//add other fields as required by validation
                insert c;
	
		AgentWork aw = new AgentWork();
                aw.AcceptDatetime = dt;
                insert aw;
	}
//do a test to see if the code does what it should
	@isTest void test_update_positive(){
		Agentwork aw = [SELECT id, AcceptDateTime FROM AgentWork LIMIT 1];
		aw.AcceptDatetime = datetime.now();
		update aw;
		Case c = [SELECT Id, Status FROM Case LIMIT 1];
		System.assertEquals('In Progress',c.Status);
	}

//should also run a negative test - does the test only run when we update the date field
	@isTest void test_update_negative(){
		Agentwork aw = [SELECT id, AcceptDateTime FROM AgentWork LIMIT 1];
		aw.someotherfield = somevaluetoudpate;
		update aw;
		Case c = [SELECT Id, Status FROM Case LIMIT 1];
		System.assertEquals('New',c.Status);
	}
}

Regards
Andrew
Eric BaniquedEric Baniqued
Hi Andrew!

Thank you for the example and for the revision of my code. I was able to understand it clearly along with the concept from Devi. They were all helpful.

I did follow your code example on the test class and made a few updates on it but I am getting a compile error message

 Compile Error: Field is not writeable: AgentWork.AcceptDateTime at line 13

What does this mean?

Thanks!

Eric
Devi ChandrikaDevi Chandrika (Salesforce Developers) 
You will get this error when you dont have edit permission on that field.
It seems like AcceptDateTime field is a standard system field where it is automatically populated during record creation or if it is a formula field you cannot edit it ,Its value will be populated based on other field value.

If it is not a standard field or a formula field,Please check field level security of the field and make you have edit access to the field.

Hope this helps you
Let me know if this helps you. Kindly mark it as solved so that it may help others in future.

Thanks and Regards
Andrew GAndrew G
Hi Eric

Yep, Devi's response regarding that compile error is correct.

If you can check out that field an determine the FLS / editability it would be great.  

Regards
Andrew
 
Andrew GAndrew G
Just did some checking on AgentWork object.  Seems it's related to Omni-Channel

https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_agentwork.htm

Usage
AgentWork records can only be deleted if they have the status Closed, Declined, or Unavailable. They can’t be deleted if their status is Assigned or Opened because they’re active in Omni-Channel.
AgentWork records have the status Assigned when they’re created. Once created, the record is automatically pushed to the assigned agent.
While the metadata for AgentWork indicates support for upsert() and update(), these calls aren’t used with AgentWork because none of its fields can be updated.
Apex triggers are supported with AgentWork.

So this issue may need some further thought.

Regards
Andrew
Eric BaniquedEric Baniqued
Some questions:

1.) What would be the syntax for creating AgentWork? seems that new AgentWork(); is not the correct way to create an AgentWork
2.) Would system.assertEquals also work in place of AcceptDateTime? value of dt for the positive test and null for the negative test?

This is basically my first apex code that worked in the sandbox and its saddening that I can't deploy it in the production environment due to code coverage.

Thanks!

Eric

 
Eric BaniquedEric Baniqued
so I was able to compile it with the current code
 
@isTest
private class AgentWorkTriggerTest{
//by using @testSetup we can create the test data once and use it in multiple tests

    @testSetup static void setup() {
                //DateTime dt = datetime.now();

        Case c = new Case(Status='New');
        //add other fields as required by validation
                insert c;
    
        AgentWork aw = new AgentWork();
                //aw.AcceptDatetime = null;
                insert aw;
    }
//do a test to see if the code does what it should
    @isTest static void test_update_positive(){
        Agentwork aw = [SELECT id, AcceptDateTime FROM AgentWork LIMIT 1];
        DateTime dt = datetime.now();
        //aw.AcceptDatetime = datetime.now();
        update aw;
        Case c = [SELECT Id, Status FROM Case LIMIT 1];
        System.assertEquals('In Progress',c.Status);
        System.assertEquals(dt,aw.AcceptDateTime);
        
    }

//should also run a negative test - does the test only run when we update the date field
    @isTest static void test_update_negative(){
        Agentwork aw = [SELECT id, AcceptDateTime FROM AgentWork LIMIT 1];
        DateTime dt = datetime.now();
        //aw.someotherfield = somevaluetoudpate;
        update aw;
        Case c = [SELECT Id, Status FROM Case LIMIT 1];
        System.assertEquals('New',c.Status);
        System.assertEquals(null,aw.AcceptDateTime);
    }
}

I ran the test and it failed with an error message below:

ClassAgent: WorkTriggerTest
Method Name: test_update_positive
Pass/Fail: Fail
Error Message: System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, The agent's status is not associated with the channel for this work.: [ServiceChannelId]
Stack Trace: Class.AgentWorkTriggerTest.setup: line 14, column 1

looks like I need to specify the ServiceChannelId for this error

 
Andrew GAndrew G
Hi Eric

I think to save you some angst, the way around this is to perhaps try a Process Builder.
If I read the intent of your code, it is that once a piece of work has been accepted, update the related Case status to "In Progress"

First caveat, i don't have a lot of experience with Omni Channel - well, none, only what I have quickly read this last hour or so.  And I don't have an environment with OmniChannel enabled.

So, create a Process Builder if you can on the Agent Work object.
Criteria would be that 1. Is Not Null for AcceptDateTime and 2. WorkItem starts with 005 (prefix for Case object). And set the advanced setting for "Do you want to execute the actions only when specified changes are made to the record?"

IA would be to update the related Case Status to "In progress"

note, this answer does hinge on being able to do a process builder on the Agent Work Object
This will alleviate the need for a test class in Apex.


Regards
Andrew
Youssef HamrouniYoussef Hamrouni
HI eric,

I'm working on the same topic and i'm facing the same error on the test class. Did you find any solution? 

thanks
youssef