• Matt Metros
  • NEWBIE
  • 20 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 10
    Questions
  • 2
    Replies
public with sharing class InsertPreOpportunity {
	public static void handleTrigger(List<Form__c> newForms) 
	{
		// check if this is a demo set form

		Map<Id, Opportunity> contact_With_pre_Opptys_to_Insert = new Map<Id, Opportunity>();

		for(Form__c form: newForms)
		{

			if(form.RecordType.Name == 'Demo Set Form')
			{
				Opportunity preOppty = new Opportunity(
					OwnerId			= form.AE_Owner__c,
					AccountId	 	= form.Account__c,
					SDR_Owner__c 	= form.SDR_Owner__c,
					SDR_Notes__C 	= form.SDR_Notes__c,
					LinkedIn_URL__c = form.LinkedIn_URL__c,
					ERP_Systems__c 	= form.ERP_Systems__c,
					RecordTypeId	= '0126A000000yudDQAQ',
					Estimated_Annual_Spend__c = form.Estimated_Annual_Spend__c
				);


				contact_With_pre_Opptys_to_Insert.put(form.Contact__c, preOppty);



			}
		}


		for(ID con: contact_With_pre_Opptys_to_Insert.keySet())
		{
			Opportunity opp = contact_With_pre_Opptys_to_Insert.get(con) ;

			OpportunityContactRole oppConRole = new OpportunityContactRole(
				OpportunityId 	= opp.Id,
				ContactId		= con,
				isPrimary		= true

			);
		}

	}
}

Hi, Do I need to insert the opportunities before I insert opportunitycontactroles? Or will the code above work.
I am receiving the following error from my HttpCallOutMock Class:

System.XmlException: start tag unexpected character \ua0 (position: START_DOCUMENT seen <rss\ua0... @1:5)
 
@isTest
global class getRSSFeedMockCallout implements HttpCalloutMock 
{

  global HttpResponse respond(HttpRequest request)
  {
      String sessionBody = '<rss xmlns:media=\"http://search.yahoo.com/mrss/\" version=\"2.0\">' +
      '<channel>'+
        '<item>'+
          '<title>Draymond Green Is a SoulCycle Devotee - Bicycling</title>'+
          '<link>https://www.bicycling.com/news/a27024393/draymond-green-soulcycle/</link>'+
          '<pubDate>Wed, 03 Apr 2019 12:00:00 GMT</pubDate>'+
          '<description><a href=\"https://www.bicycling.com/news/a27024393/draymond-green-soulcycle/\" target=\"_blank\">Draymond Green Is a SoulCycle Devotee</a>&nbsp;&nbsp;<font color=\"#6f6f6f\">Bicycling</font><p>If you take SoulCycle classes in the Bay Area, and you notice one extremely tall guy in the room, you may be looking at Golden State Warriors star Draymond ...</p></description>'+
          '<source url=\"https://www.bicycling.com\">Bicycling</source>'+
          '<media:contenturl=\"https://lh5.googleusercontent.com/proxy/QvLCgDJMIqLENGFBUt1CCoUPO1XB6gJkGFPV5FuM0QKfyaG8WdhuHGtfcVaTzNzPAYyHo-arnqUBkWkZ8s7-p7WBUbKlfJ4xr0hl8hltQWsBCG0yDDh13Ul5qKrZgLvjQitRecmu=-w150-h150-c\" medium=\"image\" width=\"150\"height=\"150\"/>'+
        '</item>'+
      '</channel>'+
    '</rss>';


      HttpResponse res = new HttpResponse();
      res.setHeader('Content-Type', 'text/xml');
      res.setBody( sessionBody );
      res.setStatusCode(200);
      return res;
  }   
}

This is my apex class that is requesting.
 
