]> git.openstreetmap.org Git - rails.git/blob - test/controllers/api/user_preferences_controller_test.rb
Lock note during status update to avoid race condition
[rails.git] / test / controllers / api / user_preferences_controller_test.rb
1 require "test_helper"
2
3 module Api
4   class UserPreferencesControllerTest < ActionDispatch::IntegrationTest
5     ##
6     # test all routes which lead to this controller
7     def test_routes
8       assert_routing(
9         { :path => "/api/0.6/user/preferences", :method => :get },
10         { :controller => "api/user_preferences", :action => "index" }
11       )
12       assert_routing(
13         { :path => "/api/0.6/user/preferences.json", :method => :get },
14         { :controller => "api/user_preferences", :action => "index", :format => "json" }
15       )
16       assert_routing(
17         { :path => "/api/0.6/user/preferences", :method => :put },
18         { :controller => "api/user_preferences", :action => "update_all" }
19       )
20       assert_routing(
21         { :path => "/api/0.6/user/preferences/key", :method => :get },
22         { :controller => "api/user_preferences", :action => "show", :preference_key => "key" }
23       )
24       assert_routing(
25         { :path => "/api/0.6/user/preferences/key", :method => :put },
26         { :controller => "api/user_preferences", :action => "update", :preference_key => "key" }
27       )
28       assert_routing(
29         { :path => "/api/0.6/user/preferences/key", :method => :delete },
30         { :controller => "api/user_preferences", :action => "destroy", :preference_key => "key" }
31       )
32     end
33
34     ##
35     # test showing all preferences
36     def test_index
37       # first try without auth
38       get user_preferences_path
39       assert_response :unauthorized, "should be authenticated"
40
41       # authenticate as a user with no preferences
42       auth_header = basic_authorization_header create(:user).email, "test"
43
44       # try the read again
45       get user_preferences_path, :headers => auth_header
46       assert_select "osm" do
47         assert_select "preferences", :count => 1 do
48           assert_select "preference", :count => 0
49         end
50       end
51
52       # authenticate as a user with preferences
53       user = create(:user)
54       user_preference = create(:user_preference, :user => user)
55       user_preference2 = create(:user_preference, :user => user)
56       auth_header = basic_authorization_header user.email, "test"
57
58       # try the read again
59       get user_preferences_path, :headers => auth_header
60       assert_response :success
61       assert_equal "application/xml", @response.media_type
62       assert_select "osm" do
63         assert_select "preferences", :count => 1 do
64           assert_select "preference", :count => 2
65           assert_select "preference[k=\"#{user_preference.k}\"][v=\"#{user_preference.v}\"]", :count => 1
66           assert_select "preference[k=\"#{user_preference2.k}\"][v=\"#{user_preference2.v}\"]", :count => 1
67         end
68       end
69
70       # Test json
71       get user_preferences_path(:format => "json"), :headers => auth_header
72       assert_response :success
73       assert_equal "application/json", @response.media_type
74
75       js = ActiveSupport::JSON.decode(@response.body)
76       assert_not_nil js
77       assert_equal 2, js["preferences"].count
78       assert_equal user_preference.v, js["preferences"][user_preference.k]
79     end
80
81     ##
82     # test showing one preference
83     def test_show
84       user = create(:user)
85       create(:user_preference, :user => user, :k => "key", :v => "value")
86
87       # try a read without auth
88       get user_preference_path(:preference_key => "key")
89       assert_response :unauthorized, "should be authenticated"
90
91       # authenticate as a user with preferences
92       auth_header = basic_authorization_header user.email, "test"
93
94       # try the read again
95       get user_preference_path(:preference_key => "key"), :headers => auth_header
96       assert_response :success
97       assert_equal "text/plain", @response.media_type
98       assert_equal "value", @response.body
99
100       # try the read again for a non-existent key
101       get user_preference_path(:preference_key => "unknown_key"), :headers => auth_header
102       assert_response :not_found
103     end
104
105     ##
106     # test bulk update action
107     def test_update_all
108       user = create(:user)
109       create(:user_preference, :user => user, :k => "key", :v => "value")
110       create(:user_preference, :user => user, :k => "some_key", :v => "some_value")
111
112       # try a put without auth
113       assert_no_difference "UserPreference.count" do
114         put user_preferences_path, :params => "<osm><preferences><preference k='key' v='new_value'/><preference k='new_key' v='value'/></preferences></osm>"
115       end
116       assert_response :unauthorized, "should be authenticated"
117       assert_equal "value", UserPreference.find([user.id, "key"]).v
118       assert_equal "some_value", UserPreference.find([user.id, "some_key"]).v
119       assert_raises ActiveRecord::RecordNotFound do
120         UserPreference.find([user.id, "new_key"])
121       end
122
123       # authenticate as a user with preferences
124       auth_header = basic_authorization_header user.email, "test"
125
126       # try the put again
127       assert_no_difference "UserPreference.count" do
128         put user_preferences_path, :params => "<osm><preferences><preference k='key' v='new_value'/><preference k='new_key' v='value'/></preferences></osm>", :headers => auth_header
129       end
130       assert_response :success
131       assert_equal "text/plain", @response.media_type
132       assert_equal "", @response.body
133       assert_equal "new_value", UserPreference.find([user.id, "key"]).v
134       assert_equal "value", UserPreference.find([user.id, "new_key"]).v
135       assert_raises ActiveRecord::RecordNotFound do
136         UserPreference.find([user.id, "some_key"])
137       end
138
139       # try a put with duplicate keys
140       assert_no_difference "UserPreference.count" do
141         put user_preferences_path, :params => "<osm><preferences><preference k='key' v='value'/><preference k='key' v='newer_value'/></preferences></osm>", :headers => auth_header
142       end
143       assert_response :bad_request
144       assert_equal "text/plain", @response.media_type
145       assert_equal "Duplicate preferences with key key", @response.body
146       assert_equal "new_value", UserPreference.find([user.id, "key"]).v
147
148       # try a put with invalid content
149       assert_no_difference "UserPreference.count" do
150         put user_preferences_path, :params => "nonsense", :headers => auth_header
151       end
152       assert_response :bad_request
153
154       # try a put with unicode characters
155       assert_no_difference "UserPreference.count" do
156         put user_preferences_path, :params => "<osm><preferences><preference k='kêy' v='néw_vâlué'/><preference k='nêw_kêy' v='vâlué'/></preferences></osm>", :headers => auth_header
157       end
158       assert_response :success
159       assert_equal "text/plain", @response.media_type
160       assert_equal "", @response.body
161       assert_equal "néw_vâlué", UserPreference.find([user.id, "kêy"]).v
162       assert_equal "vâlué", UserPreference.find([user.id, "nêw_kêy"]).v
163       assert_raises ActiveRecord::RecordNotFound do
164         UserPreference.find([user.id, "some_key"])
165       end
166     end
167
168     ##
169     # test update action
170     def test_update
171       user = create(:user)
172       create(:user_preference, :user => user)
173
174       # try a put without auth
175       assert_no_difference "UserPreference.count" do
176         put user_preference_path(:preference_key => "new_key"), :params => "new_value"
177       end
178       assert_response :unauthorized, "should be authenticated"
179       assert_raises ActiveRecord::RecordNotFound do
180         UserPreference.find([user.id, "new_key"])
181       end
182
183       # authenticate as a user with preferences
184       auth_header = basic_authorization_header user.email, "test"
185
186       # try adding a new preference
187       assert_difference "UserPreference.count", 1 do
188         put user_preference_path(:preference_key => "new_key"), :params => "new_value", :headers => auth_header
189       end
190       assert_response :success
191       assert_equal "text/plain", @response.media_type
192       assert_equal "", @response.body
193       assert_equal "new_value", UserPreference.find([user.id, "new_key"]).v
194
195       # try changing the value of a preference
196       assert_no_difference "UserPreference.count" do
197         put user_preference_path(:preference_key => "new_key"), :params => "newer_value", :headers => auth_header
198       end
199       assert_response :success
200       assert_equal "text/plain", @response.media_type
201       assert_equal "", @response.body
202       assert_equal "newer_value", UserPreference.find([user.id, "new_key"]).v
203
204       # try changing the value of a preference to include unicode characters
205       assert_difference "UserPreference.count", 1 do
206         put user_preference_path(:preference_key => "nêw_kêy"), :params => "néwèr_vâlué", :headers => auth_header
207       end
208       assert_response :success
209       assert_equal "text/plain", @response.media_type
210       assert_equal "", @response.body
211       assert_equal "néwèr_vâlué", UserPreference.find([user.id, "nêw_kêy"]).v
212     end
213
214     ##
215     # test destroy action
216     def test_destroy
217       user = create(:user)
218       create(:user_preference, :user => user, :k => "key", :v => "value")
219
220       # try a delete without auth
221       assert_no_difference "UserPreference.count" do
222         delete user_preference_path(:preference_key => "key")
223       end
224       assert_response :unauthorized, "should be authenticated"
225       assert_equal "value", UserPreference.find([user.id, "key"]).v
226
227       # authenticate as a user with preferences
228       auth_header = basic_authorization_header user.email, "test"
229
230       # try the delete again
231       assert_difference "UserPreference.count", -1 do
232         delete user_preference_path(:preference_key => "key"), :headers => auth_header
233       end
234       assert_response :success
235       assert_equal "text/plain", @response.media_type
236       assert_equal "", @response.body
237       assert_raises ActiveRecord::RecordNotFound do
238         UserPreference.find([user.id, "key"])
239       end
240
241       # try the delete again for the same key
242       assert_no_difference "UserPreference.count" do
243         delete user_preference_path(:preference_key => "key"), :headers => auth_header
244       end
245       assert_response :not_found
246       assert_raises ActiveRecord::RecordNotFound do
247         UserPreference.find([user.id, "key"])
248       end
249     end
250
251     # Ensure that a valid access token with correct capabilities can be used to
252     # read preferences
253     def test_show_using_token
254       user = create(:user)
255       token = create(:oauth_access_token, :resource_owner_id => user.id, :scopes => %w[read_prefs])
256       create(:user_preference, :user => user, :k => "key", :v => "value")
257
258       get user_preference_path(:preference_key => "key"), :headers => bearer_authorization_header(token.token)
259       assert_response :success
260     end
261
262     # Ensure that a valid access token with incorrect capabilities can't be used
263     # to read preferences even, though the owner of that token could read them
264     # by other methods.
265     def test_show_using_token_fail
266       user = create(:user)
267       token = create(:oauth_access_token, :resource_owner_id => user.id)
268       create(:user_preference, :user => user, :k => "key", :v => "value")
269
270       get user_preference_path(:preference_key => "key"), :headers => bearer_authorization_header(token.token)
271       assert_response :forbidden
272     end
273   end
274 end