diff --git a/graphql_api/tests/test_owner.py b/graphql_api/tests/test_owner.py index b626a07da6..04cac63523 100644 --- a/graphql_api/tests/test_owner.py +++ b/graphql_api/tests/test_owner.py @@ -1202,3 +1202,46 @@ def test_fetch_available_plans_is_enterprise_plan(self): ] } } + + @patch("services.self_hosted.get_config") + def test_ai_enabled_repositories(self, get_config_mock): + current_org = OwnerFactory( + username="random-plan-user", + service="github", + ) + + get_config_mock.return_value = [ + {"service": "github", "ai_features_app_id": 12345}, + ] + + query = """{ + owner(username: "%s") { + aiEnabledRepos + } + } + + """ % (current_org.username) + data = self.gql_request(query, owner=current_org) + assert data["owner"]["aiEnabledRepos"] is None + + + @patch("services.self_hosted.get_config") + def test_ai_enabled_repositories_app_not_configured(self, get_config_mock): + current_org = OwnerFactory( + username="random-plan-user", + service="github", + ) + + get_config_mock.return_value = [ + {"service": "github", "ai_features_app_id": 12345}, + ] + + query = """{ + owner(username: "%s") { + aiEnabledRepos + } + } + + """ % (current_org.username) + data = self.gql_request(query, owner=current_org) + assert data["owner"]["aiEnabledRepos"] is None diff --git a/graphql_api/types/owner/owner.graphql b/graphql_api/types/owner/owner.graphql index 0f3b7c7413..0bf2749b85 100644 --- a/graphql_api/types/owner/owner.graphql +++ b/graphql_api/types/owner/owner.graphql @@ -39,6 +39,14 @@ type Owner { yaml: String aiFeaturesEnabled: Boolean! aiEnabledRepos: [String] + aiEnabledRepositories( + ordering: RepositoryOrdering + orderingDirection: OrderingDirection + first: Int + after: String + last: Int + before: String + ): RepositoryConnection! @cost(complexity: 25, multipliers: ["first", "last"]) uploadTokenRequired: Boolean activatedUserCount: Int } diff --git a/graphql_api/types/owner/owner.py b/graphql_api/types/owner/owner.py index a268472156..0ffe63b904 100644 --- a/graphql_api/types/owner/owner.py +++ b/graphql_api/types/owner/owner.py @@ -396,3 +396,33 @@ def resolve_upload_token_required( @require_shared_account_or_part_of_org def resolve_activated_user_count(owner: Owner, info: GraphQLResolveInfo) -> int: return owner.activated_user_count + +@owner_bindable.field("aiEnabledRepositories") +def resolve_ai_enabled_repositories( + owner: Owner, + info: GraphQLResolveInfo, + ordering: Optional[RepositoryOrdering] = RepositoryOrdering.ID, + ordering_direction: Optional[OrderingDirection] = OrderingDirection.ASC, + **kwargs: Any, +) -> Coroutine[Any, Any, Connection]: + ai_features_app_install = GithubAppInstallation.objects.filter( + app_id=AI_FEATURES_GH_APP_ID, owner=owner + ).first() + + if not ai_features_app_install: + return None + + current_owner = info.context["request"].current_owner + queryset = Repository.objects.filter(author=owner).viewable_repos(current_owner) + + if ai_features_app_install.repository_service_ids: + queryset = queryset.filter( + service_id__in=ai_features_app_install.repository_service_ids + ) + + return queryset_to_connection( + queryset, + ordering=(ordering, RepositoryOrdering.ID), + ordering_direction=ordering_direction, + **kwargs, + ) \ No newline at end of file