Conquering Apex Specialist

November 5, 2019

(11/05/2019 -11/10/19)

Very Exhaustive & tiring challenge. A lot of concepts to digest, definitely could not make it without trailhead and other google resources.

It took me 5 days with an average of 1+ Hour daily.

I still feel I am far away from where I would want to be with coding. I would love to be in a state where I don’t refer to trailhead or google resources. I guess practice is the only way forward…

1. Automate Record Creation (11/05/2019 5 am to 6 am)

What I Learned

https://trailhead.salesforce.com/en/content/learn/modules/apex_triggers

trigger MaintenanceRequest on Case (before update, after update) {
    // call MaintenanceRequestHelper.updateWorkOrders  
    if (trigger.isAfter){
        //if(trigger.isUpdate){
            MaintenanceRequestHelper.updateWorkOrders(Trigger.new,Trigger.OldMap);
            
        }
    }
public class MaintenanceRequestHelper {
    
    public static void updateWorkOrders(List<Case> ClosedCases,map<id,Case> ClosedCasesOldMap){
        // update workorders
        for (Case c : ClosedCases){
        
        Case oldCase = ClosedCasesOldMap.get(c.id);
        
        //https://www.sfdc99.com/2014/02/25/comparing-old-and-new-values-in-a-trigger/
        
        Boolean oldCaseisClosed = oldCase.Status.equals('Closed');
        System.debug('OldCaseisClosed=' + oldCaseisClosed);
        Boolean NewCaseisClosed = C.Status.equals('Closed');
        System.debug('NewCaseisClosed=' + NewCaseisClosed);
        List<AggregateResult> minMaintananceCyleDays = [SELECT MIN(Maintanance_cycle__c) from Work_Part__C where Maintenance_Request__c =: oldCase.id];
        Integer intminMaintananceCyleDays = Integer.valueOf(minMaintananceCyleDays[0].get('expr0'));
        System.debug('intminMaintananceCyleDays = ' + intminMaintananceCyleDays);
        List <Case> CasetobeCreated = new List<case>();
        
        
        
        if(!oldCaseisClosed && NewCaseisClosed ){
        
        if(c.IsClosed == true && (c.Type == 'Repair' || c.Type == 'Routine Maintenance')){
            
            case nc = new case();
            nc.Type = 'Routine Maintenance';
            nc.Vehicle__c = c.Vehicle__c;
            if (c.Equipment__c != null){
            nc.Equipment__c = c.Equipment__c;
            }
            if (c.Subject != null){
            nc.Subject = c.Subject;
        }
            nc.Date_Reported__c = system.today();
            if (intminMaintananceCyleDays != null){
            nc.Date_Due__c = system.today()+ intminMaintananceCyleDays;
            } else 
            nc.Date_Due__c = system.today();
            System.debug('NC: '+ nc);
            nc.Status = 'New';
            CasetobeCreated.add(nc);
            
        }
            insert CasetobeCreated;
        
        }
    }

}
    }        
    

2. Synchronize Salesforce data with an external system

What I Learned

https://trailhead.salesforce.com/en/content/learn/modules/apex_integration_services/apex_integration_rest_callouts

https://trailhead.salesforce.com/en/content/learn/modules/asynchronous_apex/async_apex_future_methods

