• Michael Christie
  • NEWBIE
  • 10 Points
  • Member since 2017

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 2
    Questions
  • 1
    Replies
Hi All,
I've created a Visualforce dynamic search page for Accounts based on their geolocation. Users on the page can select a town, enter the radius (in miles) from the selected town, and receive a list of Accounts that are within that inputted radius. The Visualforce page and controller, though basic, perform as expected. However, there is a small block of code that needs test class coverage. Here is the Salesforce documentation (https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_class_system_Location.htm) that lead me to create the code in the Controller. Could anyone provide an answer on how to increase the coverage to 100%? Assistance would be greatly appreciated.

Thank you,
Mike

Visualforce Page
<apex:page Controller="QualifiedCandidateSearchController">
    <apex:form >
       <apex:pageBlock title="Enter Information Here">
           <apex:pageBlockSection >
                <apex:selectList value="{!selectedTown}" size="1" label="Select the town's name:">
                        <apex:selectOptions value="{!twnOption}" />
                </apex:selectList>
        		<apex:inputText value="{!miles}" label="Enter the distance from the town (in miles):" required="true"/>
           </apex:pageBlockSection>
           <apex:commandButton value="Search" action="{!search}"/>
           <apex:commandButton value="Clear Results" action="{!clear}"/>
       </apex:pageBlock>
        <apex:pageBlock title="Results: {!resultCount}">
            <apex:pageBlockTable value="{!acc}" var="a">
                <apex:column value="{!a.BillingCity}"/>
                <apex:column value="{!a.Name}"/>
                <apex:column value="{!a.Job_Title__c}"/>
                <apex:column value="{!a.Work_Email__c}"/>
                <apex:column value="{!a.Personal_Email__c}"/>
                <apex:column value="{!a.Phone}"/>
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>
Controller
public class QualifiedCandidateSearchController {
    public List <Account> acc {get;set;}
    public String selectedTown{get;set;}
    public Integer miles {get;set;}
    public Integer resultCount {get;set;}
    //Pre-populate the picklist with town names
    public List<SelectOption> twnOption {set;get{
        List<SelectOption> options = new List<SelectOption>();
        for(Town__c twn : [SELECT Name
                             FROM Town__c
                         ORDER BY Name]) {
            options.add(new SelectOption(twn.id,twn.Name));
        }
         return options;
    }}
    public QualifiedCandidateSearchController() {
    }
    public void search() {
        //Create list that will store the id's of qualified accounts
		List<Id> ids = new List<Id>();
        //Create a string variable that will be used with database.query
        String stringQuery;
        //Get the exact town that was searched for
        Town__c matchingTown =[SELECT Name, Town_s_Geolocation__c, Town_s_Geolocation__Latitude__s, Town_s_Geolocation__Longitude__s 
                                 FROM Town__c
                                WHERE Id = :selectedTown];
        //Get the list of qualified accounts that have an estimated geolocation value
        List<Account> qualifiedCandidates = [SELECT Id, Name, BillingCity, Job_Title__c, Work_Email__c, Personal_Email__c, Phone, Estimated_Geolocation__c, Estimated_Geolocation__Latitude__s, Estimated_Geolocation__Longitude__s 
                                               FROM Account 
                                              WHERE Results__c = 'Qualified' AND Estimated_Geolocation__Latitude__s != null];
        System.debug('here are the candidates: ' + qualifiedCandidates);
        //Iterate through the list and establish a location object for the looped Account
        for (Account account : qualifiedCandidates){
            Location loc = account.Estimated_Geolocation__c;
            Double lat = loc.latitude;
            Double lon = loc.longitude;
        	//Instantiate new Location objects based on the looped Account and Town
        	Location loc1 = Location.newInstance(loc.latitude, loc.longitude);
            Location loc2 = Location.newInstance(matchingTown.Town_s_Geolocation__Latitude__s, matchingTown.Town_s_Geolocation__Longitude__s);
        	//Compute the distance between the Account and Town
        	Double dist = Location.getDistance(loc1, loc2, 'mi');
            //Change the distance variable into an integer to compare it to mileage entered
            Integer x = dist.intValue();
            //If the distance is less than or equal to inputted mileage...
            if (x < miles) {
                //add current Account Id to list
                ids.add(account.id);
            }
       } 
        //Convert list of Account Ids into string list and run database.query
        List<String> strings = new List<String>( (List<String>)ids );
        stringQuery = 'SELECT Name, BillingCity, Job_Title__c, Work_Email__c, Personal_Email__c, Phone FROM Account WHERE Id IN:strings ORDER BY BillingCity, Job_Title__c';
        acc = Database.query(stringQuery);
        resultCount=strings.size();
    }
    public void clear(){
        acc.clear();
        resultCount=null;
    }
  }
*The code block beginning after the for loop, following the comment "Iterate through the list and establish a location object," up until "Convert list of Account Ids into string list and run database.query" is what the test class does not cover (see screenshot below). 
**This is a demo project I've taken on for learning purposes and I am not concerned about hitting a picklist limitation if the total Town__c records exceed 1,000. 
Test Class
@isTest 
public class QualifiedCandidateSearchTest { 
    
