diff options
author | Anita Stanisz <106669481+anita-stanisz-sonarsource@users.noreply.github.com> | 2024-12-13 13:42:35 +0100 |
---|---|---|
committer | Steve Marion <steve.marion@sonarsource.com> | 2024-12-18 11:13:24 +0100 |
commit | 6729d5404b17631565797bd23401693f3e12466f (patch) | |
tree | 0664e5865ad0c27f1e4c1727a79099ca144fadf2 /server/sonar-webserver-webapi | |
parent | a0108a3b6df8e48d8aec1bee0ccb4d091274d719 (diff) | |
download | sonarqube-6729d5404b17631565797bd23401693f3e12466f.tar.gz sonarqube-6729d5404b17631565797bd23401693f3e12466f.zip |
SONAR-23893 Fix containsAiCode for community edition
Diffstat (limited to 'server/sonar-webserver-webapi')
2 files changed, 41 insertions, 13 deletions
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java index 32634203d72..20657eb6460 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/component/ws/SearchProjectsActionIT.java @@ -123,7 +123,7 @@ import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_LANGUA import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_QUALIFIER; import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_TAGS; -public class SearchProjectsActionIT { +class SearchProjectsActionIT { private static final String NCLOC = "ncloc"; private static final String COVERAGE = "coverage"; @@ -133,7 +133,7 @@ public class SearchProjectsActionIT { private static final String ANALYSIS_DATE = "analysisDate"; @RegisterExtension - public final UserSessionRule userSession = UserSessionRule.standalone(); + final UserSessionRule userSession = UserSessionRule.standalone(); @RegisterExtension public final EsTester es = EsTester.create(); @RegisterExtension @@ -222,7 +222,8 @@ public class SearchProjectsActionIT { void setUp() { when(aiCodeAssuranceEntitlement.isEnabled()).thenReturn(true); AiCodeAssuranceVerifier aiCodeAssuranceVerifier = new AiCodeAssuranceVerifier(aiCodeAssuranceEntitlement, db.getDbClient()); - underTest = new WsActionTester(new SearchProjectsAction(dbClient, index, userSession, editionProviderMock, aiCodeAssuranceVerifier)); + underTest = new WsActionTester(new SearchProjectsAction(dbClient, index, userSession, editionProviderMock, aiCodeAssuranceEntitlement + , aiCodeAssuranceVerifier)); } @Test @@ -1412,6 +1413,22 @@ public class SearchProjectsActionIT { tuple(project.getKey(), containsAiCode, Components.AiCodeAssurance.valueOf(expected.name()))); } + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void contains_ai_code_is_false_for_community_edition(boolean containsAiCode) { + userSession.logIn(); + when(aiCodeAssuranceEntitlement.isEnabled()).thenReturn(false); + ProjectData projectData = db.components().insertPublicProject(componentDto -> componentDto.setName("proj_A"), + projectDto -> projectDto.setContainsAiCode(containsAiCode)); + ProjectDto project = projectData.getProjectDto(); + authorizationIndexerTester.allowOnlyAnyone(project); + index(); + + SearchProjectsWsResponse result = call(request); + + assertThat(result.getComponentsList()).extracting(Component::getContainsAiCode).containsExactly(false); + } + private static Stream<Arguments> aiCodeAssuranceParams() { return Stream.of( Arguments.of(false, false, "OK", AiCodeAssurance.NONE), diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java index 0f20c517db0..eb065a300e7 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java @@ -58,6 +58,7 @@ import org.sonar.db.property.PropertyDto; import org.sonar.db.property.PropertyQuery; import org.sonar.db.user.TokenType; import org.sonar.server.ai.code.assurance.AiCodeAssurance; +import org.sonar.server.ai.code.assurance.AiCodeAssuranceEntitlement; import org.sonar.server.ai.code.assurance.AiCodeAssuranceVerifier; import org.sonar.server.component.ws.FilterParser.Criterion; import org.sonar.server.component.ws.SearchProjectsAction.SearchResults.SearchResultsBuilder; @@ -115,13 +116,15 @@ public class SearchProjectsAction implements ComponentsWsAction { private final UserSession userSession; private final PlatformEditionProvider editionProvider; private final AiCodeAssuranceVerifier aiCodeAssuranceVerifier; + private final AiCodeAssuranceEntitlement aiCodeAssuranceEntitlement; public SearchProjectsAction(DbClient dbClient, ProjectMeasuresIndex index, UserSession userSession, - PlatformEditionProvider editionProvider, AiCodeAssuranceVerifier aiCodeAssuranceVerifier) { + PlatformEditionProvider editionProvider, AiCodeAssuranceEntitlement aiCodeAssuranceEntitlement, AiCodeAssuranceVerifier aiCodeAssuranceVerifier ) { this.dbClient = dbClient; this.index = index; this.userSession = userSession; this.editionProvider = editionProvider; + this.aiCodeAssuranceEntitlement = aiCodeAssuranceEntitlement; this.aiCodeAssuranceVerifier = aiCodeAssuranceVerifier; } @@ -157,11 +160,13 @@ public class SearchProjectsAction implements ComponentsWsAction { action .createParam(PARAM_FILTER) .setMinimumLength(2) - .setDescription("Filter of projects on name, key, measure value, quality gate, language, tag or whether a project is a favorite or not.<br>" + + .setDescription("Filter of projects on name, key, measure value, quality gate, language, tag or whether a project is a favorite or " + + "not.<br>" + "The filter must be encoded to form a valid URL (for example '=' must be replaced by '%3D').<br>" + "Examples of use:" + HTML_UL_START_TAG + - " <li>to filter my favorite projects with a failed quality gate and a coverage greater than or equals to 60% and a coverage strictly lower than 80%:<br>" + + " <li>to filter my favorite projects with a failed quality gate and a coverage greater than or equals to 60% and a coverage " + + "strictly lower than 80%:<br>" + " <code>filter=\"alert_status = ERROR and isFavorite and coverage >= 60 and coverage < 80\"</code></li>" + " <li>to filter projects with a reliability, security and maintainability rating equals or worse than B:<br>" + " <code>filter=\"reliability_rating>=2 and security_rating>=2 and sqale_rating>=2\"</code></li>" + @@ -210,7 +215,8 @@ public class SearchProjectsAction implements ComponentsWsAction { " <li>APP - for applications</li>" + HTML_UL_END_TAG); action.createParam(Param.SORT) - .setDescription("Sort projects by numeric metric key, quality gate status (using '%s'), last analysis date (using '%s'), project name or creationDate (using '%s').", + .setDescription("Sort projects by numeric metric key, quality gate status (using '%s'), last analysis date (using '%s'), project " + + "name or creationDate (using '%s').", ALERT_STATUS_KEY, SORT_BY_LAST_ANALYSIS_DATE, PARAM_FILTER, SORT_BY_CREATION_DATE) .setDefaultValue(SORT_BY_NAME) .setPossibleValues( @@ -265,7 +271,8 @@ public class SearchProjectsAction implements ComponentsWsAction { List<SnapshotDto> snapshots = getSnapshots(dbSession, request, mainBranchByUuid.keySet()); Map<String, SnapshotDto> analysisByProjectUuid = snapshots.stream() .collect(Collectors.toMap(s -> mainBranchByUuid.get(s.getRootComponentUuid()).getProjectUuid(), s -> s)); - Map<String, Long> applicationsBranchLeakPeriod = getApplicationsLeakPeriod(dbSession, request, qualifiersBasedOnEdition, mainBranchByUuid.keySet()); + Map<String, Long> applicationsBranchLeakPeriod = getApplicationsLeakPeriod(dbSession, request, qualifiersBasedOnEdition, + mainBranchByUuid.keySet()); Map<String, Long> applicationsLeakPeriod = applicationsBranchLeakPeriod.entrySet() .stream() .collect(Collectors.toMap(e -> mainBranchByUuid.get(e.getKey()).getProjectUuid(), Entry::getValue)); @@ -342,12 +349,15 @@ public class SearchProjectsAction implements ComponentsWsAction { return emptyList(); } - private Map<String, Long> getApplicationsLeakPeriod(DbSession dbSession, SearchProjectsRequest request, Set<String> qualifiers, Collection<String> mainBranchUuids) { + private Map<String, Long> getApplicationsLeakPeriod(DbSession dbSession, SearchProjectsRequest request, Set<String> qualifiers, + Collection<String> mainBranchUuids) { if (qualifiers.contains(ComponentQualifiers.APP) && request.getAdditionalFields().contains(LEAK_PERIOD_DATE)) { - return dbClient.measureDao().selectByComponentUuidsAndMetricKeys(dbSession, mainBranchUuids, Collections.singleton(METRIC_LEAK_PROJECTS_KEY)) + return dbClient.measureDao().selectByComponentUuidsAndMetricKeys(dbSession, mainBranchUuids, + Collections.singleton(METRIC_LEAK_PROJECTS_KEY)) .stream() .filter(m -> !Objects.isNull(m.getString(METRIC_LEAK_PROJECTS_KEY))) - .map(m -> Maps.immutableEntry(m.getComponentUuid(), ApplicationLeakProjects.parse(m.getString(METRIC_LEAK_PROJECTS_KEY)).getOldestLeak())) + .map(m -> Maps.immutableEntry(m.getComponentUuid(), + ApplicationLeakProjects.parse(m.getString(METRIC_LEAK_PROJECTS_KEY)).getOldestLeak())) .filter(entry -> entry.getValue().isPresent()) .collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().get().getLeak())); } @@ -496,7 +506,7 @@ public class SearchProjectsAction implements ComponentsWsAction { .setName(dbProject.getName()) .setQualifier(dbProject.getQualifier()) .setVisibility(Visibility.getLabel(dbProject.isPrivate())) - .setContainsAiCode(dbProject.getContainsAiCode()) + .setContainsAiCode(dbProject.getContainsAiCode() && aiCodeAssuranceEntitlement.isEnabled()) .setAiCodeAssurance(Components.AiCodeAssurance.valueOf(aiCodeAssurance.name())) .setIsAiCodeFixEnabled(dbProject.getAiCodeFixEnabled()); wsComponent.getTagsBuilder().addAllTags(dbProject.getTags()); @@ -533,7 +543,8 @@ public class SearchProjectsAction implements ComponentsWsAction { private final ProjectMeasuresQuery query; private final int total; - private SearchResults(List<ProjectDto> projects, Set<String> favoriteProjectUuids, SearchIdResult<String> searchResults, Map<String, SnapshotDto> analysisByProjectUuid, + private SearchResults(List<ProjectDto> projects, Set<String> favoriteProjectUuids, SearchIdResult<String> searchResults, Map<String, + SnapshotDto> analysisByProjectUuid, Map<String, Long> applicationsLeakPeriods, ProjectMeasuresQuery query) { this.projects = projects; this.favoriteProjectUuids = favoriteProjectUuids; |