Guest User

Untitled

a guest
Feb 19th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.94 KB | None | 0 0
  1. module Merb::Test::MultipartRequestHelper
  2. require 'rubygems'
  3. require 'mime/types'
  4.  
  5. class Param
  6. attr_accessor :key, :value
  7.  
  8. # ==== Parameters
  9. # key<~to_s>:: The parameter key.
  10. # value<~to_s>:: The parameter value.
  11. def initialize(key, value)
  12. @key = key
  13. @value = value
  14. end
  15.  
  16. # ==== Returns
  17. # String:: The parameter in a form suitable for a multipart request.
  18. def to_multipart
  19. return %(Content-Disposition: form-data; name="#{key}"\r\n\r\n#{value}\r\n)
  20. end
  21. end
  22.  
  23. class FileParam
  24. attr_accessor :key, :filename, :content
  25.  
  26. # ==== Parameters
  27. # key<~to_s>:: The parameter key.
  28. # filename<~to_s>:: Name of the file for this parameter.
  29. # content<~to_s>:: Content of the file for this parameter.
  30. def initialize(key, filename, content)
  31. @key = key
  32. @filename = filename
  33. @content = content
  34. end
  35.  
  36. # ==== Returns
  37. # String::
  38. # The file parameter in a form suitable for a multipart request.
  39. def to_multipart
  40. return %(Content-Disposition: form-data; name="#{key}"; filename="#{filename}"\r\n) + "Content-Type: #{MIME::Types.type_for(@filename)}\r\n\r\n" + content + "\r\n"
  41. end
  42. end
  43.  
  44. class Post
  45. BOUNDARY = '----------0xKhTmLbOuNdArY'
  46. CONTENT_TYPE = "multipart/form-data, boundary=" + BOUNDARY
  47.  
  48. # ==== Parameters
  49. # params<Hash>:: Optional params for the controller.
  50. def initialize(params = {})
  51. @multipart_params = []
  52. push_params(params)
  53. end
  54.  
  55. # Saves the params in an array of multipart params as Param and
  56. # FileParam objects.
  57. #
  58. # ==== Parameters
  59. # params<Hash>:: The params to add to the multipart params.
  60. # prefix<~to_s>:: An optional prefix for the request string keys.
  61. def push_params(params, prefix = nil)
  62. params.sort_by {|k| k.to_s}.each do |key, value|
  63. param_key = prefix.nil? ? key : "#{prefix}[#{key}]"
  64. if value.respond_to?(:read)
  65. @multipart_params << FileParam.new(param_key, value.path, value.read)
  66. else
  67. if value.is_a?(Hash) || value.is_a?(Mash)
  68. value.keys.each do |k|
  69. push_params(value, param_key)
  70. end
  71. else
  72. @multipart_params << Param.new(param_key, value)
  73. end
  74. end
  75. end
  76. end
  77.  
  78. # ==== Returns
  79. # Array[String, String]:: The query and the content type.
  80. def to_multipart
  81. query = @multipart_params.collect { |param| "--" + BOUNDARY + "\r\n" + param.to_multipart }.join("") + "--" + BOUNDARY + "--"
  82. return query, CONTENT_TYPE
  83. end
  84. end
  85.  
  86. # Similar to dispatch_to but allows for sending files inside params.
  87. #
  88. # ==== Paramters
  89. # controller_klass<Controller>::
  90. # The controller class object that the action should be dispatched to.
  91. # action<Symbol>:: The action name, as a symbol.
  92. # params<Hash>::
  93. # An optional hash that will end up as params in the controller instance.
  94. # env<Hash>::
  95. # An optional hash that is passed to the fake request. Any request options
  96. # should go here (see +fake_request+).
  97. # &blk:: The block is executed in the context of the controller.
  98. #
  99. # ==== Example
  100. # dispatch_multipart_to(MyController, :create, :my_file => @a_file ) do |controller|
  101. # controller.stub!(:current_user).and_return(@user)
  102. # end
  103. #
  104. # ==== Notes
  105. # Set your option to contain a file object to simulate file uploads.
  106. #
  107. # Does not use routes.
  108. #---
  109. # @public
  110. def dispatch_multipart_to(controller_klass, action, params = {}, env = {}, &blk)
  111. request = multipart_fake_request(env, params)
  112. dispatch_request(request, controller_klass, action, &blk)
  113. end
  114.  
  115. # An HTTP POST request that operates through the router and uses multipart
  116. # parameters.
  117. #
  118. # ==== Parameters
  119. # path<String>:: The path that should go to the router as the request uri.
  120. # params<Hash>::
  121. # An optional hash that will end up as params in the controller instance.
  122. # env<Hash>::
  123. # An optional hash that is passed to the fake request. Any request options
  124. # should go here (see +fake_request+).
  125. # block<Proc>:: The block is executed in the context of the controller.
  126. #
  127. # ==== Notes
  128. # To include an uploaded file, put a file object as a value in params.
  129. def multipart_post(path, params = {}, env = {}, &block)
  130. env[:request_method] = "POST"
  131. env[:test_with_multipart] = true
  132. request(path, params, env, &block)
  133. end
  134.  
  135. # An HTTP PUT request that operates through the router and uses multipart
  136. # parameters.
  137. #
  138. # ==== Parameters
  139. # path<String>:: The path that should go to the router as the request uri.
  140. # params<Hash>::
  141. # An optional hash that will end up as params in the controller instance.
  142. # env<Hash>::
  143. # An optional hash that is passed to the fake request. Any request options
  144. # should go here (see +fake_request+).
  145. # block<Proc>:: The block is executed in the context of the controller.
  146. #
  147. # ==== Notes
  148. # To include an uplaoded file, put a file object as a value in params.
  149. def multipart_put(path, params = {}, env = {}, &block)
  150. env[:request_method] = "PUT"
  151. env[:test_with_multipart] = true
  152. request(path, params, env, &block)
  153. end
  154.  
  155. # ==== Parameters
  156. # env<Hash>::
  157. # An optional hash that is passed to the fake request. Any request options
  158. # should go here (see +fake_request+).
  159. # params<Hash>::
  160. # An optional hash that will end up as params in the controller instance.
  161. #
  162. # ==== Returns
  163. # FakeRequest::
  164. # A multipart Request object that is built based on the parameters.
  165. def multipart_fake_request(env = {}, params = {})
  166. if params.empty?
  167. fake_request(env)
  168. else
  169. m = Post.new(params)
  170. body, head = m.to_multipart
  171. fake_request(env.merge( :content_type => head,
  172. :content_length => body.length), :post_body => body)
  173. end
  174. end
  175. end
Add Comment
Please, Sign In to add comment