public with sharing class WarehouseCalloutService {

    private static final String WAREHOUSE_URL = 'https://th-superbadge-apex.herokuapp.com/equipment';
    
    
    // complete this method to make the callout (using @future) to the
    // REST endpoint and update equipment on hand.
    @Future(callout=true)
    public static void runWarehouseEquipmentSync(){
        List<Product2> syncprod = new List<Product2>();
        
        Http http = new Http();
        HttpRequest request  = new HttpRequest();
        request.setEndpoint(WAREHOUSE_URL);
        request.setMethod('GET');
        HttpResponse response = http.send(request);
        
        if(response.getStatusCode()==200){
            
        
            List<equipmentjson> results = (List<equipmentjson>) JSON.deserialize(response.getBody(), List<equipmentjson>.class);
            
            for(equipmentjson inst : results){
                product2 equip = new product2();
                equip.Cost__c = inst.cost;
                equip.Lifespan_Months__c = inst.lifespan;
                equip.Maintenance_Cycle__c = inst.maintenanceperiod;
                equip.Name = inst.name;
                equip.Current_Inventory__c = inst.quantity;
                equip.Replacement_Part__c = inst.replacement;
                equip.Warehouse_SKU__c = inst.sku;
                
                syncprod.add(equip);
            }
            
            }
        if(syncprod != null && syncprod.size() > 0){
            UPSERT syncprod Warehouse_SKU__c;
        }
            
    }
           
    private class equipmentjson{
        private String id;
        private Integer cost;
        private Integer lifespan;
        private Integer maintenanceperiod;
        private String name;
        private Integer quantity; 
        private boolean replacement;
        private String sku;          
    }

            
        }
        
        
        
        
    

global class WarehouseSyncSchedule implements schedulable {
  // implement scheduled code here
  global void execute(SchedulableContext sc){

      WarehouseCalloutService.runWarehouseEquipmentSync();
      
  }
}

4.  Test automation logic 

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

@isTest
public class TestDataFactory {
    public static List<case> createmr(String mrtype, integer noofcases){
        List<case> mr = new List <case>();
        if(noofcases > 0 && mrtype.length() >0 ){
            
            //create vehicle
            
            Vehicle__c v = new Vehicle__c(Name='Jetta 01', VIN_Number__c='Jetta123');
            insert v;
            
            //create Equipments: two with different maintenance cycles  
            
            List<Product2> equip = new List<Product2>();  
       		equip.add(new Product2(Name='Testequip 01', Warehouse_SKU__c='001', Lifespan_Months__c=12, Maintenance_Cycle__c=60, Replacement_Part__c=true));  
       		equip.add(new Product2(Name='Testequip 02', Warehouse_SKU__c='002', Lifespan_Months__c=24, Maintenance_Cycle__c=30, Replacement_Part__c=true));  
       	    insert equip; 
            
            //create maintenance requests  
         	for (integer i = 0; i<noofcases; i++) {  
         			mr.add(new Case(Type = mrtype, Status='New', Origin='Phone', Equipment__c=equip[0].id, Subject='Test Case'));  
                          }
            insert mr;
        	//Add two work parts for each maintenance request created  
       
            List<Work_Part__c> wp = new List<Work_Part__c>();  
       
           for (Case c: mr) {  
             
             wp.add(new Work_Part__c(Equipment__c=equip[0].id, Maintenance_Request__c=c.id, Quantity__c=1));  
             wp.add(new Work_Part__c(Equipment__c=equip[1].id, Maintenance_Request__c=c.id, Quantity__c=2));  
                             
           }  
       insert wp;  
        }
        
        
        return mr;
        
        
        
    }

}
@IsTest  
 public class MaintenanceRequestTest {  
   @IsTest  
   static void TestPositiveSingle() {  
     //Test Repair maintance request  
     testmrcreation('Repair', 1, 'Closed');  
     //Test Routine Maintenance request  
     testmrcreation('Routine Maintenance', 1, 'Closed');  
   }  
   @IsTest  
   static void TestNegativeSingle() {  
     //Test Other maintance request  
     testmrcreation('Other', 1, 'Closed');  
     //Test Repair maintance request  
     testmrcreation('Repair', 1, 'Working');  
     //Test Routin Maintenance request  
     testmrcreation('Routine Maintenance', 1, 'Escalated');  
   }  
   @IsTest  
   static void TestPositiveBulk() {  
     //Test Repair maintance request  
     testmrcreation('Routine Maintenance', 300, 'Closed');  
     //Test Repair maintance request  
     testmrcreation('Repair', 300, 'Closed');  
   }  
   @IsTest  
   static void TestNegativeBulk() {  
     //Test Other maintance request  
     testmrcreation('Other', 300, 'Closed');  
     //Test Repair maintance request  
     testmrcreation('Repair', 300, 'Working');  
     //Test Routin Maintenance request  
     testmrcreation('Routine Maintenance', 300, 'Escalated');  
   }  
   private static void testmrcreation(string requestType, integer totalCount, string newStatus) {  
     //Test Repair maintance request  
     List<Case> testRequests = TestDataFactory.createmr(requestType, totalCount);  
     for (Case tr: testRequests) {  
       tr.Status = newStatus;  
     }  
     update testRequests;  
     List<Case> newmrs = [SELECT id, Type, Status, Vehicle__c, Equipment__c, Subject, Origin, Date_Reported__c, Date_Due__c  
                      FROM Case WHERE ParentId IN: testRequests   
                      AND Status = 'New'];  
     integer expectedTotal = 0;  
     if(newStatus == 'Closed' && (requestType =='Repair' || requestType == 'Routine Maintenance')) {  
       expectedTotal = totalCount;  
     }  
     // System.assertEquals(expectedTotal,newFollowupRequests.size());  
     if (expectedTotal>0) {  
       for (Case newmr: newmrs) {  
         System.assertEquals('Routine Maintenance', newmr.Type);  
         System.assertEquals('System Generated Routine Maintenance', newmr.Subject);  
         System.assertEquals('System', newmr.Origin);  
         System.assertEquals(Date.today(), newmr.Date_Reported__c);  
         System.assertEquals(Date.today().addDays(30), newmr.Date_Due__c);  
       }  
     }  
   }  
 }  

