forked from thoughtbot/shoulda-matchers
-
Notifications
You must be signed in to change notification settings - Fork 1
/
respond_with_matcher.rb
148 lines (137 loc) · 3.89 KB
/
respond_with_matcher.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
module Shoulda
module Matchers
module ActionController
# The `respond_with` matcher tests that an action responds with a certain
# status code.
#
# You can specify that the status should be a number:
#
# class PostsController < ApplicationController
# def index
# render status: 403
# end
# end
#
# # RSpec
# RSpec.describe PostsController, type: :controller do
# describe 'GET #index' do
# before { get :index }
#
# it { should respond_with(403) }
# end
# end
#
# # Minitest (Shoulda)
# class PostsControllerTest < ActionController::TestCase
# context 'GET #index' do
# setup { get :index }
#
# should respond_with(403)
# end
# end
#
# You can specify that the status should be within a range of numbers:
#
# class PostsController < ApplicationController
# def destroy
# render status: 508
# end
# end
#
# # RSpec
# RSpec.describe PostsController, type: :controller do
# describe 'DELETE #destroy' do
# before { delete :destroy }
#
# it { should respond_with(500..600) }
# end
# end
#
# # Minitest (Shoulda)
# class PostsControllerTest < ActionController::TestCase
# context 'DELETE #destroy' do
# setup { delete :destroy }
#
# should respond_with(500..600)
# end
# end
#
# Finally, you can specify that the status should be a symbol:
#
# class PostsController < ApplicationController
# def show
# render status: :locked
# end
# end
#
# # RSpec
# RSpec.describe PostsController, type: :controller do
# describe 'GET #show' do
# before { get :show }
#
# it { should respond_with(:locked) }
# end
# end
#
# # Minitest (Shoulda)
# class PostsControllerTest < ActionController::TestCase
# context 'GET #show' do
# setup { get :show }
#
# should respond_with(:locked)
# end
# end
#
# @return [RespondWithMatcher]
#
def respond_with(status)
RespondWithMatcher.new(status)
end
# @private
class RespondWithMatcher
def initialize(status)
@status = symbol_to_status_code(status)
end
def matches?(controller)
@controller = controller
correct_status_code? || correct_status_code_range?
end
def failure_message
"Expected #{expectation}"
end
def failure_message_when_negated
"Did not expect #{expectation}"
end
def description
"respond with #{@status}"
end
protected
def correct_status_code?
response_code == @status
end
def correct_status_code_range?
@status.is_a?(Range) &&
@status.include?(response_code)
end
def response_code
@controller.response.response_code
end
def symbol_to_status_code(potential_symbol)
case potential_symbol
when :success then 200
when :redirect then 300..399
when :missing then 404
when :error then 500..599
when Symbol
::Rack::Utils::SYMBOL_TO_STATUS_CODE[potential_symbol]
else
potential_symbol
end
end
def expectation
"response to be a #{@status}, but was #{response_code}"
end
end
end
end
end