Prior to upgrading, you will need to find and record your currently installed version:
Note: if your current version is 2605.0, you are on the most recent package and should proceed to the Application Review Upgrade. See also: How can I tell which version of Communities I'm on when I 'manually' upgrade Communities.
Communities is an unmanaged package. You have two options to upgrade the Communities package:
With this option, you will need to Uninstall the existing Communities package and install the latest package. You will need to reapply any customizations you had previously applied.
Tip: Take screenshots, or copy them to Notepad, to document your page names/assignments before uninstalling Communities.
Upgrading Communities by deleting the package and reinstalling.
This is your "ending version" (i.e., the version you want to upgrade to). You can select any version that's higher than your current package version. Packages are cumulative, meaning the upgraded package you select includes all features from previous packages. For example, if you're upgrading from Package A to Package D, that package includes all features from Packages B and C.
If you are unsure about what customizations you have, you can save the Visualforce pages as text documents to use as a backup after upgrading. You can then use a free tool like textcompare.com to view the differences between your 'backup' file and the updated components.
CAPTCHA was introduced in the 1902.0 version of Communities. Follow the steps to Configure CAPTCHA for the Online Application.
Do not proceed to Upgrade Path Option 2. You may proceed to the Application Review Upgrade.
If you completed all the steps for Upgrade Path Option 1, you do not need to complete the following changes. With Option 2, you do not install a new package but manually apply the latest changes to the unmanaged package using the information below. If you choose this option, you must complete the steps in a sandbox environment before pushing to production via an Outbound Change Set.
Your starting package version number determines what, if any, additional configuration steps may be required. Please click the link for your initial version number (identified in Step 1 above) from the list below. You will be directed to the first step required for your upgrade and should complete all steps that follow. If you do not see your version number listed, please get in touch with the TargetX Support team.
|
Starting Version |
Ending Version |
Configuration Steps by Release These are the steps you need to complete, from the starting version to the ending version. For example, if your starting version is 2205.0 (May '22) and you're upgrading to 2208.6 (August '22), you'll need to complete the configuration steps for 2206.3 (June '22), 2207.0 (July '22), and 2208.6 (August '22). |
|---|---|---|
| 2411.1 | 2505.0 (May '25) |
Item 1: Update TX_UniqueNicknameTests Apex Class Each block listed below is considered a complete unit. If you notice any discrepancies, replace the entire block with the recommended version and verify its functionality in a sandbox environment.
System.assert(nickname2 + '_amamama.com' == [select CommunityNickname from User where Id =:u2.Id].CommunityNickname);
System.assert(([select CommunityNickname from User where Id = :u2.Id].CommunityNickname).StartsWith(nickname2)); Note: if the above lines don’t exist in your Apex class version, follow these steps:
nickname = [select CommunityNickname from User where Id = :u2.Id].CommunityNickname; System.assertEquals(40, nickname.length());
System.assert(([select CommunityNickname from User where Id = :u2.Id].CommunityNickname).StartsWith(nickname2)); Item 2: Update TX_CommunitiesSelfReg Visualforce Page Each block listed below is considered a complete unit. If you notice any discrepancies, replace the entire block with the recommended version and verify its functionality in a sandbox environment.
<apex:commandButton action="{!registerUser}" styleClass="targetx-button" value="{!$Label.site.submit}" id="submit" onclick="this.onclick=function(){return false;}"/>
<apex:commandButton action="{!registerUser}" styleClass="targetx-button" value="{!$Label.site.submit}" id="submit" status="submitStatus"/>
<apex:actionStatus id="submitStatus">
<apex:facet name="start">
<script>
var submitBtn = document.getElementById('submit');
if (submitBtn) {
submitBtn.disabled = true;
}
</script>
</apex:facet>
<apex:facet name="stop">
<script>
var submitBtn = document.getElementById('submit');
if (submitBtn) {
submitBtn.disabled = false;
}
</script>
</apex:facet>
</apex:actionStatus>
Item 3: Update API Version on Apex Classes
Item 4: Update API Version on Apex Triggers
Item 5: Update API Version on Visualforce Pages
Item 6: Update API Version on Visualforce Components
|
| 2505.0 | 2602.0 (February '26) |
Item 1: Update TX_CommunitiesSelfRegController Apex class
public String accountId {get;set;}
public String accountId {get;set {accountId = value?.trim().escapeHtml4().escapeJava(); } }
Example: |
| 2602.0 | 2605.0 (May '26) |
*The May ’26 Communities update is only necessary if you have previously implemented UTM Tracking. Item 1: Update TX_TestCommunities Apex class (Optional*)
Replace the contents with the following code or download it here: @isTest(SeeAllData=false)
public with sharing class TX_TestCommunities {
public static testMethod void testCommunitiesLoginController () {
TX_CommunitiesLoginController controller = new TX_CommunitiesLoginController();
System.assertNotEquals(null, controller.forwardToAuthPage());
}
public static testMethod void testCommunitiesSelfRegController() {
TX_CommunitiesSelfRegController controller = new TX_CommunitiesSelfRegController();
controller.firstName = 'FirstName';
controller.lastName = 'LastName';
controller.email = 'test@force.com';
controller.communityNickname = 'test';
controller.tokenValue = 'testcode';
// registerUser will always return null when the page isn't accessed as a guest user
System.assert(controller.registerUser() == null);
controller.password = 'abcd1234';
controller.confirmPassword = 'abcd123';
Account a = new Account(Name='Test') ;
insert a ;
controller.accountId = a.Id ;
System.assert(controller.registerUser() == null);
TX_SiteLoginController s = new TX_SiteLoginController ();
s.username = 'test@salesforce.com';
s.password = '123456';
System.assertEquals(s.login(),null);
}
public static testMethod void testCommunitiesLandingController() {
// Instantiate a new controller with all parameters in the page
TX_CommunitiesLandingController controller = new TX_CommunitiesLandingController();
system.assertNotEquals(null,controller.forwardToStartPage());
}
public static testMethod void testForgotPasswordController() {
// Instantiate a new controller with all parameters in the page
TX_ForgotPasswordController controller = new TX_ForgotPasswordController();
controller.username = 'test@salesforce.com';
System.assertEquals(controller.forgotPassword(),null);
}
public static testMethod void testChangePasswordController() {
// Instantiate a new controller with all parameters in the page
TX_ChangePasswordController controller = new TX_ChangePasswordController();
controller.oldPassword = '123456';
controller.newPassword = 'qwerty1';
controller.verifyNewPassword = 'qwerty1';
System.assertEquals(controller.changePassword(),null);
}
public static testMethod void testMyProfileSetContactFields() {
User u = [select title, firstname, lastname, email, phone, mobilephone, fax, street, city, state, postalcode, country
FROM User WHERE id =: UserInfo.getUserId()];
Contact c = new Contact();
TX_MyProfilePageController.setContactFields(c, u);
System.assertEquals(c.firstname, u.firstname, 'firstname should have been set as the firstname of the user for the contact');
System.assertEquals(c.lastname, u.lastname, 'lastname should have been set as the lastname of the user for the contact');
}
public static testMethod void testMyProfileSave() {
// Modify the test to query for a portal user that exists in your org
List<User> existingPortalUsers = [SELECT id, profileId, userRoleId FROM User WHERE UserRoleId <> null AND UserType='CustomerSuccess'];
if (existingPortalUsers.isEmpty()) {
User currentUser = [select id, title, firstname, lastname, email, phone, mobilephone, fax, street, city, state, postalcode, country
FROM User WHERE id =: UserInfo.getUserId()];
TX_MyProfilePageController controller = new TX_MyProfilePageController();
System.assertEquals(currentUser.Id, controller.getUser().Id, 'Did not successfully load the current user');
System.assert(controller.getIsEdit() == false, 'isEdit should default to false');
controller.edit();
System.assert(controller.getIsEdit() == true);
controller.cancel();
System.assert(controller.getIsEdit() == false);
Contact c = new Contact();
c.LastName = 'TestContact';
insert c;
c.title = currentUser.title;
c.firstname = currentUser.firstname;
c.lastname = currentUser.lastname;
c.email = currentUser.email;
c.phone = currentUser.phone;
c.mobilephone = currentUser.mobilephone;
c.fax = currentUser.fax;
c.mailingstreet = currentUser.street;
c.mailingcity = currentUser.city;
c.mailingstate = currentUser.state;
c.mailingpostalcode = currentUser.postalcode;
c.mailingcountry = currentUser.country;
controller.save();
System.assert(Page.TX_ChangePassword.getUrl().equals(controller.changePassword().getUrl()));
} else {
User existingPortalUser = existingPortalUsers[0];
String randFax = Math.rint(Math.random() * 1000) + '5551234';
System.runAs(existingPortalUser) {
TX_MyProfilePageController controller = new TX_MyProfilePageController();
System.assertEquals(existingPortalUser.Id, controller.getUser().Id, 'Did not successfully load the current user');
System.assert(controller.getIsEdit() == false, 'isEdit should default to false');
controller.edit();
System.assert(controller.getIsEdit() == true);
controller.cancel();
System.assert(controller.getIsEdit() == false);
controller.getUser().Fax = randFax;
controller.save();
System.assert(controller.getIsEdit() == false);
}
// verify that the user and contact were updated
existingPortalUser = [Select id, fax, Contact.Fax from User where id =: existingPortalUser.Id];
System.assert(existingPortalUser.fax == randFax);
System.assert(existingPortalUser.Contact.fax == randFax);
}
}
public static testMethod void testSiteLoginController () {
// Instantiate a new controller with all parameters in the page
TX_SiteLoginController controller = new TX_SiteLoginController ();
controller.username = 'test@salesforce.com';
controller.password = '123456';
System.assertEquals(controller.login(),null);
PageReference pageRef = Page.TX_SiteLogin;
Test.setCurrentPage(pageRef);
ApexPages.currentPage().getParameters().put('startURL','testurl');
System.PageReference selfRegURL = controller.getSelfRegURL();
System.assert(selfRegURL != null);
}
public static testMethod void testMore() {
ApexPages.currentPage().getParameters().put('username', 'test') ;
TX_CommunitiesSelfRegController src = new TX_CommunitiesSelfRegController() ;
src = new TX_CommunitiesSelfRegController(new TargetX_Base.TX_CommunitiesBase()) ;
Account a = new Account(Name='Test') ;
insert a ;
src.firstName = 'FirstNames';
src.lastName = 'LastName';
src.email = 'test@force.com';
src.insertContactFirst() ;
src.password = 'abcd1234';
src.confirmPassword = 'abcd1234';
src.communityNickname = '' ;
src.accountId = a.Id ;
System.assert(src.registerUser() == null);
// We can't actually assert the welcome email sending, but we can test the class
TX_CommunitiesSelfRegConfirmController asdf = new TX_CommunitiesSelfRegConfirmController() ;
TX_CommunitiesSelfRegConfirmController asdf2 = new TX_CommunitiesSelfRegConfirmController(new TargetX_Base.TX_CommunitiesBase()) ;
}
public static testMethod void testDupe() {
Profile[] profiles = [SELECT Id FROM Profile WHERE Name = 'System Administrator'] ;
UserRole ur = new UserRole(Name = 'X-TESTING-CEO-00');
insert ur;
User u = new User() ;
u.Alias = 'Admin' ;
u.LastName = 'Admin' ;
u.Email = 'testDupe@test.test' ;
u.Username = 'testDupe@test.test' ;
u.CommunityNickname = 'TestCodeAdmin' ;
u.ProfileId = profiles[0].Id ;
u.UserRoleId = ur.Id ;
u.TimeZoneSidKey = 'America/New_York' ;
u.LocaleSidKey = 'en_US' ;
u.EmailEncodingKey = 'ISO-8859-1' ;
u.LanguageLocaleKey = 'en_US' ;
insert u ;
System.runAs(u) {
TX_CommunitiesSelfRegController controller = new TX_CommunitiesSelfRegController();
controller.firstName = 'FirstName';
controller.lastName = 'LastName';
controller.email = 'testDupe@test.test';
controller.communityNickname = 'test';
controller.password = 'abcd1234';
controller.confirmPassword = 'abcd1234';
Account a = new Account(Name='Test', OwnerId=u.Id) ;
insert a ;
controller.accountId = a.Id ;
System.assert(controller.registerUser() == null);
System.assertEquals(Label.Duplicate_User_Exists, ApexPages.getMessages()[0].getDetail()) ;
}
}
public static testMethod void testNoRole() {
Profile[] profiles = [SELECT Id FROM Profile WHERE Name = 'System Administrator'] ;
User u = new User() ;
u.Alias = 'Admin' ;
u.LastName = 'Admin' ;
u.Email = 'noRole@test.test' ;
u.Username = 'noRole@test.test' ;
u.CommunityNickname = 'TestCodeAdmin' ;
u.ProfileId = profiles[0].Id ;
u.TimeZoneSidKey = 'America/New_York' ;
u.LocaleSidKey = 'en_US' ;
u.EmailEncodingKey = 'ISO-8859-1' ;
u.LanguageLocaleKey = 'en_US' ;
insert u ;
TX_CommunitiesSelfRegController controller = new TX_CommunitiesSelfRegController();
controller.firstName = 'FirstName';
controller.lastName = 'LastName';
controller.email = 'testDupe@test.test';
controller.communityNickname = 'test';
controller.password = 'abcd1234';
controller.confirmPassword = 'abcd1234';
Account a = new Account(Name='Test') ;
a.OwnerId = u.Id ;
insert a ;
// this should help people who have a workflow set up to make HEDA work
a.OwnerId = u.Id ;
update a ;
controller.accountId = a.Id ;
System.assert(controller.registerUser() == null);
Boolean foundError = false;
for(ApexPages.Message message: ApexPages.getMessages()) {
if(message.getDetail() == 'Account Owner Missing Role') {
foundError = true;
break;
}
}
System.assert(foundError, '\'Account Owner Missing Role\' error not found') ;
}
public static testMethod void testUpdateContactAccount() {
// Need to make sure role is set on the user
UserRole ur = new UserRole(Name = 'X-TESTING-CEO-00');
insert ur;
User u = new User(Id=UserInfo.getUserId(), UserRoleId=ur.Id);
update u;
System.runAs(u) {
TX_CommunitiesSelfRegController controller = new TX_CommunitiesSelfRegController();
controller.firstName = 'FirstName';
controller.lastName = 'LastName';
controller.email = 'testDupe@test.test';
controller.communityNickname = 'test';
controller.password = 'abcd1234';
controller.confirmPassword = 'abcd1234';
Account a = new Account(Name='Test') ;
insert a ;
controller.accountId = a.Id ;
Account b = new Account(Name='Test2') ;
insert b ;
Contact c = new Contact(AccountId=b.Id, LastName='LastTest', Email='testDupe@test.test') ;
insert c ;
System.assert(controller.registerUser() == null);
}
// Can't actually assert this because the database ends up getting rolled back
//Contact c2 = [SELECT Id, AccountId FROM Contact WHERE Email = 'testDupe@test.test'][0] ;
//System.assertEquals(c2.AccountId, a.Id) ;
}
public static testMethod void testExceptionCatch() {
TX_CommunitiesSelfRegController controller = new TX_CommunitiesSelfRegController();
controller.accountId = 'BadId';
System.assertEquals(null, controller.registerUser());
}
}
Item 2: Update the TX_CommunitiesSelfRegController apex class (Optional*)
|
| Upgrading from 2206.0 | Visualforce Page:
|
| Upgrading from 2209.0 | Apex Class:
|
| Upgrading from 2210.0 | Component:
Visualforce Page:
|
| Upgrading from 2211.0 |
Apex Class:
|
| Upgrading from 2402.0 |
Apex Class:
|
| Upgrading from 2411.1 |
Apex Classes:
Apex Triggers:
Visualforce Pages:
Visualforce Components:
|
| Upgrading from 2505.0 |
Apex class:
|
| Upgrading from 2602.0 |
Apex class:
|
Note: If you need to create the additional Apex Classes from the article listed above, check the boxes for those as well:
Note: Uploading the Change Set will send it to the Target Org; it will NOT make changes in your production Org until you Deploy the Change Set.
Notes:
No further configuration is required. You may proceed to the Application Review Upgrade.