You need to sign in to do that
Don't have an account?
Priya Raj 22
Help in writing Test Class
I am new to Apex programming, please help me to write a test class for below controller:
/**
* Controller used by the "scheduleOppsLwc" Lightning Web Component.
* @since 2021-10-05
* @version 2021-10-05
*/
public class ScheduleOppsCC {
/**
* On-load method used to determine if the "Schedule Opportunities" quick action
* is available for use based on Opportunity details/user status.
* @param parentOpp ID of Opportunity from quick action context
* @return String with reason for closing action if invalid use, empty string otherwise
*/
@AuraEnabled(cacheable=true)
public static String canSchedule(String parentOpp) {
/* escape String for SOQL injection safety and validate that is for an Opportunity */
Id parentOppId = Id.valueOf( String.escapeSingleQuotes(parentOpp) );
if ( Schema.Opportunity.SObjectType != parentOppId.getSObjectType() ) {
return 'This action is only available for Opportunity records.';
}
/* query for the Opportunity and related team members and check that the ID exists */
List<Opportunity> oppList = [ SELECT Id, OwnerId, Scheduled_as_Child__c, Scheduled_with_Children__c,
Total_SIMs__c, (Select UserId From OpportunityTeamMembers)
FROM Opportunity
WHERE Id = :parentOppId ];
if ( (oppList == null) || oppList.isEmpty() ) {
return 'This Opportunity cannot be found.';
}
if (oppList[0].Scheduled_with_Children__c) {
return 'This Opportunity has already been scheduled, please review existing installments.';
}
if (oppList[0].Scheduled_as_Child__c) {
return 'This Opportunity was scheduled as an installment and cannot be scheduled.';
}
if ( oppList[0].Total_SIMs__c == 0 ) {
return 'Please provide line items in order to proceed with initiating the scheduler.';
}
/* loop through Opportunity team members to get user IDs and compare against running user */
Set<Id> teamMemberIds = new Set<Id>();
if ( (oppList[0].OpportunityTeamMembers != null) && !oppList[0].OpportunityTeamMembers.isEmpty() ) {
for ( OpportunityTeamMember otm : oppList[0].OpportunityTeamMembers ) {
teamMemberIds.add(otm.UserId);
}
}
if ( (UserInfo.getUserId() != oppList[0].OwnerId) && !teamMemberIds.contains( UserInfo.getUserId() ) ) {
return 'Only the Opportunity owner or any team members can schedule installments.';
}
/* if here, all checks to prevent scheduling fail, so return an empty string to allow */
return '';
}
/**
* Creates new child installment Opportunities related to the Opportunity
* used for the "Schedule Opportunities" quick action and updates the parent
* as needed to CPQ-related details.
* @param parentOpp ID of Opportunity from quick action context
* @param parentOppJson JSON string-representation of the parent opportunity with new values for update
* @param childOppsJson JSON string-representation of a list of child opportunities to create
*/
@AuraEnabled
public static void createChildrenUpdateParent(String parentOpp, String parentOppJson, String childOppsJson) {
/* escape String for SOQL injection safety and validate that is for an Opportunity */
Id parentOppId = Id.valueOf( String.escapeSingleQuotes(parentOpp) );
if ( Schema.Opportunity.SObjectType != parentOppId.getSObjectType() ) {
throw new AuraHandledException('This action is only available for Opportunity records.');
}
try {
/* get all accessible fields for the running user to properly query for cloning */
Set<String> accessibleFields = new Set<String>();
Map<String, Schema.SObjectField> fields = Schema.Opportunity.SObjectType.getDescribe().fields.getMap();
for ( String api : fields.keySet() ) {
if ( fields.get(api).getDescribe().isAccessible() ) { accessibleFields.add(api); }
}
if ( (accessibleFields == null) || accessibleFields.isEmpty() ) {
throw new ScheduleOppsException('There are no fields available to the current user.');
}
/* query for the Opportunity and related line items and check that the ID exists */
List<Opportunity> parentList = Database.query( 'Select ' + String.join( new List<String>(accessibleFields), ', ' ) +
// '(Select Id From OpportunityLineItems)' +
' From Opportunity' +
' Where Id = :parentOppId' );
List<OpportunityLineItem> Oit = [select Id from OpportunityLineItem where OpportunityId = :parentOppId];
System.debug( '-> parentList1 = ' + parentList );
if ( (parentList == null) || parentList.isEmpty() ) {
throw new ScheduleOppsException('This Opportunity cannot be found.');
}
/* convert the child Opportunity JSON string to a list of Opportunities */
List<Opportunity> oppList = (List<Opportunity>)JSON.deserialize(childOppsJson, List<Opportunity>.class);
if ( (oppList == null) || oppList.isEmpty() ) {
throw new ScheduleOppsException('No child Opportunity records were passed for creation.');
}
/* loop through the child Opportunity records and create them as clones of the parent
* with updates to their fields as passed in via the JSON string */
Opportunity parClone;
for ( Integer i = 0; i < oppList.size(); ++i ) {
parClone = parentList[0].clone(false, true, false, false);
Map<String, Object> childVals = oppList[i].getPopulatedFieldsAsMap();
for ( String field : childVals.keySet() ) {
parClone.put( field, childVals.get(field) );
}
parClone.Is_Child__c = true;
oppList[i] = parClone;
}
/* convert the parent Opportunity JSON to an Opportunity to update to represent scheduling */
Opportunity parent = (Opportunity)JSON.deserialize( parentOppJson, Opportunity.class );
// parent.Include_in_Funnel__c = 'No';
parent.StageName = 'Discovery';
oppList.add(parent);
/* upsert to create children and update parent, delete all parent-related line items */
upsert oppList;
if( Oit.size() > 0 )
{
delete Oit;
}
//delete parentList[0].OpportunityLineItems;
} catch(Exception ex) {
System.debug( 'EXCEPTION @ ' + ex.getLineNumber() + ' (' + ex.getLineNumber() + ': ' +
ex.getMessage() + '): ScheduleOppsCC.createChildrenUpdateParent()\n -> parentOpp = ' +
parentOpp + '\n -> parentOppJson = ' + parentOppJson +
'\n -> childOppsJson = ' + childOppsJson);
throw new AuraHandledException('An error occurred, please reach out to your administrator for assistance.');
}
}
private class ScheduleOppsException extends Exception {}
}
/**
* Controller used by the "scheduleOppsLwc" Lightning Web Component.
* @since 2021-10-05
* @version 2021-10-05
*/
public class ScheduleOppsCC {
/**
* On-load method used to determine if the "Schedule Opportunities" quick action
* is available for use based on Opportunity details/user status.
* @param parentOpp ID of Opportunity from quick action context
* @return String with reason for closing action if invalid use, empty string otherwise
*/
@AuraEnabled(cacheable=true)
public static String canSchedule(String parentOpp) {
/* escape String for SOQL injection safety and validate that is for an Opportunity */
Id parentOppId = Id.valueOf( String.escapeSingleQuotes(parentOpp) );
if ( Schema.Opportunity.SObjectType != parentOppId.getSObjectType() ) {
return 'This action is only available for Opportunity records.';
}
/* query for the Opportunity and related team members and check that the ID exists */
List<Opportunity> oppList = [ SELECT Id, OwnerId, Scheduled_as_Child__c, Scheduled_with_Children__c,
Total_SIMs__c, (Select UserId From OpportunityTeamMembers)
FROM Opportunity
WHERE Id = :parentOppId ];
if ( (oppList == null) || oppList.isEmpty() ) {
return 'This Opportunity cannot be found.';
}
if (oppList[0].Scheduled_with_Children__c) {
return 'This Opportunity has already been scheduled, please review existing installments.';
}
if (oppList[0].Scheduled_as_Child__c) {
return 'This Opportunity was scheduled as an installment and cannot be scheduled.';
}
if ( oppList[0].Total_SIMs__c == 0 ) {
return 'Please provide line items in order to proceed with initiating the scheduler.';
}
/* loop through Opportunity team members to get user IDs and compare against running user */
Set<Id> teamMemberIds = new Set<Id>();
if ( (oppList[0].OpportunityTeamMembers != null) && !oppList[0].OpportunityTeamMembers.isEmpty() ) {
for ( OpportunityTeamMember otm : oppList[0].OpportunityTeamMembers ) {
teamMemberIds.add(otm.UserId);
}
}
if ( (UserInfo.getUserId() != oppList[0].OwnerId) && !teamMemberIds.contains( UserInfo.getUserId() ) ) {
return 'Only the Opportunity owner or any team members can schedule installments.';
}
/* if here, all checks to prevent scheduling fail, so return an empty string to allow */
return '';
}
/**
* Creates new child installment Opportunities related to the Opportunity
* used for the "Schedule Opportunities" quick action and updates the parent
* as needed to CPQ-related details.
* @param parentOpp ID of Opportunity from quick action context
* @param parentOppJson JSON string-representation of the parent opportunity with new values for update
* @param childOppsJson JSON string-representation of a list of child opportunities to create
*/
@AuraEnabled
public static void createChildrenUpdateParent(String parentOpp, String parentOppJson, String childOppsJson) {
/* escape String for SOQL injection safety and validate that is for an Opportunity */
Id parentOppId = Id.valueOf( String.escapeSingleQuotes(parentOpp) );
if ( Schema.Opportunity.SObjectType != parentOppId.getSObjectType() ) {
throw new AuraHandledException('This action is only available for Opportunity records.');
}
try {
/* get all accessible fields for the running user to properly query for cloning */
Set<String> accessibleFields = new Set<String>();
Map<String, Schema.SObjectField> fields = Schema.Opportunity.SObjectType.getDescribe().fields.getMap();
for ( String api : fields.keySet() ) {
if ( fields.get(api).getDescribe().isAccessible() ) { accessibleFields.add(api); }
}
if ( (accessibleFields == null) || accessibleFields.isEmpty() ) {
throw new ScheduleOppsException('There are no fields available to the current user.');
}
/* query for the Opportunity and related line items and check that the ID exists */
List<Opportunity> parentList = Database.query( 'Select ' + String.join( new List<String>(accessibleFields), ', ' ) +
// '(Select Id From OpportunityLineItems)' +
' From Opportunity' +
' Where Id = :parentOppId' );
List<OpportunityLineItem> Oit = [select Id from OpportunityLineItem where OpportunityId = :parentOppId];
System.debug( '-> parentList1 = ' + parentList );
if ( (parentList == null) || parentList.isEmpty() ) {
throw new ScheduleOppsException('This Opportunity cannot be found.');
}
/* convert the child Opportunity JSON string to a list of Opportunities */
List<Opportunity> oppList = (List<Opportunity>)JSON.deserialize(childOppsJson, List<Opportunity>.class);
if ( (oppList == null) || oppList.isEmpty() ) {
throw new ScheduleOppsException('No child Opportunity records were passed for creation.');
}
/* loop through the child Opportunity records and create them as clones of the parent
* with updates to their fields as passed in via the JSON string */
Opportunity parClone;
for ( Integer i = 0; i < oppList.size(); ++i ) {
parClone = parentList[0].clone(false, true, false, false);
Map<String, Object> childVals = oppList[i].getPopulatedFieldsAsMap();
for ( String field : childVals.keySet() ) {
parClone.put( field, childVals.get(field) );
}
parClone.Is_Child__c = true;
oppList[i] = parClone;
}
/* convert the parent Opportunity JSON to an Opportunity to update to represent scheduling */
Opportunity parent = (Opportunity)JSON.deserialize( parentOppJson, Opportunity.class );
// parent.Include_in_Funnel__c = 'No';
parent.StageName = 'Discovery';
oppList.add(parent);
/* upsert to create children and update parent, delete all parent-related line items */
upsert oppList;
if( Oit.size() > 0 )
{
delete Oit;
}
//delete parentList[0].OpportunityLineItems;
} catch(Exception ex) {
System.debug( 'EXCEPTION @ ' + ex.getLineNumber() + ' (' + ex.getLineNumber() + ': ' +
ex.getMessage() + '): ScheduleOppsCC.createChildrenUpdateParent()\n -> parentOpp = ' +
parentOpp + '\n -> parentOppJson = ' + parentOppJson +
'\n -> childOppsJson = ' + childOppsJson);
throw new AuraHandledException('An error occurred, please reach out to your administrator for assistance.');
}
}
private class ScheduleOppsException extends Exception {}
}
https://salesforce.stackexchange.com/questions/244788/how-do-i-write-an-apex-unit-test
https://salesforce.stackexchange.com/questions/244794/how-do-i-increase-my-code-coverage-or-why-cant-i-cover-these-lines
If you face any specific issue while attempting do post that here.
Thanks!