diff --git a/src/openhound_github/models/enterprise_organization.py b/src/openhound_github/models/enterprise_organization.py index 0abca03..d917fed 100644 --- a/src/openhound_github/models/enterprise_organization.py +++ b/src/openhound_github/models/enterprise_organization.py @@ -55,6 +55,8 @@ def node_id(self) -> str: @property def as_node(self) -> GHNode: + # Only collected if the org was explicitly collected (present in the lookup). + collected = self._lookup.org_login_for_id(self.node_id) is not None return GHNode( kinds=[nk.ORGANIZATION], properties=GHEnterpriseOrganizationProperties( @@ -64,7 +66,7 @@ def as_node(self) -> GHNode: environmentid=self.node_id, environment_name=self.login, login=self.login, - collected=False, + collected=collected, query_enterprise=f"MATCH p=(:GH_Enterprise {{node_id:'{self.enterprise_node_id}'}})-[:GH_Contains]->(:GH_Organization {{node_id:'{self.node_id}'}}) RETURN p", ), ) diff --git a/tests/test_enterprise_organization.py b/tests/test_enterprise_organization.py new file mode 100644 index 0000000..310f56e --- /dev/null +++ b/tests/test_enterprise_organization.py @@ -0,0 +1,69 @@ +""" +Tests for EnterpriseOrganization.as_node `collected` resolution. + +An organization discovered via the enterprise is a stub node. Its `collected` +flag must be derived from the organizations lookup table so that it agrees with +the full Organization node regardless of ingestion order: + + - explicitly collected org (present in lookup) -> collected=True + - enterprise-only discovered org (absent) -> collected=False +""" +from unittest.mock import MagicMock + +from openhound_github.models import EnterpriseOrganization + + +def _make_org(node_id: str = "ORG_NODE_1", login: str = "acme") -> EnterpriseOrganization: + org = EnterpriseOrganization( + id=node_id, + login=login, + enterprise_node_id="ENT_NODE_1", + enterprise_slug="acme-enterprise", + ) + return org + + +def test_collected_true_when_org_in_lookup() -> None: + """An org present in the organizations lookup is marked collected=True.""" + org = _make_org(node_id="ORG_NODE_1", login="acme") + lookup = MagicMock() + lookup.org_login_for_id.return_value = "acme" + org._lookup = lookup + + node = org.as_node + + assert node.properties.collected is True + lookup.org_login_for_id.assert_called_once_with("ORG_NODE_1") + + +def test_collected_false_when_org_not_in_lookup() -> None: + """An enterprise-only discovered org (absent from lookup) is collected=False.""" + org = _make_org(node_id="ORG_NODE_2", login="beta") + lookup = MagicMock() + lookup.org_login_for_id.return_value = None + org._lookup = lookup + + node = org.as_node + + assert node.properties.collected is False + lookup.org_login_for_id.assert_called_once_with("ORG_NODE_2") + + +def test_collected_resolved_per_node_id_in_multi_org_enterprise() -> None: + """Each stub resolves `collected` against its own node_id independently.""" + collected_ids = {"ORG_NODE_COLLECTED"} + + def fake_lookup(node_id: str): + return "login" if node_id in collected_ids else None + + lookup = MagicMock() + lookup.org_login_for_id.side_effect = fake_lookup + + collected_org = _make_org(node_id="ORG_NODE_COLLECTED", login="collected") + collected_org._lookup = lookup + + stub_org = _make_org(node_id="ORG_NODE_STUB", login="stub") + stub_org._lookup = lookup + + assert collected_org.as_node.properties.collected is True + assert stub_org.as_node.properties.collected is False