Merge remote-tracking branch 'upstream/pull/2134'
[rails.git] / test / controllers / changeset_comments_controller_test.rb
1 require "test_helper"
2
3 class ChangesetCommentsControllerTest < ActionController::TestCase
4   ##
5   # test all routes which lead to this controller
6   def test_routes
7     assert_routing(
8       { :path => "/api/0.6/changeset/1/comment", :method => :post },
9       { :controller => "changeset_comments", :action => "create", :id => "1" }
10     )
11     assert_routing(
12       { :path => "/api/0.6/changeset/comment/1/hide", :method => :post },
13       { :controller => "changeset_comments", :action => "destroy", :id => "1" }
14     )
15     assert_routing(
16       { :path => "/api/0.6/changeset/comment/1/unhide", :method => :post },
17       { :controller => "changeset_comments", :action => "restore", :id => "1" }
18     )
19     assert_routing(
20       { :path => "/changeset/1/comments/feed", :method => :get },
21       { :controller => "changeset_comments", :action => "index", :id => "1", :format => "rss" }
22     )
23     assert_routing(
24       { :path => "/history/comments/feed", :method => :get },
25       { :controller => "changeset_comments", :action => "index", :format => "rss" }
26     )
27   end
28
29   ##
30   # create comment success
31   def test_create_comment_success
32     user = create(:user)
33     user2 = create(:user)
34     private_user = create(:user, :data_public => false)
35     suspended_user = create(:user, :suspended)
36     deleted_user = create(:user, :deleted)
37     private_user_closed_changeset = create(:changeset, :closed, :user => private_user)
38
39     basic_authorization user.email, "test"
40
41     assert_difference "ChangesetComment.count", 1 do
42       assert_no_difference "ActionMailer::Base.deliveries.size" do
43         perform_enqueued_jobs do
44           post :create, :params => { :id => private_user_closed_changeset.id, :text => "This is a comment" }
45         end
46       end
47     end
48     assert_response :success
49
50     changeset = create(:changeset, :closed, :user => private_user)
51     changeset.subscribers.push(private_user)
52     changeset.subscribers.push(user)
53     changeset.subscribers.push(suspended_user)
54     changeset.subscribers.push(deleted_user)
55
56     assert_difference "ChangesetComment.count", 1 do
57       assert_difference "ActionMailer::Base.deliveries.size", 1 do
58         perform_enqueued_jobs do
59           post :create, :params => { :id => changeset.id, :text => "This is a comment" }
60         end
61       end
62     end
63     assert_response :success
64
65     email = ActionMailer::Base.deliveries.first
66     assert_equal 1, email.to.length
67     assert_equal "[OpenStreetMap] #{user.display_name} has commented on one of your changesets", email.subject
68     assert_equal private_user.email, email.to.first
69
70     ActionMailer::Base.deliveries.clear
71
72     basic_authorization user2.email, "test"
73
74     assert_difference "ChangesetComment.count", 1 do
75       assert_difference "ActionMailer::Base.deliveries.size", 2 do
76         perform_enqueued_jobs do
77           post :create, :params => { :id => changeset.id, :text => "This is a comment" }
78         end
79       end
80     end
81     assert_response :success
82
83     email = ActionMailer::Base.deliveries.find { |e| e.to.first == private_user.email }
84     assert_not_nil email
85     assert_equal 1, email.to.length
86     assert_equal "[OpenStreetMap] #{user2.display_name} has commented on one of your changesets", email.subject
87
88     email = ActionMailer::Base.deliveries.find { |e| e.to.first == user.email }
89     assert_not_nil email
90     assert_equal 1, email.to.length
91     assert_equal "[OpenStreetMap] #{user2.display_name} has commented on a changeset you are interested in", email.subject
92
93     ActionMailer::Base.deliveries.clear
94   end
95
96   ##
97   # create comment fail
98   def test_create_comment_fail
99     # unauthorized
100     post :create, :params => { :id => create(:changeset, :closed).id, :text => "This is a comment" }
101     assert_response :unauthorized
102
103     basic_authorization create(:user).email, "test"
104
105     # bad changeset id
106     assert_no_difference "ChangesetComment.count" do
107       post :create, :params => { :id => 999111, :text => "This is a comment" }
108     end
109     assert_response :not_found
110
111     # not closed changeset
112     assert_no_difference "ChangesetComment.count" do
113       post :create, :params => { :id => create(:changeset).id, :text => "This is a comment" }
114     end
115     assert_response :conflict
116
117     # no text
118     assert_no_difference "ChangesetComment.count" do
119       post :create, :params => { :id => create(:changeset, :closed).id }
120     end
121     assert_response :bad_request
122
123     # empty text
124     assert_no_difference "ChangesetComment.count" do
125       post :create, :params => { :id => create(:changeset, :closed).id, :text => "" }
126     end
127     assert_response :bad_request
128   end
129
130   ##
131   # test hide comment fail
132   def test_destroy_comment_fail
133     # unauthorized
134     comment = create(:changeset_comment)
135     assert_equal true, comment.visible
136
137     post :destroy, :params => { :id => comment.id }
138     assert_response :unauthorized
139     assert_equal true, comment.reload.visible
140
141     basic_authorization create(:user).email, "test"
142
143     # not a moderator
144     post :destroy, :params => { :id => comment.id }
145     assert_response :forbidden
146     assert_equal true, comment.reload.visible
147
148     basic_authorization create(:moderator_user).email, "test"
149
150     # bad comment id
151     post :destroy, :params => { :id => 999111 }
152     assert_response :not_found
153     assert_equal true, comment.reload.visible
154   end
155
156   ##
157   # test hide comment succes
158   def test_hide_comment_success
159     comment = create(:changeset_comment)
160     assert_equal true, comment.visible
161
162     basic_authorization create(:moderator_user).email, "test"
163
164     post :destroy, :params => { :id => comment.id }
165     assert_response :success
166     assert_equal false, comment.reload.visible
167   end
168
169   ##
170   # test unhide comment fail
171   def test_restore_comment_fail
172     # unauthorized
173     comment = create(:changeset_comment, :visible => false)
174     assert_equal false, comment.visible
175
176     post :restore, :params => { :id => comment.id }
177     assert_response :unauthorized
178     assert_equal false, comment.reload.visible
179
180     basic_authorization create(:user).email, "test"
181
182     # not a moderator
183     post :restore, :params => { :id => comment.id }
184     assert_response :forbidden
185     assert_equal false, comment.reload.visible
186
187     basic_authorization create(:moderator_user).email, "test"
188
189     # bad comment id
190     post :restore, :params => { :id => 999111 }
191     assert_response :not_found
192     assert_equal false, comment.reload.visible
193   end
194
195   ##
196   # test unhide comment succes
197   def test_unhide_comment_success
198     comment = create(:changeset_comment, :visible => false)
199     assert_equal false, comment.visible
200
201     basic_authorization create(:moderator_user).email, "test"
202
203     post :restore, :params => { :id => comment.id }
204     assert_response :success
205     assert_equal true, comment.reload.visible
206   end
207
208   ##
209   # test comments feed
210   def test_feed
211     changeset = create(:changeset, :closed)
212     create_list(:changeset_comment, 3, :changeset => changeset)
213
214     get :index, :params => { :format => "rss" }
215     assert_response :success
216     assert_equal "application/rss+xml", @response.content_type
217     assert_select "rss", :count => 1 do
218       assert_select "channel", :count => 1 do
219         assert_select "item", :count => 3
220       end
221     end
222
223     get :index, :params => { :format => "rss", :limit => 2 }
224     assert_response :success
225     assert_equal "application/rss+xml", @response.content_type
226     assert_select "rss", :count => 1 do
227       assert_select "channel", :count => 1 do
228         assert_select "item", :count => 2
229       end
230     end
231
232     get :index, :params => { :id => changeset.id, :format => "rss" }
233     assert_response :success
234     assert_equal "application/rss+xml", @response.content_type
235     assert_select "rss", :count => 1 do
236       assert_select "channel", :count => 1 do
237         assert_select "item", :count => 3
238       end
239     end
240   end
241
242   ##
243   # test comments feed
244   def test_feed_bad_limit
245     get :index, :params => { :format => "rss", :limit => 0 }
246     assert_response :bad_request
247
248     get :index, :params => { :format => "rss", :limit => 100001 }
249     assert_response :bad_request
250   end
251
252   # This test ensures that token capabilities behave correctly for a method that
253   # requires the terms to have been agreed.
254   # (This would be better as an integration or system testcase, since the changeset_comment
255   # create method is simply a stand-in for any method that requires terms agreement.
256   # But writing oauth tests is hard, and so it's easier to put in a controller test.)
257   def test_api_write_and_terms_agreed_via_token
258     with_terms_agreed(true) do
259       user = create(:user, :terms_agreed => nil)
260       token = create(:access_token, :user => user, :allow_write_api => true)
261       changeset = create(:changeset, :closed)
262
263       # Hack together an oauth request - an alternative would be to sign the request properly
264       @request.env["oauth.version"] = 1
265       @request.env["oauth.strategies"] = [:token]
266       @request.env["oauth.token"] = token
267
268       assert_difference "ChangesetComment.count", 0 do
269         post :create, :params => { :id => changeset.id, :text => "This is a comment" }
270       end
271       assert_response :forbidden
272
273       # Try again, after agreement with the terms
274       user.terms_agreed = Time.now
275       user.save!
276
277       assert_difference "ChangesetComment.count", 1 do
278         post :create, :params => { :id => changeset.id, :text => "This is a comment" }
279       end
280       assert_response :success
281     end
282   end
283
284   # This test does the same as above, but with basic auth, to similarly test that the
285   # abilities take into account terms agreement too.
286   def test_api_write_and_terms_agreed_via_basic_auth
287     with_terms_agreed(true) do
288       user = create(:user, :terms_agreed => nil)
289       changeset = create(:changeset, :closed)
290
291       basic_authorization user.email, "test"
292
293       assert_difference "ChangesetComment.count", 0 do
294         post :create, :params => { :id => changeset.id, :text => "This is a comment" }
295       end
296       assert_response :forbidden
297
298       # Try again, after agreement with the terms
299       user.terms_agreed = Time.now
300       user.save!
301
302       assert_difference "ChangesetComment.count", 1 do
303         post :create, :params => { :id => changeset.id, :text => "This is a comment" }
304       end
305       assert_response :success
306     end
307   end
308
309   private
310
311   def with_terms_agreed(value)
312     require_terms_agreed = Object.send("remove_const", "REQUIRE_TERMS_AGREED")
313     Object.const_set("REQUIRE_TERMS_AGREED", value)
314
315     yield
316
317     Object.send("remove_const", "REQUIRE_TERMS_AGREED")
318     Object.const_set("REQUIRE_TERMS_AGREED", require_terms_agreed)
319   end
320 end