@@ -298,6 +298,84 @@ def test_delete_org_permission():
298298 client .organizations .delete_organization (ctx .superorg .id , missing_ok = False )
299299
300300
301+ def test_update_organization_owner ():
302+ with (
303+ setup_organizations () as ctx ,
304+ create_user (
dict (
email = "[email protected] " ,
name = "Claudia Tiedemann" ))
as org_admin ,
305+ ):
306+ first_owner_client = JamAI (user_id = ctx .user .id )
307+ org_admin_client = JamAI (user_id = org_admin .id )
308+
309+ # Should fail because organization does not exist
310+ with pytest .raises (ResourceNotFoundError , match = "is not found." ):
311+ first_owner_client .organizations .update_owner (
312+ new_owner_id = "fake" , organization_id = ctx .org .id
313+ )
314+
315+ # Should fail because new owner is not a current member of the organization
316+ with pytest .raises (
317+ ForbiddenError , match = "The new owner is not a member of this organization"
318+ ):
319+ first_owner_client .organizations .update_owner (
320+ new_owner_id = org_admin .id , organization_id = ctx .org .id
321+ )
322+
323+ # Should fail because the User sending the request is not the owner.
324+ membership = first_owner_client .organizations .join_organization (
325+ org_admin .id , organization_id = ctx .org .id , role = Role .ADMIN
326+ )
327+ assert isinstance (membership , OrgMemberRead )
328+
329+ with pytest .raises (
330+ ForbiddenError , match = "Only the owner can transfer the ownership of an organization."
331+ ):
332+ org_admin_client .organizations .update_owner (
333+ new_owner_id = org_admin .id , organization_id = ctx .org .id
334+ )
335+
336+ # Should return the same org since the new owner id is the same as the current one
337+ first_owner_client .organizations .update_owner (
338+ new_owner_id = ctx .user .id , organization_id = ctx .org .id
339+ )
340+
341+ # Should succeed since the new owner is now a member of the organization
342+ new_org = first_owner_client .organizations .update_owner (
343+ new_owner_id = org_admin .id , organization_id = ctx .org .id
344+ )
345+ assert new_org .model_dump (
346+ exclude = ["owner" , "updated_at" , "credit_grant" ]
347+ ) == ctx .org .model_dump (exclude = ["owner" , "updated_at" , "credit_grant" ])
348+ assert new_org .owner != ctx .org .owner
349+ assert new_org .updated_at != ctx .org .updated_at
350+ assert new_org .owner == org_admin .id
351+
352+ # Should fail because this user is no longer the owner
353+ with pytest .raises (
354+ ForbiddenError , match = "Only the owner can transfer the ownership of an organization."
355+ ):
356+ first_owner_client .organizations .update_owner (
357+ new_owner_id = org_admin .id , organization_id = ctx .org .id
358+ )
359+ # New owner will be ADMIN
360+ membership = org_admin_client .organizations .get_member (
361+ user_id = org_admin .id , organization_id = ctx .org .id
362+ )
363+ assert isinstance (membership , OrgMemberRead )
364+ assert membership .role == Role .ADMIN
365+
366+ # Should fail because this is the last membership for this user and he is the current owner of the organization
367+ with pytest .raises (ForbiddenError , match = "Owner cannot leave the organization." ):
368+ org_admin_client .organizations .leave_organization (org_admin .id , ctx .org .id )
369+
370+ # Return the organization to the first owner
371+ org_admin_client .organizations .update_owner (
372+ new_owner_id = ctx .user .id , organization_id = ctx .org .id
373+ )
374+
375+ # Should succeed after returning the organization to the old owner.
376+ org_admin_client .organizations .leave_organization (org_admin .id , ctx .org .id )
377+
378+
301379def test_organisation_model_catalogue ():
302380 """
303381 Test listing model configs:
0 commit comments