• Tim May 12
  • NEWBIE
  • 0 Points
  • Member since 2018

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 6
    Replies
I was poking around the new IdeaExchange and came across this component. It is on this page.

https://ideas.salesforce.com/s/post

And looks like this:

User-added image

Can anyone identify it? Is this a custom component for the IdeaExchange? We have a need to do a Category / Sub Category and this is a great replacement to that idea.

Thanks for the help!
Hello,

Before starting, I know about DML operations and the order they should be performed in for test cases. Please do not comment on that. These test cases succeed and have been succeeding in partial and production for over 2 years. 

We recently enabled the Office 365 Outlook Configuration and we started getting test cases failing in production.

Here is the error that we see:
first error: MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): Case, original object: S2XUserMap: []

We saw this was once an issue in Winter'18 but has (apparently) been fixed.

https://trailblazer.salesforce.com/issues_view?id=a1p3A0000008gVyQAI

I think my next step is to go through all of the test cases and use a user and profile that is not mapped in the Outlook Office 365 config. These would be used in just the test case execution. 

Our current test cases were written by persona/profile so that we would test specific areas that our code needed to run against. We do create users and use System.runAs() for that test. 

Does anyone else have this happening to them also? Or did this happen to anyone else?
Hello,

I have implemented a Configurable Self Registration Handler in a Community and used the Auth.ConfigurableSelfRegHandler to extend how the User / Contact is created.

I want the Contact that is made to have a particular RecordType. I updated the method generateContact() to either look for a Contact or create a new Contact. I started with the example code that is created when you enable a handler in the Community.

Here is the error I am getting:

Update failed. First exception on row 0 with id <ID>; first error: MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): User, original object: Contact: []

I know the User object is a setup object but I figured Site.createExternalUser() would be able to bypass that. 

Thanks for the assistance, code is below. 
 
