1 # frozen_string_literal: true
6 class ChangesetCommentsControllerTest < ActionDispatch::IntegrationTest
8 # test all routes which lead to this controller
11 { :path => "/api/0.6/changeset_comments", :method => :get },
12 { :controller => "api/changeset_comments", :action => "index" }
15 { :path => "/api/0.6/changeset_comments.json", :method => :get },
16 { :controller => "api/changeset_comments", :action => "index", :format => "json" }
19 { :path => "/api/0.6/changeset/1/comment", :method => :post },
20 { :controller => "api/changeset_comments", :action => "create", :changeset_id => "1" }
23 { :path => "/api/0.6/changeset/1/comment.json", :method => :post },
24 { :controller => "api/changeset_comments", :action => "create", :changeset_id => "1", :format => "json" }
31 changeset1 = create(:changeset, :closed, :user => user2)
32 comment11 = create(:changeset_comment, :changeset => changeset1, :author => user1, :created_at => "2023-01-01", :body => "changeset 1 question")
33 comment12 = create(:changeset_comment, :changeset => changeset1, :author => user2, :created_at => "2023-02-01", :body => "changeset 1 answer")
34 changeset2 = create(:changeset, :closed, :user => user1)
35 comment21 = create(:changeset_comment, :changeset => changeset2, :author => user1, :created_at => "2023-03-01", :body => "changeset 2 note")
36 comment22 = create(:changeset_comment, :changeset => changeset2, :author => user1, :created_at => "2023-04-01", :body => "changeset 2 extra note")
37 comment23 = create(:changeset_comment, :changeset => changeset2, :author => user2, :created_at => "2023-05-01", :body => "changeset 2 review")
39 get api_changeset_comments_path
40 assert_response :success
41 assert_comments_in_order [comment23, comment22, comment21, comment12, comment11]
43 get api_changeset_comments_path(:limit => 3)
44 assert_response :success
45 assert_comments_in_order [comment23, comment22, comment21]
47 get api_changeset_comments_path(:from => "2023-03-15T00:00:00Z")
48 assert_response :success
49 assert_comments_in_order [comment23, comment22]
51 get api_changeset_comments_path(:from => "2023-01-15T00:00:00Z", :to => "2023-04-15T00:00:00Z")
52 assert_response :success
53 assert_comments_in_order [comment22, comment21, comment12]
55 get api_changeset_comments_path(:user => user1.id)
56 assert_response :success
57 assert_comments_in_order [comment22, comment21, comment11]
59 get api_changeset_comments_path(:from => "2023-03-15T00:00:00Z", :format => "json")
60 assert_response :success
61 js = ActiveSupport::JSON.decode(@response.body)
63 assert_equal 2, js["comments"].count
64 assert_equal comment23.id, js["comments"][0]["id"]
65 assert_equal comment22.id, js["comments"][1]["id"]
68 def test_create_by_unauthorized
69 assert_no_difference "ChangesetComment.count" do
70 post api_changeset_changeset_comments_path(create(:changeset, :closed), :text => "This is a comment")
71 assert_response :unauthorized
75 def test_create_on_missing_changeset
76 assert_no_difference "ChangesetComment.count" do
77 post api_changeset_changeset_comments_path(999111, :text => "This is a comment"), :headers => bearer_authorization_header
78 assert_response :not_found
82 def test_create_on_open_changeset
83 assert_no_difference "ChangesetComment.count" do
84 post api_changeset_changeset_comments_path(create(:changeset), :text => "This is a comment"), :headers => bearer_authorization_header
85 assert_response :conflict
89 def test_create_without_text
90 assert_no_difference "ChangesetComment.count" do
91 post api_changeset_changeset_comments_path(create(:changeset, :closed)), :headers => bearer_authorization_header
92 assert_response :bad_request
96 def test_create_with_empty_text
97 assert_no_difference "ChangesetComment.count" do
98 post api_changeset_changeset_comments_path(create(:changeset, :closed), :text => ""), :headers => bearer_authorization_header
99 assert_response :bad_request
103 def test_create_when_not_agreed_to_terms
104 user = create(:user, :terms_agreed => nil)
105 auth_header = bearer_authorization_header user
106 changeset = create(:changeset, :closed)
108 assert_difference "ChangesetComment.count", 0 do
109 post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
110 assert_response :forbidden
114 def test_create_without_required_scope
116 auth_header = bearer_authorization_header user, :scopes => %w[read_prefs]
117 changeset = create(:changeset, :closed)
119 assert_difference "ChangesetComment.count", 0 do
120 post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
121 assert_response :forbidden
125 def test_create_with_write_changeset_comments_scope
127 auth_header = bearer_authorization_header user, :scopes => %w[write_changeset_comments]
128 changeset = create(:changeset, :closed)
130 assert_difference "ChangesetComment.count", 1 do
131 post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
132 assert_response :success
135 comment = ChangesetComment.last
136 assert_equal changeset.id, comment.changeset_id
137 assert_equal user.id, comment.author_id
138 assert_equal "This is a comment", comment.body
139 assert comment.visible
142 def test_create_with_write_api_scope
144 auth_header = bearer_authorization_header user, :scopes => %w[write_api]
145 changeset = create(:changeset, :closed)
147 assert_difference "ChangesetComment.count", 1 do
148 post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
149 assert_response :success
152 comment = ChangesetComment.last
153 assert_equal changeset.id, comment.changeset_id
154 assert_equal user.id, comment.author_id
155 assert_equal "This is a comment", comment.body
156 assert comment.visible
159 def test_create_on_changeset_with_no_subscribers
160 changeset = create(:changeset, :closed)
161 auth_header = bearer_authorization_header
163 assert_difference "ChangesetComment.count", 1 do
164 assert_no_difference "ActionMailer::Base.deliveries.size" do
165 perform_enqueued_jobs do
166 post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
167 assert_response :success
173 def test_create_on_changeset_with_commenter_subscriber
175 changeset = create(:changeset, :closed, :user => user)
176 changeset.subscribers << user
177 auth_header = bearer_authorization_header user
179 assert_difference "ChangesetComment.count", 1 do
180 assert_no_difference "ActionMailer::Base.deliveries.size" do
181 perform_enqueued_jobs do
182 post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
183 assert_response :success
189 def test_create_on_changeset_with_invisible_subscribers
190 changeset = create(:changeset, :closed)
191 changeset.subscribers << create(:user, :suspended)
192 changeset.subscribers << create(:user, :deleted)
193 auth_header = bearer_authorization_header
195 assert_difference "ChangesetComment.count", 1 do
196 assert_no_difference "ActionMailer::Base.deliveries.size" do
197 perform_enqueued_jobs do
198 post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
199 assert_response :success
205 def test_create_on_changeset_with_changeset_creator_subscriber
206 creator_user = create(:user)
207 changeset = create(:changeset, :closed, :user => creator_user)
208 changeset.subscribers << creator_user
209 commenter_user = create(:user)
210 auth_header = bearer_authorization_header commenter_user
212 assert_difference "ChangesetComment.count", 1 do
213 assert_difference "ActionMailer::Base.deliveries.size", 1 do
214 perform_enqueued_jobs do
215 post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
216 assert_response :success
221 email = ActionMailer::Base.deliveries.first
222 assert_equal 1, email.to.length
223 assert_equal "[OpenStreetMap] #{commenter_user.display_name} has commented on one of your changesets", email.subject
224 assert_equal creator_user.email, email.to.first
227 def test_create_on_changeset_with_changeset_creator_and_other_user_subscribers
228 creator_user = create(:user)
229 changeset = create(:changeset, :closed, :user => creator_user)
230 changeset.subscribers << creator_user
231 subscriber_user = create(:user)
232 changeset.subscribers << subscriber_user
233 commenter_user = create(:user)
234 auth_header = bearer_authorization_header commenter_user
235 unrelated_user = create(:user)
237 assert_difference "ChangesetComment.count", 1 do
238 assert_difference "ActionMailer::Base.deliveries.size", 2 do
239 perform_enqueued_jobs do
240 post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
241 assert_response :success
246 assert_email_received creator_user.email, "[OpenStreetMap] #{commenter_user.display_name} has commented on one of your changesets"
247 assert_email_received subscriber_user.email, "[OpenStreetMap] #{commenter_user.display_name} has commented on a changeset you are interested in"
248 assert_email_not_received commenter_user.email
249 assert_email_not_received unrelated_user.email
252 def test_create_on_changeset_with_changeset_commenter_does_not_receive_email
253 creator_user = create(:user)
254 changeset = create(:changeset, :closed, :user => creator_user)
255 changeset.subscribers << creator_user
256 commenter_user = create(:user)
257 changeset.subscribers << commenter_user
258 auth_header = bearer_authorization_header commenter_user
260 assert_difference "ChangesetComment.count", 1 do
261 assert_difference "ActionMailer::Base.deliveries.size", 1 do
262 perform_enqueued_jobs do
263 post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
264 assert_response :success
269 assert_email_received creator_user.email, "[OpenStreetMap] #{commenter_user.display_name} has commented on one of your changesets"
270 assert_email_not_received commenter_user.email
274 # create comment rate limit for new users
275 def test_create_by_new_user_with_rate_limit
276 changeset = create(:changeset, :closed)
279 auth_header = bearer_authorization_header user
281 assert_difference "ChangesetComment.count", Settings.initial_changeset_comments_per_hour do
282 1.upto(Settings.initial_changeset_comments_per_hour) do |count|
283 post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
284 assert_response :success
288 assert_no_difference "ChangesetComment.count" do
289 post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
290 assert_response :too_many_requests
295 # create comment rate limit for experienced users
296 def test_create_by_experienced_user_with_rate_limit
297 changeset = create(:changeset, :closed)
299 create_list(:changeset_comment, Settings.comments_to_max_changeset_comments, :author_id => user.id, :created_at => Time.now.utc - 1.day)
301 auth_header = bearer_authorization_header user
303 assert_difference "ChangesetComment.count", Settings.max_changeset_comments_per_hour do
304 1.upto(Settings.max_changeset_comments_per_hour) do |count|
305 post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
306 assert_response :success
310 assert_no_difference "ChangesetComment.count" do
311 post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
312 assert_response :too_many_requests
317 # create comment rate limit for reported users
318 def test_create_by_reported_user_with_rate_limit
319 changeset = create(:changeset, :closed)
321 create(:issue_with_reports, :reportable => user, :reported_user => user)
323 auth_header = bearer_authorization_header user
325 assert_difference "ChangesetComment.count", Settings.initial_changeset_comments_per_hour / 2 do
326 1.upto(Settings.initial_changeset_comments_per_hour / 2) do |count|
327 post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
328 assert_response :success
332 assert_no_difference "ChangesetComment.count" do
333 post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
334 assert_response :too_many_requests
339 # create comment rate limit for moderator users
340 def test_create_by_moderator_user_with_rate_limit
341 changeset = create(:changeset, :closed)
342 user = create(:moderator_user)
344 auth_header = bearer_authorization_header user
346 assert_difference "ChangesetComment.count", Settings.moderator_changeset_comments_per_hour do
347 1.upto(Settings.moderator_changeset_comments_per_hour) do |count|
348 post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
349 assert_response :success
353 assert_no_difference "ChangesetComment.count" do
354 post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
355 assert_response :too_many_requests
362 # check that certain comments exist in the output in the specified order
363 def assert_comments_in_order(comments)
364 assert_dom "osm > comment", comments.size do |dom_comments|
365 comments.zip(dom_comments).each do |comment, dom_comment|
366 assert_dom dom_comment, "> @id", comment.id.to_s
367 assert_dom dom_comment, "> @uid", comment.author.id.to_s
368 assert_dom dom_comment, "> @user", comment.author.display_name
369 assert_dom dom_comment, "> text", comment.body