Visualforce email template unit test - salesforce

I have a trigger that sends an email using a VF template. I'm trying to write a unit test for that code, but keep running into a problem when trying to create the test data.
Here is my test method:
static TestMethod void testQuestionAttachment(){
Id profileId = SYSTEM_ADMIN_PROFILE_ID;
List<User> users = TestUtils.createUsers(profileId, 1);
insert users;
string templateText = '<messaging:emailTemplate subject="{!relatedTo.Name}" recipientType="User" relatedToType="Cutom_Object__c"><messaging:htmlEmailBody ><ul><li>test content</li></ul></messaging:htmlEmailBody></messaging:emailTemplate>';
EmailTemplate template = new EmailTemplate(
developerName = 'TestEmailVFTemplate',
TemplateType= 'visualforce',
FolderId = users[0].Id,
Name = 'TestEmailVFTemplate',
IsActive = true);
template.HtmlValue = templateText;
template.Body = templateText;
System.runAs(users[0]){
insert template;
}
...
And it fails with FIELD_INTEGRITY_EXCEPTION, <messaging:emailTemplate> is required and must be the outermost tag in the markup at line 1 column 1: [Markup].
I really don't understand why this isn't working. I must be missing something...

The issue is with your TemplateType = 'Visualforce'. Instead change it to template.Markup=templateText;. Markup field can be used to assign the body of visualforce template. I tried it in my test class.
Refer below example:
static #isTest void myTest () {
Profile pf = [SELECT Id,Name FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
User usr = new User(
Alias = 'usralias',
Email = 'theuser#email.com',
Emailencodingkey = 'UTF-8',
Lastname = 'user_lastname',
Languagelocalekey = 'en_US',
Localesidkey = 'en_US',
Profileid = pf.Id,
Timezonesidkey = 'America/Los_Angeles',
Username = Math.random() + 'test#testuser.com',
CompanyName = 'the company',
UserRoleId='00E28000000zqCy'
);
insert usr;
string templateText = '<messaging:emailTemplate subject="{!relatedTo.Name}" recipientType="User" relatedToType="Custom_Object__c"><messaging:htmlEmailBody ><ul><li>test content</li></ul></messaging:htmlEmailBody></messaging:emailTemplate>';
EmailTemplate template = new EmailTemplate(DeveloperName = 'TestEmailVFTemplate', TemplateType= 'Visualforce', FolderId = UserInfo.getUserId(),
Name = 'TestEmailVFTemplate',
IsActive = true);
template.Markup=templateText;
System.runAs(usr){
insert template;
}
}

Related

Salesforce- retrieve Contact.opportunites

Here is snippet I am using in my anonymous window . Purpose is to retrieve Opportunities of a contact. Even after adding opportunity contact role , contact.Opportunities.size is resulting in zero (last debug line). Am I missing something ? you may use the below code directly.
Update: able to get size now but same logic doesn't work for code coverage in test class . details listed below:
Only 'if' part of controller is covered and 'else' part is never covered even though size of contact.opportunities is more than 0.
Controller method :
public PageReference sendingEmail() {
//contact1 has query records
sizeVar = contact1.Opportunities.size();
if(contact1.npo02__OppAmountLastYear__c>0 ) {
if(sizeVar==0) {
// if size is 0 then navigate to a particular vf page
PageReference pr = Page.NoDonationOrNoEmail;
pr.getParameters().put('id',(String)contact1.id);
pr.setRedirect(true);
return pr;
}
else
{ //when contact.opportunities size is more than 0 then navigate to
other vf page.
PageReference pr1 = Page.NoPrint;
pr1.getParameters().put('id',(String)contact1.id);
pr1.setRedirect(true);
return pr1;
}
} return null;
}
Test Class:
//creating account
Account a = new Account();
a.Name = 'Test Co.';
a.BillingStreet = '298 S. Ringo Street';
a.BillingCity = 'Little Rock';
insert a;
//Creating contact
Contact contact1 = new Contact();
contact1.FirstName = 'Paul';
contact1.LastName = 'Test';
contact1.AccountId = a.id;
contact1.npo02__OppAmountLastYear__c=100;
insert contact1;
//creating opportunity
Opportunity o = new Opportunity();
o.RecordType = [SELECT Id, Name, DeveloperName FROM RecordType
WHERE Name = 'Membership' LIMIT 1];
o.Name = 'New Record';
o.StageName = 'Posted';
o.AccountId = contact1.AccountId;
o.CloseDate = Date.today();
o.Description = 'Test Record';
insert o;
//creating opportunity contact role
OpportunityContactRole ocr = new OpportunityContactRole();
ocr.ContactId = contact1.Id;
ocr.OpportunityId = o.Id;
ocr.IsPrimary = TRUE;
ocr.Role = 'Decision Maker';
insert ocr;
System.debug('created opportunity contact role for primary');
Update o;
contact1 = [SELECT Id, Name,(SELECT id FROM opportunities) FROM
Contact WHERE Id=:contact1.Id];
PageReference pr = Page.NoPrint;
pr.getParameters().put('id', String.valueOf(contact1.id));
Test.setCurrentPage(pr);
ApexPages.StandardController cont5 = new
ApexPages.StandardController(contact1);
BulkEmailController testAccPlan = new
BulkEmailController(cont5);
testAccPlan.sendingEmail();
When you create and insert a record, you don't get formula fields nor you can navigate lookup. The same goes with child relationship.
You have to query the fields you need.
Change Update contact1; to contact1 = [SELECT Id, (SELECT Id FROM Opportunities) FROM Contact WHERE Id = :contact1.Id]; and the last debug line will print 1.

Upload File (image/audio/video) to FeedItem in chunks

​public static String upload(String folderId, String documentId, String fileName, String base64BlobValue) {
if(documentId == '' || documentId == null) {
Document document = new Document(Name=fileName, FolderId=folderId, Body=EncodingUtil.Base64Decode(base64BlobValue), IsPublic=true);
insert document;
return document.Id;
} else {
Document document = [select Id, Body from Document where Id = :documentId];
update new Document(Id = documentId, Body = EncodingUtil.Base64Decode(EncodingUtil.Base64Encode(document.Body) + base64BlobValue));
return documentId;
}
}
I'm trying to upload files (image/audio/video) to FeedItem in chunks, the above example shows how I'm doing the same while writing to a document. But If try to do the same with FeedItem it says "FeedItem.ContentData is not writeable" so I've tried the following code:
FeedItem imageFeedItem = [select Id, ContentData, RelatedRecordId from FeedItem where Id = :imageFeedItemId];
ContentVersion content = new ContentVersion();
content.versionData = EncodingUtil.Base64Decode(EncodingUtil.Base64Encode(imageFeedItem.ContentData) + base64BlobValue);
content.pathOnClient = fileName;
content.ContentDocumentId = [Select ContentDocumentId from ContentVersion where id=:imageFeedItem.RelatedRecordId].ContentDocumentId;
insert content;
But this creates ContentVersions of incomplete chunks. Any pointers on how can I achieve this more neat.
Thanks
You can try setting IsMajorVersion to false
ContentVersion content = new ContentVersion();
content.versionData = EncodingUtil.Base64Decode(EncodingUtil.Base64Encode(imageFeedItem.ContentData) + base64BlobValue);
content.pathOnClient = fileName;
content.IsMajorVersion = false;
content.ContentDocumentId = [Select ContentDocumentId from ContentVersion where id=:imageFeedItem.RelatedRecordId].ContentDocumentId;
insert content;
I hope this help!

Share primary Contacts along with the Opportunity using Sales Force to Sales Force Connector

Lead - gets converted to an Account , Contact and an Opportunity
I developed a trigger which shares an Opportunity and related Account with another Org of ours, and the piece i am missing is sharing the Contact along with this . Need some help for sharing the contact also.
Trigger autoforwardOpportunity on Opportunity(after insert) {
String UserName = UserInfo.getName();
String orgName = UserInfo.getOrganizationName();
List<PartnerNetworkConnection> connMap = new List<PartnerNetworkConnection>(
[select Id, ConnectionStatus, ConnectionName from PartnerNetworkConnection where ConnectionStatus = 'Accepted']
);
System.debug('Size of connection map: '+connMap.size());
List<PartnerNetworkRecordConnection> prncList = new List<PartnerNetworkRecordConnection>();
for(Integer i =0; i< Trigger.size; i++) {
Opportunity Opp = Trigger.new[i];
String acId = Opp.Id;
System.debug('Value of OpportunityId: '+acId);
for(PartnerNetworkConnection network : connMap) {
String cid = network.Id;
String status = network.ConnectionStatus;
String connName = network.ConnectionName;
String AssignedBusinessUnit = Opp.Assigned_Business_Unit__c;
System.debug('Connectin Details.......Cid:::'+cid+'Status:::'+Status+'ConnName:::'+connName+','+AssignedBusinessUnit);
if(AssignedBusinessUnit!=Null && (AssignedBusinessUnit.equalsIgnoreCase('IT') || AssignedBusinessUnit.equalsIgnoreCase('Proservia'))) {
// Send account to IT instance
PartnerNetworkRecordConnection newAccount = new PartnerNetworkRecordConnection();
newAccount.ConnectionId = cid;
newAccount.LocalRecordId = Opp.AccountId;
newAccount.SendClosedTasks = true;
newAccount.SendOpenTasks = true;
newAccount.SendEmails = true;
newAccount.RelatedRecords = 'Contact';
System.debug('Inserting New Record'+newAccount);
insert newAccount;
// Send opportunity to IT instance
PartnerNetworkRecordConnection newrecord = new PartnerNetworkRecordConnection();
newrecord.ConnectionId = cid;
newrecord.LocalRecordId = acId;
newrecord.SendClosedTasks = true;
newrecord.SendOpenTasks = true;
newrecord.SendEmails = true;
//newrecord.ParentRecordId = Opp.AccountId;
System.debug('Inserting New Record'+newrecord);
insert newrecord;
}
}
}
}
newrecord.RelatedRecords = 'Contact,Opportunity'; //etc

First error: INVALID_CROSS_REFERENCE_KEY, Assigned To ID: owner cannot be blank: [OwnerId]

I am writing a test for my controller. For that I have to insert an event in the test database.
My test method is:
static TestMethod void Test1_TestInsertWithValue()
{
Meeting_Master__c master = new Meeting_Master__c();
Event event = new Event();
Profile p = [SELECT Id From Profile WHERE Name='Standard User'];
User u2 = new User(Alias = 'newUser', Email = 'newuser#testorg.com', EmailEncodingKey = 'UTF-8', LastName = 'Testing',
LanguageLocaleKey = 'en_US', LocaleSidKey='America/Los_Angeles', UserName='newuser#testorg.com', ProfileId=p.Id);
event.OwnerId = u2.Id;
event.StartDateTime = datetime.newInstance(2008, 12, 1);
event.EndDateTime = datetime.newInstance(2008, 12, 30);
event.subject = 'call';
event.WhatId = master.Id;
insert master;
insert event;
...........
}
When the insert event occurs, I am facing this error:
System.DmlException: Insert failed. First exception on row 0; first error: INVALID_CROSS_REFERENCE_KEY, Assigned To ID: owner cannot be blank: [OwnerId]
How do I rectify this error?
You forgot to insert u2 before the line event.OwnerId =u2.Id;.
As the first option you can insert test user:
#isTest
private class test{
static TestMethod void Test1_TestInsertWithValue() {
Meeting_Master__c master=new Meeting_Master__c();
Event event =new Event();
Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
User u2 =new User( Alias = 'newUser1' ,
Email ='newuser123#testorg.com',
EmailEncodingKey = 'UTF-8',
LastName = 'Testing',
LanguageLocaleKey='en_US',
LocaleSidKey='en_US', // changed for to avoid: INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST, Locale: bad value for restricted picklist field: America/Los_Angeles
UserName='newuser123#testorg.com',
ProfileId=p.Id,
TimeZoneSidKey = 'America/Los_Angeles');
insert u2;
event.OwnerId = u2.Id;
event.StartDateTime = datetime.newInstance(2008, 12, 1);
event.EndDateTime = datetime.newInstance(2008,12,10); // changed to 10-12-2008 for to avoid: FIELD_INTEGRITY_EXCEPTION, Event duration can not be longer than 14 days
event.subject='call';
event.WhatId=master.Id;
Insert master;
insert event;
}
}
The second option is a trying to use System.runAs()
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_tools_runas.htm
#isTest
private class test{
static TestMethod void Test1_TestInsertWithValue() {
Meeting_Master__c master=new Meeting_Master__c();
Event event =new Event();
Profile p=[SELECT Id From Profile WHERE Name='Standard User'];
User u2 =new User( Alias = 'newUser1' ,
Email ='newuser123#testorg.com',
EmailEncodingKey = 'UTF-8',
LastName = 'Testing',
LanguageLocaleKey='en_US',
LocaleSidKey='en_US',
UserName='newuser123#testorg.com',
ProfileId=p.Id,
TimeZoneSidKey = 'America/Los_Angeles');
Insert master;
System.runAs(u2) {
event.StartDateTime = datetime.newInstance(2008, 12, 1);
event.EndDateTime = datetime.newInstance(2008,12,10);
event.subject='call';
event.WhatId=master.Id;
insert event;
}
}
}

Create a User with aspnet schema and UserRepository/ EF ASPNET MVC 4

I have a question for creating a user in my bd.
I use a userRepository for creating a user in aspnet schema.
So for creating a user, i must create one row in aspnet_user and aspnet_membership table
the userId is an identity key so it's my bdd who manage this... So for now, i have this code in my UserRepository class :
public aspnet_User CreateUser(string username, string password, string email)
{
using (WebsiteEntities db = new WebsiteEntities())
{
aspnet_User user = new aspnet_User();
user.UserName = username;
user.Email = email;
db.aspnet_User.Add(user);
db.SaveChanges();
**User u = GetUser(username);**
Aspnet_Membership member = new Aspnet_Membership();
member.UserId = u.UserId;
member.PasswordSalt = CreateSalt();
member.Password = CreatePasswordHash(password, user.PasswordSalt);
member.CreateDate = DateTime.Now;
member.IsApproved = false;
member.IsLockedOut = false;
member.LastLockoutDate = DateTime.Now;
member.LastLoginDate = DateTime.Now;
db.aspnet_Membership.Add(member);
db.SaveChanges();
return u;
}
}
But, i don't think that it's a good way for creating a user with a foreign key between aspnet_User and aspnet_Membership ... Here, i have a username who is unique but if it wasn't i don't know how i will done ...
Someone can help me ? thank for your helps
You should add the new member in through the Membership Framework. After that is done get the UserId to use as the foreign key.
This is what I do, it may not be ideal but it works for me:
var createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email);
if (createStatus == System.Web.Security.MembershipCreateStatus.Success)
{
var newUser = new User();
newUser.DisplayName = model.DisplayName;
newUser.Email = model.Email;
newUser.UserUnits.Add(new UserUnit { UnitId = model.UnitId, Status = (int)UserUnitStatus.Request });
using(var db = new Entities())
{
var temp = db.aspnet_Membership.Single(a => a.LoweredEmail == newUser.Email.ToLower());
newUser.GUID = temp.UserId;
db.Users.AddObject(newUser);
try
{
db.SubmitChanges()
}
catch
{
MembershipService.DeleteUser(model.UserName);
throw;
}
return RedirectToAction("Welcome");
}

Resources