summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-08-04 05:40:54 +0200
committererdgeist <erdgeist@erdgeist.org>2026-08-04 05:40:54 +0200
commit974062f16169f6d07f2289564be6d72610b8770e (patch)
treeb18f297a9d4326a3ce36f5192fbc4992fcb28e7d /test
parentbe2cdea85177ac016e56dcce6cbe6015d754adf5 (diff)
Witness every promotion and demotion made through the roles form
Diffstat (limited to 'test')
-rw-r--r--test/controllers/users_controller_test.rb46
-rw-r--r--test/models/user_test.rb66
2 files changed, 112 insertions, 0 deletions
diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb
index 69c535f5..aeff9bc7 100644
--- a/test/controllers/users_controller_test.rb
+++ b/test/controllers/users_controller_test.rb
@@ -357,4 +357,50 @@ class UsersControllerTest < ActionController::TestCase
357 assert_redirected_to new_elevation_path 357 assert_redirected_to new_elevation_path
358 assert_equal ["admin", "redaktion"], users(:aaron).reload.roles.sort 358 assert_equal ["admin", "redaktion"], users(:aaron).reload.roles.sort
359 end 359 end
360
361 test "promoting through the roles form leaves a log entry" do
362 login_as :aaron
363 elevate_session!
364 target = users(:redella)
365 target.update_column(:otp_secret, ROTP::Base32.random)
366
367 assert_difference -> { NodeAction.where(:action => "admin_grant").count }, 1 do
368 put :update, params: { :locale => "de", :id => target.id,
369 :user => { :roles => ["", "redaktion", "admin"] } }
370 end
371
372 assert_redirected_to user_path(target)
373 assert_equal %w[admin redaktion], target.reload.roles.sort
374 end
375
376 test "a refused promotion re-renders with an error and changes nothing" do
377 login_as :aaron
378 elevate_session!
379 target = users(:quentin)
380
381 assert_no_difference -> { NodeAction.count } do
382 put :update, params: { :locale => "de", :id => target.id,
383 :user => { :roles => ["", "admin"] } }
384 end
385
386 assert_response :success
387 assert_empty target.reload.roles
388 assert_not_nil flash[:error]
389 assert_nil flash[:notice]
390 end
391
392 test "a validation failure leaves no promotion behind" do
393 login_as :aaron
394 elevate_session!
395 target = users(:redella)
396 target.update_column(:otp_secret, ROTP::Base32.random)
397
398 assert_no_difference -> { NodeAction.count } do
399 put :update, params: { :locale => "de", :id => target.id,
400 :user => { :email => "", :roles => ["", "redaktion", "admin"] } }
401 end
402
403 assert_response :success
404 assert_equal %w[redaktion], target.reload.roles
405 end
360end 406end
diff --git a/test/models/user_test.rb b/test/models/user_test.rb
index 62552ee7..5ccc53a9 100644
--- a/test/models/user_test.rb
+++ b/test/models/user_test.rb
@@ -6,6 +6,11 @@ class UserTest < ActiveSupport::TestCase
6 include AuthenticatedTestHelper 6 include AuthenticatedTestHelper
7 fixtures :users 7 fixtures :users
8 8
9 def role_entries
10 NodeAction.where(:action => %w[admin_grant admin_revoke redaktion_grant
11 redaktion_revoke user_deactivate user_reactivate])
12 end
13
9 def test_should_create_user 14 def test_should_create_user
10 assert_difference 'User.count' do 15 assert_difference 'User.count' do
11 user = create_user 16 user = create_user
@@ -187,6 +192,67 @@ class UserTest < ActiveSupport::TestCase
187 redella.update_column(:last_login_at, nil) 192 redella.update_column(:last_login_at, nil)
188 assert_equal :never, redella.staleness_tier(now) 193 assert_equal :never, redella.staleness_tier(now)
189 end 194 end
195
196 test "granting a role through update_roles! is witnessed" do
197 target = users(:redella)
198 target.update_column(:otp_secret, ROTP::Base32.random)
199
200 assert_difference -> { role_entries.count }, 1 do
201 assert_empty target.update_roles!(%w[redaktion admin], :actor => users(:aaron))
202 end
203
204 assert_equal %w[admin redaktion], target.reload.roles.sort
205 entry = role_entries.order(:id).last
206 assert_equal "admin_grant", entry.action
207 assert_equal users(:aaron).id, entry.user_id
208 assert_equal "redella", entry.metadata["target_login"]
209 end
210
211 test "a refused grant applies nothing at all" do
212 target = users(:quentin)
213 assert_not target.otp_enrolled?
214
215 assert_no_difference -> { role_entries.count } do
216 refusals = target.update_roles!(%w[redaktion admin], :actor => users(:aaron))
217 assert_includes refusals, :admin_needs_otp
218 assert_includes refusals, :redaktion_needs_otp
219 end
220
221 assert_empty target.reload.roles, "a refusal must leave the stored set untouched"
222 end
223
224 test "nobody demotes themselves through update_roles!" do
225 actor = users(:aaron)
226
227 refusals = actor.update_roles!([], :actor => actor)
228
229 assert_includes refusals, :admin_not_self
230 assert_includes refusals, :redaktion_not_self
231 assert_equal %w[admin redaktion], actor.reload.roles.sort
232 end
233
234 test "marking an account alumni through update_roles! is witnessed as a deactivation" do
235 target = users(:redella)
236
237 assert_difference -> { role_entries.where(:action => "user_deactivate").count }, 1 do
238 assert_empty target.update_roles!(%w[redaktion alumni], :actor => users(:aaron))
239 end
240
241 assert target.reload.alumni?
242 assert target.redaktion?, "deactivate! preserves the other roles"
243 end
244
245 test "revoking and granting in one submission apply in the right order" do
246 target = users(:redella)
247 target.update_column(:otp_secret, ROTP::Base32.random)
248
249 assert_empty target.update_roles!(%w[admin], :actor => users(:aaron))
250
251 assert_equal %w[admin], target.reload.roles
252 actions = role_entries.order(:id).last(2).map(&:action)
253 assert_includes actions, "redaktion_revoke"
254 assert_includes actions, "admin_grant"
255 end
190 256
191protected 257protected
192 def create_user(options = {}) 258 def create_user(options = {})