I cannot figure out how to create/insert a Customer Portal user record in an Apex Test.
After the necessary google hunt, I came across this piece of Salesforce documentation: Apex Testing with runAs. The Short version: use System.runAs
to avoid mixed DML operations, and make sure your runAs user has a role assigned.
In the Testing with a Portal User section, it has some great example code that I worked into my existing attempts.
I've run into a lot of errors over my fight with this (Mixed DML, stuff with UserRole, etc), and up to this point have been able to solve them. But, this one I cannot seem to resolve. If I continue to beat my head against this, I am afraid my head might crack.
The error I am faced with is as follows:
System.DmlException: Insert failed. First exception on row 0;
first error: PORTAL_NO_ACCESS, no access to portal: []
To ensure my sanity (and that I didn't miss something when I translated the example code into my own style), I copy-pasted the code block in from the salesforce documentation into a new test class, and received the same error.
This is where the error occurs.
knownPortalUser = setupUserWithContact('portal', portalProfile.Id);
// ...
static User setupUserWithContact(String name, Id profileId) {
Contact usersContact;
System.runAs(userWithRole) {
usersContact = new Contact(AccountId = knownAccount.Id, LastName = name);
insert usersContact;
}
User userWithContact = getNewBaseUser(name, profileId);
userWithContact.ContactId = usersContact.Id;
insert userWithContact; // FAILS HERE
return userWithContact;
}
My best guess
My issue lies somewhere with the pre-conditions listed in the aforementioned Testing with a Portal User:
- The organization (your Developer Edition environment, for example) in which this is run MUST have the requisite portal licenses
- The respective portal MUST be enabled in the organization before this test can pass.
- The user that creates the portal user MUST have a Role.
In my Dev Edition Org, I went to Setup | Customize | Customer Portal | Customer Portal Settings
to enable the customer portal. Maybe I did this wrong? Or need to somehow give the test user I am creating permissions to this customer portal?
I do believe that licenses are a non-issue inside a test context @isTest
, because any data created is just blown away in cleanup anyway.
I definitely gave the user that creates the portal user a role. It took me a while to decipher that one fully. Basically, I learned to not attempt to create my own UserRole
record for testing… it was far easier to treat it as I do profiles, and find an existing one.
Anyone think they know what I'm doing wrong? or have some code that is currently working? I'm somewhat afraid that my issues are with org setup, not apex. But I have no clue what they could be…
Some stuff you might want to know:
getNewBaseUser()
just returns an instantiated user object with the obligatory required fields filled out: Name, Username, etc.
userWithRole
and knownAccount
are setup with the following:
// Need a user with a role assigned to be able to create portal users
userWithRole = getNewBaseUser('hasrole', sysAdminProfile.Id);
userWithRole.UserRoleId = someUserRole.Id;
insert userWithRole;
// Avoid Mixed DML
System.runAs(userWithRole) {
// Setup Accounts
knownAccount = new Account(Name = 'Known Account');
insert knownAccount;
}
The profile & role variables are set with the following
portalProfile = [SELECT Id FROM Profile WHERE Name = 'High Volume Customer Portal' LIMIT 1];
sysAdminProfile = [SELECT Id FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
someUserRole = [SELECT Id FROM UserRole LIMIT 1];
Best Answer
First, you'll want to create your RunAs user who should be someone with the profile that has the permissions needed to create accounts and enable your contacts as portal users. Worst case, that can always be a System Administrator.
I usually create a Test Class Utility in most orgs that creates an Admin User for me and a "Standard User" to use for testing. It will have methods that look something like below:
As I noted, I'll do the same or similar for a user with a Standard profile
Once you have your RunAs user, a portal user needs to be created by first creating an Account, then a related contact. Once you do that, you can finally create the portal user. An account needs an own, so in the class below, I created users who would be owners. In this test class the owner of the portal user was going to be changed at a later time. I used code that looks something like below:
Now, on to creating the portal users...
This code didn't cause any mixed DML errors.