global class AutocreatedConfigSelfReg implements Auth.ConfigurableSelfRegHandler {

    private final Long CURRENT_TIME = Datetime.now().getTime();
    private final String[] UPPERCASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
    private final String[] LOWERCASE_CHARS = 'abcdefghijklmnopqrstuvwxyz'.split('');
    private final String[] NUMBER_CHARS = '1234567890'.split('');
    private final String[] SPECIAL_CHARS = '!#$%-_=+<>'.split('');

    // This method is called once after verification (if any was configured).
    // This method should create a user and insert it.
    // Password can be null.
    // Return null or throw an exception to fail creation.
    global Id createUser(Id accountId, Id profileId, Map<SObjectField, String> registrationAttributes, String password) {
        User u = new User();
        u.ProfileId = profileId;
        for (SObjectField field : registrationAttributes.keySet()) {
            String value = registrationAttributes.get(field);
            u.put(field, value);
        }

        u = handleUnsetRequiredFields(u);
        Contact cnct = generateContact(u, accountId);
        if (cnct.Id != null) {
            u.ContactId = cnct.Id;
        }
        if (String.isBlank(password)) {
            password = generateRandomPassword();
        }
        Site.validatePassword(u, password, password);
        if (u.contactId == null) {
            return Site.createExternalUser(u, accountId, password, True);
        }
        u.languagelocalekey = UserInfo.getLocale();
        u.localesidkey = UserInfo.getLocale();
        u.emailEncodingKey = 'UTF-8';
        u.timeZoneSidKey = UserInfo.getTimezone().getID();
        insert u;
        System.setPassword(u.Id, password);
        return u.id;
    }
    // Method to autogenerate a password if one isn't passed in.
    // By setting a password for a user, we won't send a 
    // welcome email to set the password.
    private String generateRandomPassword() {
        String[] characters = new List<String>(UPPERCASE_CHARS);
        characters.addAll(LOWERCASE_CHARS);
        characters.addAll(NUMBER_CHARS);
        characters.addAll(SPECIAL_CHARS);
        String newPassword = '';
        Boolean needsUpper = true, needsLower = true, needsNumber = true, needsSpecial = true;
        while (newPassword.length() < 50) {
            Integer randomInt = generateRandomInt(characters.size());
            String c = characters[randomInt];
            if (needsUpper && c.isAllUpperCase()) {
                needsUpper = false;
            } else if (needsLower && c.isAllLowerCase()) {
                needsLower = false;
            } else if (needsNumber && c.isNumeric()) {
                needsNumber = false;
            } else if (needsSpecial && !c.isAlphanumeric()) {
                needsSpecial = false;
            }
            newPassword += c; 
        }
        newPassword = addMissingPasswordRequirements(newPassword, needsLower, needsUpper, needsNumber, needsSpecial);
        return newPassword;
    }

    private String addMissingPasswordRequirements(String password, Boolean addLowerCase, Boolean addUpperCase, Boolean addNumber, Boolean addSpecial) {
        if (addLowerCase) {
            password += LOWERCASE_CHARS[generateRandomInt(LOWERCASE_CHARS.size())];
        }
        if (addUpperCase) {
            password += UPPERCASE_CHARS[generateRandomInt(UPPERCASE_CHARS.size())];
        }
        if (addNumber) {
            password += NUMBER_CHARS[generateRandomInt(NUMBER_CHARS.size())];
        }
        if (addSpecial) {
            password += SPECIAL_CHARS[generateRandomInt(SPECIAL_CHARS.size())];
        }
        return password;
    }
   // Generates a random number from 0 up to, but not including, max.
    private Integer generateRandomInt(Integer max) {
        return Math.mod(Math.abs(Crypto.getRandomInteger()), max);
    }

    // Loops over required fields that were not passed in to 
    // set to some default value.
    private User handleUnsetRequiredFields(User u) {
        if (String.isBlank(u.LastName)){
            u.LastName = generateLastName();
        }
        if (String.isBlank(u.Username)) {
            u.Username = generateUsername();
        }
        if (String.isBlank(u.Email)) {
            u.Email = generateEmail();
        }
        if (String.isBlank(u.Alias)) {
            u.Alias = generateAlias();
        }
        if (String.isBlank(u.CommunityNickname)) {
            u.CommunityNickname = generateCommunityNickname();
        }
        return u;
    }
    
    // Method to construct a contact for a user.
    private void generateContact(User u, Id accountId) {
    
        Contact cntct;
        
        // Contacts from the Community will have an additional contact record type
        List<RecordType> contactRecordTypes = [SELECT Id FROM RecordType
                                               WHERE SObjectType = 'Contact' and DeveloperName = 'Community_Contact'];

        // First step, look to see if there is a Contact already
        List<Contact> contactCheck = [SELECT Id, FirstName, LastName, AccountId
                                      FROM Contact WHERE Email = :u.Email];

        // There is one and only one Contact that we found, so return it.
        if (contactCheck.isEmpty() == false && contactCheck.size() == 1) {

            System.debug('Found an existing Contact based on Email Address');

            // Update the contact record with the information from the registration form
            // but make sure to not adjust the Account Id for security reasons.
            cntct = contactCheck.get(0);
            cntct.RecordTypeId = contactRecordTypes.get(0).Id;
            cntct.Active_Contact__c = true;
            cntct.LeadSource = 'Salesforce Community';
            cntct.FirstName = u.FirstName;
            cntct.LastName = u.LastName;
            update cntct;
        
        } else {
        
            // There was no Contact record found, so we need to make one
            // and put it in the right location.

            System.debug('Creating a new Contact');
            cntct.RecordTypeId = contactRecordTypes.get(0).Id;
            cntct.AccountId = accountId;
            cntct.Active_Contact__c = true;
            cntct.LeadSource = 'Salesforce Community';
            cntct.FirstName = u.FirstName;
            cntct.LastName = u.LastName;
            cntct.Email = u.Email;
            insert cntct;

        }

        System.debug('cntct: ' + cntct);
        return cntct;

    }
    // Default implementation to try to provide uniqueness.
    private String generateAlias() {
        String timeString = String.valueOf(CURRENT_TIME);
        return timeString.substring(timeString.length() - 8);
    }
    // Default implementation to try to provide uniqueness.
    private String generateLastName() {
        return 'ExternalUser' + CURRENT_TIME;
    }
    // Default implementation to try to provide uniqueness.
    private String generateUsername() {
        return 'externaluser' + CURRENT_TIME + '@company.com';
    }
    // Default implementation to try to provide uniqueness.
    private String generateEmail() {
        return 'externaluser' + CURRENT_TIME + '@company.com';
    }
    // Default implementation to try to provide uniqueness.
    private String generateCommunityNickname() {
        return 'ExternalUser' + CURRENT_TIME;
    }
}

 
I was poking around the new IdeaExchange and came across this component. It is on this page.