	@isTest static void findAccount() {    
        
        //Create and insert an Account
        Account testAccount  = new Account();
        testAccount.RecordTypeId						= '01215000001UW0v';
		testAccount.Name 								= 'John Doe';
        testAccount.BillingCity 						= 'Stirling';
        testAccount.Job_Title__c 						= 'Therapist';
        testAccount.Type								= 'Talent Acquisition';
        testAccount.Account_Type__c						= 'HR';
       	testAccount.Work_Email__c 						= 'jdoe@workemail.org';
        testAccount.Personal_Email__c 					= 'jdoe@gmail.com';
        testAccount.Phone 								= '111-111-1111';
       	testAccount.Estimated_Geolocation__Latitude__s 	= 40.672968;
        testAccount.Estimated_Geolocation__Longitude__s = -74.49171;
        testAccount.Results__c 							= 'Qualified';
		insert testAccount;
        
        //Create and insert a Town__c
        Town__c testTown = new Town__c();
        testTown.Name 							  	= 'Stirling';
        testTown.Town_s_Zip_Code__c 			  	= '07980';
        testTown.Town_s_County__c 					= 'Morris';
        testTown.Town_s_Geolocation__Latitude__s  	= 40.672968;
        testTown.Town_s_Geolocation__Longitude__s 	= -74.49171;
        insert testTown;
        
        Test.startTest();
        
        PageReference pageRef = Page.QualifiedCandidateSearch;
        Test.setCurrentPage(pageref);
        
        QualifiedCandidateSearchController testQual = new QualifiedCandidateSearchController();
        	if(testQual.twnOption.size() == 1) {
            	System.assertEquals(true, testQual.twnOption.size() == 1);
        	}
        testQual.miles = 2;
        testQual.selectedTown = testQual.twnOption.get(0).getValue();
        
        testQual.search();
        if(testQual.acc.size() == 1) {
            System.assertEquals(true, testQual.acc.size() == 1);
        }
        testQual.clear();
        if (testQual.acc.size() == 0) {
            System.assertEquals(true, testQual.acc.size() == 0);
        }
        
         Test.stopTest();
	}
}
Code Coverage Screenshot - 73% (25/34)
QualifiedCandidateSearchTest

 
Hi, I'm very new to creating triggers so I apologize if this question is somewhat basic. I am trying to create a trigger on an attachment that, when an attachment with a specific file name is uploaded to an account, will update a custom Datetime field on that account. When the attachment with the specific file name is deleted from the account, the value in the Datetime account field should be erased. Using this thread: https://developer.salesforce.com/forums/?id=9060G000000I8UmQAK#!/feedtype=SINGLE_QUESTION_SEARCH_RESULT&id=906F0000000Ayf8IAC  I was able to create a simple trigger, but I am missing the logic portion to limit the trigger to attachments containing the string "Admissions Packet" in the file name. Here is what I have so far: 
trigger AdmissionsPacketUploaded on Attachment (before insert, before delete)
{
if(trigger.isinsert){
List<Account> co = [select id from Account where id =: Trigger.New[0].ParentId];
If(co.size()>0 && Attachment.Name.contains('Admissions Packet'))
{            
    co[0].Date_Admissions_Packet_Uploaded__c = Date.Today();            
update co;        
}
}


if(trigger.isdelete){

List<Account> co = [select id from Account where id =: Trigger.old[0].ParentId];        
If(co.size()>0 && Attachment.Name.contains('Admissions Packet'))        
{            
    co[0].Date_Admissions_Packet_Uploaded__c = NULL;            
update co;        
}
}
}
My two error messages (for both isinsert and isdelete) read "Method does not exist or incorrect signature: void contains(String) from the type Schema.SObjectField." 

Any assistance would be greatly appreciated!
Hi, I'm very new to creating triggers so I apologize if this question is somewhat basic. I am trying to create a trigger on an attachment that, when an attachment with a specific file name is uploaded to an account, will update a custom Datetime field on that account. When the attachment with the specific file name is deleted from the account, the value in the Datetime account field should be erased. Using this thread: https://developer.salesforce.com/forums/?id=9060G000000I8UmQAK#!/feedtype=SINGLE_QUESTION_SEARCH_RESULT&id=906F0000000Ayf8IAC  I was able to create a simple trigger, but I am missing the logic portion to limit the trigger to attachments containing the string "Admissions Packet" in the file name. Here is what I have so far: 
trigger AdmissionsPacketUploaded on Attachment (before insert, before delete)
{
if(trigger.isinsert){
List<Account> co = [select id from Account where id =: Trigger.New[0].ParentId];
If(co.size()>0 && Attachment.Name.contains('Admissions Packet'))
{            
    co[0].Date_Admissions_Packet_Uploaded__c = Date.Today();            
update co;        
}
}


if(trigger.isdelete){

List<Account> co = [select id from Account where id =: Trigger.old[0].ParentId];        
If(co.size()>0 && Attachment.Name.contains('Admissions Packet'))        
{            
    co[0].Date_Admissions_Packet_Uploaded__c = NULL;            
update co;        
}
}
}
My two error messages (for both isinsert and isdelete) read "Method does not exist or incorrect signature: void contains(String) from the type Schema.SObjectField." 

Any assistance would be greatly appreciated!