PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/plugins/shoulda/lib/shoulda/controller/resource_options.rb

https://github.com/technicalpickles/flockup
Ruby | 236 lines | 77 code | 31 blank | 128 comment | 6 complexity | 24932c95ef42170ad06d7659d512e54f MD5 | raw file
Possible License(s): GPL-2.0
  1. module ThoughtBot # :nodoc:
  2. module Shoulda # :nodoc:
  3. module Controller
  4. # Formats tested by #should_be_restful. Defaults to [:html, :xml]
  5. VALID_FORMATS = Dir.glob(File.join(File.dirname(__FILE__), 'formats', '*.rb')).map { |f| File.basename(f, '.rb') }.map(&:to_sym) # :doc:
  6. VALID_FORMATS.each {|f| require "shoulda/controller/formats/#{f}"}
  7. # Actions tested by #should_be_restful
  8. VALID_ACTIONS = [:index, :show, :new, :edit, :create, :update, :destroy] # :doc:
  9. # A ResourceOptions object is passed into should_be_restful in order to configure the tests for your controller.
  10. #
  11. # Example:
  12. # class UsersControllerTest < Test::Unit::TestCase
  13. # fixtures :all
  14. #
  15. # def setup
  16. # ...normal setup code...
  17. # @user = User.find(:first)
  18. # end
  19. #
  20. # should_be_restful do |resource|
  21. # resource.identifier = :id
  22. # resource.klass = User
  23. # resource.object = :user
  24. # resource.parent = []
  25. # resource.actions = [:index, :show, :new, :edit, :update, :create, :destroy]
  26. # resource.formats = [:html, :xml]
  27. #
  28. # resource.create.params = { :name => "bob", :email => 'bob@bob.com', :age => 13}
  29. # resource.update.params = { :name => "sue" }
  30. #
  31. # resource.create.redirect = "user_url(@user)"
  32. # resource.update.redirect = "user_url(@user)"
  33. # resource.destroy.redirect = "users_url"
  34. #
  35. # resource.create.flash = /created/i
  36. # resource.update.flash = /updated/i
  37. # resource.destroy.flash = /removed/i
  38. # end
  39. # end
  40. #
  41. # Whenever possible, the resource attributes will be set to sensible defaults.
  42. #
  43. class ResourceOptions
  44. # Configuration options for the create, update, destroy actions under should_be_restful
  45. class ActionOptions
  46. # String evaled to get the target of the redirection.
  47. # All of the instance variables set by the controller will be available to the
  48. # evaled code.
  49. #
  50. # Example:
  51. # resource.create.redirect = "user_url(@user.company, @user)"
  52. #
  53. # Defaults to a generated url based on the name of the controller, the action, and the resource.parents list.
  54. attr_accessor :redirect
  55. # String or Regexp describing a value expected in the flash. Will match against any flash key.
  56. #
  57. # Defaults:
  58. # destroy:: /removed/
  59. # create:: /created/
  60. # update:: /updated/
  61. attr_accessor :flash
  62. # Hash describing the params that should be sent in with this action.
  63. attr_accessor :params
  64. end
  65. # Configuration options for the denied actions under should_be_restful
  66. #
  67. # Example:
  68. # context "The public" do
  69. # setup do
  70. # @request.session[:logged_in] = false
  71. # end
  72. #
  73. # should_be_restful do |resource|
  74. # resource.parent = :user
  75. #
  76. # resource.denied.actions = [:index, :show, :edit, :new, :create, :update, :destroy]
  77. # resource.denied.flash = /get outta here/i
  78. # resource.denied.redirect = 'new_session_url'
  79. # end
  80. # end
  81. #
  82. class DeniedOptions
  83. # String evaled to get the target of the redirection.
  84. # All of the instance variables set by the controller will be available to the
  85. # evaled code.
  86. #
  87. # Example:
  88. # resource.create.redirect = "user_url(@user.company, @user)"
  89. attr_accessor :redirect
  90. # String or Regexp describing a value expected in the flash. Will match against any flash key.
  91. #
  92. # Example:
  93. # resource.create.flash = /created/
  94. attr_accessor :flash
  95. # Actions that should be denied (only used by resource.denied). <i>Note that these actions will
  96. # only be tested if they are also listed in +resource.actions+</i>
  97. # The special value of :all will deny all of the REST actions.
  98. attr_accessor :actions
  99. end
  100. # Name of key in params that references the primary key.
  101. # Will almost always be :id (default), unless you are using a plugin or have patched rails.
  102. attr_accessor :identifier
  103. # Name of the ActiveRecord class this resource is responsible for. Automatically determined from
  104. # test class if not explicitly set. UserTest => "User"
  105. attr_accessor :klass
  106. # Name of the instantiated ActiveRecord object that should be used by some of the tests.
  107. # Defaults to the underscored name of the AR class. CompanyManager => :company_manager
  108. attr_accessor :object
  109. # Name of the parent AR objects. Can be set as parent= or parents=, and can take either
  110. # the name of the parent resource (if there's only one), or an array of names (if there's
  111. # more than one).
  112. #
  113. # Example:
  114. # # in the routes...
  115. # map.resources :companies do
  116. # map.resources :people do
  117. # map.resources :limbs
  118. # end
  119. # end
  120. #
  121. # # in the tests...
  122. # class PeopleControllerTest < Test::Unit::TestCase
  123. # should_be_restful do |resource|
  124. # resource.parent = :companies
  125. # end
  126. # end
  127. #
  128. # class LimbsControllerTest < Test::Unit::TestCase
  129. # should_be_restful do |resource|
  130. # resource.parents = [:companies, :people]
  131. # end
  132. # end
  133. attr_accessor :parent
  134. alias parents parent
  135. alias parents= parent=
  136. # Actions that should be tested. Must be a subset of VALID_ACTIONS (default).
  137. # Tests for each actionw will only be generated if the action is listed here.
  138. # The special value of :all will test all of the REST actions.
  139. #
  140. # Example (for a read-only controller):
  141. # resource.actions = [:show, :index]
  142. attr_accessor :actions
  143. # Formats that should be tested. Must be a subset of VALID_FORMATS (default).
  144. # Each action will be tested against the formats listed here. The special value
  145. # of :all will test all of the supported formats.
  146. #
  147. # Example:
  148. # resource.actions = [:html, :xml]
  149. attr_accessor :formats
  150. # ActionOptions object specifying options for the create action.
  151. attr_accessor :create
  152. # ActionOptions object specifying options for the update action.
  153. attr_accessor :update
  154. # ActionOptions object specifying options for the desrtoy action.
  155. attr_accessor :destroy
  156. # DeniedOptions object specifying which actions should return deny a request, and what should happen in that case.
  157. attr_accessor :denied
  158. def initialize # :nodoc:
  159. @create = ActionOptions.new
  160. @update = ActionOptions.new
  161. @destroy = ActionOptions.new
  162. @denied = DeniedOptions.new
  163. @create.flash ||= /created/i
  164. @update.flash ||= /updated/i
  165. @destroy.flash ||= /removed/i
  166. @denied.flash ||= /denied/i
  167. @create.params ||= {}
  168. @update.params ||= {}
  169. @actions = VALID_ACTIONS
  170. @formats = VALID_FORMATS
  171. @denied.actions = []
  172. end
  173. def normalize!(target) # :nodoc:
  174. @denied.actions = VALID_ACTIONS if @denied.actions == :all
  175. @actions = VALID_ACTIONS if @actions == :all
  176. @formats = VALID_FORMATS if @formats == :all
  177. @denied.actions = @denied.actions.map(&:to_sym)
  178. @actions = @actions.map(&:to_sym)
  179. @formats = @formats.map(&:to_sym)
  180. ensure_valid_members(@actions, VALID_ACTIONS, 'actions')
  181. ensure_valid_members(@denied.actions, VALID_ACTIONS, 'denied.actions')
  182. ensure_valid_members(@formats, VALID_FORMATS, 'formats')
  183. @identifier ||= :id
  184. @klass ||= target.name.gsub(/ControllerTest$/, '').singularize.constantize
  185. @object ||= @klass.name.tableize.singularize
  186. @parent ||= []
  187. @parent = [@parent] unless @parent.is_a? Array
  188. collection_helper = [@parent, @object.to_s.pluralize, 'url'].flatten.join('_')
  189. collection_args = @parent.map {|n| "@#{object}.#{n}"}.join(', ')
  190. @destroy.redirect ||= "#{collection_helper}(#{collection_args})"
  191. member_helper = [@parent, @object, 'url'].flatten.join('_')
  192. member_args = [@parent.map {|n| "@#{object}.#{n}"}, "@#{object}"].flatten.join(', ')
  193. @create.redirect ||= "#{member_helper}(#{member_args})"
  194. @update.redirect ||= "#{member_helper}(#{member_args})"
  195. @denied.redirect ||= "new_session_url"
  196. end
  197. private
  198. def ensure_valid_members(ary, valid_members, name) # :nodoc:
  199. invalid = ary - valid_members
  200. raise ArgumentError, "Unsupported #{name}: #{invalid.inspect}" unless invalid.empty?
  201. end
  202. end
  203. end
  204. end
  205. end