You need to sign in to do that
Don't have an account?
STar14
Trailhead - Apex Automation logic Challenge failing for Apex Specialist Superbadge !
Hi, I have completed the test class for the Test Automation logic challenge. Both my trigger and helper class are getting 100% covered. But the challenge is not complted due to the following error:
Challenge Not yet complete... here's what's wrong:
The 'MaintenanceRequestHelper' class did not achieve 100% code coverage via your test methods. Make sure that you chose 'Run All' tests in the Developer Console at least once before attempting to verify this challenge.
Can some one point me in the right direction to move forward with the badge completion. TIA !!!
Challenge Not yet complete... here's what's wrong:
The 'MaintenanceRequestHelper' class did not achieve 100% code coverage via your test methods. Make sure that you chose 'Run All' tests in the Developer Console at least once before attempting to verify this challenge.
Can some one point me in the right direction to move forward with the badge completion. TIA !!!
create a test class : MaintenanceRequestTest.apex
paste the following code in it ...
MaintenanceRequestTest.apex:
------------------------------------------------------------------------------------------
@isTest
private class MaintenanceRequestTest{
@testSetup
static void setup(){
//Equipment SETUP
List<Product2> lstOfEqpmnts = new List<Product2>();
Product2 eqip = new Product2(Name = 'Test Equipment',
Maintenance_Cycle__c = 10,
Cost__c = 100,
Current_Inventory__c = 10,
Lifespan_Months__c = 10,
Replacement_Part__c = true,
Warehouse_SKU__c = 'abc');
lstOfEqpmnts.add(eqip);
INSERT lstOfEqpmnts;
}
@isTest
static void testMaintenanceRequest(){
List<Case> lstOfInsertMRs = new List<Case>();
List<Case> lstOfUpdtMRs = new List<Case>();
Id equipId = [SELECT Id FROM Product2 LIMIT 1].get(0).Id;
Case newCase = new Case(Type = 'Routine Maintenance',Status = 'New', Origin = 'Phone');
newCase.Equipment__c = equipId;
lstOfInsertMRs.add(newCase);
Case mrInsert = new Case(Type = 'Routine Maintenance2', Status = 'New', Origin = 'Phone');
mrInsert.Equipment__c = equipId;
lstOfInsertMRs.add(mrInsert);
Test.startTest();
INSERT lstOfInsertMRs;
System.assertEquals(2, lstOfInsertMRs.size());
for(Case mrUpdt : lstOfInsertMRs){
mrUpdt.Status = 'Closed';
lstOfUpdtMRs.add(mrUpdt);
}
UPDATE lstOfUpdtMRs;
System.assertEquals(2, lstOfUpdtMRs.size());
Test.stopTest();
}
}
------------------------------------------------------------------------------------------------------
then in the MaintenanceRequest.trigger
paste the following code .
MaintenanceRequest.trigger :
------------------------------------------------------------------------------------------------------
trigger MaintenanceRequest on Case (before update, after update) {
// call MaintenanceRequestHelper.updateWorkOrders
Map<Id,Case> caseLst = new Map<Id,Case>();
if(Trigger.isUpdate && Trigger.isAfter){
for(Case oCase: Trigger.new){
if (oCase.IsClosed && (oCase.Type.equals('Repair') || oCase.Type.equals('Routine Maintenance'))){
caseLst.put(oCase.Id, oCase);
}
}
if(caseLst.size() > 0){
System.debug('*******Calling updateWorkOrders from MaintenanceRequestHelper Class*******');
MaintenanceRequestHelper.updateWorkOrders(caseLst);
}
}
}
------------------------------------------------------------------------------------------------------
then run the above test class ...
it works fine .challenge will be completed
thanks
in case you still face any problem because of using list in helper class and map here being used by "lakshmi prasanna 84"
you can replace:
" MaintenanceRequestHelper.updateWorkOrders(caseLst); " by :" MaintenanceRequestHelper.updateWorkOrders(Trigger.New); ".
Challenge Not yet complete... here's what's wrong:
The 'MaintenanceRequestHelper' class did not achieve 100% code coverage via your test methods. Make sure to 'Run All' tests in the Developer Console at least once before attempting to verify this challenge.
MaintenanceRequest.apxt
trigger MaintenanceRequest on Case (before update, after update) {
// call MaintenanceRequestHelper.updateWorkOrders
Map<Id,Case> caseLst = new Map<Id,Case>();
if(Trigger.isUpdate && Trigger.isAfter){
for(Case oCase: Trigger.new){
if (oCase.IsClosed && (oCase.Type.equals('Repair') || oCase.Type.equals('Routine Maintenance'))){
caseLst.put(oCase.Id, oCase);
}
}
if(caseLst.size() > 0){
System.debug('*******Calling updateWorkOrders from MaintenanceRequestHelper Class*******');
MaintenanceRequestHelper.updateWorkOrders(Trigger.New, Trigger.oldMap);
}
}
}
MaintenanceRequestHelper.cls
public class MaintenanceRequestHelper {
public static void updateWorkOrders(List<Case> updatedCases, Map<Id,Case> oldCaseMap){
// updatedCases <= Trigger.New
// oldCaseMap <= Trigger.oldMap
// we only need to create new Routine Maintenance cases if
// 1. the case has been updated to 'Closed'
// 2. the case Type is either 'Repair' or 'Routine Maintenance'
Set<Id> validCaseIds = new Set<Id>(); // holds all Case Ids that need to be touched
for (Case c: updatedCases) {
// continue only if the Case status has just been updated to 'Closed'
if (oldCaseMap.get(c.Id).Status != 'Closed' && c.Status == 'Closed') {
// continue only if the Type is 'Repair' or 'Routine Maintenance'
if (c.Type == 'Repair' || c.Type == 'Routine Maintenance') {
// add the Case to the map of valid cases that need to be touched
validCaseIds.add(c.Id);
}
}
}
// continue only if there's something to do
if (!validCaseIds.isEmpty()) {
// create a list to hold all the new Cases
List<Case> newCases = new List<Case>();
// create a map to hold all the old Case info including the associated Work Parts
// we need the map because we're going to assign the old Case Id to be the parent of the new Case
// we're going to use that ParentId to look up related Work Parts so that we can CLONE them to the new Case
// NOTE: after the challenge, I looked online at some other solutions; the three that I found all said
// to RE-PARENT the Work Parts to the new Case. Not only is there nothing in the scenario to suggest that this
// is correct, but common sense suggests that you don't want to remove data (like these related records) from the
// old, closed Cases. Seems like that would be an audit problem if anyone ever wanted to go back and see what
// was done for that old case.
// NOTE: to clone (or re-parent) the Work Parts, we need to know from which closed Case the new Routine Maintenance Case
// was created. I used the standard 'Parent' field to hold that history. All the other solutions I saw created
// a new custom field. In retrospect, the custom field might have been a better choice. The scenario is not
// very detailed. A requirements discussion with the customer should elicit how the Parent field is or might be used.
Map<Id,Case> closedCaseMap = new Map<Id,Case>([SELECT Id, Vehicle__c, Equipment__c, Equipment__r.Maintenance_Cycle__c,
(SELECT Id, Equipment__c, Quantity__c FROM Work_Parts__r)
FROM Case
WHERE Id IN :validCaseIds]);
// create a map to hold the minimum cycle time for each of the valid cases
Map<Id, Decimal> maintCycleMap = new Map<Id, Decimal>();
// use the MIN aggregate to get the minimum value of Maintenance_Cycle__c for each Case and map it to the Case ID
AggregateResult[] results = [SELECT Maintenance_Request__c, MIN(Equipment__r.Maintenance_Cycle__c)cycle
FROM Work_Part__c
WHERE Maintenance_Request__c IN :validCaseIds
GROUP BY Maintenance_Request__c];
// build the map; remember, the Case Id is for the old, closed case
for (AggregateResult ar : results) {
maintCycleMap.put((Id) ar.get('Maintenance_Request__c'), (Decimal) ar.get('cycle') );
}
for (Case cc: closedCaseMap.values()){
// create a new child Case; keep the Vehicle and Equipment fields from the parent case; the other fields are defaulted
// all the other field assignments are per requirements
Case nc = new Case (ParentId = cc.Id,
Status = 'New',
Subject = 'Routine Maintenance',
Type = 'Routine Maintenance',
Vehicle__c = cc.Vehicle__c,
Equipment__c = cc.Equipment__c,
Origin = 'Web', // NOTE: Origin is required, but the valued was not specified; I used a standard value; a better solution would have been to create a new custom value
Date_Reported__c = Date.today());
// if there are no Work Parts, there won't be a minimum value to assign to the new Case
// the req'ts don't specify what to do in this case; it seems reasonable to use the cycle from Equipment__c
if (maintCycleMap.containsKey(cc.Id) ) {
nc.Date_Due__c = Date.today().addDays((Integer) maintCycleMap.get(cc.Id));
} else {
nc.Date_Due__c = Date.today().addDays((Integer) cc.Equipment__r.Maintenance_Cycle__c);
}
newCases.add(nc);
}
// insert the new Cases
insert newCases;
// clone the Work Parts and assign them to the new Case
List<Work_Part__c> clonedWorkParts = new List<Work_Part__c>();
for (Case nc: newCases) {
// for each new Case, clone all the Work Parts from the parent case, and assign them to the new Case
for (Work_Part__c wp: closedCaseMap.get(nc.ParentId).Work_Parts__r) {
Work_Part__c wpClone = wp.clone();
wpClone.Maintenance_Request__c = nc.Id;
clonedWorkParts.add(wpClone);
}
}
// insert the cloned work parts
insert clonedWorkParts;
}
}
}
MaintenanceRequestTest.apxc
@isTest
private class MaintenanceRequestTest{
@testSetup
static void setup(){
//Equipment SETUP
List<Product2> lstOfEqpmnts = new List<Product2>();
Product2 eqip = new Product2(Name = 'Test Equipment',
Maintenance_Cycle__c = 10,
Cost__c = 100,
Current_Inventory__c = 10,
Lifespan_Months__c = 10,
Replacement_Part__c = true,
Warehouse_SKU__c = 'abc');
lstOfEqpmnts.add(eqip);
INSERT lstOfEqpmnts;
}
@isTest
static void testMaintenanceRequest(){
List<Case> lstOfInsertMRs = new List<Case>();
List<Case> lstOfUpdtMRs = new List<Case>();
Id equipId = [SELECT Id FROM Product2 LIMIT 1].get(0).Id;
Case newCase = new Case(Type = 'Routine Maintenance',Status = 'New', Origin = 'Phone');
newCase.Equipment__c = equipId;
lstOfInsertMRs.add(newCase);
Case mrInsert = new Case(Type = 'Routine Maintenance2', Status = 'New', Origin = 'Phone');
mrInsert.Equipment__c = equipId;
lstOfInsertMRs.add(mrInsert);
Test.startTest();
INSERT lstOfInsertMRs;
System.assertEquals(2, lstOfInsertMRs.size());
for(Case mrUpdt : lstOfInsertMRs){
mrUpdt.Status = 'Closed';
lstOfUpdtMRs.add(mrUpdt);
}
UPDATE lstOfUpdtMRs;
System.assertEquals(2, lstOfUpdtMRs.size());
Test.stopTest();
}
}
Pavan Raj N , i am also stuck at same point