]> git.openstreetmap.org Git - rails.git/blob - test/controllers/api/users_controller_test.rb
feat: add social links and company to user api endpoint
[rails.git] / test / controllers / api / users_controller_test.rb
1 # frozen_string_literal: true
2
3 require "test_helper"
4
5 module Api
6   class UsersControllerTest < ActionDispatch::IntegrationTest
7     ##
8     # test all routes which lead to this controller
9     def test_routes
10       assert_routing(
11         { :path => "/api/0.6/user/1", :method => :get },
12         { :controller => "api/users", :action => "show", :id => "1" }
13       )
14       assert_routing(
15         { :path => "/api/0.6/user/1.json", :method => :get },
16         { :controller => "api/users", :action => "show", :id => "1", :format => "json" }
17       )
18       assert_routing(
19         { :path => "/api/0.6/user/details", :method => :get },
20         { :controller => "api/users", :action => "details" }
21       )
22       assert_routing(
23         { :path => "/api/0.6/user/details.json", :method => :get },
24         { :controller => "api/users", :action => "details", :format => "json" }
25       )
26       assert_routing(
27         { :path => "/api/0.6/users", :method => :get },
28         { :controller => "api/users", :action => "index" }
29       )
30       assert_routing(
31         { :path => "/api/0.6/users.json", :method => :get },
32         { :controller => "api/users", :action => "index", :format => "json" }
33       )
34     end
35
36     def test_show
37       user = create(:user,
38                     :description => "test",
39                     :terms_agreed => Date.yesterday,
40                     :home_lat => 12.1, :home_lon => 23.4,
41                     :languages => ["en"]) do |user|
42                       create(:social_link, :user => user, :url => "https://twitter.com/testuser")
43                       create(:social_link, :user => user, :url => "https://github.com/testuser")
44                     end
45
46       # check that a visible user is returned properly
47       get api_user_path(:id => user.id)
48       assert_response :success
49       assert_equal "application/xml", response.media_type
50
51       # check the data that is returned
52       check_xml_details(user, false, false)
53
54       # check that a suspended user is not returned
55       get api_user_path(:id => create(:user, :suspended).id)
56       assert_response :gone
57
58       # check that a deleted user is not returned
59       get api_user_path(:id => create(:user, :deleted).id)
60       assert_response :gone
61
62       # check that a non-existent user is not returned
63       get api_user_path(:id => 0)
64       assert_response :not_found
65
66       # check that a visible user is returned properly in json
67       get api_user_path(:id => user.id, :format => "json")
68       assert_response :success
69       assert_equal "application/json", response.media_type
70
71       # parse the response
72       js = ActiveSupport::JSON.decode(@response.body)
73       assert_not_nil js
74
75       # check the data that is returned
76       check_json_details(js, user, false, false)
77     end
78
79     def test_show_oauth2
80       user = create(:user,
81                     :home_lat => 12.1, :home_lon => 23.4,
82                     :languages => ["en"])
83       good_auth = bearer_authorization_header(user, :scopes => %w[read_prefs])
84       bad_auth = bearer_authorization_header(user, :scopes => %w[])
85       other_user = create(:user,
86                           :home_lat => 12.1, :home_lon => 23.4,
87                           :languages => ["en"])
88
89       # check that we can fetch our own details as XML with read_prefs
90       get api_user_path(:id => user.id), :headers => good_auth
91       assert_response :success
92       assert_equal "application/xml", response.media_type
93
94       # check the data that is returned
95       check_xml_details(user, true, false)
96
97       # check that we can fetch a different user's details as XML with read_prefs
98       get api_user_path(:id => other_user.id), :headers => good_auth
99       assert_response :success
100       assert_equal "application/xml", response.media_type
101
102       # check the data that is returned
103       check_xml_details(other_user, false, false)
104
105       # check that we can fetch our own details as XML without read_prefs
106       get api_user_path(:id => user.id), :headers => bad_auth
107       assert_response :success
108       assert_equal "application/xml", response.media_type
109
110       # check the data that is returned
111       check_xml_details(user, false, false)
112
113       # check that we can fetch our own details as JSON with read_prefs
114       get api_user_path(:id => user.id, :format => "json"), :headers => good_auth
115       assert_response :success
116       assert_equal "application/json", response.media_type
117
118       # parse the response
119       js = ActiveSupport::JSON.decode(@response.body)
120       assert_not_nil js
121
122       # check the data that is returned
123       check_json_details(js, user, true, false)
124
125       # check that we can fetch a different user's details as JSON with read_prefs
126       get api_user_path(:id => other_user.id, :format => "json"), :headers => good_auth
127       assert_response :success
128       assert_equal "application/json", response.media_type
129
130       # parse the response
131       js = ActiveSupport::JSON.decode(@response.body)
132       assert_not_nil js
133
134       # check the data that is returned
135       check_json_details(js, other_user, false, false)
136
137       # check that we can fetch our own details as JSON without read_prefs
138       get api_user_path(:id => user.id, :format => "json"), :headers => bad_auth
139       assert_response :success
140       assert_equal "application/json", response.media_type
141
142       # parse the response
143       js = ActiveSupport::JSON.decode(@response.body)
144       assert_not_nil js
145
146       # check the data that is returned
147       check_json_details(js, user, false, false)
148     end
149
150     def test_details
151       user = create(:user,
152                     :description => "test",
153                     :terms_agreed => Date.yesterday,
154                     :home_lat => 12.1, :home_lon => 23.4,
155                     :languages => ["en"])
156       create(:message, :read, :recipient => user)
157       create(:message, :sender => user)
158
159       # check that nothing is returned when not logged in
160       get api_user_details_path
161       assert_response :unauthorized
162
163       # check that we get a response when logged in
164       auth_header = bearer_authorization_header user
165       get api_user_details_path, :headers => auth_header
166       assert_response :success
167       assert_equal "application/xml", response.media_type
168
169       # check the data that is returned
170       check_xml_details(user, true, false)
171
172       # check that data is returned properly in json
173       auth_header = bearer_authorization_header user
174       get api_user_details_path(:format => "json"), :headers => auth_header
175       assert_response :success
176       assert_equal "application/json", response.media_type
177
178       # parse the response
179       js = ActiveSupport::JSON.decode(@response.body)
180       assert_not_nil js
181
182       # check the data that is returned
183       check_json_details(js, user, true, false)
184     end
185
186     def test_details_oauth2
187       user = create(:user,
188                     :home_lat => 12.1, :home_lon => 23.4,
189                     :languages => ["en"])
190       good_auth = bearer_authorization_header(user, :scopes => %w[read_prefs])
191       bad_auth = bearer_authorization_header(user, :scopes => %w[])
192       email_auth = bearer_authorization_header(user, :scopes => %w[read_prefs read_email])
193
194       # check that we can't fetch details as XML without read_prefs
195       get api_user_details_path, :headers => bad_auth
196       assert_response :forbidden
197
198       # check that we can fetch details as XML without read_email
199       get api_user_details_path, :headers => good_auth
200       assert_response :success
201       assert_equal "application/xml", response.media_type
202
203       # check the data that is returned
204       check_xml_details(user, true, false)
205
206       # check that we can fetch details as XML with read_email
207       get api_user_details_path, :headers => email_auth
208       assert_response :success
209       assert_equal "application/xml", response.media_type
210
211       # check the data that is returned
212       check_xml_details(user, true, true)
213
214       # check that we can't fetch details as JSON without read_prefs
215       get api_user_details_path(:format => "json"), :headers => bad_auth
216       assert_response :forbidden
217
218       # check that we can fetch details as JSON without read_email
219       get api_user_details_path(:format => "json"), :headers => good_auth
220       assert_response :success
221       assert_equal "application/json", response.media_type
222
223       # parse the response
224       js = ActiveSupport::JSON.decode(@response.body)
225       assert_not_nil js
226
227       # check the data that is returned
228       check_json_details(js, user, true, false)
229
230       # check that we can fetch details as JSON with read_email
231       get api_user_details_path(:format => "json"), :headers => email_auth
232       assert_response :success
233       assert_equal "application/json", response.media_type
234
235       # parse the response
236       js = ActiveSupport::JSON.decode(@response.body)
237       assert_not_nil js
238
239       # check the data that is returned
240       check_json_details(js, user, true, true)
241     end
242
243     def test_index
244       user1 = create(:user, :description => "test1", :terms_agreed => Date.yesterday)
245       user2 = create(:user, :description => "test2", :terms_agreed => Date.yesterday)
246       user3 = create(:user, :description => "test3", :terms_agreed => Date.yesterday)
247
248       get api_users_path, :params => { :users => user1.id }
249       assert_response :success
250       assert_equal "application/xml", response.media_type
251       assert_select "user", :count => 1 do
252         check_xml_details(user1, false, false)
253         assert_select "user[id='#{user2.id}']", :count => 0
254         assert_select "user[id='#{user3.id}']", :count => 0
255       end
256
257       get api_users_path, :params => { :users => user2.id }
258       assert_response :success
259       assert_equal "application/xml", response.media_type
260       assert_select "user", :count => 1 do
261         assert_select "user[id='#{user1.id}']", :count => 0
262         check_xml_details(user2, false, false)
263         assert_select "user[id='#{user3.id}']", :count => 0
264       end
265
266       get api_users_path, :params => { :users => "#{user1.id},#{user3.id}" }
267       assert_response :success
268       assert_equal "application/xml", response.media_type
269       assert_select "user", :count => 2 do
270         check_xml_details(user1, false, false)
271         assert_select "user[id='#{user2.id}']", :count => 0
272         check_xml_details(user3, false, false)
273       end
274
275       get api_users_path, :params => { :users => user1.id, :format => "json" }
276       assert_response :success
277       assert_equal "application/json", response.media_type
278       js = ActiveSupport::JSON.decode(@response.body)
279       assert_not_nil js
280       assert_equal 1, js["users"].count
281       check_json_details(js["users"][0], user1, false, false)
282
283       get api_users_path, :params => { :users => user2.id, :format => "json" }
284       assert_response :success
285       assert_equal "application/json", response.media_type
286       js = ActiveSupport::JSON.decode(@response.body)
287       assert_not_nil js
288       assert_equal 1, js["users"].count
289       check_json_details(js["users"][0], user2, false, false)
290
291       get api_users_path, :params => { :users => "#{user1.id},#{user3.id}", :format => "json" }
292       assert_response :success
293       assert_equal "application/json", response.media_type
294       js = ActiveSupport::JSON.decode(@response.body)
295       assert_not_nil js
296       assert_equal 2, js["users"].count
297       check_json_details(js["users"][0], user1, false, false)
298       check_json_details(js["users"][1], user3, false, false)
299
300       get api_users_path, :params => { :users => create(:user, :suspended).id }
301       assert_response :success
302       assert_equal "application/xml", response.media_type
303       assert_select "user", :count => 0
304
305       get api_users_path, :params => { :users => create(:user, :deleted).id }
306       assert_response :success
307       assert_equal "application/xml", response.media_type
308       assert_select "user", :count => 0
309
310       get api_users_path, :params => { :users => 0 }
311       assert_response :success
312       assert_equal "application/xml", response.media_type
313       assert_select "user", :count => 0
314     end
315
316     def test_index_oauth2
317       user1 = create(:user, :description => "test1", :terms_agreed => Date.yesterday)
318       user2 = create(:user, :description => "test2", :terms_agreed => Date.yesterday)
319       user3 = create(:user, :description => "test3", :terms_agreed => Date.yesterday)
320       good_auth = bearer_authorization_header(user1, :scopes => %w[read_prefs])
321       bad_auth = bearer_authorization_header(user1, :scopes => %w[])
322
323       get api_users_path, :params => { :users => user1.id }, :headers => good_auth
324       assert_response :success
325       assert_equal "application/xml", response.media_type
326       assert_select "user", :count => 1 do
327         check_xml_details(user1, true, false)
328         assert_select "user[id='#{user2.id}']", :count => 0
329         assert_select "user[id='#{user3.id}']", :count => 0
330       end
331
332       get api_users_path, :params => { :users => user2.id }, :headers => good_auth
333       assert_response :success
334       assert_equal "application/xml", response.media_type
335       assert_select "user", :count => 1 do
336         assert_select "user[id='#{user1.id}']", :count => 0
337         check_xml_details(user2, false, false)
338         assert_select "user[id='#{user3.id}']", :count => 0
339       end
340
341       get api_users_path, :params => { :users => "#{user1.id},#{user3.id}" }, :headers => good_auth
342       assert_response :success
343       assert_equal "application/xml", response.media_type
344       assert_select "user", :count => 2 do
345         check_xml_details(user1, true, false)
346         assert_select "user[id='#{user2.id}']", :count => 0
347         check_xml_details(user3, false, false)
348       end
349
350       get api_users_path, :params => { :users => "#{user1.id},#{user3.id}" }, :headers => bad_auth
351       assert_response :success
352       assert_equal "application/xml", response.media_type
353       assert_select "user", :count => 2 do
354         check_xml_details(user1, false, false)
355         assert_select "user[id='#{user2.id}']", :count => 0
356         check_xml_details(user3, false, false)
357       end
358
359       get api_users_path, :params => { :users => user1.id, :format => "json" }, :headers => good_auth
360       assert_response :success
361       assert_equal "application/json", response.media_type
362       js = ActiveSupport::JSON.decode(@response.body)
363       assert_not_nil js
364       assert_equal 1, js["users"].count
365       check_json_details(js["users"][0], user1, true, false)
366
367       get api_users_path, :params => { :users => user2.id, :format => "json" }, :headers => good_auth
368       assert_response :success
369       assert_equal "application/json", response.media_type
370       js = ActiveSupport::JSON.decode(@response.body)
371       assert_not_nil js
372       assert_equal 1, js["users"].count
373       check_json_details(js["users"][0], user2, false, false)
374
375       get api_users_path, :params => { :users => "#{user1.id},#{user3.id}", :format => "json" }, :headers => good_auth
376       assert_response :success
377       assert_equal "application/json", response.media_type
378       js = ActiveSupport::JSON.decode(@response.body)
379       assert_not_nil js
380       assert_equal 2, js["users"].count
381       check_json_details(js["users"][0], user1, true, false)
382       check_json_details(js["users"][1], user3, false, false)
383
384       get api_users_path, :params => { :users => "#{user1.id},#{user3.id}", :format => "json" }, :headers => bad_auth
385       assert_response :success
386       assert_equal "application/json", response.media_type
387       js = ActiveSupport::JSON.decode(@response.body)
388       assert_not_nil js
389       assert_equal 2, js["users"].count
390       check_json_details(js["users"][0], user1, false, false)
391       check_json_details(js["users"][1], user3, false, false)
392
393       get api_users_path, :params => { :users => create(:user, :suspended).id }, :headers => good_auth
394       assert_response :success
395       assert_equal "application/xml", response.media_type
396       assert_select "user", :count => 0
397
398       get api_users_path, :params => { :users => create(:user, :deleted).id }, :headers => good_auth
399       assert_response :success
400       assert_equal "application/xml", response.media_type
401       assert_select "user", :count => 0
402
403       get api_users_path, :params => { :users => 0 }, :headers => good_auth
404       assert_response :success
405       assert_equal "application/xml", response.media_type
406       assert_select "user", :count => 0
407     end
408
409     private
410
411     def check_xml_details(user, include_private, include_email)
412       assert_select "user[id='#{user.id}']", :count => 1 do
413         assert_select "description", :count => 1, :text => user.description
414         assert_select "company", :count => 1, :text => user.company if user.company
415
416         if user.social_links.present?
417           assert_select "social-links link", :count => user.social_links.count do
418             user.social_links.each do |link|
419               details = link.parsed
420               assert_select "link[platform='#{details[:platform]}']", :count => 1, :text => details[:url]
421             end
422           end
423         else
424           assert_select "social-links link", :count => 0
425         end
426
427         assert_select "contributor-terms", :count => 1 do
428           if user.terms_agreed.present?
429             assert_select "[agreed='true']", :count => 1
430           else
431             assert_select "[agreed='false']", :count => 1
432           end
433
434           if include_private
435             assert_select "[pd='false']", :count => 1
436           else
437             assert_select "[pd]", :count => 0
438           end
439         end
440
441         assert_select "img", :count => 0
442
443         assert_select "roles", :count => 1 do
444           assert_select "role", :count => 0
445         end
446
447         assert_select "changesets", :count => 1 do
448           assert_select "[count='0']", :count => 1
449         end
450
451         assert_select "traces", :count => 1 do
452           assert_select "[count='0']", :count => 1
453         end
454
455         assert_select "blocks", :count => 1 do
456           assert_select "received", :count => 1 do
457             assert_select "[count='0'][active='0']", :count => 1
458           end
459
460           assert_select "issued", :count => 0
461         end
462
463         if include_private && user.home_lat.present? && user.home_lon.present?
464           assert_select "home", :count => 1 do
465             assert_select "[lat='12.1'][lon='23.4'][zoom='3']", :count => 1
466           end
467         else
468           assert_select "home", :count => 0
469         end
470
471         if include_private
472           assert_select "languages", :count => 1 do
473             assert_select "lang", :count => user.languages.count
474
475             user.languages.each do |language|
476               assert_select "lang", :count => 1, :text => language
477             end
478           end
479
480           assert_select "messages", :count => 1 do
481             assert_select "received", :count => 1 do
482               assert_select "[count='#{user.messages.count}'][unread='0']", :count => 1
483             end
484
485             assert_select "sent", :count => 1 do
486               assert_select "[count='#{user.sent_messages.count}']", :count => 1
487             end
488           end
489         else
490           assert_select "languages", :count => 0
491           assert_select "messages", :count => 0
492         end
493
494         if include_email
495           assert_select "email", :count => 1, :text => user.email
496         else
497           assert_select "email", :count => 0
498         end
499       end
500     end
501
502     def check_json_details(js, user, include_private, include_email)
503       assert_equal user.id, js["user"]["id"]
504       assert_equal user.description, js["user"]["description"]
505       if user.company
506         assert_equal user.company, js["user"]["company"]
507       else
508         assert_nil js["user"]["company"]
509       end
510
511       if user.social_links.present?
512         ordered_js_links = js.dig("user", "social_links").sort_by { |link| link["url"] }
513         ordered_user_links = user.social_links.sort_by(&:url).map(&:parsed)
514
515         assert_equal ordered_user_links.count, ordered_js_links.count
516
517         ordered_user_links.zip(ordered_js_links).each do |user_link, js_link|
518           assert_equal user_link[:url], js_link["url"]
519           assert_equal user_link[:platform], js_link["platform"]
520         end
521       else
522         assert_empty js["user"]["social_links"]
523       end
524
525       assert_operator js["user"]["contributor_terms"], :[], "agreed"
526
527       if include_private
528         assert_not js["user"]["contributor_terms"]["pd"]
529       else
530         assert_nil js["user"]["contributor_terms"]["pd"]
531       end
532
533       assert_nil js["user"]["img"]
534       assert_empty js["user"]["roles"]
535       assert_equal 0, js["user"]["changesets"]["count"]
536       assert_equal 0, js["user"]["traces"]["count"]
537       assert_equal 0, js["user"]["blocks"]["received"]["count"]
538       assert_equal 0, js["user"]["blocks"]["received"]["active"]
539       assert_nil js["user"]["blocks"]["issued"]
540
541       if include_private && user.home_lat.present? && user.home_lon.present?
542         assert_in_delta 12.1, js["user"]["home"]["lat"]
543         assert_in_delta 23.4, js["user"]["home"]["lon"]
544         assert_equal 3, js["user"]["home"]["zoom"]
545       else
546         assert_nil js["user"]["home"]
547       end
548
549       if include_private && user.languages.present?
550         assert_equal user.languages, js["user"]["languages"]
551       else
552         assert_nil js["user"]["languages"]
553       end
554
555       if include_private
556         assert_equal user.messages.count, js["user"]["messages"]["received"]["count"]
557         assert_equal 0, js["user"]["messages"]["received"]["unread"]
558         assert_equal user.sent_messages.count, js["user"]["messages"]["sent"]["count"]
559       else
560         assert_nil js["user"]["messages"]
561       end
562
563       if include_email
564         assert_equal user.email, js["user"]["email"]
565       else
566         assert_nil js["user"]["email"]
567       end
568     end
569   end
570 end