from typing import Any from uuid import UUID import pytest from backfill.connectors.ows_pdp.models.tenant_type import TenantType from backfill.constants import AttachAndDetachOperation from backfill.models import AttachAndDetachRow @pytest.mark.parametrize( "row, expected", [ pytest.param({}, ValueError, id="row cannot be empty"), pytest.param( { "identity_uuid": "99750de3-303d-490d-b294-96adb894a71f", "tenant_uuid": "f5b456ea-10c6-11f0-96b2-3e17271fba6f", "tenant_type": "account", "role": "can do things", "operation": "attach", }, AttachAndDetachRow( identity_uuid=UUID("99750de3-303d-490d-b294-96adb894a71f"), tenant_uuid=UUID("f5b456ea-10c6-11f0-96b2-3e17271fba6f"), tenant_type=TenantType.ACCOUNT, role="can do things", operation=AttachAndDetachOperation.OPERATION_ATTACH, ), id="happy path, attach", ), pytest.param( { "identity_uuid": "99750de3-303d-490d-b294-96adb894a71f", "tenant_uuid": "f5b456ea-10c6-11f0-96b2-3e17271fba6f", "tenant_type": "subaccount", "role": "can do things", "operation": "detach", }, AttachAndDetachRow( identity_uuid=UUID("99750de3-303d-490d-b294-96adb894a71f"), tenant_uuid=UUID("f5b456ea-10c6-11f0-96b2-3e17271fba6f"), tenant_type=TenantType.SUBACCOUNT, role="can do things", operation=AttachAndDetachOperation.OPERATION_DETACH, ), id="happy path, detach", ), pytest.param( { "identity_uuid": " 99750de3-303d-490d-b294-96adb894a71f ", "tenant_uuid": " f5b456ea-10c6-11f0-96b2-3e17271fba6f ", "tenant_type": " subaccount ", "role": " can do things ", "operation": " detach ", }, AttachAndDetachRow( identity_uuid=UUID("99750de3-303d-490d-b294-96adb894a71f"), tenant_uuid=UUID("f5b456ea-10c6-11f0-96b2-3e17271fba6f"), tenant_type=TenantType.SUBACCOUNT, role="can do things", operation=AttachAndDetachOperation.OPERATION_DETACH, ), id="happy path, whitespace is handled", ), pytest.param( { "identity_uuid": "8b5b6bde-10c7-11f0-9b38-3e17271fba6f", "tenant_uuid": "f5b456ea-10c6-11f0-96b2-3e17271fba6f", "tenant_type": "account", "role": "can do things", "operation": "attach", }, ValueError, id="identity_uuid must be uuid v4", ), pytest.param( { "identity_uuid": "99750de3-303d-490d-b294-96adb894a71f", "tenant_uuid": "not-a-uuid", "tenant_type": "account", "role": "can do things", "operation": "attach", }, ValueError, id="tenant_uuid must be uuid", ), pytest.param( { "identity_uuid": "99750de3-303d-490d-b294-96adb894a71f", "tenant_uuid": "f5b456ea-10c6-11f0-96b2-3e17271fba6f", "tenant_type": "tenant", "role": "can do things", "operation": "detach", }, ValueError, id="only legit tenant types", ), pytest.param( { "identity_uuid": "99750de3-303d-490d-b294-96adb894a71f", "tenant_uuid": "f5b456ea-10c6-11f0-96b2-3e17271fba6f", "tenant_type": "subaccount", "role": "can do things", "operation": "not an op", }, ValueError, id="operation is either attach or detach", ), ], ) def test_attach_detach_row_model_validate(row: dict[str, Any], expected: Any) -> None: """Test AttachAndDetachRow validates.""" if expected is ValueError: with pytest.raises(ValueError): AttachAndDetachRow.model_validate(row) else: actual = AttachAndDetachRow.model_validate(row) assert actual == expected