# frozen_string_literal: true module LeapSalesforce # A test user used to execute tests # TODO: Handle approach of assigning a profile including role hierarchy. # I.e, Sales user and Sales Manager have one role but different position class User # @return [String] Name to identify user by attr_accessor :key # @return [String] Username of User interpreted by ERB (in email address format). Use ERB to define users that can vary # according to environment attr_writer :username # @return [String] Long form description of user. Could be used to reference them where a human # readable format is required such as in a Cucumber test attr_accessor :description # @return [String] Security token of user. Recommend this be set through ENV variable attr_accessor :security_token # @param [String, Symbol] user_params[0] key Key used to identify a test user # @param [String] user_params[1] username Name used to login with user. In email address format. # @param [String] user_params[1] security_token Security token of user def initialize(*user_params, description: nil) self.key = user_params[0] self.username = user_params[1] self.security_token = ENV["#{key}_token"] || nil self.description = description end # @return [User] Salesforce soql object for User def soql_object admin_query_user { ::User.find username: username } end # @return [String] First name of user def first_name admin_query_user { soql_object.first_name } end # Query for user in Salesforce instance # @return [Boolean] Whether Salesforce user exists in environment running against def exists? admin_query_user { ::User.any?(username: username) } end # @return [String] Username of User interpreted by ERB (in email address format). # Use ERB to define users that can vary according to environment def username raise LeapSalesforce::SetupError, "User #{inspect} has no username" if @username.nil? || @username.empty? ERB.new(@username).result(binding) end # @param [String] password Password to set def password=(password) user = ::User.find(username: username) set = ::User.new("Set password for #{username}, #{user.id} to '#{password}'", method: :post, suburl: "sobjects/User/#{user.id}/password", body: { NewPassword: password }) set.successful? end # Using https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_user_password.htm # @todo: Setting temp password is currently not working. Need to investigate # @param [String] password Temporary password to reset to. def reset_password(password = nil) admin_query_user do user = ::User.find(username: username) params = { method: :delete, suburl: "sobjects/User/#{user.id}/password" } params.merge!(body: { NewPassword: password }) if password reset = ::User.new("Reset password for #{username}, #{user.id} to '#{password}'", **params) reset.successful? return reset[:NewPassword] end end # @param [Symbol, String] field Field to check # @param [Object, Regex] criteria Either object with same value or regex that has a match anywhere in string # @return [Boolean] Whether key and criteria match current user def match?(field, criteria) actual_value = send(field.to_s) case criteria when Regexp then !actual_value[criteria].nil? else actual_value == criteria end end private # Execute block as admin user, raising error if User class is not defined def admin_query_user(&block) if defined? ::User Users.execute_as_if_present key: :admin, &block else raise LeapSalesforce::SetupError, "'User' class must be defined " \ " to check presence of user in environment #{LeapSalesforce.environment}" end end end end