# Path: repokid/datasource/iam.py
# class IAMDatasource(DatasourcePlugin[str, IAMEntry], metaclass=Singleton):
#     _arn_to_id: Dict[str, str] = {}
# 
#     def __init__(self, config: Optional[RepokidConfig] = None):
#         super().__init__(config=config)
# 
#     def _fetch_account(self, account_number: str) -> Dict[str, IAMEntry]:
#         logger.info("getting role data for account %s", account_number)
#         conn = copy.deepcopy(self.config.get("connection_iam", {}))
#         conn["account_number"] = account_number
#         auth_details = get_account_authorization_details(filter="Role", **conn)
#         auth_details_by_id = {item["Arn"]: item for item in auth_details}
#         self._arn_to_id.update({item["Arn"]: item["RoleId"] for item in auth_details})
#         # convert policies list to dictionary to maintain consistency with old call which returned a dict
#         for _, data in auth_details_by_id.items():
#             data["RolePolicyList"] = {
#                 item["PolicyName"]: item["PolicyDocument"]
#                 for item in data["RolePolicyList"]
#             }
#         return auth_details_by_id
# 
#     def _fetch(self, arn: str) -> IAMEntry:
#         logger.info("getting role data for role %s", arn)
#         conn = copy.deepcopy(self.config["connection_iam"])
#         conn["account_number"] = arn.split(":")[4]
#         role = {"RoleName": arn.split("/")[-1]}
#         role_info: IAMEntry = get_role(role, flags=FLAGS.INLINE_POLICIES, **conn)
#         self._arn_to_id[arn] = role_info["RoleId"]
#         if not role_info:
#             raise NotFoundError
#         self._data[arn] = role_info
#         return role_info
# 
#     def get(self, arn: str) -> IAMEntry:
#         result = self._data.get(arn)
#         if not result:
#             return self._fetch(arn)
#         return result
# 
#     def get_id_for_arn(self, arn: str) -> Optional[str]:
#         return self._arn_to_id.get(arn)
# 
#     def _get_ids_for_account(self, account_number: str) -> Iterable[str]:
#         ids_for_account = [
#             k for k, v in self.items() if v["Arn"].split(":")[4] == account_number
#         ]
#         return ids_for_account
# 
#     def seed(self, account_number: str) -> Iterable[str]:
#         if account_number in self._seeded:
#             return self._get_ids_for_account(account_number)
#         fetched_data = self._fetch_account(account_number)
#         new_keys = fetched_data.keys()
#         self._data.update(fetched_data)
#         self._seeded.append(account_number)
#         return new_keys
# 
# Path: repokid/exceptions.py
# class NotFoundError(Exception):
#     pass


from unittest.mock import patch
from repokid.datasource.iam import IAMDatasource
from repokid.exceptions import NotFoundError
import pytest




def test_iam_get():
    ds = IAMDatasource()
    arn = "pretend_arn"
    expected = {"a": "b"}
    ds._data = {arn: expected}
    result = ds.get(arn)
    assert result == expected


@patch("repokid.datasource.iam.IAMDatasource._fetch")
def test_iam_get_fallback_not_found(mock_fetch):
    mock_fetch.side_effect = NotFoundError

# Path: repokid/datasource/iam.py
# class IAMDatasource(DatasourcePlugin[str, IAMEntry], metaclass=Singleton):
#     _arn_to_id: Dict[str, str] = {}
# 
#     def __init__(self, config: Optional[RepokidConfig] = None):
#         super().__init__(config=config)
# 
#     def _fetch_account(self, account_number: str) -> Dict[str, IAMEntry]:
#         logger.info("getting role data for account %s", account_number)
#         conn = copy.deepcopy(self.config.get("connection_iam", {}))
#         conn["account_number"] = account_number
#         auth_details = get_account_authorization_details(filter="Role", **conn)
#         auth_details_by_id = {item["Arn"]: item for item in auth_details}
#         self._arn_to_id.update({item["Arn"]: item["RoleId"] for item in auth_details})
#         # convert policies list to dictionary to maintain consistency with old call which returned a dict
#         for _, data in auth_details_by_id.items():
#             data["RolePolicyList"] = {
#                 item["PolicyName"]: item["PolicyDocument"]
#                 for item in data["RolePolicyList"]
#             }
#         return auth_details_by_id
# 
#     def _fetch(self, arn: str) -> IAMEntry:
#         logger.info("getting role data for role %s", arn)
#         conn = copy.deepcopy(self.config["connection_iam"])
#         conn["account_number"] = arn.split(":")[4]
#         role = {"RoleName": arn.split("/")[-1]}
#         role_info: IAMEntry = get_role(role, flags=FLAGS.INLINE_POLICIES, **conn)
#         self._arn_to_id[arn] = role_info["RoleId"]
#         if not role_info:
#             raise NotFoundError
#         self._data[arn] = role_info
#         return role_info
# 
#     def get(self, arn: str) -> IAMEntry:
#         result = self._data.get(arn)
#         if not result:
#             return self._fetch(arn)
#         return result
# 
#     def get_id_for_arn(self, arn: str) -> Optional[str]:
#         return self._arn_to_id.get(arn)
# 
#     def _get_ids_for_account(self, account_number: str) -> Iterable[str]:
#         ids_for_account = [
#             k for k, v in self.items() if v["Arn"].split(":")[4] == account_number
#         ]
#         return ids_for_account
# 
#     def seed(self, account_number: str) -> Iterable[str]:
#         if account_number in self._seeded:
#             return self._get_ids_for_account(account_number)
#         fetched_data = self._fetch_account(account_number)
#         new_keys = fetched_data.keys()
#         self._data.update(fetched_data)
#         self._seeded.append(account_number)
#         return new_keys
# 
# Path: repokid/exceptions.py
# class NotFoundError(Exception):
#     pass


# Path: tests/datasource/test_iam.py
from unittest.mock import patch
from repokid.datasource.iam import IAMDatasource
from repokid.exceptions import NotFoundError
import pytest





def test_iam_get():
    ds = IAMDatasource()
    arn = "pretend_arn"
    expected = {"a": "b"}
    ds._data = {arn: expected}
    result = ds.get(arn)
    assert result == expected


@patch("repokid.datasource.iam.IAMDatasource._fetch")
def test_iam_get_fallback_not_found(mock_fetch):
    mock_fetch.side_effect = NotFoundError

    ds = IAMDatasource()