From ae49ca686664b229b51b5f74299d45d87d663e30 Mon Sep 17 00:00:00 2001 From: Damien Urruty Date: Thu, 7 Nov 2024 11:40:57 +0100 Subject: [PATCH] CODEFIX-183 Check project enablement to show the 'Generate AI Fix' button --- .../sonar-web/src/main/js/api/components.ts | 1 + .../js/apps/issues/__tests__/IssueApp-it.tsx | 38 +++++++++++++++++-- .../src/main/js/queries/fix-suggestions.tsx | 14 ++----- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/server/sonar-web/src/main/js/api/components.ts b/server/sonar-web/src/main/js/api/components.ts index b98c6c1e0cf..05e518efa37 100644 --- a/server/sonar-web/src/main/js/api/components.ts +++ b/server/sonar-web/src/main/js/api/components.ts @@ -55,6 +55,7 @@ export interface ProjectBase { export interface ComponentRaw { analysisDate?: string; isAiCodeAssured?: boolean; + isAiCodeFixEnabled?: boolean; isFavorite?: boolean; key: string; leakPeriodDate?: string; diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssueApp-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssueApp-it.tsx index 1e03aaa26df..4b70147a63b 100644 --- a/server/sonar-web/src/main/js/apps/issues/__tests__/IssueApp-it.tsx +++ b/server/sonar-web/src/main/js/apps/issues/__tests__/IssueApp-it.tsx @@ -23,10 +23,12 @@ import userEvent from '@testing-library/user-event'; import { range } from 'lodash'; import React from 'react'; import { byRole, byText } from '~sonar-aligned/helpers/testSelector'; -import { ISSUE_101, ISSUE_1101 } from '../../../api/mocks/data/ids'; +import { ISSUE_101, ISSUE_1101, ISSUE_2 } from '../../../api/mocks/data/ids'; import { TabKeys } from '../../../components/rules/RuleTabViewer'; +import { mockComponent } from '../../../helpers/mocks/component'; import { mockCurrentUser, mockCve, mockLoggedInUser } from '../../../helpers/testMocks'; import { Feature } from '../../../types/features'; +import { Component } from '../../../types/types'; import { RestUserDetailed } from '../../../types/users'; import { branchHandler, @@ -94,7 +96,10 @@ describe('issue app', () => { }); it('should be able to trigger a fix when feature is available', async () => { - settingsHandler.set('sonar.ai.suggestions.enabled', 'true'); + componentsHandler.registerComponent({ + ...mockComponent({ key: 'myproject' }), + isAiCodeFixEnabled: true, + } as Component); sourcesHandler.setSource( range(0, 1) .map((n) => `line: ${n}`) @@ -102,7 +107,7 @@ describe('issue app', () => { ); const user = userEvent.setup(); renderProjectIssuesApp( - 'project/issues?issueStatuses=CONFIRMED&open=issue2&id=myproject', + `project/issues?issueStatuses=CONFIRMED&open=${ISSUE_2}&id=myproject`, {}, mockLoggedInUser(), [Feature.BranchSupport, Feature.FixSuggestions], @@ -130,6 +135,28 @@ describe('issue app', () => { expect(ui.issueCodeFixTab.query()).not.toBeInTheDocument(); }); + it('should not be able to trigger a fix when the feature is disabled', async () => { + componentsHandler.registerComponent({ + ...mockComponent({ key: 'myproject' }), + isAiCodeFixEnabled: false, + } as Component); + sourcesHandler.setSource( + range(0, 1) + .map((n) => `line: ${n}`) + .join('\n'), + ); + renderProjectIssuesApp( + `project/issues?issueStatuses=CONFIRMED&open=${ISSUE_2}&id=myproject`, + {}, + mockLoggedInUser(), + [Feature.BranchSupport, Feature.FixSuggestions], + ); + + expect(await ui.issueCodeTab.find(undefined, { timeout: 10_000 })).toBeInTheDocument(); + expect(ui.getFixSuggestion.query()).not.toBeInTheDocument(); + expect(ui.issueCodeFixTab.query()).not.toBeInTheDocument(); + }); + it('should not be able to trigger a fix when issue is not eligible', async () => { renderProjectIssuesApp( `project/issues?issueStatuses=CONFIRMED&open=${ISSUE_1101}&id=myproject`, @@ -143,7 +170,10 @@ describe('issue app', () => { }); it('should show error when no fix is available', async () => { - settingsHandler.set('sonar.ai.suggestions.enabled', 'true'); + componentsHandler.registerComponent({ + ...mockComponent({ key: 'myproject' }), + isAiCodeFixEnabled: true, + } as Component); const user = userEvent.setup(); renderProjectIssuesApp( `project/issues?issueStatuses=CONFIRMED&open=${ISSUE_101}&id=myproject`, diff --git a/server/sonar-web/src/main/js/queries/fix-suggestions.tsx b/server/sonar-web/src/main/js/queries/fix-suggestions.tsx index 8faafa97a5a..fc70ff12e2c 100644 --- a/server/sonar-web/src/main/js/queries/fix-suggestions.tsx +++ b/server/sonar-web/src/main/js/queries/fix-suggestions.tsx @@ -31,10 +31,9 @@ import { import { useAvailableFeatures } from '../app/components/available-features/withAvailableFeatures'; import { CurrentUserContext } from '../app/components/current-user/CurrentUserContext'; import { Feature } from '../types/features'; -import { SettingsKey } from '../types/settings'; import { Issue } from '../types/types'; import { isLoggedIn } from '../types/users'; -import { useGetValueQuery } from './settings'; +import { useComponentDataQuery } from './component'; import { useRawSourceQuery } from './sources'; const UNKNOWN = -1; @@ -151,14 +150,9 @@ export function useGetFixSuggestionsIssuesQuery(issue: Issue) { const { currentUser } = useContext(CurrentUserContext); const { hasFeature } = useAvailableFeatures(); - const { data: codeFixSetting } = useGetValueQuery( - { - key: SettingsKey.CodeSuggestion, - }, - { staleTime: Infinity }, - ); - - const isCodeFixEnabled = codeFixSetting?.value === 'true'; + const isCodeFixEnabled = + useComponentDataQuery({ component: issue.project }).data?.component?.isAiCodeFixEnabled || + false; return useQuery({ queryKey: ['code-suggestions', 'issues', 'details', issue.key], -- 2.39.5