# frozen_string_literal: true # rubocop:disable Layout/IndentHash RSpec.configure do |config| config.around(:each, :authentication => lambda { |v| !!v }) do |example| config.rspeckled_logger.debug("Around Each - Start - #{__FILE__}") options = if example.metadata[:authentication].is_a?(::Hash) example.metadata[:authentication] else { :token => { :roles => example.metadata[:authentication], }, } end options[:class] ||= described_class .name[/\A([^:]+)::/, 1] .concat('::User') .constantize class_name_underscored = options[:class] .name[/(?:.*::)?(\w+)\z/, 1] .gsub(/([a-z])([A-Z])/, '\1_\2') .downcase defaults = { :type => :json_web_token, :authentication_method => :"authenticate_#{class_name_underscored}!", :class_instance_overrides => {}, :class_instance_traits => {}, :method => :"current_#{class_name_underscored}", :strategy => :factory, :successful? => true, :token => { :roles => 'standard', }, } options = defaults.deep_merge(options) instance = case options[:strategy] when :factory ::FactoryBot.create(class_name_underscored.to_sym, *options[:class_instance_traits], options[:class_instance_overrides]) when :instance options[:class].new(options[:class_instance_overrides]) end authentication_result = options[:successful?] ? instance : nil case options[:type] when :standard authentication_controller_class = (example.metadata[:type] == :controller) ? described_class : ApplicationController authentication_controller_instance = authentication_controller_class.new authentication_method = if authentication_controller_instance.respond_to?(options[:authentication_method], true) options[:authentication_method] elsif authentication_controller_instance.respond_to?(:authenticate, true) :authenticate end authentication_controller_class.__send__(:define_method, authentication_method) { options[:successful?] } authentication_controller_class.__send__(:define_method, options[:method]) { authentication_result } authentication_controller_class.__send__(:helper_method, options[:method]) example.example_group_instance.class.let(options[:method]) { authentication_result } example.run authentication_controller_class.__send__(:remove_method, options[:method]) when :json_web_token @token_data = [ { 'aid' => options[:token][:audience_id] || instance['account_id'] || instance['id'], 'aud' => options[:token][:audience] || instance.class.name, 'exp' => options[:token][:expired_at] || 1.day.from_now.utc.to_i, 'iat' => options[:token][:issued_at] || ::Time.now.utc.to_i, 'iss' => options[:token][:issuer] || 'rspeckled', 'jti' => options[:token][:token_id] || ::SecureRandom.uuid, 'nbf' => options[:token][:not_before] || 1.day.ago.utc.to_i, 'rol' => options[:token][:roles] || 'standard', 'sid' => options[:token][:subject_id], 'sub' => options[:token][:subject], }, { 'typ' => 'JWT', 'cty' => 'application/json-web-token', }, ] example.example_group_instance.class.let(options[:method]) { authentication_result } example.run end instance.delete unless options[:strategy] == :instance config.rspeckled_logger.debug("Around Each - End - #{__FILE__}") end config.before(:each, :authentication => lambda { |v| !!v }) do |_example| config.rspeckled_logger.debug("Before Each - Start - #{__FILE__}") request.env['X_JSON_WEB_TOKEN'] = @token_data config.rspeckled_logger.debug("Before Each - End - #{__FILE__}") end end # rubocop:enable Layout/IndentHash