RSpec.configure do |config| config.around(:each, mock_auth: ->(v) { !!v }) do |example| options = example.metadata[:mock_auth] authentication_type = if options.is_a?(Hash) && options[:type] options[:type] else :standard end klass = case options when TrueClass User when Hash options[:class] || User else options end underscored_class_name = klass. name[/(?:.*::)?(\w+)\z/, 1]. gsub(/([a-z])([A-Z])/, '\1_\2'). downcase current_class_method = if options.is_a?(Hash) && options[:method] options[:method] else :"current_#{underscored_class_name}" end instance = if options.is_a?(Hash) && options[:strategy] == :instance klass.new else FactoryGirl.create(underscored_class_name.to_sym) end inferred_auth_method = if options.is_a?(Hash) && options[:authentication_method] options[:authentication_method] else :"authenticate_#{underscored_class_name}!" end authentication_controller_class = if example.metadata[:type] == :controller described_class else ApplicationController end authentication_controller_instance = authentication_controller_class.new authentication_successful = if options.is_a?(Hash) && options.key?(:status) options[:status] == :authorized else true end authentication_result = authentication_successful ? instance : nil if authentication_type == :standard authentication_method = if authentication_controller_instance.respond_to?(inferred_auth_method, true) inferred_auth_method elsif authentication_controller_instance.respond_to?(:authenticate, true) :authenticate end authentication_controller_class.__send__(:define_method, authentication_method) { authentication_successful } authentication_controller_class.__send__(:define_method, current_class_method) { authentication_result } authentication_controller_class.__send__(:helper_method, current_class_method) example.example_group_instance.class.let(current_class_method) { authentication_result } example.run authentication_controller_class.__send__(:remove_method, current_class_method) elsif authentication_type == :json_web_token @token_data = if options.is_a?(Hash) && options[:data] options[:data] else [ { 'iss' => 'rspectacular', 'own' => instance['account_id'] || instance['id'], 'sub' => example.file_path, 'aud' => 'rspec', 'exp' => 1.day.from_now.utc.to_i, 'nbf' => 1.day.ago.utc.to_i, 'iat' => Time.now.utc.to_i, 'jti' => SecureRandom.uuid, 'sid' => instance['account_id'] || instance['id'], 'rol' => options[:role] || 'basic', }, { 'typ' => 'JWT', 'cty' => 'application/json-web-token', }, ] end example.example_group_instance.class.let(current_class_method) { authentication_result } example.run else fail 'You must specify a valid type for the :mock_auth metadata' end instance.delete unless options.is_a?(Hash) && options[:strategy] == :instance end config.before(:each, mock_auth: ->(v) { !!v }) do |_example| request.env['X_DECRYPTED_JSON_WEB_TOKEN'] = @token_data end end