5. Test Call out Logic

https://trailhead.salesforce.com/en/content/learn/modules/apex_integration_services/apex_integration_rest_callouts

global class WarehouseCalloutServiceMock implements HttpCalloutMock {
    // implement http mock callout
    //Mock responce created  to test the call out
    global HttpResponse respond(HttpRequest request){
        System.assertEquals('https://th-superbadge-apex.herokuapp.com/equipment', request.getEndpoint());
        System.assertEquals('GET', request.getMethod());
        HttpResponse response = new HttpResponse();
        response.setHeader('Content-Type', 'application/json');
        response.setBody('[{"_id":"55d66226726b611100aaf741","replacement":false,"quantity":5,"name":"Generator 1000 kW","maintenanceperiod":365,"lifespan":120,"cost":5000,"sku":"100003"}]');
        response.setStatusCode(200);
        return response;
    }
}
 @isTest  
 private class WarehouseCalloutServiceTest {  
  // implement your mock callout test here  
   @isTest  
   static void WarehouseEquipmentSync(){  
     Test.startTest();  
     // Set mock callout class   
     Test.setMock(HttpCalloutMock.class, new WarehouseCalloutServiceMock());   
     // This causes a fake response to be sent from the class that implements HttpCalloutMock.   
     WarehouseCalloutService.runWarehouseEquipmentSync();  
     Test.stopTest();    
        
   }  
 }  

6.Test scheduling logic

https://trailhead.salesforce.com/content/learn/modules/asynchronous_apex/async_apex_scheduled

@isTest
public class WarehouseSyncSheduleTest {
@isTest static void WarehousescheduleTest(){
        String scheduleTime = '00 00 01 * * ?';
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new WarehouseCalloutServiceMock());
        String jobID=System.schedule('Warehouse Time To Schedule to Test', scheduleTime, new WarehouseSyncSchedule());
        Test.stopTest();
        //Contains schedule information for a scheduled job. CronTrigger is similar to a cron job on UNIX systems.
        // This object is available in API version 17.0 and later.
        CronTrigger a=[SELECT Id FROM CronTrigger where NextFireTime > today];
        System.assertEquals(jobID, a.Id,'Schedule ');
       
       
    }
}