public with sharing class getRSSFeed {

	@AuraEnabled
	public static List<Map<String,String>> getCompanyRSSFeed(String url, String recordID) {
		
		String recordName = getRecordName(recordID);

		List<Map<String,String>> newsArticles = search(url, recordName);

		return newsArticles;
	}
	
	@AuraEnabled
	public static String getRecordName(String recordID)
	{
		String accountRecordID = recordID;
		return [SELECT Name From Account WHERE ID = : accountRecordID limit 1].Name;
	}

	@AuraEnabled
	public static  List<Map<String,String>> search(String remoteSiteURL, String query)
	{
		String url = remoteSiteURL + EncodingUtil.urlEncode(query, 'UTF-8');

		Http h = new Http();
		HttpRequest req = new HttpRequest();
		HttpResponse res = new HttpResponse();
		if (!Test.IsRunningTest())
		{
		    req.setEndpoint(url);
	    	req.setMethod('GET');
		    res = h.send(req);
		}
		else
		{
			 getRSSFeedMockCallout mock = new getRSSFeedMockCallout();
             res = mock.respond(req);
		}


	    while (res.getStatusCode() == 302) {
		    req.setEndpoint(res.getHeader('Location'));
		    System.debug(res.getHeader('Location'));
		    res = new Http().send(req);
		}

	    Dom.Document doc = res.getBodyDocument();
	    Dom.XMLNode root = doc.getRootElement();

	   	Dom.XMLNode bodyNode = root.getChildElement('channel', null);

	   	//Dom.XMLNode bodyNode = bodyNode.getChildElement('');
		List<Map<String,String>> newsStories = new List<Map<String,String>>();
	   	Integer sizeOfList = 20;
	   	Integer i = 0;


	    for(DOM.XmlNode x : bodyNode.getChildren())
	    {
	    	//System.debug(x.getName());
	    	//System.debug(x.getText());
	    	if(x.getName() == 'item' &&
	    		i != sizeOfList)
	    	{
	    		Map<String,String> story = new Map<String, String>();
	    		story.put('publisher', '');
	    		story.put('date', '');
	    		story.put('link', '');
	    		story.put('image', '');
	    		story.put('title', '');
	    		story.put('description', '');


	    		for(DOM.XmlNode itemChildren : x.getChildElements())
	    		{
	    			System.debug(itemChildren.getName());

	    			//System.debug(itemChildren.getName());
	    			//System.debug(itemChildren.getText());
	    			if(itemChildren.getName() == 'link')
	    			{
	    				story.put('link', itemChildren.getText());
	    			}
	    			else if(itemChildren.getName() == 'title')
	    			{
	    				story.put('title', itemChildren.getText());
	    			}
	    			else if(itemChildren.getName() == 'pubDate')
	    			{
	    				story.put('date', itemChildren.getText());
	    			}
	    			else if(itemChildren.getName() == 'description')
	    			{

	    				String stripTags = itemChildren.getText();
	    				List<String> description = stripTags.split('(<.*?>)');
	    				story.put('description', description[5]);
	    			}
	    			else if(itemChildren.getName() == 'content')
	    			{
	    				story.put('image', itemChildren.getAttributeValue(itemChildren.getAttributeKeyAt(0), itemChildren.getAttributeKeyNsAt(0)));
	    			}
	    			else if(itemChildren.getName() == 'source')
	    			{
	    				story.put('publisher', itemChildren.getText());
	    			}


	    		}

	    		newsStories.add(story);
	    		i += 1;

	    	}

	    }
	    return newsStories;
	}


}
Hello Everybody. I am very new to HTTP Callouts and now I am in the testing phase. My HTTP Callout returns XML

This is the link. I input a company already, soulcycle, in case anybody wanted to see what was being returned from the HTTP Request.

https://news.google.com/rss/search?q=soulcycle&hl=en-US&gl=US&ceid=US:en


Anyways, here is my Apex Class:
 
public with sharing class getRSSFeed {

	@AuraEnabled
	public static List<Map<String,String>> getCompanyRSSFeed(String url, String recordID) {
		
		String recordName = getRecordName(recordID);

		List<Map<String,String>> newsArticles = search(url, recordName);

		return newsArticles;
	}
	
	@AuraEnabled
	public static String getRecordName(String recordID)
	{
		String accountRecordID = recordID;
		return [SELECT Name From Account WHERE ID = : accountRecordID limit 1].Name;
	}

	@AuraEnabled
	public static  List<Map<String,String>> search(String remoteSiteURL, String query)
	{
		String url = remoteSiteURL + EncodingUtil.urlEncode(query, 'UTF-8');

		Http h = new Http();
	    HttpRequest req = new HttpRequest();
	    req.setEndpoint(url);
    	req.setMethod('GET');
	    HttpResponse res = h.send(req);

	    while (res.getStatusCode() == 302) {
		    req.setEndpoint(res.getHeader('Location'));
		    System.debug(res.getHeader('Location'));
		    res = new Http().send(req);
		}

	    Dom.Document doc = res.getBodyDocument();
	    Dom.XMLNode root = doc.getRootElement();

	   	Dom.XMLNode bodyNode = root.getChildElement('channel', null);

	   	//Dom.XMLNode bodyNode = bodyNode.getChildElement('');
		List<Map<String,String>> newsStories = new List<Map<String,String>>();
	   	Integer sizeOfList = 20;
	   	Integer i = 0;


	    for(DOM.XmlNode x : bodyNode.getChildren())
	    {
	    	//System.debug(x.getName());
	    	//System.debug(x.getText());
	    	if(x.getName() == 'item' &&
	    		i != sizeOfList)
	    	{
	    		Map<String,String> story = new Map<String, String>();
	    		story.put('publisher', '');
	    		story.put('date', '');
	    		story.put('link', '');
	    		story.put('image', '');
	    		story.put('title', '');
	    		story.put('description', '');


	    		for(DOM.XmlNode itemChildren : x.getChildElements())
	    		{
	    			System.debug(itemChildren.getName());

	    			//System.debug(itemChildren.getName());
	    			//System.debug(itemChildren.getText());
	    			if(itemChildren.getName() == 'link')
	    			{
	    				story.put('link', itemChildren.getText());
	    			}
	    			else if(itemChildren.getName() == 'title')
	    			{
	    				story.put('title', itemChildren.getText());
	    			}
	    			else if(itemChildren.getName() == 'pubDate')
	    			{
	    				story.put('date', itemChildren.getText());
	    			}
	    			else if(itemChildren.getName() == 'description')
	    			{

	    				String stripTags = itemChildren.getText();
	    				List<String> description = stripTags.split('(<.*?>)');
	    				story.put('description', description[5]);
	    			}
	    			else if(itemChildren.getName() == 'content')
	    			{
	    				story.put('image', itemChildren.getAttributeValue(itemChildren.getAttributeKeyAt(0), itemChildren.getAttributeKeyNsAt(0)));
	    			}
	    			else if(itemChildren.getName() == 'source')
	    			{
	    				story.put('publisher', itemChildren.getText());
	    			}


	    		}

	    		newsStories.add(story);
	    		i += 1;

	    	}

	    }
	    return newsStories;
	}


}

