408 lines
10 KiB
Ruby
408 lines
10 KiB
Ruby
require 'unit_spec_helper'
|
|
|
|
describe 'Shoulda::Matchers::Routing::RouteMatcher', type: :routing do
|
|
shared_examples_for 'core tests' do
|
|
context 'when the given method, path, controller, and action match an existing route' do
|
|
it 'accepts' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'index',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'index'
|
|
)
|
|
|
|
is_expected.to(matcher)
|
|
end
|
|
|
|
context 'and the expected controller is specified as a symbol' do
|
|
it 'accepts' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'index',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/',
|
|
controller: :things,
|
|
action: 'index'
|
|
)
|
|
|
|
is_expected.to(matcher)
|
|
end
|
|
end
|
|
|
|
context 'and the expected action is specified as a symbol' do
|
|
it 'accepts' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'index',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: :index,
|
|
)
|
|
|
|
is_expected.to(matcher)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when the given method, path, controller, and action do not match an existing route' do
|
|
it 'rejects' do
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/non_existent_route',
|
|
controller: 'some_controller',
|
|
action: 'some_action',
|
|
)
|
|
|
|
is_expected.not_to(matcher)
|
|
end
|
|
end
|
|
|
|
context 'when the given path, controller, and action match an existing route but the method does not' do
|
|
it 'rejects' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'index',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :post,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'index',
|
|
)
|
|
|
|
is_expected.not_to(matcher)
|
|
end
|
|
end
|
|
|
|
context 'when the given method, controller, and action match an existing route but the path does not' do
|
|
it 'rejects' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'index',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/something_else',
|
|
controller: 'things',
|
|
action: 'index',
|
|
)
|
|
|
|
is_expected.not_to(matcher)
|
|
end
|
|
end
|
|
|
|
context 'when the given method and path match an existing route but the controller does not' do
|
|
it 'rejects' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'index',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'some_other_controller',
|
|
action: 'index',
|
|
)
|
|
|
|
is_expected.not_to(matcher)
|
|
end
|
|
end
|
|
|
|
context 'when the given method, path, and controller match an existing route but the action does not' do
|
|
it 'rejects' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'index',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'another_action',
|
|
)
|
|
|
|
is_expected.not_to(matcher)
|
|
end
|
|
end
|
|
|
|
context 'when the actual route has a param' do
|
|
context 'and the expected params include that param' do
|
|
it 'accepts' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/things/:id',
|
|
controller: 'things',
|
|
action: 'show',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/things/1',
|
|
controller: 'things',
|
|
action: 'show',
|
|
id: '1',
|
|
)
|
|
|
|
is_expected.to(matcher)
|
|
end
|
|
|
|
context 'but its value was not specified as a string' do
|
|
it 'accepts, treating it as a string' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/things/:id',
|
|
controller: 'things',
|
|
action: 'show',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/things/1',
|
|
controller: 'things',
|
|
action: 'show',
|
|
id: 1,
|
|
)
|
|
|
|
is_expected.to(matcher)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'and the expected params do not match the actual params' do
|
|
it 'rejects' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/things/:id',
|
|
controller: 'things',
|
|
action: 'show',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/things/1',
|
|
controller: 'things',
|
|
action: 'show',
|
|
some: 'other',
|
|
params: 'here',
|
|
)
|
|
|
|
is_expected.not_to(matcher)
|
|
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_controller_and_routes(
|
|
method: :post,
|
|
path: '/things(.:format)',
|
|
controller: 'things',
|
|
action: 'create',
|
|
defaults: { format: :json },
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :post,
|
|
path: '/things',
|
|
controller: 'things',
|
|
action: 'create',
|
|
format: :json,
|
|
)
|
|
|
|
is_expected.to(matcher)
|
|
end
|
|
end
|
|
|
|
context 'as a string' do
|
|
it 'accepts' do
|
|
define_controller_and_routes(
|
|
method: :post,
|
|
path: '/things(.:format)',
|
|
controller: 'things',
|
|
action: 'create',
|
|
defaults: { format: :json },
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :post,
|
|
path: '/things',
|
|
controller: 'things',
|
|
action: 'create',
|
|
format: 'json',
|
|
)
|
|
|
|
is_expected.to(matcher)
|
|
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_controller_and_routes(
|
|
method: :get,
|
|
path: '/things/*id',
|
|
controller: 'things',
|
|
action: 'show',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/things/foo/bar',
|
|
controller: 'things',
|
|
action: 'show',
|
|
id: 'foo/bar',
|
|
)
|
|
|
|
is_expected.to(matcher)
|
|
end
|
|
end
|
|
|
|
context 'and no param is given which represents the segment' do
|
|
it 'rejects' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/things/*id',
|
|
controller: 'things',
|
|
action: 'show',
|
|
)
|
|
|
|
matcher = build_route_matcher(
|
|
method: :get,
|
|
path: '/things',
|
|
controller: 'things',
|
|
action: 'show',
|
|
)
|
|
|
|
is_expected.not_to(matcher)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'qualified with #with_port' do
|
|
context 'when the route is constrained to the same port' do
|
|
it 'accepts' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'show',
|
|
constraints: port_constraint_class.new(12345),
|
|
)
|
|
|
|
matcher =
|
|
build_route_matcher(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'show',
|
|
).
|
|
with_port(12345)
|
|
|
|
is_expected.to(matcher)
|
|
end
|
|
end
|
|
|
|
context 'when the route is not constrained to the same port' do
|
|
it 'rejects' do
|
|
define_controller_and_routes(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'show',
|
|
constraints: port_constraint_class.new(12345),
|
|
)
|
|
|
|
matcher =
|
|
build_route_matcher(
|
|
method: :get,
|
|
path: '/',
|
|
controller: 'things',
|
|
action: 'show',
|
|
).
|
|
with_port(99999)
|
|
|
|
is_expected.not_to(matcher)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'given a controller and action specified as individual options' do
|
|
include_examples 'core tests' do
|
|
def build_route_matcher(method:, path:, **params)
|
|
super.to(params)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'given a controller and action joined together in a string' do
|
|
include_examples 'core tests' do
|
|
def build_route_matcher(method:, path:, controller:, action:, **rest)
|
|
super.to("#{controller}##{action}", **rest)
|
|
end
|
|
end
|
|
end
|
|
|
|
def define_controller_and_routes(method:, path:, controller:, action:, **params)
|
|
define_controller(controller.camelize)
|
|
|
|
define_routes do
|
|
send(method, path, controller: controller, action: action, **params)
|
|
end
|
|
end
|
|
|
|
def build_route_matcher(method:, path:, **)
|
|
route(method, path)
|
|
end
|
|
|
|
let(:port_constraint_class) do
|
|
Class.new do
|
|
def initialize(port)
|
|
@port = port
|
|
end
|
|
|
|
def matches?(request)
|
|
request.port == port
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :port
|
|
end
|
|
end
|
|
end
|