設定済みのroutesをRails内部で動的にとる。
家にいると無限にものを食べてしまい、無職期間中にどれだけ体重が増えるかこわい。
兎にも角にもとりあえずとる
rake routes
で見れる感じのやつが欲しかったんです。
こういうので
class RoutesReader
def self.all
@stored ||= Rails.application.routes.routes.map do |route|
controller = route.defaults[:controller]
verb = %W{ GET POST PUT PATCH DELETE }.grep(route.verb).first.downcase.to_sym
action = route.defaults[:action]
path = route.path.spec.to_s.gsub(/\(\.:format\)/, "")
params = path.scan(/:([a-zA-Z0-9_]+)/).flatten.collect(&:to_sym)
{
path: path,
verb: verb,
action: action.try(:to_sym),
controller: controller,
params: params
}
end
end
end
はしょってますが、ドバッととれる。
RoutesReader.all
[{:path=>"/assets", :verb=>:get, :action=>nil,:controller=>nil, :params=>[]},
{:path=>"/entry/new", :verb=>:get, :action=>:new, :controller=>"editor/entries", :params=>[]},
{:path=>"/entry/new", :verb=>:post, :action=>:create, :controller=>"editor/entries", :params=>[]},
{:path=>"/v/:id", :verb=>:get, :action=>:show, :controller=>"viewer/entries", :params=>[:id]},
{:path=>"/m/:year/:month", :verb=>:get, :action=>:index_date, :controller=>"viewer/entries", :params=>[:year, :month]}]
なにをしたくてこんなことをしたのか
あるパス以下の行動には、必ず承認が必要であるというのはよくある設計ですが、それのテストを抜かりなくやるために何かないかな~と考えて、とりあえず総当たりはどうだろうとこういうことをしていた。
RoutesReader.all.each do |config|
controller = eval(config[:controller].split('/').map(&:capitalize).join('::') << 'Controller') rescue next
verb = config[:verb]
action = config[:action]
params = config[:params].map { |key| {key => 'params'} }
login = case config[:path]
when %r{^/entry/}
<<-EOS
activate_authlogic
user = FactoryGirl.create(:user, :valid)
UserSession.create!(user)
EOS
when %r{^/manager/}
<<-EOS
manager = FactoryGirl.create(:manager, :valid)
sign_in manager, :manager
EOS
else
# 指定パス以外はテストしない
next
end
RSpec.describe controller, :type => :controller do
describe "#{verb} ##{action}" do
context 'when logined' do
it do
eval(login)
begin
send(verb, action, *params)
rescue ActionController::ParameterMissing
# do nothing
end
expect(response).not_to redirect_to(root_path)
end
end
context 'when not logined' do
it do
send(verb, action, *params)
expect(response).to redirect_to(root_path)
end
end
end
end
end
根本的に解決したい
controllerで承認するから各controllerのテストがいるわけで、routes側で承認を行えるなら一発で漏れがなくていいのでは?と思ってやってたのが、前回、前々回のroutes.rbで承認をやっていくやつです。