Here is my Test Class (Which is honestly embarrassing right now, because I have no clue what I am doing.)

 
@isTest
private class getRSSFeedTest {

	Public static final Integer numOfAccounts = 1;
	Public static final Integer numOfContacts = 1;
	
	@testsetup 
	public static void setupEnvironment()
	{
		createAccountsAndContacts(numOfAccounts,numOfContacts);
	}
	
	@isTest static void testAccountNews() 
	{
		String accId 	= [SELECT name from Account limit 1].id;
		String link		= 'https://news.google.com/rss/search?q=';

		 String accName = getRSSFeed.getRecordName(accId);
	 
	 	Test.setMock(HttpCalloutMock.class, new mockCallout());
	  	//getRSSFeed r = new getRSSFeed.search(link, 'Airbnb');
	 }


	

	public static void createAccountsAndContacts(Integer numberOfAccounts, Integer numberOfContactsPerAccount)
	 {
	   Database.DMLOptions dml = new Database.DMLOptions();
	   dml.DuplicateRuleHeader.allowSave = true;

	   List<Account> accountsToInsert = new List<Account>();

	   for(Integer i=0 ; i< numberOfAccounts; i++)
	   {

	     Account newAccount = new Account(
	           Name = 'Airbnb ' +  String.valueOf(i),
	           Industry = 'Accounting',
	           of_Locations__c = 5 + i
	      );

	     accountsToInsert.add(newAccount);
	   }

	   Database.insert(accountsToInsert, dml);


	   List<Contact> contactsToInsert = new List<Contact>();
	   for(Account acc: accountsToInsert)
	   {

	     for(Integer i = 0; i < numberOfContactsPerAccount; i++)
	     {
	       Contact newContact = new Contact(
	         lastName     = 'Test' + String.valueOf(i),
	         accountId   = acc.ID ,
	         title       = 'Test' ,
	         email       = String.valueOf(i)+'test@test.com',
	         Outreach_Status__c = 'Client'
	       );
	       contactsToInsert.add(newContact);
	     }

	   Database.insert(contactsToInsert, dml);

	   }
	 }  
}



I know this test class is really bad. I am researching a lot on how to achieve 100% code coverage. If you have any tips, please send them over. I appreciate all the help I can get!

Thanks in advance.
    public static List<Dom.XMLNode> search(String remoteSiteURL, String query)
    {

        String url = remoteSiteURL + EncodingUtil.urlEncode(query, 'UTF-8');

        Http h = new Http();
        HttpRequest req = new HttpRequest();
        // url that returns the XML in the response body  
      

        req.setEndpoint(url);
        req.setMethod('GET');
        HttpResponse res = h.send(req);
        Dom.Document doc = res.getBodyDocument();


        Dom.XMLNode rss = doc.getRootElement();


}

I am not sure if I need to convert this into JSON.
Hi everybody.

I am going to create an RSS feed lightning component.

This is the link to the RSS feed that we want to connect to
https://news.google.com/rss/search?q={Company_Name}



How do I whitelist this, so that Salesforce allows me to pull in this data?

This is how the info comes in. Do whitelist Google or Yahoo?

<rss xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
<channel>...</channel>
</rss>
@isTest
private class NumberOfEmailsSchedulableTest {
    
    public static final Integer numberOfAcc = 5;
    public static final Integer numberOfCon = 2;