https://ideas.salesforce.com/s/post

And looks like this:

User-added image

Can anyone identify it? Is this a custom component for the IdeaExchange? We have a need to do a Category / Sub Category and this is a great replacement to that idea.

Thanks for the help!
Hello,

Before starting, I know about DML operations and the order they should be performed in for test cases. Please do not comment on that. These test cases succeed and have been succeeding in partial and production for over 2 years. 

We recently enabled the Office 365 Outlook Configuration and we started getting test cases failing in production.

Here is the error that we see:
first error: MIXED_DML_OPERATION, DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): Case, original object: S2XUserMap: []

We saw this was once an issue in Winter'18 but has (apparently) been fixed.

https://trailblazer.salesforce.com/issues_view?id=a1p3A0000008gVyQAI

I think my next step is to go through all of the test cases and use a user and profile that is not mapped in the Outlook Office 365 config. These would be used in just the test case execution. 

Our current test cases were written by persona/profile so that we would test specific areas that our code needed to run against. We do create users and use System.runAs() for that test. 

Does anyone else have this happening to them also? Or did this happen to anyone else?
Can anyone explain what the body attribute is used for.... I want to decrease the size of the FileCard , it is now 20rem and I am not able to change it to 10rem;
HI ,

I am having a small issue with Coverage on a class , little help please . I am using this code to auto add users to public group

Here is the code
 
trigger Add2Publicgroup on User (after insert) {
   AddUser2CommunityPublicGroup.AddToGroups(trigger.newMap.keySet());

}
public class AddUser2CommunityPublicGroup{

@future
public static void AddToGroups(Set<Id> userIds)
{
 //Get the groups that the user should be added to
Group g=[select Id,Name from Group Where Name='Community Users '];

 List<User> users=[Select Id,Name from user Where Id IN :userIds and (Profileid = '00eM0000000Dyrp')];
 
 List<GroupMember>listGroupMember =new List<GroupMember>();  
 // loop the users that have been created
 for (User user : users){
      GroupMember gm= new GroupMember();   // These are the lines that need coverage 
      gm.GroupId=g.id;
      gm.UserOrGroupId = user.id;
      listGroupMember.add(gm);   
 } 
 insert listGroupMember;
}
}
 
@isTest
private class TestAddUser2CommunityPublicGroup {
static testMethod void TestAddUser2CommunityPublicGroup (){
        Profile profile = [select Id from Profile where name = 'Standard User'];
        
        
        List<User> userList = new List<User>{};
        
            for(Integer i = 0; i < 200; i++){
                User u = new User (FirstName = 'Joe' + i);
                          u.LastName = 'Smith' + i;
                          u.Email = 'joe.smith@xxi.com' + i;
                          u.EmailEncodingKey = 'UTF-8';
                          u.LanguageLocaleKey = 'en_US';
                          u.LocaleSidKey = 'en_US';
                          u.CommunityNickname = 'Jjsmith' + i;
                          u.TimeZoneSidKey = 'America/Los_Angeles';
                          u.ProfileId= profile.Id;
                          u.Alias = 'Jsmith';
                          u.Username = 'jjsmith@constantcontact.com' + i;
                          u.CompanyName = 'xxxI';           
                         
                userList.add(u);
            }                       

        test.startTest();        
        insert userList;        
        test.stopTest();

        List<CollaborationGroupMember> cgm = [SELECT id FROM CollaborationGroupMember 
                                                WHERE CollaborationGroup.Name='Community Users'  AND MemberId IN : userList];
            for (CollaborationGroupMember m: cgm ){
                System.assertequals(200,cgm.size());

            }

    }
    }


