Skip to content

Commit a3c86de

Browse files
Rails model, controller, and route tests
1 parent 8ca0a4b commit a3c86de

File tree

9 files changed

+514
-0
lines changed

9 files changed

+514
-0
lines changed

.rubocop.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,14 @@ Metrics/MethodLength:
2828

2929
Metrics/BlockLength:
3030
Max: 105
31+
ExcludedMethods: [describe]
3132

3233
Style/StringLiterals:
3334
EnforcedStyle: double_quotes
3435

3536
Style/Documentation:
3637
Enabled: false
38+
39+
Style/BracesAroundHashParameters:
40+
Exclude:
41+
- spec/controllers/**/*

Gemfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ group :development, :test do
9292
end
9393

9494
group :test do
95+
gem "airborne"
96+
gem "api_matchers"
9597
gem "capybara", "2.13.0"
9698
gem "capybara-screenshot"
9799
gem "capybara-webkit", "1.14.0"
@@ -101,6 +103,7 @@ group :test do
101103
gem "generator_spec"
102104
gem "launchy"
103105
gem "poltergeist"
106+
gem "rails-controller-testing"
104107
gem "rails_best_practices"
105108
gem "rspec-rails", "3.6.1"
106109
gem "rspec-retry"
Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
require "rails_helper"
2+
require "airborne"
3+
require "controllers/shared/comments_factory"
4+
5+
describe CommentsController do
6+
render_views
7+
8+
include_examples "Comments Factory", true
9+
10+
subject(:comment_attrs) do
11+
{ author: author, text: text }
12+
end
13+
let(:author) { "Ponkey" }
14+
let(:text) { "Says wheeeee..." }
15+
16+
describe "GET #index," do
17+
subject(:index_comments) { get :index, format: format }
18+
let(:format) { :html }
19+
20+
before { index_comments }
21+
22+
it "assigns @comments with Comments.all in DESC order," do
23+
expect(assigns(:comments)).to match_array(comments_list.reverse)
24+
end
25+
26+
it "renders the :index template," do
27+
expect(response).to render_template :index
28+
end
29+
30+
describe "when JSON is requested" do
31+
let(:format) { :json }
32+
33+
it "returns JSON comments list in DESC order," do
34+
expect_json(
35+
"comments.0",
36+
author: "Iesha",
37+
text: "And a comment response..."
38+
)
39+
expect_json(
40+
"comments.1",
41+
author: "Bai",
42+
text: "Some comment text..."
43+
)
44+
end
45+
end
46+
end
47+
48+
describe "GET #show," do
49+
subject(:show_comment) do
50+
get :show,
51+
params: { id: comment.id },
52+
format: format
53+
end
54+
let(:format) { :html }
55+
56+
before { show_comment }
57+
58+
it "assigns id'ed Comment as @comment," do
59+
expect(assigns(:comment)).to eq(comment)
60+
end
61+
62+
it "renders the :show template," do
63+
expect(response).to render_template :show
64+
end
65+
66+
describe "when JSON is requested" do
67+
let(:format) { :json }
68+
69+
it "returns JSON for @comment," do
70+
expect_json({ author: "Bai", text: "Some comment text..." })
71+
end
72+
end
73+
end
74+
75+
describe "GET @new" do
76+
subject(:new_comment) do
77+
get :new
78+
end
79+
80+
before { new_comment }
81+
82+
it "assigns a new Comment as @comment," do
83+
expect(assigns(:comment)).to be_a_new(Comment)
84+
end
85+
86+
it "renders the :new template," do
87+
expect(response).to render_template(:new)
88+
end
89+
end
90+
91+
describe "GET @edit" do
92+
subject(:edit_comment) do
93+
get :edit, params: { id: comment.id }
94+
end
95+
96+
before { edit_comment }
97+
98+
it "assigns the id'ed Comment as @comment," do
99+
expect(assigns(:comment)).to eq(comment)
100+
end
101+
102+
it "renders the :edit template," do
103+
expect(response).to render_template(:edit)
104+
end
105+
end
106+
107+
describe "POST #create," do
108+
subject(:create_comment) do
109+
post :create, params: { comment: comment_attrs, format: format }, xhr: true
110+
end
111+
let(:format) { :json }
112+
113+
context "when creating succeeds," do
114+
it "saves a Comment in the database," do
115+
expect { create_comment }.to change(Comment, :count).by(1)
116+
end
117+
118+
it "assigns @comment with the created Comment," do
119+
create_comment
120+
expect(assigns(:comment)).to be_a(Comment)
121+
expect(assigns(:comment)).to have_attributes(
122+
author: "Ponkey",
123+
text: "Says wheeeee..."
124+
)
125+
end
126+
127+
context "when JSON is requested," do
128+
before { create_comment }
129+
130+
it "renders the :show template," do
131+
expect(response).to render_template(:show)
132+
end
133+
134+
it "returns JSON for the created comment," do
135+
expect_json({ author: "Ponkey", text: "Says wheeeee..." })
136+
end
137+
138+
it "returns a HTTP status of 201," do
139+
expect(response).to have_http_status(:created)
140+
end
141+
142+
it "sets the @comments' HTTP location header," do
143+
expect(response.header["Location"])
144+
.to eq("http://test.host/comments/#{assigns(:comment).id}")
145+
end
146+
end
147+
148+
context "when HTML is requested," do
149+
before { create_comment }
150+
let(:format) { :html }
151+
152+
it "returns a HTTP status of 302," do
153+
expect(response).to have_http_status(:found)
154+
end
155+
156+
it "sets a flash notice," do
157+
expect(flash[:notice]).to eq("Comment was successfully created.")
158+
end
159+
160+
it "redirects to the @comment," do
161+
expect(response).to redirect_to(assigns(:comment))
162+
end
163+
end
164+
end
165+
166+
context "when creating fails," do
167+
let(:comment_attrs) do
168+
{ author: "", text: "text" }
169+
end
170+
171+
it "assigns @comment with new Comment JSON," do
172+
create_comment
173+
expect(assigns(@comment)["comment"]).to be_a_new(Comment)
174+
end
175+
176+
it "does not save a new Comment to the database," do
177+
expect { create_comment }.not_to change(Comment, :count)
178+
end
179+
180+
context "when JSON is requested," do
181+
before { create_comment }
182+
183+
it "returns a HTTP status of 422," do
184+
expect(response).to have_http_status(:unprocessable_entity)
185+
end
186+
187+
it "renders error information JSON," do
188+
expect_json({ author: ["can't be blank"] })
189+
end
190+
end
191+
192+
context "when HTML is requested," do
193+
let(:format) { :html }
194+
195+
it "renders the :new template," do
196+
create_comment
197+
expect(response).to render_template(:new)
198+
end
199+
end
200+
end
201+
end
202+
203+
describe "PATCH #update," do
204+
subject(:update_comment) do
205+
patch :update,
206+
params: { id: comment.id, comment: comment_attrs, format: format },
207+
xhr: true
208+
end
209+
let(:format) { :json }
210+
211+
before do
212+
update_comment
213+
comment.reload
214+
end
215+
216+
context "when updating succeeds," do
217+
it "locates a Comment and assigns it to @comment," do
218+
expect(assigns(:comment)).to eq(comment)
219+
end
220+
221+
it "updates the Comment," do
222+
expect(assigns(:comment)).to have_attributes(
223+
author: "Ponkey",
224+
text: "Says wheeeee..."
225+
)
226+
end
227+
228+
context "when JSON is requested," do
229+
it "renders the :show template," do
230+
expect(response).to render_template(:show)
231+
end
232+
233+
it "returns JSON for the created comment," do
234+
expect_json({ author: "Ponkey", text: "Says wheeeee..." })
235+
end
236+
237+
it "returns a HTTP status of 201," do
238+
expect(response).to have_http_status(:ok)
239+
end
240+
241+
it "sets the @comments' HTTP location header," do
242+
expect(response.header["Location"])
243+
.to eq("http://test.host/comments/#{assigns(:comment).id}")
244+
end
245+
end
246+
247+
context "when HTML is requested," do
248+
let(:format) { :html }
249+
250+
it "returns a HTTP status of 302," do
251+
expect(response).to have_http_status(:found)
252+
end
253+
254+
it "sets a flash notice," do
255+
expect(flash[:notice]).to eq("Comment was successfully updated.")
256+
end
257+
258+
it "redirects to the @comment," do
259+
expect(response).to redirect_to(assigns(:comment))
260+
end
261+
end
262+
end
263+
264+
context "when updating fails," do
265+
let(:comment_attrs) do
266+
{ author: nil, text: "Text present..." }
267+
end
268+
269+
it "does not update the @comment," do
270+
expect(comment).to have_attributes(
271+
author: "Bai",
272+
text: "Some comment text..."
273+
)
274+
end
275+
276+
context "when JSON is requested," do
277+
it "renders error information JSON," do
278+
expect_json({ author: ["can't be blank"] })
279+
end
280+
281+
it "returns a HTTP status of 422," do
282+
expect(response).to have_http_status(:unprocessable_entity)
283+
end
284+
end
285+
286+
context "when HTML is requested," do
287+
before { update_comment }
288+
let(:format) { :html }
289+
290+
it "renders the :new template," do
291+
expect(response).to render_template(:edit)
292+
end
293+
end
294+
end
295+
end
296+
297+
describe "DELETE destroy" do
298+
before { comment }
299+
300+
subject(:destroy_comment) do
301+
delete :destroy, params: { id: comment_id, format: format }, xhr: true
302+
end
303+
let(:comment_id) { comment.id }
304+
let(:format) { :json }
305+
306+
describe "when an existing Comment is id'ed," do
307+
it "deletes the id'ed @comment" do
308+
expect { destroy_comment }.to change(Comment, :count).by(-1)
309+
end
310+
311+
describe "when JSON is requested" do
312+
it "returns an HTTP status of 204," do
313+
destroy_comment
314+
expect(response).to have_http_status(:no_content)
315+
end
316+
end
317+
318+
describe "when HTML is requested" do
319+
let(:format) { :html }
320+
321+
it "deletes the id'ed @comment" do
322+
expect { destroy_comment }.to change(Comment, :count).by(-1)
323+
end
324+
325+
it "redirects to comments_url," do
326+
destroy_comment
327+
expect(response).to redirect_to(comments_url)
328+
end
329+
330+
it "adds a flash:notice message," do
331+
destroy_comment
332+
expect(flash[:notice]).to eq("Comment was successfully destroyed.")
333+
end
334+
end
335+
end
336+
337+
describe "when the id'ed Comment does not exist," do
338+
let(:comment_id) { 23 }
339+
340+
it "raises a RecordNotFound error," do
341+
expect { destroy_comment }.to raise_error(ActiveRecord::RecordNotFound)
342+
end
343+
end
344+
end
345+
end

0 commit comments

Comments
 (0)