    static testmethod void schedulerTest() 
       {
               CreateTestAccountsContactsAndTasks(numberOfAcc, numberOfCon);
               
               List<Task> tasks = [SELECT id, subject, ActivityDate, Sequence_Name__c FROM Task];



           String CRON_EXP = '0 0 0 15 3 ? *';
           
           // Create your test data
           Account acc = new Account();
           acc.name= 'test';
           insert
            acc;
           
           Test.startTest();

               String jobId = System.schedule('ScheduleApexClassTest',  CRON_EXP, new NumberOfEmailsSchedulable());
               CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE id = :jobId];
               System.assertEquals(CRON_EXP, ct.CronExpression);
               System.assertEquals(0, ct.TimesTriggered);

           Test.stopTest();
           // Add assert here to validate result
       }


       public static void CreateTestAccountsContactsAndTasks(Integer numOfAccounts, Integer contactsPerAccount)
        {

            Database.DMLOptions dml = new Database.DMLOptions(); 
            dml.DuplicateRuleHeader.allowSave = true;

          List<Account> accounts = new List<Account>();

          for(Integer i = 0; i < numOfAccounts; i++)
            {
            // create new account
                  Account newAccount = new Account(
                      Name         = 'Test' + String.valueOf(i),
                      Industry       = 'Accounting',
                      of_Locations__c = 5 + i,
                    sdr_owner__c = userinfo.getuserid()
                  );

                accounts.add(newAccount);
          }

          Database.insert(accounts, dml);

            List<Contact> contacts = new List<Contact>();

          for(Account act: accounts){
              for(Integer i = 0; i < contactsPerAccount; i++)
              {
                // create new contact
                 Contact con = new Contact(
                    LastName   = 'Test',
                    AccountId   = act.id,
                    Outreach_Status__c = 'In Contact',
                    Title     = 'Test' + String.valueOf(i),
                    Email     = 'test@test.com'
                  );

                  contacts.add(con);
              }
          }

           Database.insert(contacts, dml);

           List<Task> tasksToInsert = new List<Task>();

           for(Contact con : contacts)
           {
                   Task regularTask = new Task(
                       whoid = con.Id,
                       ActivityDate = Date.today(),
                       Status = 'Completed'
                   );
                   Task personalizedTask = new Task(
                       Sequence_Name__c = 'personalized',
                       whoid = con.Id,
                       ActivityDate = Date.today(),
                       Status = 'Completed'
                   );
                   Task sequencedTask = new Task(
                       Sequence_Name__c = 'WYWYN19',
                       whoid = con.Id,
                       ActivityDate = Date.today(),
                       Status = 'Completed'

                   );


                   tasksToInsert.add(regularTask);
                   tasksToInsert.add(personalizedTask);
                   tasksToInsert.add(sequencedTask);
           }

           Database.insert(tasksToInsert, dml);
        }

        public static User createUser(String username , String theAlias)
        {
          Integer randomInt = Integer.valueOf(math.rint(math.random()*1000));
            User u = new User
            (
               Alias = theAlias + String.valueOf(randomInt),
              Email = username + String.valueOf(randomInt)+ '@test.com',
            FirstName = 'Joe',
            LastName = username + String.valueOf(randomInt),
            TimeZoneSidKey = 'America/Los_Angeles',
            UserName = username + String.valueOf(randomInt) + '@test.com',
            LocaleSidKey = 'en_US',
            EmailEncodingKey = 'UTF-8',
            LanguageLocaleKey = 'en_US',
            ProfileID = UserInfo.getProfileId()
            );

            insert u;
            return u;
        }
    
}

