331 lines
9.2 KiB
Ruby
331 lines
9.2 KiB
Ruby
require 'unit_spec_helper'
|
|
|
|
describe 'Shoulda::Matchers::ActionController::RouteMatcher', type: :controller do
|
|
shared_examples_for 'tests involving expected route parts' do |args|
|
|
include_controller_in_expected_route_options =
|
|
args.fetch(:include_controller_in_expected_route_options)
|
|
|
|
context 'when all parts of the expected route match an existing route' do
|
|
it 'accepts' do
|
|
define_route :get, '/', action: 'index'
|
|
|
|
assert_accepts add_target_to(
|
|
route(:get, '/'),
|
|
build_expected_route_options(
|
|
include_controller_in_expected_route_options,
|
|
action: 'index',
|
|
),
|
|
)
|
|
end
|
|
|
|
if include_controller_in_expected_route_options
|
|
context 'and the expected controller is specified as a symbol' do
|
|
it 'accepts' do
|
|
define_route :get, '/', action: 'index'
|
|
|
|
assert_accepts add_target_to(
|
|
route(:get, '/'),
|
|
build_expected_route_options(
|
|
include_controller_in_expected_route_options,
|
|
action: 'index',
|
|
),
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'and the expected action is specified as a symbol' do
|
|
it 'accepts' do
|
|
define_route :get, '/', action: 'index'
|
|
|
|
assert_accepts add_target_to(
|
|
route(:get, '/'),
|
|
build_expected_route_options(
|
|
include_controller_in_expected_route_options,
|
|
action: :index,
|
|
),
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when no parts of the expected route match an existing route' do
|
|
it 'rejects' do
|
|
assert_rejects add_target_to(
|
|
route(:get, '/non_existent_route'),
|
|
controller: 'no_controller',
|
|
action: 'no_action',
|
|
)
|
|
end
|
|
end
|
|
|
|
context 'when all parts of the expected route but the method match an existing route' do
|
|
it 'rejects' do
|
|
define_route :post, '/', action: 'index'
|
|
|
|
assert_rejects add_target_to(
|
|
route(:get, '/'),
|
|
build_expected_route_options(
|
|
include_controller_in_expected_route_options,
|
|
action: 'index',
|
|
),
|
|
)
|
|
end
|
|
end
|
|
|
|
context 'when all parts of the expected route but the path match an existing route' do
|
|
it 'rejects' do
|
|
define_route :get, '/', action: 'index'
|
|
|
|
assert_rejects add_target_to(
|
|
route(:get, '/different_path'),
|
|
build_expected_route_options(
|
|
include_controller_in_expected_route_options,
|
|
action: 'index',
|
|
),
|
|
)
|
|
end
|
|
end
|
|
|
|
if include_controller_in_expected_route_options
|
|
context 'when all parts of the expected route but the controller match an existing route' do
|
|
it 'rejects' do
|
|
define_route :get, '/', controller: 'another_controller', action: 'index'
|
|
|
|
assert_rejects add_target_to(
|
|
route(:get, '/'),
|
|
build_expected_route_options(
|
|
include_controller_in_expected_route_options,
|
|
action: 'index',
|
|
),
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when all parts of the expected route but the action match an existing route' do
|
|
it 'rejects' do
|
|
define_route :get, '/', action: 'index'
|
|
|
|
assert_rejects add_target_to(
|
|
route(:get, '/'),
|
|
build_expected_route_options(
|
|
include_controller_in_expected_route_options,
|
|
action: 'another_action',
|
|
),
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
shared_examples_for 'tests involving params' do
|
|
context 'when the actual route has a param' do
|
|
context 'and the expected params include that param' do
|
|
it 'accepts' do
|
|
define_route :get, "/#{controller_name}/:id", action: 'show'
|
|
|
|
assert_accepts add_target_to(
|
|
route(:get, "/#{controller_name}/1"),
|
|
controller: controller_name,
|
|
action: 'show',
|
|
id: '1',
|
|
)
|
|
end
|
|
|
|
context 'but its value was not specified as a string' do
|
|
it 'accepts, treating it as a string' do
|
|
define_route :get, "/#{controller_name}/:id", action: 'show'
|
|
|
|
assert_accepts add_target_to(
|
|
route(:get, "/#{controller_name}/1"),
|
|
controller: controller_name,
|
|
action: 'show',
|
|
id: 1,
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'and the expected params do not match the actual params' do
|
|
it 'rejects' do
|
|
define_route :get, "/#{controller_name}/:id", action: 'show'
|
|
|
|
params = {
|
|
controller: controller_name,
|
|
action: 'show',
|
|
some: 'other',
|
|
params: 'here',
|
|
}
|
|
assert_rejects add_target_to(
|
|
route(:get, "/#{controller_name}/:id"),
|
|
params,
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when the actual route has a default param whose value is a symbol' do
|
|
context 'and the expected params include a value for it' do
|
|
context 'as a symbol' do
|
|
it 'accepts' do
|
|
define_route :post, "/#{controller_name}/(.:format)",
|
|
action: 'create',
|
|
defaults: { format: :json }
|
|
|
|
assert_accepts add_target_to(
|
|
route(:post, "/#{controller_name}"),
|
|
controller: controller_name,
|
|
action: 'create',
|
|
format: :json,
|
|
)
|
|
end
|
|
end
|
|
|
|
context 'as a string' do
|
|
it 'accepts' do
|
|
define_route :post, "/#{controller_name}/(.:format)",
|
|
action: 'create',
|
|
defaults: { format: :json }
|
|
|
|
assert_accepts add_target_to(
|
|
route(:post, "/#{controller_name}"),
|
|
controller: controller_name,
|
|
action: 'create',
|
|
format: 'json',
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when the existing route has a glob segment' do
|
|
context 'and a param is given which represents the segment' do
|
|
it 'accepts' do
|
|
define_route :get, "/#{controller_name}/*id", action: 'whatever'
|
|
|
|
assert_accepts add_target_to(
|
|
route(:get, "/#{controller_name}/foo/bar"),
|
|
controller: controller_name,
|
|
action: 'whatever',
|
|
id: 'foo/bar',
|
|
)
|
|
end
|
|
end
|
|
|
|
context 'and no param is given which represents the segment' do
|
|
it 'rejects' do
|
|
define_route :get, "/#{controller_name}/*id", action: 'whatever'
|
|
|
|
assert_rejects add_target_to(
|
|
route(:get, "/#{controller_name}"),
|
|
controller: controller_name,
|
|
action: 'whatever',
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
shared_examples_for 'core tests' do
|
|
context 'given a controller and action specified as individual options' do
|
|
include_examples 'tests involving expected route parts',
|
|
include_controller_in_expected_route_options: true
|
|
|
|
include_examples 'tests involving params'
|
|
|
|
def add_target_to(route_matcher, params)
|
|
route_matcher.to(params)
|
|
end
|
|
end
|
|
|
|
context 'given a controller and action joined together in a string' do
|
|
include_examples 'tests involving expected route parts',
|
|
include_controller_in_expected_route_options: true
|
|
|
|
include_examples 'tests involving params'
|
|
|
|
def add_target_to(route_matcher, args)
|
|
controller = args.fetch(:controller)
|
|
action = args.fetch(:action)
|
|
route_matcher.to("#{controller}##{action}", args)
|
|
end
|
|
end
|
|
|
|
context 'given just an action' do
|
|
include_examples 'tests involving expected route parts',
|
|
include_controller_in_expected_route_options: false
|
|
|
|
include_examples 'tests involving params'
|
|
|
|
def add_target_to(route_matcher, params)
|
|
route_matcher.to(params)
|
|
end
|
|
end
|
|
end
|
|
|
|
before do
|
|
setup_rails_controller_test(controller_class)
|
|
end
|
|
|
|
context 'given a controller that is not namespaced' do
|
|
include_examples 'core tests'
|
|
|
|
def controller_class_name
|
|
'ExamplesController'
|
|
end
|
|
end
|
|
|
|
context 'given a controller that is namespaced' do
|
|
def define_controller_under_test
|
|
define_module('Admin')
|
|
super
|
|
end
|
|
|
|
include_examples 'core tests'
|
|
|
|
def controller_class_name
|
|
'Admin::ExamplesController'
|
|
end
|
|
end
|
|
|
|
let(:controller_class) do
|
|
define_controller_under_test
|
|
end
|
|
|
|
def define_controller_under_test
|
|
define_controller(controller_class_name)
|
|
end
|
|
|
|
def controller_name
|
|
controller_class_name.sub(/Controller$/, '').underscore
|
|
end
|
|
|
|
def define_route(method, path, args)
|
|
action = args.fetch(:action)
|
|
controller = args.fetch(:controller) { controller_name }
|
|
define_routes do
|
|
public_send(
|
|
method,
|
|
path,
|
|
args.merge(controller: controller, action: action),
|
|
)
|
|
end
|
|
end
|
|
|
|
def build_expected_route_options(include_controller_in_expected_route_options, default_options)
|
|
default_options.dup.tap do |options|
|
|
if include_controller_in_expected_route_options
|
|
options[:controller] = controller_name
|
|
end
|
|
end
|
|
end
|
|
|
|
def assert_accepts(matcher)
|
|
expect(controller).to matcher
|
|
end
|
|
|
|
def assert_rejects(matcher)
|
|
expect(controller).not_to matcher
|
|
end
|
|
end
|