import uuid from typing import Any import pytest import requests from mypy_boto3_dynamodb import DynamoDBClient from pdp.config import DYNAMODB_TABLE_IDENTITY, IDENTITY_HASH_KEY from pdp.fastapi.schemas.identity import AttachDetachRolesRequest from tests.integration import config, utils from tests.integration.api.identity.helpers import assert_get_identity_roles_empty from tests.integration.conftest import seed_test_pp_identity PARENT_COMPANY_UUID_ORCHARD = "955a1bbd-b623-4ea1-ab5f-8d6620c442fb" PARENT_COMPANY_UUID_SME = "f1594122-7f99-4916-b103-08b0444c7b46" COMPANY_BRAND_UUID_HRS = "ae886607-ae74-42f4-b7a7-d33f6a6288f4" COMPANY_BRAND_UUID_AWAL = "31f4f0f0-cbb4-4a2c-9eb0-d7288c5a2588" ACCOUNT_UUID_UNDER_ORCHARD_PC = "79a391d5-85d2-416a-9551-b26faaf09311" ACCOUNT_UUID_UNDER_SME_PC = "c0956e7f-4c7b-48f7-b064-d84e94ea796c" SUBACCOUNT_UUID_UNDER_ORCHARD_PC = "7d7b32c8-4e75-48d4-bce7-633fdf87646b" LP_UUID_UNDER_ORCHARD_PC = "73745b31-ae7c-40f6-879b-60b845bc26c7" COLLAB_UUID_UNDER_ORCHARD_PC = "2af78801-beb4-4f5c-96cd-c3f7a528555d" @pytest.mark.parametrize( "body, expected_status, expected_response", [ pytest.param( AttachDetachRolesRequest( **{ "tenant_uuid": "955a1bbd-b623-4ea1-ab5f-8d6620c442fb", "tenant_type": "parent_company", "roles_to_attach": [{"role": "contract_viewer"}], "roles_to_detach": [], }, ), 200, { "cursor": {"cursor": None, "shorthand": None}, "errors": {}, "tenants": { PARENT_COMPANY_UUID_ORCHARD: { "tenant_uuid": PARENT_COMPANY_UUID_ORCHARD, "tenant_type": "parent_company", "roles": [ {"role": "contract_viewer"}, ], }, }, }, id="SEAT user can attach/detach for the orchard parent_company", ), pytest.param( AttachDetachRolesRequest( **{ "tenant_uuid": PARENT_COMPANY_UUID_SME, "tenant_type": "parent_company", "roles_to_attach": [{"role": "contract_viewer"}], "roles_to_detach": [], }, ), 403, { "code": "bad_request", "message": f"Principal {{identity_uuid}} not authorized to attach_and_detach_role on identity {utils.PDP_TEST_USER_UUID}", # noqa: E501 }, id="SEAT user cannot attach/detach for the sme parent_company", ), pytest.param( AttachDetachRolesRequest( **{ "tenant_uuid": COMPANY_BRAND_UUID_HRS, "tenant_type": "company_brand", "roles_to_attach": [{"role": "contract_viewer"}], "roles_to_detach": [], }, ), 200, { "cursor": {"cursor": None, "shorthand": None}, "errors": {}, "tenants": { COMPANY_BRAND_UUID_HRS: { "tenant_uuid": COMPANY_BRAND_UUID_HRS, "tenant_type": "company_brand", "roles": [ {"role": "contract_viewer"}, ], }, }, }, id="SEAT user can attach/detach for the hrs company_brand, under orchard pc", # noqa: E501 ), pytest.param( AttachDetachRolesRequest( **{ "tenant_uuid": COMPANY_BRAND_UUID_AWAL, "tenant_type": "company_brand", "roles_to_attach": [{"role": "contract_viewer"}], "roles_to_detach": [], }, ), 403, { "code": "bad_request", "message": f"Principal {{identity_uuid}} not authorized to attach_and_detach_role on identity {utils.PDP_TEST_USER_UUID}", # noqa: E501 }, id="SEAT user cannot attach/detach for the awal company_brand, under sme pc", # noqa: E501 ), pytest.param( AttachDetachRolesRequest( **{ "tenant_uuid": ACCOUNT_UUID_UNDER_ORCHARD_PC, "tenant_type": "account", "roles_to_attach": [{"role": "contract_viewer"}], "roles_to_detach": [], }, ), 200, { "cursor": {"cursor": None, "shorthand": None}, "errors": {}, "tenants": { ACCOUNT_UUID_UNDER_ORCHARD_PC: { "tenant_uuid": ACCOUNT_UUID_UNDER_ORCHARD_PC, "tenant_type": "account", "roles": [ {"role": "contract_viewer"}, ], }, }, }, id="SEAT user can attach/detach for an account, under orchard pc", # noqa: E501 ), pytest.param( AttachDetachRolesRequest( **{ "tenant_uuid": ACCOUNT_UUID_UNDER_SME_PC, "tenant_type": "account", "roles_to_attach": [{"role": "contract_viewer"}], "roles_to_detach": [], }, ), 403, { "code": "bad_request", "message": f"Principal {{identity_uuid}} not authorized to attach_and_detach_role on identity {utils.PDP_TEST_USER_UUID}", # noqa: E501 }, id="SEAT user cannot attach/detach for an account, under sme pc", # noqa: E501 ), pytest.param( AttachDetachRolesRequest( **{ "tenant_uuid": SUBACCOUNT_UUID_UNDER_ORCHARD_PC, "tenant_type": "subaccount", "roles_to_attach": [{"role": "contract_viewer"}], "roles_to_detach": [], }, ), 403, { "code": "bad_request", "message": f"Principal {{identity_uuid}} not authorized to attach_and_detach_role on identity {utils.PDP_TEST_USER_UUID}", # noqa: E501 }, id="SEAT user cannot attach/detach for a subaccount, even under orchard pc", ), pytest.param( AttachDetachRolesRequest( **{ "tenant_uuid": LP_UUID_UNDER_ORCHARD_PC, "tenant_type": "label_participant", "roles_to_attach": [{"role": "contract_viewer"}], "roles_to_detach": [], }, ), 403, { "code": "bad_request", "message": f"Principal {{identity_uuid}} not authorized to attach_and_detach_role on identity {utils.PDP_TEST_USER_UUID}", # noqa: E501 }, id="SEAT user cannot attach/detach for a label participant/artist, even under orchard pc", # noqa: E501 ), pytest.param( AttachDetachRolesRequest( **{ "tenant_uuid": COLLAB_UUID_UNDER_ORCHARD_PC, "tenant_type": "account", # PP-677 Update this to collaborator "roles_to_attach": [{"role": "contract_viewer"}], "roles_to_detach": [], }, ), 403, { "code": "bad_request", "message": f"Principal {{identity_uuid}} not authorized to attach_and_detach_role on identity {utils.PDP_TEST_USER_UUID}", # noqa: E501 }, marks=pytest.mark.skip, id=""" SEAT user cannot attach/detach for a label participant/artist, even under orchard pc. PP-677: ows-pdp doesn't support attach by collaborator tenant type """, # noqa: E501 ), ], ) def test_attach_detach_roles( body: AttachDetachRolesRequest, expected_status: int, expected_response: dict[str, Any], default_boto_client: DynamoDBClient, bearer_token_pdptest_seat_rap_admin_user: str, bearer_token_pdptest_seat_rap_admin_user_identity_uuid: str, ) -> None: """Test SEAT user can/not attach detach roles.""" # Ensure pdptest_seat_rap_admin_user has seat_can_administer_users role # for the orchard parent_company seed_test_pp_identity( default_boto_client, bearer_token_pdptest_seat_rap_admin_user_identity_uuid, PARENT_COMPANY_UUID_ORCHARD, "seat_can_administer_users", tenant_type="parent_company", ) tenant_uuid = body.tenant_uuid url = f"{config.QA_BASE_URL}/identity/{utils.PDP_TEST_USER_UUID}/tenant/{tenant_uuid}/attach-and-detach/roles/" # noqa: E501 response = requests.put( url, headers={"Authorization": f"Bearer {bearer_token_pdptest_seat_rap_admin_user}"}, json=body.model_dump(mode="json"), ) assert response.status_code == expected_status, f"Response: {response.text}" if response.status_code == 200: assert response.json() == expected_response, response.text else: expected_response["message"] = expected_response["message"].format( identity_uuid=bearer_token_pdptest_seat_rap_admin_user_identity_uuid, ) assert response.json() == expected_response, response.text def test_get_roles_by_identity_empty( default_boto_client: DynamoDBClient, identity_uuid: uuid.UUID, bearer_token_pdptest_seat_rap_admin_user: str, bearer_token_pdptest_seat_rap_admin_user_identity_uuid: str, ) -> None: """GET /identity/{identity_uuid}/roles/ endpoint (empty database).""" # Ensure pdptest_seat_rap_admin_user has seat_can_administer_users role # for the orchard parent_company seed_test_pp_identity( default_boto_client, bearer_token_pdptest_seat_rap_admin_user_identity_uuid, PARENT_COMPANY_UUID_ORCHARD, "seat_can_administer_users", tenant_type="parent_company", ) url = f"{config.QA_BASE_URL}/identity/{identity_uuid}/roles/" # noqa: E501 assert_get_identity_roles_empty( url=url, bearer_token=bearer_token_pdptest_seat_rap_admin_user ) def test_get_roles_by_identity_not_allowed_tenant_types( default_boto_client: DynamoDBClient, identity_uuid: uuid.UUID, bearer_token_pdptest_seat_rap_admin_user: str, bearer_token_pdptest_seat_rap_admin_user_identity_uuid: str, ) -> None: """ SEAT user receives empty roles for an identity with only un-allowed tenants types. """ # Ensure pdptest_seat_rap_admin_user has seat_can_administer_users role # for the orchard parent_company seed_test_pp_identity( default_boto_client, bearer_token_pdptest_seat_rap_admin_user_identity_uuid, PARENT_COMPANY_UUID_ORCHARD, "seat_can_administer_users", tenant_type="parent_company", ) # Fixture the identity_uuid with roles for tenant types unallowed for SEAT: # subaccount, label participant under theorchard pc # PP-677 Update to include collaborator seed_test_pp_identity( default_boto_client, str(identity_uuid), SUBACCOUNT_UUID_UNDER_ORCHARD_PC, "contract_viewer", tenant_type="subaccount", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), LP_UUID_UNDER_ORCHARD_PC, "contract_viewer", tenant_type="label_participant", ) # Fetch identity_uuid's seeded tenants # Note this isn't based on the Authenticated Principal's view, # but what DynamoDB was just seeded with for identity_uuid. seeded_global_tenants = default_boto_client.query( TableName=DYNAMODB_TABLE_IDENTITY, ExpressionAttributeValues={":hash_key": {"S": str(identity_uuid)}}, KeyConditionExpression=f"{IDENTITY_HASH_KEY} = :hash_key", ) seeded_tenants = set( [ seeded_tenant["tenant_uuid"]["S"] for seeded_tenant in seeded_global_tenants.get("Items", []) ] ) overlap = seeded_tenants.intersection( [SUBACCOUNT_UUID_UNDER_ORCHARD_PC, LP_UUID_UNDER_ORCHARD_PC] ) assert overlap == set( [SUBACCOUNT_UUID_UNDER_ORCHARD_PC, LP_UUID_UNDER_ORCHARD_PC] ), "Confirm the expected tenants are fixtured" url = f"{config.QA_BASE_URL}/identity/{identity_uuid}/roles/" # noqa: E501 assert_get_identity_roles_empty( url=url, bearer_token=bearer_token_pdptest_seat_rap_admin_user ) def test_get_roles_by_identity_different_tenant_hierarchy( default_boto_client: DynamoDBClient, identity_uuid: uuid.UUID, bearer_token_pdptest_seat_rap_admin_user: str, bearer_token_pdptest_seat_rap_admin_user_identity_uuid: str, ) -> None: """ SEAT user receives empty roles for an identity with only un-allowed tenants (by hierarchy). """ # Ensure pdptest_seat_rap_admin_user has seat_can_administer_users role # for the orchard parent_company seed_test_pp_identity( default_boto_client, bearer_token_pdptest_seat_rap_admin_user_identity_uuid, PARENT_COMPANY_UUID_ORCHARD, "seat_can_administer_users", tenant_type="parent_company", ) # Fixture the identity_uuid with roles for tenants unallowed per hierarchy: # parent_company, company brand, account under sme pc seed_test_pp_identity( default_boto_client, str(identity_uuid), PARENT_COMPANY_UUID_SME, "contract_viewer", tenant_type="parent_company", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), COMPANY_BRAND_UUID_AWAL, "contract_viewer", tenant_type="company_brand", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), ACCOUNT_UUID_UNDER_SME_PC, "contract_viewer", tenant_type="account", ) # Fetch identity_uuid's seeded tenants # Note this isn't based on the Authenticated Principal's view, # but what DynamoDB was just seeded with for identity_uuid. seeded_global_tenants = default_boto_client.query( TableName=DYNAMODB_TABLE_IDENTITY, ExpressionAttributeValues={":hash_key": {"S": str(identity_uuid)}}, KeyConditionExpression=f"{IDENTITY_HASH_KEY} = :hash_key", ) seeded_tenants = set( [ seeded_tenant["tenant_uuid"]["S"] for seeded_tenant in seeded_global_tenants.get("Items", []) ] ) overlap = seeded_tenants.intersection( [ PARENT_COMPANY_UUID_SME, COMPANY_BRAND_UUID_AWAL, ACCOUNT_UUID_UNDER_SME_PC, ] ) assert overlap == set( [ PARENT_COMPANY_UUID_SME, COMPANY_BRAND_UUID_AWAL, ACCOUNT_UUID_UNDER_SME_PC, ] ), "Confirm the expected tenants are fixtured" url = f"{config.QA_BASE_URL}/identity/{identity_uuid}/roles/" # noqa: E501 assert_get_identity_roles_empty( url=url, bearer_token=bearer_token_pdptest_seat_rap_admin_user ) def test_get_roles_by_identity( default_boto_client: DynamoDBClient, identity_uuid: uuid.UUID, bearer_token_pdptest_seat_rap_admin_user: str, bearer_token_pdptest_seat_rap_admin_user_identity_uuid: str, ) -> None: """ SEAT user receives allowed tenant roles for an identity. """ # Ensure pdptest_seat_rap_admin_user has seat_can_administer_users role # for the orchard parent_company seed_test_pp_identity( default_boto_client, bearer_token_pdptest_seat_rap_admin_user_identity_uuid, PARENT_COMPANY_UUID_ORCHARD, "seat_can_administer_users", tenant_type="parent_company", ) # Fixture the identity_uuid with tenants that should be visible seed_test_pp_identity( default_boto_client, str(identity_uuid), PARENT_COMPANY_UUID_ORCHARD, "contract_viewer", tenant_type="parent_company", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), COMPANY_BRAND_UUID_HRS, "contract_viewer", tenant_type="company_brand", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), ACCOUNT_UUID_UNDER_ORCHARD_PC, "contract_viewer", tenant_type="account", ) # Fixture the identity_uuid with tenants that should not be visible # PP-677 Update to include collaborator seed_test_pp_identity( default_boto_client, str(identity_uuid), SUBACCOUNT_UUID_UNDER_ORCHARD_PC, "contract_viewer", tenant_type="subaccount", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), LP_UUID_UNDER_ORCHARD_PC, "contract_viewer", tenant_type="label_participant", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), PARENT_COMPANY_UUID_SME, "contract_viewer", tenant_type="parent_company", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), COMPANY_BRAND_UUID_AWAL, "contract_viewer", tenant_type="company_brand", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), ACCOUNT_UUID_UNDER_SME_PC, "contract_viewer", tenant_type="account", ) # Fetch identity_uuid's seeded tenants # Note this isn't based on the Authenticated Principal's view, # but what DynamoDB was just seeded with for identity_uuid. seeded_global_tenants = default_boto_client.query( TableName=DYNAMODB_TABLE_IDENTITY, ExpressionAttributeValues={":hash_key": {"S": str(identity_uuid)}}, KeyConditionExpression=f"{IDENTITY_HASH_KEY} = :hash_key", ) seeded_tenants = set( [ seeded_tenant["tenant_uuid"]["S"] for seeded_tenant in seeded_global_tenants.get("Items", []) ] ) overlap = seeded_tenants.intersection( [ PARENT_COMPANY_UUID_ORCHARD, PARENT_COMPANY_UUID_SME, COMPANY_BRAND_UUID_HRS, COMPANY_BRAND_UUID_AWAL, ACCOUNT_UUID_UNDER_ORCHARD_PC, ACCOUNT_UUID_UNDER_SME_PC, SUBACCOUNT_UUID_UNDER_ORCHARD_PC, LP_UUID_UNDER_ORCHARD_PC, ], ) assert overlap == set( [ PARENT_COMPANY_UUID_ORCHARD, PARENT_COMPANY_UUID_SME, COMPANY_BRAND_UUID_HRS, COMPANY_BRAND_UUID_AWAL, ACCOUNT_UUID_UNDER_ORCHARD_PC, ACCOUNT_UUID_UNDER_SME_PC, SUBACCOUNT_UUID_UNDER_ORCHARD_PC, LP_UUID_UNDER_ORCHARD_PC, ] ), "Confirm the expected tenants are fixtured" url = f"{config.QA_BASE_URL}/identity/{identity_uuid}/roles/" # noqa: E501 response = requests.get( url, headers={"Authorization": f"Bearer {bearer_token_pdptest_seat_rap_admin_user}"}, ) assert response.status_code == 200, f"Response: {response.text}" assert response.json() == { "cursor": {"cursor": None, "shorthand": None}, "errors": {}, "tenants": { ACCOUNT_UUID_UNDER_ORCHARD_PC: { "roles": [ { "role": "contract_viewer", }, ], "tenant_type": "account", "tenant_uuid": ACCOUNT_UUID_UNDER_ORCHARD_PC, }, PARENT_COMPANY_UUID_ORCHARD: { "roles": [ { "role": "contract_viewer", }, ], "tenant_type": "parent_company", "tenant_uuid": PARENT_COMPANY_UUID_ORCHARD, }, COMPANY_BRAND_UUID_HRS: { "roles": [ { "role": "contract_viewer", }, ], "tenant_type": "company_brand", "tenant_uuid": COMPANY_BRAND_UUID_HRS, }, }, } @pytest.mark.parametrize( "fixtured_tenant_uuid, fixtured_tenant_type, expected_status_code", [ pytest.param( PARENT_COMPANY_UUID_ORCHARD, "parent_company", 200, id="seat user can deactivate for orchard pc", ), pytest.param( COMPANY_BRAND_UUID_HRS, "company_brand", 200, id="seat user can deactivate for company brand under orchard pc", ), pytest.param( ACCOUNT_UUID_UNDER_ORCHARD_PC, "account", 200, id="seat user can deactivate for account under orchard pc", ), pytest.param( SUBACCOUNT_UUID_UNDER_ORCHARD_PC, "subaccount", 200, id="seat user can deactivate for subaccount under orchard pc", ), pytest.param( LP_UUID_UNDER_ORCHARD_PC, "label_participant", 200, id="seat user can deactivate for label_participant under orchard pc", ), pytest.param( PARENT_COMPANY_UUID_SME, "parent_company", 403, id="seat user cannot deactivate sme pc", ), pytest.param( COMPANY_BRAND_UUID_AWAL, "company_brand", 403, id="seat user cannot deactivate for account under sme pc", ), ], ) def test_deactivate_one( fixtured_tenant_uuid: str, fixtured_tenant_type: str, expected_status_code: int, default_boto_client: DynamoDBClient, identity_uuid: uuid.UUID, bearer_token_pdptest_seat_rap_admin_user: str, bearer_token_pdptest_seat_rap_admin_user_identity_uuid: str, ) -> None: """Test seat user can/cannot deactivate one.""" # Ensure pdptest_seat_rap_admin_user has seat_can_administer_users role # for the orchard parent_company seed_test_pp_identity( default_boto_client, bearer_token_pdptest_seat_rap_admin_user_identity_uuid, PARENT_COMPANY_UUID_ORCHARD, "seat_can_administer_users", tenant_type="parent_company", ) # Fixture the identity_uuid with tenants that should be visible seed_test_pp_identity( default_boto_client, str(identity_uuid), fixtured_tenant_uuid, "contract_viewer", tenant_type=fixtured_tenant_type, ) url = f"{config.QA_BASE_URL}/identity/{identity_uuid}/tenant/{fixtured_tenant_uuid}/deactivate/" # noqa: E501 response = requests.post( url, headers={"Authorization": f"Bearer {bearer_token_pdptest_seat_rap_admin_user}"}, json={"tenant_type": fixtured_tenant_type, "tenant_uuid": fixtured_tenant_uuid}, ) assert response.status_code == expected_status_code, f"Response: {response.text}" if expected_status_code == 200: assert response.json() == { "summary": { "deleted": 1, "remaining": 0, } } else: assert response.json() == { "code": "bad_request", "message": f"Principal {bearer_token_pdptest_seat_rap_admin_user_identity_uuid} not authorized to deactivate on identity {identity_uuid}", # noqa: E501 } def test_deactivate_all( default_boto_client: DynamoDBClient, identity_uuid: uuid.UUID, bearer_token_pdptest_seat_rap_admin_user: str, bearer_token_pdptest_seat_rap_admin_user_identity_uuid: str, ) -> None: """ Test seat user can deactivate all within tenant hierarchy. """ # Ensure pdptest_seat_rap_admin_user has seat_can_administer_users role # for the orchard parent_company seed_test_pp_identity( default_boto_client, bearer_token_pdptest_seat_rap_admin_user_identity_uuid, PARENT_COMPANY_UUID_ORCHARD, "seat_can_administer_users", tenant_type="parent_company", ) # Fixture the identity_uuid with tenants that should be deactivated seed_test_pp_identity( default_boto_client, str(identity_uuid), PARENT_COMPANY_UUID_ORCHARD, "contract_viewer", tenant_type="parent_company", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), COMPANY_BRAND_UUID_HRS, "contract_viewer", tenant_type="company_brand", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), ACCOUNT_UUID_UNDER_ORCHARD_PC, "contract_viewer", tenant_type="account", ) # PP-677 Update to include collaborator seed_test_pp_identity( default_boto_client, str(identity_uuid), SUBACCOUNT_UUID_UNDER_ORCHARD_PC, "contract_viewer", tenant_type="subaccount", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), LP_UUID_UNDER_ORCHARD_PC, "contract_viewer", tenant_type="label_participant", ) # Fixture the identity_uuid with tenants that should not be deactivated seed_test_pp_identity( default_boto_client, str(identity_uuid), PARENT_COMPANY_UUID_SME, "contract_viewer", tenant_type="parent_company", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), COMPANY_BRAND_UUID_AWAL, "contract_viewer", tenant_type="company_brand", ) seed_test_pp_identity( default_boto_client, str(identity_uuid), ACCOUNT_UUID_UNDER_SME_PC, "contract_viewer", tenant_type="account", ) # Fetch identity_uuid's seeded tenants # Note this isn't based on the Authenticated Principal's view, # but what DynamoDB was just seeded with for identity_uuid. seeded_global_tenants = default_boto_client.query( TableName=DYNAMODB_TABLE_IDENTITY, ExpressionAttributeValues={":hash_key": {"S": str(identity_uuid)}}, KeyConditionExpression=f"{IDENTITY_HASH_KEY} = :hash_key", ) seeded_tenants = set( [ seeded_tenant["tenant_uuid"]["S"] for seeded_tenant in seeded_global_tenants.get("Items", []) ] ) overlap = seeded_tenants.intersection( [ PARENT_COMPANY_UUID_ORCHARD, PARENT_COMPANY_UUID_SME, COMPANY_BRAND_UUID_HRS, COMPANY_BRAND_UUID_AWAL, ACCOUNT_UUID_UNDER_ORCHARD_PC, ACCOUNT_UUID_UNDER_SME_PC, SUBACCOUNT_UUID_UNDER_ORCHARD_PC, LP_UUID_UNDER_ORCHARD_PC, ], ) assert overlap == set( [ PARENT_COMPANY_UUID_ORCHARD, PARENT_COMPANY_UUID_SME, COMPANY_BRAND_UUID_HRS, COMPANY_BRAND_UUID_AWAL, ACCOUNT_UUID_UNDER_ORCHARD_PC, ACCOUNT_UUID_UNDER_SME_PC, SUBACCOUNT_UUID_UNDER_ORCHARD_PC, LP_UUID_UNDER_ORCHARD_PC, ] ), "Confirm the expected tenants are fixtured" url = f"{config.QA_BASE_URL}/identity/{identity_uuid}/deactivate/" # noqa: E501 response = requests.delete( url, headers={"Authorization": f"Bearer {bearer_token_pdptest_seat_rap_admin_user}"}, ) assert response.status_code == 200, f"Response: {response.text}" assert response.json() == { "summary": { "deleted": 5, "remaining": 0, } } # Fetch identity_uuid's remaining tenants # Note this isn't based on the Authenticated Principal's view, # but what DynamoDB was just still has for identity_uuid. remaining_global_tenants = default_boto_client.query( TableName=DYNAMODB_TABLE_IDENTITY, ExpressionAttributeValues={":hash_key": {"S": str(identity_uuid)}}, KeyConditionExpression=f"{IDENTITY_HASH_KEY} = :hash_key", ) remaining_tenants = set( [ remaining_tenant["tenant_uuid"]["S"] for remaining_tenant in remaining_global_tenants.get("Items", []) ] ) assert len(remaining_tenants) == 3 overlap = remaining_tenants.intersection( [ PARENT_COMPANY_UUID_SME, COMPANY_BRAND_UUID_AWAL, ACCOUNT_UUID_UNDER_SME_PC, ], ) assert overlap == set( [ PARENT_COMPANY_UUID_SME, COMPANY_BRAND_UUID_AWAL, ACCOUNT_UUID_UNDER_SME_PC, ], ), "Expect sme tenants to remain activated (not deactivated)"