I user database.Insert and no tasks appear. Why?
public with sharing class NumberOfAccountsRelatedToUser {

	public static void triggerHandler( System.TriggerOperation triggerEvent , list<Account> newAccounts, List<Account> oldAccounts) {

		Set<ID> related_user_IDs = new Set<ID>();

		if(triggerEvent == TriggerOperation.AFTER_INSERT){
			for(Account a: newAccounts){
				related_user_IDs.add(a.SDR_Owner__c);
				related_user_IDs.add(a.OwnerID);
			}
		}
		if(triggerEvent == TriggerOperation.AFTER_UPDATE){
			for(Account a: newAccounts){
				related_user_IDs.add(a.SDR_Owner__c);
				related_user_IDs.add(a.OwnerID);
			}
			for(Account a: oldAccounts){
				related_user_IDs.add(a.SDR_Owner__c);
				related_user_IDs.add(a.OwnerID);
			}
		}

		if(triggerEvent == TriggerOperation.AFTER_DELETE){
			for(Account a: oldAccounts){
				related_user_IDs.add(a.SDR_Owner__c);
				related_user_IDs.add(a.OwnerID);
			}
		}

		// now we want to say hey, we have these User ID's
		// lets go found how many accounts in which they are the SDR Owner and Account Owner


		List<AggregateResult> related_user_prospect_accounts = [SELECT COUNT(ID) sdr_owner_accounts, SDR_Owner__c FROM Account WHERE SDR_Owner__c in :related_user_IDs and (type ='Prospect - Being Worked' OR type='Prospect - Open' ) GROUP BY SDR_Owner__c];
		List<AggregateResult> related_user_owner_prospect_accounts = [SELECT COUNT(ID) owner_accounts, OwnerID FROM Account WHERE OwnerID in :related_user_IDs and (type ='Prospect - Being Worked' OR type='Prospect - Open' ) GROUP BY OwnerId];


		Map<Id, List<Integer>> userID_And_num_of_accounts = new Map<Id, List<Integer>>();

		// we are assuming there will always be an account owner
		// which is definitely a fine assertion, because an account cannot be created without an owner
		for(AggregateResult ar: related_user_owner_prospect_accounts){
		    ID owner_ID = (ID)ar.get('OwnerID');

		    // check if Id is in Map, only initialize new list if ID not in map
		    if(!userID_And_num_of_accounts.containsKey(owner_ID)){
		        userID_And_num_of_accounts.put(owner_ID, new List<Integer>());
		    }

		    userID_And_num_of_accounts.get(owner_ID).add((Integer)ar.get('owner_accounts'));
		
		}



		for(AggregateResult ar: related_user_prospect_accounts){
		    ID sdr_owner_ID = (ID)ar.get('SDR_Owner__c');

		    // check if Id is in Map, only initialize new list if ID not in map
		    if(!userID_And_num_of_accounts.containsKey(sdr_owner_ID)){
		        userID_And_num_of_accounts.put(sdr_owner_ID, new List<Integer>());
		    }

		    if(sdr_owner_ID == null){
		    	continue;
		    }
		    else{
		    	// add the number of sdr accounts to that IDs map
		    	userID_And_num_of_accounts.get(sdr_owner_ID).add((Integer)ar.get('sdr_owner_accounts'));
		    }

	
		}


		// now we want to update the users field
		List<ID> user_IDs = new List<ID>();

		for(ID user_ID: userID_And_num_of_accounts.keySet()){
			user_IDs.add(user_ID);
		}

		// now we want to get the actual user object
		List<User> users = [SELECT ID, SDR_Owner_Prospect__c , Account_Owner_Prospect__c FROM User WHERE ID in :user_IDs];


		List<User> users_to_update = new List<User>();
		for(User u: users){
			List<Integer> sdr_and_owner_accounts = userID_And_num_of_accounts.get(u.ID);			
			if(sdr_and_owner_accounts.size() == 1){
				u.Account_Owner_Prospect__c = sdr_and_owner_accounts[0];
				u.SDR_Owner_Prospect__c = 0;
			}
			else{
				u.Account_Owner_Prospect__c = sdr_and_owner_accounts[0];
				u.SDR_Owner_Prospect__c = sdr_and_owner_accounts[1];	
			}

			users_to_update.add(u);
		}

		update users_to_update;

	}


}

What is going on with this trigger. All I am trying to do is update two user fields when the trigger fires.
@isTest(SeeAllData=true)
private class NumberOfAccountsRelatedToUserTest {
	
	@isTest static void test_method_one() {
		Integer num = 5;
		List<Account> accounts = createAccounts(num);
		List<Contact> contacts = createContacts(num, accounts);

		List<Account> accounts2 = createAccounts(num);
		List<Contact> contacts2 = createContacts(num, accounts2);

		User u  = createUser('myname', 'myname');
		User u2 = createUser('Test', 'Test');

		System.runAs(u){
			insert accounts;
			insert contacts;
		}

		System.runAs(u2){
			insert accounts2;
			insert contacts2;
		}

		Test.startTest();

			for(Account acc: accounts){
				acc.Account_Notes__c = 'Test Update';
				acc.SDR_Owner__c = u2.ID;
			}	

			update accounts;




		Test.stopTest();


	}


	public static User createUser(String username ,String theAlias){
		User u = new User(
			Alias = theAlias,
			Email = username + '@test.com',
			FirstName = 'Joe',
			LastName = username,
			TimeZoneSidKey = 'America/Los_Angeles',
			UserName = username + '@test.com',
			LocaleSidKey = 'en_US',
			EmailEncodingKey = 'UTF-8',
			LanguageLocaleKey = 'en_US'
			);

		u.profileID = userinfo.getProfileId();


		return u;
	}

	public static List<Account> createAccounts(Integer numOfAccounts){
		list<Account> accountsToInsert = new List<Account>();

		for(integer i = 0; i < numOfAccounts; i++){
			Account newAccount = new Account(
				Name = 'Test' + String.valueOf(i),
				Industry = 'Accounting',
				of_Locations__c = 5 + i
				);

			accountsToInsert.add(newAccount);

		}


		return accountsToInsert;
	}

