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 other_user = create(:user)
232 changeset.subscribers << other_user
233 commenter_user = create(:user)
234 auth_header = bearer_authorization_header commenter_user
236 assert_difference "ChangesetComment.count", 1 do
237 assert_difference "ActionMailer::Base.deliveries.size", 2 do
238 perform_enqueued_jobs do
239 post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
240 assert_response :success
245 email = ActionMailer::Base.deliveries.find { |e| e.to.first == creator_user.email }
247 assert_equal 1, email.to.length
248 assert_equal "[OpenStreetMap] #{commenter_user.display_name} has commented on one of your changesets", email.subject
250 email = ActionMailer::Base.deliveries.find { |e| e.to.first == other_user.email }
252 assert_equal 1, email.to.length
253 assert_equal "[OpenStreetMap] #{commenter_user.display_name} has commented on a changeset you are interested in", email.subject
257 # create comment rate limit for new users
258 def test_create_by_new_user_with_rate_limit
259 changeset = create(:changeset, :closed)
262 auth_header = bearer_authorization_header user
264 assert_difference "ChangesetComment.count", Settings.initial_changeset_comments_per_hour do
265 1.upto(Settings.initial_changeset_comments_per_hour) do |count|
266 post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
267 assert_response :success
271 assert_no_difference "ChangesetComment.count" do
272 post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
273 assert_response :too_many_requests
278 # create comment rate limit for experienced users
279 def test_create_by_experienced_user_with_rate_limit
280 changeset = create(:changeset, :closed)
282 create_list(:changeset_comment, Settings.comments_to_max_changeset_comments, :author_id => user.id, :created_at => Time.now.utc - 1.day)
284 auth_header = bearer_authorization_header user
286 assert_difference "ChangesetComment.count", Settings.max_changeset_comments_per_hour do
287 1.upto(Settings.max_changeset_comments_per_hour) do |count|
288 post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
289 assert_response :success
293 assert_no_difference "ChangesetComment.count" do
294 post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
295 assert_response :too_many_requests
300 # create comment rate limit for reported users
301 def test_create_by_reported_user_with_rate_limit
302 changeset = create(:changeset, :closed)
304 create(:issue_with_reports, :reportable => user, :reported_user => user)
306 auth_header = bearer_authorization_header user
308 assert_difference "ChangesetComment.count", Settings.initial_changeset_comments_per_hour / 2 do
309 1.upto(Settings.initial_changeset_comments_per_hour / 2) do |count|
310 post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
311 assert_response :success
315 assert_no_difference "ChangesetComment.count" do
316 post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
317 assert_response :too_many_requests
322 # create comment rate limit for moderator users
323 def test_create_by_moderator_user_with_rate_limit
324 changeset = create(:changeset, :closed)
325 user = create(:moderator_user)
327 auth_header = bearer_authorization_header user
329 assert_difference "ChangesetComment.count", Settings.moderator_changeset_comments_per_hour do
330 1.upto(Settings.moderator_changeset_comments_per_hour) do |count|
331 post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
332 assert_response :success
336 assert_no_difference "ChangesetComment.count" do
337 post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
338 assert_response :too_many_requests
345 # check that certain comments exist in the output in the specified order
346 def assert_comments_in_order(comments)
347 assert_dom "osm > comment", comments.size do |dom_comments|
348 comments.zip(dom_comments).each do |comment, dom_comment|
349 assert_dom dom_comment, "> @id", comment.id.to_s
350 assert_dom dom_comment, "> @uid", comment.author.id.to_s
351 assert_dom dom_comment, "> @user", comment.author.display_name
352 assert_dom dom_comment, "> text", comment.body