GroupMember gm= new GroupMember(); 
      gm.GroupId=g.id;
      gm.UserOrGroupId = user.id;
      listGroupMember.add(gm);   

 These are the lines that need coverage .


Thanks 
G
When I try to deploy some component (without any link to chatter) i have the error : 

"ChatterAnswersAuthProviderRegTest.validateCreateUpdateUser(), Details: System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [ProfileId]: [ProfileId] Class.ChatterAnswersAuthProviderRegTest.validateCreateUpdateUser: line 31, column 1"

the test class ask for a ProfileId, while i can't modify it.

Name                            Version       Nom d'espace       Type
API salesforce.com        33.0             API                     salesforce.com
____________________________________________________________________________________________________
@isTest
private class ChatterAnswersAuthProviderRegTest {
  static testMethod void validateCreateUpdateUser() {
    User thisUser = [ select Id from User where Id = :UserInfo.getUserId() ];
    System.runAs ( thisUser ) {
      Auth.UserData userData = new Auth.UserData('testId', 'testFirst', 'testLast',
      'testFirst testLast', 'no-reply@salesforce.com', null, 'testuserlong', 'en_US', 'facebook',
      null, new Map<String, String>{'language' => 'en_US'});
      ChatterAnswersAuthProviderRegistration reg = new ChatterAnswersAuthProviderRegistration();
      Profile[] p = [SELECT Id FROM Profile WHERE Name = 'System Administrator'];
      User[] adminUser = [SELECT Id, Firstname, Lastname FROM User WHERE IsActive = true and ProfileId =: p[0].Id LIMIT 1];
      reg.setSiteAdminUserId(adminUser[0].Id);
      User newUser = reg.createUser(null, userData);
      System.assert(newUser != null, 'A new user should have been created');
      System.assertEquals(newUser.Firstname, 'testFirst', 'First name should have been same');
      System.assertEquals(newUser.Lastname, 'testLast', 'Last name should have been same');
      System.assertEquals(newUser.Email, 'no-reply@salesforce.com', 'Email should have been same');
      
      Contact c = new Contact();
      c.AccountId = (newUser.Username.split('@'))[0];
      c.LastName = 'contactLast';
      insert(c);
      
      newUser.Alias = 'firstusr';
      newUser.TimeZoneSidKey = 'America/Los_Angeles';
      newUser.LocaleSidKey = 'en_US';
      newUser.EmailEncodingKey = 'UTF-8';
      newUser.LanguageLocaleKey = 'en_US';
      newUser.ContactId = c.Id;
      // newUser.ProfileId = [SELECT Id FROM Profile WHERE Name = 'Standard User' LIMIT 1].Id;  [try to add this but i can't save]

      insert(newUser); // <= this is where the error is located :
      
      Auth.UserData updateUserData = new Auth.UserData('testId', 'updatedFirst', 'updatedLast',
      'updatedFirst updatedLast', 'no-reply@new.salesforce.com', null, 'testuserlong', 'en_US', 'facebook',
      null, new Map<String, String>{'language' => 'en_US'});
      reg.updateUser(newUser.Id, null, updateUserData);
      
      User dbUser =  [SELECT Id, Firstname, Lastname, Email FROM User WHERE Id = :newUser.Id];
      System.assertEquals(dbUser.Firstname, 'updatedFirst', 'First name should have been updated');
      System.assertEquals(dbUser.Lastname, 'updatedLast', 'Last name should have been updated');
      System.assertEquals(dbUser.Email, 'no-reply@new.salesforce.com', 'Email should have been updated');
    }
  }
}
________________________________________________________________________________________________

Hi,

 

I'm unable to view "content delivery" option in Customize (in App Setup). Can any one help ???????

 

Thanks in Advance