	public static List<Contact> createContacts(Integer numOfContacts, List<Account> accounts){

		list<Contact> contactsToInsert = new List<Contact>();

		for(Integer i = 0; i < numOfContacts; i++){
			Contact newCon = new Contact (
				lastName 	= 'Test' + String.valueOf(i) ,
				accountId 	= accounts[i].ID ,
				title 		= 'Test' ,
    			email 		= String.valueOf(i) + 'test@test.com'
				);
			contactsToInsert.add(newCon);
		}

		return contactsToInsert;
	}
	
	
}

System.DmlException: Insert failed. First exception on row 0; first error: DUPLICATES_DETECTED, You're creating a duplicate record. We recommend you use an existing record instead.: []

Class.NumberOfAccountsRelatedToUserTest.test_method_one: line 22, column 1

How on earth am I creating a duplicate record???
public with sharing class NumberOfAccountsRelatedToUser {

	public static void triggerHandler( System.TriggerOperation triggerEvent , list<Account> newAccounts, List<Account> oldAccounts) {

		Set<ID> sdr_owner_IDs = new Set<ID>();
		Set<ID> account_owner_IDs = new set<ID>();


		if(triggerEvent == TriggerOperation.AFTER_INSERT){
			for(Account a: newAccounts){
				sdr_owner_IDs.add(a.SDR_Owner__c);
				account_owner_IDs.add(a.OwnerID);
			}
		}
		if(triggerEvent == TriggerOperation.AFTER_UPDATE){
			for(Account a: newAccounts){
				sdr_owner_IDs.add(a.SDR_Owner__c);
				account_owner_IDs.add(a.OwnerID);
			}
			for(Account a: oldAccounts){
				sdr_owner_IDs.add(a.SDR_Owner__c);
				account_owner_IDs.add(a.OwnerID);
			}
		}

		if(triggerEvent == TriggerOperation.AFTER_DELETE){
			for(Account a: oldAccounts){
				sdr_owner_IDs.add(a.SDR_Owner__c);
				account_owner_IDs.add(a.OwnerID);
			}
		}

		System.debug(sdr_owner_IDs);
		System.debug(account_owner_IDs);


		List<AggregateResult> sdr_prospect_accounts = [SELECT COUNT(ID) sdr_accounts, SDR_Owner__c FROM Account WHERE SDR_Owner__c in :sdr_owner_IDs and (type ='Prospect - Being Worked' OR type='Prospect - Open' ) GROUP BY SDR_Owner__c];
		List<AggregateResult> owner_prospect_accounts = [SELECT COUNT(ID) owner_accounts, OwnerID FROM Account WHERE OwnerID in :account_owner_IDs and (type ='Prospect - Being Worked' OR type='Prospect - Open' ) GROUP BY OwnerID];

		Map<Id, List<Integer>> userID_And_num_of_accounts = new Map<Id, List<Integer>>();

		for(AggregateResult ar: sdr_prospect_accounts){
			// put the id in the list
			userID_And_num_of_accounts.put((ID)ar.get('SDR_Owner__c'), new List<Integer>());

			// add the number of sdr accounts to that IDs map
			userID_And_num_of_accounts.get((ID)ar.get('SDR_Owner__c')).add((Integer)ar.get('sdr_accounts'));
			userID_And_num_of_accounts.get((ID)ar.get('SDR_Owner__c')).add(0);
		}

		for(AggregateResult ar: owner_prospect_accounts){

			// if the id already exists
			if(userID_And_num_of_accounts.containsKey((ID)ar.get('OwnerID'))){

				userID_And_num_of_accounts.get((ID)ar.get('OwnerID')).add(1, (Integer)ar.get('owner_accounts'));
			} else {
				userID_And_num_of_accounts.put((ID)ar.get('SDR_Owner__c'), new List<Integer>());

				userID_And_num_of_accounts.get((ID)ar.get('SDR_Owner__c')).add(0);
				userID_And_num_of_accounts.get((ID)ar.get('SDR_Owner__c')).add((Integer)ar.get('owner_accounts'));
			}
		}

		// now we want to update the users field
		List<ID> user_IDs = new List<ID>();

		for(ID user_ID: userID_And_num_of_accounts.keySet()){
			user_IDs.add(user_ID);
		}

		// now we want to get the actual user object
		List<User> users = [SELECT ID, SDR_Owner_Prospect__c , Account_Owner_Prospect__c FROM User WHERE ID in :user_IDs];


		List<User> users_to_update = new List<User>();
		for(User u: users){
			List<Integer> sdr_and_owner_accounts = userID_And_num_of_accounts.get(u.ID);
			u.SDR_Owner_Prospect__c = sdr_and_owner_accounts[0];
			u.Account_Owner_Prospect__c = sdr_and_owner_accounts[1];
			users_to_update.add(u);
		}

		// update users
		update users_to_update;

	}


}

