request.rb 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. module ZammadSpecSupportRequest
  2. # This ruby meta programming action creates the methods to perform:
  3. # GET, POST, PATCH, PUT, DELETE and HEAD
  4. # HTTP "requests".
  5. # They overwrite the ones of `ActionDispatch::Integration::RequestHelpers`
  6. # to add the headers set by #add_headers before
  7. %i[get post patch put delete head].each do |method_id|
  8. define_method(method_id) do |path, **args|
  9. args = args.with_indifferent_access
  10. args[:headers] = Hash(args[:headers]).merge!(Hash(@headers))
  11. super(path, **args.symbolize_keys)
  12. end
  13. end
  14. # Adds one or more HTTP headers to all requests of the current example.
  15. #
  16. # @param [Hash{String => String}] headers Hash of HTTP headers
  17. #
  18. # @example
  19. # add_headers('Eg Some X-Header' => 'Some value')
  20. # @example
  21. # add_headers(
  22. # 'Header 1' => 'Some value',
  23. # 'Header 2' => 'Some value',
  24. # ...
  25. # )
  26. #
  27. # @return [Hash] The current headers Hash
  28. def add_headers(headers)
  29. @headers = Hash(@headers).merge(headers)
  30. end
  31. # Parses the response.body as JSON.
  32. #
  33. # @example
  34. # json_response
  35. # @example
  36. # json_response.is_a?(Array)
  37. #
  38. # @return [Array, Hash, ...] Parsed JSON structure as Ruby object
  39. def json_response
  40. JSON.parse(response.body)
  41. end
  42. # Authenticates all requests of the current example as the given user.
  43. #
  44. # @example
  45. # authenticated_as(some_admin_user)
  46. #
  47. # @example
  48. # authenticated_as(some_admin_user, on_behalf_of: customer_user)
  49. #
  50. # @example
  51. # authenticated_as(some_admin_user, password: 'wrongpw')
  52. #
  53. # @example
  54. # authenticated_as(some_admin_user, password: 'wrongpw', token: create(:token, action: 'api', user_id: some_admin_user.id) )
  55. #
  56. # @example
  57. # authenticated_as(nil, login: 'not_existing', password: 'wrongpw' )
  58. #
  59. # @return nil
  60. def authenticated_as(user, login: nil, password: nil, token: nil, on_behalf_of: nil)
  61. password ||= user.password
  62. login ||= user.login
  63. # mock authentication otherwise login won't
  64. # if user has no password (which is expensive to create)
  65. if password.nil?
  66. allow(User).to receive(:authenticate).with(login, '') { user.update_last_login }.and_return(user)
  67. end
  68. # if we want to authenticate by token
  69. if token.present?
  70. credentials = "Token token=#{token.name}"
  71. return add_headers('Authorization' => credentials)
  72. end
  73. credentials = ActionController::HttpAuthentication::Basic.encode_credentials(login, password)
  74. add_headers('Authorization' => credentials, 'X-On-Behalf-Of' => on_behalf_of)
  75. end
  76. # Provides a Hash of attributes for the given FactoryBot
  77. # factory parameters which can be used as the params payload.
  78. # Note that the attributes are "cleaned" so no created_by_id etc.
  79. # is present.
  80. #
  81. # @see FactoryBot#attributes_for
  82. #
  83. # @example
  84. # attributes_params_for(:admin_user, email: 'custom@example.com')
  85. # # => {firstname: 'Nicole', email: 'custom@example.com', ...}
  86. #
  87. # @return [Hash{Symbol => <String, Array, Hash>}] request cleaned attributes
  88. def attributes_params_for(*args)
  89. filter_unused_params(attributes_for(*args))
  90. end
  91. # Provides a Hash of attributes for the given Model instance which can
  92. # be used as the params payload.
  93. # Note that the attributes are "cleaned" so no created_by_id etc.
  94. # is present.
  95. #
  96. # @param [Hash] instance An ActiveRecord instance
  97. #
  98. # @example
  99. # cleaned_params_for(some_admin_user)
  100. # # => {firstname: 'Nicole', email: 'admin@example.com', ...}
  101. #
  102. # @return [Hash{Symbol => <String, Array, Hash>}] request cleaned attributes
  103. def cleaned_params_for(instance)
  104. filter_unused_params(instance.attributes)
  105. end
  106. # This is a self explaining internal method.
  107. #
  108. # @see ApplicationModel#filter_unused_params
  109. def filter_unused_params(unfiltered)
  110. # let's get private
  111. ApplicationModel.send(:filter_unused_params, unfiltered)
  112. end
  113. end
  114. RSpec.configure do |config|
  115. config.include ZammadSpecSupportRequest, type: :request
  116. config.before(:each, type: :request) do
  117. Setting.set('system_init_done', true)
  118. end
  119. # This helper allows you to authenticate as a given user in request specs
  120. # via the example metadata, rather than directly:
  121. #
  122. # it 'does something', authenticated_as: :user
  123. #
  124. # In order for this to work, you must define the user in a `let` block first:
  125. #
  126. # let(:user) { create(:customer_user) }
  127. #
  128. config.before(:each, :authenticated_as) do |example|
  129. @current_user = if example.metadata[:authenticated_as].is_a? Proc
  130. instance_exec(&example.metadata[:authenticated_as])
  131. else
  132. create(*Array(example.metadata[:authenticated_as]))
  133. end
  134. authenticated_as @current_user unless @current_user.nil?
  135. end
  136. end