@@ -251,11 +251,51 @@ def test_create_from_copy_should_not_copy_layout_from_non_editable_dashboard
251251 assert_not_equal original_layout , new_dashboard . layout
252252 end
253253
254- def test_lock_dashboard_with_permission
254+ def test_lock_action_registered_in_save_dashboards_permission
255+ # IMPORTANT: lock action must be registered in save_dashboards permission
256+ # Without this, the action is not properly documented in Redmine's permission system
257+ permission = Redmine ::AccessControl . permission :save_dashboards
258+
259+ assert_not_nil permission , 'save_dashboards permission should exist'
260+ assert_includes permission . actions , 'dashboards/lock' ,
261+ 'lock action must be registered in save_dashboards permission'
262+ end
263+
264+ def test_unlock_action_registered_in_save_dashboards_permission
265+ # IMPORTANT: unlock action must be registered in save_dashboards permission
266+ permission = Redmine ::AccessControl . permission :save_dashboards
267+
268+ assert_not_nil permission , 'save_dashboards permission should exist'
269+ assert_includes permission . actions , 'dashboards/unlock' ,
270+ 'unlock action must be registered in save_dashboards permission'
271+ end
272+
273+ def test_lock_action_registered_in_share_dashboards_permission
274+ # IMPORTANT: lock action must be registered in share_dashboards permission
275+ permission = Redmine ::AccessControl . permission :share_dashboards
276+
277+ assert_not_nil permission , 'share_dashboards permission should exist'
278+ assert_includes permission . actions , 'dashboards/lock' ,
279+ 'lock action must be registered in share_dashboards permission'
280+ end
281+
282+ def test_unlock_action_registered_in_share_dashboards_permission
283+ # IMPORTANT: unlock action must be registered in share_dashboards permission
284+ permission = Redmine ::AccessControl . permission :share_dashboards
285+
286+ assert_not_nil permission , 'share_dashboards permission should exist'
287+ assert_includes permission . actions , 'dashboards/unlock' ,
288+ 'unlock action must be registered in share_dashboards permission'
289+ end
290+
291+ def test_lock_dashboard_as_author
292+ # User 2 is author of private_welcome2 and has save_dashboards permission
255293 @request . session [ :user_id ] = @user . id
256294
257295 dashboard = dashboards :private_welcome2
258296
297+ assert_equal @user . id , dashboard . author_id , 'Test user should be the dashboard author'
298+ assert_not @user . admin? , 'Test user should not be admin'
259299 assert_not dashboard . locked? , 'Dashboard should not be locked initially'
260300
261301 put :lock , params : { id : dashboard . id }
@@ -266,11 +306,15 @@ def test_lock_dashboard_with_permission
266306 assert dashboard . locked? , 'Dashboard should be locked after lock action'
267307 end
268308
269- def test_lock_dashboard_without_permission
309+ def test_lock_dashboard_as_non_author
310+ # User 4 is not author and not admin - should be forbidden
270311 @request . session [ :user_id ] = @user_without_permission . id
271312
272313 dashboard = dashboards :private_welcome2
273314
315+ assert_not_equal @user_without_permission . id , dashboard . author_id , 'Test user should not be the author'
316+ assert_not @user_without_permission . admin? , 'Test user should not be admin'
317+
274318 put :lock , params : { id : dashboard . id }
275319
276320 assert_response :forbidden
@@ -279,12 +323,14 @@ def test_lock_dashboard_without_permission
279323 assert_not dashboard . locked? , 'Dashboard should remain unlocked'
280324 end
281325
282- def test_unlock_dashboard_with_permission
326+ def test_unlock_dashboard_as_author
283327 @request . session [ :user_id ] = @user . id
284328
285329 dashboard = dashboards :private_welcome2
286330 dashboard . update! locked : true
287331
332+ assert_equal @user . id , dashboard . author_id , 'Test user should be the dashboard author'
333+ assert_not @user . admin? , 'Test user should not be admin'
288334 assert dashboard . locked? , 'Dashboard should be locked initially'
289335
290336 put :unlock , params : { id : dashboard . id }
@@ -295,12 +341,15 @@ def test_unlock_dashboard_with_permission
295341 assert_not dashboard . locked? , 'Dashboard should be unlocked after unlock action'
296342 end
297343
298- def test_unlock_dashboard_without_permission
344+ def test_unlock_dashboard_as_non_author
299345 @request . session [ :user_id ] = @user_without_permission . id
300346
301347 dashboard = dashboards :private_welcome2
302348 dashboard . update! locked : true
303349
350+ assert_not_equal @user_without_permission . id , dashboard . author_id , 'Test user should not be the author'
351+ assert_not @user_without_permission . admin? , 'Test user should not be admin'
352+
304353 put :unlock , params : { id : dashboard . id }
305354
306355 assert_response :forbidden
@@ -309,11 +358,13 @@ def test_unlock_dashboard_without_permission
309358 assert dashboard . locked? , 'Dashboard should remain locked'
310359 end
311360
312- def test_lock_project_dashboard_with_permission
361+ def test_lock_project_dashboard_as_author
313362 @request . session [ :user_id ] = @user . id
314363
315364 dashboard = dashboards :private_project2
316365
366+ assert_equal @user . id , dashboard . author_id , 'Test user should be the dashboard author'
367+ assert_not @user . admin? , 'Test user should not be admin'
317368 assert_not dashboard . locked? , 'Dashboard should not be locked initially'
318369
319370 put :lock , params : { project_id : dashboard . project_id , id : dashboard . id }
@@ -324,12 +375,15 @@ def test_lock_project_dashboard_with_permission
324375 assert dashboard . locked? , 'Dashboard should be locked after lock action'
325376 end
326377
327- def test_unlock_project_dashboard_with_permission
378+ def test_unlock_project_dashboard_as_author
328379 @request . session [ :user_id ] = @user . id
329380
330381 dashboard = dashboards :private_project2
331382 dashboard . update! locked : true
332383
384+ assert_equal @user . id , dashboard . author_id , 'Test user should be the dashboard author'
385+ assert_not @user . admin? , 'Test user should not be admin'
386+
333387 put :unlock , params : { project_id : dashboard . project_id , id : dashboard . id }
334388
335389 assert_response :redirect
0 commit comments