mirror of
https://github.com/thoughtbot/shoulda-matchers.git
synced 2022-11-09 12:01:38 -05:00

Why: * We recently added Routing::RouteMatcher; the tests for those were roughly copied from those for ActionController::RouteMatcher but were rewritten, so we want to make the tests consistent between the two. * The names of the existing tests weren't descriptive enough. * The tests involving globs inside of routes should have been run twice -- once in the case that controller and action are separate options, another in the case that controller and action are specified together.
330 lines
9.2 KiB
Ruby
330 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
|