Line 45 is saying I am out of bounds. Does not make sense.
trigger UpdateOpportunityContacts on Opportunity (after insert, before update) {


	for(Opportunity opp: Trigger.new){

		List<Id> contactIds = new List<Id>();

		for(OpportunityContactRole oppContactId : [SELECT ContactId FROM OpportunityContactRole WHERE OpportunityId =:opp.Id]){
    		contactIds.add(oppContactId.id);
    	}

    	if(contactIds.size()>0){

			List<Contact> contacts = new List<Contact>();
			for(Id contactId: contactIds ){
				Contact contact = [SELECT Outreach_Status__c FROM Contact WHERE id =:contactId];
				if(contact != null){
					contacts.add(contact);
				}
			}
			List<Contact> updatedContacts = new List<Contact>();

			for(Contact contact: Contacts){
				if(opp.StageName == 'Closed Won'){
					//move the contacts outreach status to either closed won or lost
					contact.Outreach_Status__c = 'Client';
				}
				else if (opp.StageName == 'Closed Lost'){
					contact.Outreach_Status__c = 'Closed Lost';
				}
				else {
					contact.Outreach_Status__c = 'Opportunity';
				}
				updatedContacts.add(contact);
			}
			insert updatedContacts;
		}

	}
}
 
@isTest
private class UpdateOpportunityContactsTest {
	
	@isTest static void test_method_one() {
		// Create New Opp
		Opportunity opp = new Opportunity();
		opp.name = 'Test';
		opp.accountId = '0010v00000KYsWoAAL';
		opp.stageName = 'Demo Completed - DM';
		opp.CloseDate = date.newinstance(2019, 3, 10);
		opp.Role_Persona__c = '-';
		opp.ERP_Sofware__c = 'Microsoft Dynamics';
		opp.Existing_Systems__c = '-';
		opp.DM_Involvement_in_Purchasing__c = '-';
		opp.NextStep = '-';

		insert opp;

		// Create New Account
		Account a = new Account();
		a.name = 'Test';
		a.industry = 'Accounting';
		a.of_Locations__c = 10;


		// create new contact
		Contact con = new Contact();
		con.lastName = 'Test';
		con.accountId = a.id;
		con.title = 'Test';
		con.email = 'test@test.com';

		insert con;


		//Create oppcontactrole
		OpportunityContactRole oppContactRole = new OpportunityContactRole();
		oppcontactRole.OpportunityId = opp.id;
		oppContactRole.ContactId = con.id;
		oppContactRole.isPrimary = true;

		insert oppcontactRole;


		opp.stageName = 'Piloting';

		update opp;

		system.debug(con.Outreach_Status__c);
	}
	
	
}



Not sure what is going on here. I literally am filtering from the beginning to make sure that there won't be any null values.
 
@isTest
private class NumberOfEmailsSchedulableTest {
    
    public static final Integer numberOfAcc = 5;
    public static final Integer numberOfCon = 2;


    static testmethod void schedulerTest() 
       {
               CreateTestAccountsContactsAndTasks(numberOfAcc, numberOfCon);
               
               List<Task> tasks = [SELECT id, subject, ActivityDate, Sequence_Name__c FROM Task];



           String CRON_EXP = '0 0 0 15 3 ? *';
           
           // Create your test data
           Account acc = new Account();
           acc.name= 'test';
           insert
            acc;
           
           Test.startTest();

               String jobId = System.schedule('ScheduleApexClassTest',  CRON_EXP, new NumberOfEmailsSchedulable());
               CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered, NextFireTime FROM CronTrigger WHERE id = :jobId];
               System.assertEquals(CRON_EXP, ct.CronExpression);
               System.assertEquals(0, ct.TimesTriggered);

