"""Tests for dataloader utilities.""" from dataclasses import dataclass from typing import Any from permissions.utils.dataloader_utils import format_for_dataloader @dataclass class TestItem: """Test item with uuid.""" uuid: str name: str @dataclass class TestItemWithId: """Test item with id.""" id: int name: str @dataclass class TestItemWithNested: """Test item with nested data.""" uuid: str name: str nested: dict[str, str] list_field: list[int] @dataclass class TestItemWithIdentityUuid: """Test item with identity_uuid.""" identity_uuid: str tenants: list[dict[str, Any]] def test_returns_items_in_key_order(): """Items should be returned in the order of keys.""" items = [ TestItem(uuid='456', name='Item B'), TestItem(uuid='123', name='Item A'), ] keys = ['123', '456'] result = format_for_dataloader(items, keys, 'uuid') assert result == [ TestItem(uuid='123', name='Item A'), TestItem(uuid='456', name='Item B'), ] def test_returns_none_for_missing_items(): """None should be returned for keys with no matching item.""" items = [ TestItem(uuid='123', name='Item A'), ] keys = ['123', '456', '789'] result = format_for_dataloader(items, keys, 'uuid') assert result == [ TestItem(uuid='123', name='Item A'), None, None, ] def test_handles_empty_items(): """Empty items list should return all None values.""" items = [] keys = ['123', '456'] result = format_for_dataloader(items, keys, 'uuid') assert result == [None, None] def test_handles_empty_keys(): """Empty keys list should return empty list.""" items = [TestItem(uuid='123', name='Item A')] keys = [] result = format_for_dataloader(items, keys, 'uuid') assert result == [] def test_handles_duplicate_keys(): """Duplicate keys should return the same item multiple times.""" items = [ TestItem(uuid='123', name='Item A'), ] keys = ['123', '123', '123'] result = format_for_dataloader(items, keys, 'uuid') assert result == [ TestItem(uuid='123', name='Item A'), TestItem(uuid='123', name='Item A'), TestItem(uuid='123', name='Item A'), ] def test_converts_keys_to_string(): """Keys should be converted to string for comparison.""" items = [ TestItemWithId(id=123, name='Item A'), TestItemWithId(id=456, name='Item B'), ] keys = [123, 456] result = format_for_dataloader(items, keys, 'id') assert result == [ TestItemWithId(id=123, name='Item A'), TestItemWithId(id=456, name='Item B'), ] def test_preserves_all_item_data(): """All data from the original item should be preserved.""" items = [ TestItemWithNested( uuid='123', name='Item A', nested={'key': 'value'}, list_field=[1, 2, 3], ), ] keys = ['123'] result = format_for_dataloader(items, keys, 'uuid') assert result == [ TestItemWithNested( uuid='123', name='Item A', nested={'key': 'value'}, list_field=[1, 2, 3], ), ] def test_uses_custom_lookup_key(): """Should use the specified lookup_key for matching.""" items = [ TestItemWithIdentityUuid(identity_uuid='uuid-123', tenants=[]), TestItemWithIdentityUuid(identity_uuid='uuid-456', tenants=[{'name': 'tenant1'}]), ] keys = ['uuid-456', 'uuid-123'] result = format_for_dataloader(items, keys, 'identity_uuid') assert result == [ TestItemWithIdentityUuid(identity_uuid='uuid-456', tenants=[{'name': 'tenant1'}]), TestItemWithIdentityUuid(identity_uuid='uuid-123', tenants=[]), ] def test_when_item_does_not_have_attribute(): """Should return None for all items if lookup_key is missing.""" items = [ TestItem(uuid='456', name='Item B'), TestItem(uuid='123', name='Item A'), ] keys = ['123', '456'] result = format_for_dataloader(items, keys, 'badattr') assert result == [None, None]