           Test.stopTest();
           // Add assert here to validate result
       }


       public static void CreateTestAccountsContactsAndTasks(Integer numOfAccounts, Integer contactsPerAccount)
        {

            Database.DMLOptions dml = new Database.DMLOptions(); 
            dml.DuplicateRuleHeader.allowSave = true;

          List<Account> accounts = new List<Account>();

          for(Integer i = 0; i < numOfAccounts; i++)
            {
            // create new account
                  Account newAccount = new Account(
                      Name         = 'Test' + String.valueOf(i),
                      Industry       = 'Accounting',
                      of_Locations__c = 5 + i,
                    sdr_owner__c = userinfo.getuserid()
                  );

                accounts.add(newAccount);
          }

          Database.insert(accounts, dml);

            List<Contact> contacts = new List<Contact>();

          for(Account act: accounts){
              for(Integer i = 0; i < contactsPerAccount; i++)
              {
                // create new contact
                 Contact con = new Contact(
                    LastName   = 'Test',
                    AccountId   = act.id,
                    Outreach_Status__c = 'In Contact',
                    Title     = 'Test' + String.valueOf(i),
                    Email     = 'test@test.com'
                  );

                  contacts.add(con);
              }
          }

           Database.insert(contacts, dml);

           List<Task> tasksToInsert = new List<Task>();

           for(Contact con : contacts)
           {
                   Task regularTask = new Task(
                       whoid = con.Id,
                       ActivityDate = Date.today(),
                       Status = 'Completed'
                   );
                   Task personalizedTask = new Task(
                       Sequence_Name__c = 'personalized',
                       whoid = con.Id,
                       ActivityDate = Date.today(),
                       Status = 'Completed'
                   );
                   Task sequencedTask = new Task(
                       Sequence_Name__c = 'WYWYN19',
                       whoid = con.Id,
                       ActivityDate = Date.today(),
                       Status = 'Completed'

                   );


                   tasksToInsert.add(regularTask);
                   tasksToInsert.add(personalizedTask);
                   tasksToInsert.add(sequencedTask);
           }

           Database.insert(tasksToInsert, dml);
        }

        public static User createUser(String username , String theAlias)
        {
          Integer randomInt = Integer.valueOf(math.rint(math.random()*1000));
            User u = new User
            (
               Alias = theAlias + String.valueOf(randomInt),
              Email = username + String.valueOf(randomInt)+ '@test.com',
            FirstName = 'Joe',
            LastName = username + String.valueOf(randomInt),
            TimeZoneSidKey = 'America/Los_Angeles',
            UserName = username + String.valueOf(randomInt) + '@test.com',
            LocaleSidKey = 'en_US',
            EmailEncodingKey = 'UTF-8',
            LanguageLocaleKey = 'en_US',
            ProfileID = UserInfo.getProfileId()
            );

            insert u;
            return u;
        }
    
}

I user database.Insert and no tasks appear. Why?
trigger UpdateOpportunityContacts on Opportunity (after insert, before update) {


	for(Opportunity opp: Trigger.new){

		List<Id> contactIds = new List<Id>();

		for(OpportunityContactRole oppContactId : [SELECT ContactId FROM OpportunityContactRole WHERE OpportunityId =:opp.Id]){
    		contactIds.add(oppContactId.id);
    	}

    	if(contactIds.size()>0){

			List<Contact> contacts = new List<Contact>();
			for(Id contactId: contactIds ){
				Contact contact = [SELECT Outreach_Status__c FROM Contact WHERE id =:contactId];
				if(contact != null){
					contacts.add(contact);
				}
			}
			List<Contact> updatedContacts = new List<Contact>();

			for(Contact contact: Contacts){
				if(opp.StageName == 'Closed Won'){
					//move the contacts outreach status to either closed won or lost
					contact.Outreach_Status__c = 'Client';
				}
				else if (opp.StageName == 'Closed Lost'){
					contact.Outreach_Status__c = 'Closed Lost';
				}
				else {
					contact.Outreach_Status__c = 'Opportunity';
				}
				updatedContacts.add(contact);
			}
			insert updatedContacts;
		}

	}
}
 
@isTest
private class UpdateOpportunityContactsTest {
	
	@isTest static void test_method_one() {
		// Create New Opp
		Opportunity opp = new Opportunity();
		opp.name = 'Test';
		opp.accountId = '0010v00000KYsWoAAL';
		opp.stageName = 'Demo Completed - DM';
		opp.CloseDate = date.newinstance(2019, 3, 10);
		opp.Role_Persona__c = '-';
		opp.ERP_Sofware__c = 'Microsoft Dynamics';
		opp.Existing_Systems__c = '-';
		opp.DM_Involvement_in_Purchasing__c = '-';
		opp.NextStep = '-';

		insert opp;

		// Create New Account
		Account a = new Account();
		a.name = 'Test';
		a.industry = 'Accounting';
		a.of_Locations__c = 10;


		// create new contact
		Contact con = new Contact();
		con.lastName = 'Test';
		con.accountId = a.id;
		con.title = 'Test';
		con.email = 'test@test.com';

		insert con;


		//Create oppcontactrole
		OpportunityContactRole oppContactRole = new OpportunityContactRole();
		oppcontactRole.OpportunityId = opp.id;
		oppContactRole.ContactId = con.id;
		oppContactRole.isPrimary = true;

		insert oppcontactRole;


		opp.stageName = 'Piloting';

		update opp;

		system.debug(con.Outreach_Status__c);
	}
	
	
}



Not sure what is going on here. I literally am filtering from the beginning to make sure that there won't be any null values.