From: Teryk Bellahsene Date: Fri, 11 Nov 2016 10:38:19 +0000 (+0100) Subject: SONAR-8363 Mark just created projects as favorite X-Git-Tag: 6.2-RC1~114 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=82060eef2e3e582862fc746e6ce1bfceeb5e035d;p=sonarqube.git SONAR-8363 Mark just created projects as favorite --- diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java index 4bcdb4b567f..6168cbcc122 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java @@ -326,7 +326,6 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { UserPermissionChanger.class, GroupPermissionChanger.class, - // components ComponentFinder.class, // used in ComponentService ComponentService.class, // used in ReportSubmitter diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java index 2442a85c96f..895abe96775 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java @@ -126,13 +126,15 @@ public class ComponentService { projectMeasuresIndexer.index(projectUuid); } + // Used by SQ and Governance public ComponentDto create(DbSession session, NewComponent newComponent) { userSession.checkPermission(GlobalPermissions.PROVISIONING); checkKeyFormat(newComponent.qualifier(), newComponent.key()); - ComponentDto project = createProject(session, newComponent); - removeDuplicatedProjects(session, project.getKey()); - projectMeasuresIndexer.index(project.uuid()); - return project; + ComponentDto rootComponent = createRootComponent(session, newComponent); + removeDuplicatedProjects(session, rootComponent.getKey()); + projectMeasuresIndexer.index(rootComponent.uuid()); + + return rootComponent; } /** @@ -141,10 +143,10 @@ public class ComponentService { * No need to remove duplicated components as it's not possible to create the same developer twice in the same time. */ public ComponentDto createDeveloper(DbSession session, NewComponent newComponent) { - return createProject(session, newComponent); + return createRootComponent(session, newComponent); } - private ComponentDto createProject(DbSession session, NewComponent newComponent) { + private ComponentDto createRootComponent(DbSession session, NewComponent newComponent) { checkBranchFormat(newComponent.qualifier(), newComponent.branch()); String keyWithBranch = ComponentKeys.createKey(newComponent.key(), newComponent.branch()); diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java index 9c4343aff3d..7f5399a64f7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java @@ -26,6 +26,7 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.component.Component; import org.sonar.api.component.RubyComponentService; +import org.sonar.api.resources.Qualifiers; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; @@ -40,12 +41,15 @@ public class DefaultRubyComponentService implements RubyComponentService { private final ResourceDao resourceDao; private final ComponentService componentService; private final PermissionTemplateService permissionTemplateService; + private final FavoriteService favoriteService; - public DefaultRubyComponentService(DbClient dbClient, ResourceDao resourceDao, ComponentService componentService, PermissionTemplateService permissionTemplateService) { + public DefaultRubyComponentService(DbClient dbClient, ResourceDao resourceDao, ComponentService componentService, PermissionTemplateService permissionTemplateService, + FavoriteService favoriteService) { this.dbClient = dbClient; this.resourceDao = resourceDao; this.componentService = componentService; this.permissionTemplateService = permissionTemplateService; + this.favoriteService = favoriteService; } @Override @@ -81,6 +85,11 @@ public class DefaultRubyComponentService implements RubyComponentService { public long createComponent(DbSession dbSession, String key, @Nullable String branch, String name, @Nullable String qualifier) { ComponentDto provisionedComponent = componentService.create(dbSession, NewComponent.create(key, name).setQualifier(qualifier).setBranch(branch)); permissionTemplateService.applyDefaultPermissionTemplate(dbSession, provisionedComponent.getKey()); + if (Qualifiers.PROJECT.equals(provisionedComponent.qualifier())) { + favoriteService.put(dbSession, provisionedComponent.getId()); + dbSession.commit(); + } + return provisionedComponent.getId(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/FavoriteService.java b/server/sonar-server/src/main/java/org/sonar/server/component/FavoriteService.java new file mode 100644 index 00000000000..bf1045f4eb0 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/component/FavoriteService.java @@ -0,0 +1,52 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.component; + +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.property.PropertyDto; +import org.sonar.server.user.UserSession; + +public class FavoriteService { + private static final String PROP_FAVORITE_KEY = "favourite"; + + private final DbClient dbClient; + private final UserSession userSession; + + public FavoriteService(DbClient dbClient, UserSession userSession) { + this.dbClient = dbClient; + this.userSession = userSession; + } + + /** + * Set favorite to the logged in user. If no user is logged, no action is done + */ + public void put(DbSession dbSession, long componentDbId) { + if (!userSession.isLoggedIn()) { + return; + } + + dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto() + .setKey(PROP_FAVORITE_KEY) + .setResourceId(componentDbId) + .setUserId(Long.valueOf(userSession.getUserId()))); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java index 81003ce173d..6997d28bf35 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/ReportSubmitter.java @@ -34,6 +34,7 @@ import org.sonar.db.DbSession; import org.sonar.db.ce.CeTaskTypes; import org.sonar.db.component.ComponentDto; import org.sonar.server.component.ComponentService; +import org.sonar.server.component.FavoriteService; import org.sonar.server.component.NewComponent; import org.sonar.server.permission.PermissionTemplateService; import org.sonar.server.user.UserSession; @@ -49,14 +50,16 @@ public class ReportSubmitter { private final ComponentService componentService; private final PermissionTemplateService permissionTemplateService; private final DbClient dbClient; + private final FavoriteService favoriteService; public ReportSubmitter(CeQueue queue, UserSession userSession, - ComponentService componentService, PermissionTemplateService permissionTemplateService, DbClient dbClient) { + ComponentService componentService, PermissionTemplateService permissionTemplateService, DbClient dbClient, FavoriteService favoriteService) { this.queue = queue; this.userSession = userSession; this.componentService = componentService; this.permissionTemplateService = permissionTemplateService; this.dbClient = dbClient; + this.favoriteService = favoriteService; } public CeTask submit(String projectKey, @Nullable String projectBranch, @Nullable String projectName, InputStream reportInput) { @@ -84,8 +87,11 @@ public class ReportSubmitter { newProject.setQualifier(Qualifiers.PROJECT); // "provisioning" permission is check in ComponentService ComponentDto project = componentService.create(dbSession, newProject); + favoriteService.put(dbSession, project.getId()); + dbSession.commit(); permissionTemplateService.applyDefault(dbSession, project, projectCreatorUserId); + return project; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java index 41f1509dd3b..c3c1dba76a9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java @@ -149,7 +149,7 @@ public class PermissionTemplateService { */ public void applyDefault(DbSession dbSession, ComponentDto component, @Nullable Long projectCreatorUserId) { PermissionTemplateDto template = findDefaultTemplate(dbSession, component); - checkArgument(template != null, "Can not retrieve default permission template"); + checkArgument(template != null, "Cannot retrieve default permission template"); copyPermissions(dbSession, template, component, projectCreatorUserId); dbSession.commit(); indexProjectPermissions(dbSession, asList(component.uuid())); diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index f093c2e6d8b..594d98a044e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -41,6 +41,7 @@ import org.sonar.server.component.ComponentFinder; import org.sonar.server.component.ComponentService; import org.sonar.server.component.DefaultComponentFinder; import org.sonar.server.component.DefaultRubyComponentService; +import org.sonar.server.component.FavoriteService; import org.sonar.server.component.es.ProjectsEsModule; import org.sonar.server.component.ws.ComponentsWsModule; import org.sonar.server.config.ws.PropertiesWs; @@ -379,6 +380,7 @@ public class PlatformLevel4 extends PlatformLevel { NewAlerts.class, NewAlerts.newMetadata(), ComponentCleanerService.class, + FavoriteService.class, // views ViewIndexDefinition.class, diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java index f75f6814fa0..3b7adea5518 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java @@ -61,19 +61,20 @@ public class DefaultRubyComponentServiceTest { @Rule public EsTester es = new EsTester(new ProjectMeasuresIndexDefinition(new MapSettings())); - I18nRule i18n = new I18nRule(); + private I18nRule i18n = new I18nRule(); - DbClient dbClient = db.getDbClient(); - DbSession dbSession = db.getSession(); + private DbClient dbClient = db.getDbClient(); + private DbSession dbSession = db.getSession(); - ResourceDao resourceDao = dbClient.resourceDao(); - ComponentService componentService = new ComponentService(dbClient, i18n, userSession, System2.INSTANCE, new ComponentFinder(dbClient), + private ResourceDao resourceDao = dbClient.resourceDao(); + private ComponentService componentService = new ComponentService(dbClient, i18n, userSession, System2.INSTANCE, new ComponentFinder(dbClient), new ProjectMeasuresIndexer(dbClient, es.client())); - PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); + private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); + private FavoriteService favoriteService = mock(FavoriteService.class); ComponentDbTester componentDb = new ComponentDbTester(db); - DefaultRubyComponentService service = new DefaultRubyComponentService(dbClient, resourceDao, componentService, permissionTemplateService); + DefaultRubyComponentService service = new DefaultRubyComponentService(dbClient, resourceDao, componentService, permissionTemplateService, favoriteService); @Test public void find_by_key() { @@ -111,6 +112,7 @@ public class DefaultRubyComponentServiceTest { assertThat(project.qualifier()).isEqualTo(qualifier); assertThat(project.getId()).isEqualTo(result); verify(permissionTemplateService).applyDefaultPermissionTemplate(any(DbSession.class), eq(componentKey)); + verify(favoriteService).put(any(DbSession.class), eq(project.getId())); } @Test(expected = BadRequestException.class) diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/FavoriteServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/FavoriteServiceTest.java new file mode 100644 index 00000000000..8c5cdafe572 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/component/FavoriteServiceTest.java @@ -0,0 +1,89 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.component; + +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.property.PropertyQuery; +import org.sonar.server.tester.UserSessionRule; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FavoriteServiceTest { + private static final long COMPONENT_ID = 23L; + private static final long USER_ID = 42L; + + @Rule + public UserSessionRule userSession = UserSessionRule.standalone().login().setUserId((int) USER_ID); + + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + private DbClient dbClient = db.getDbClient(); + private DbSession dbSession = db.getSession(); + + private FavoriteService underTest = new FavoriteService(dbClient, userSession); + + @Test + public void put_favorite() { + assertNoFavorite(); + + underTest.put(dbSession, COMPONENT_ID); + + assertFavorite(); + } + + @Test + public void do_nothing_when_not_logged_in() { + userSession.anonymous(); + + underTest.put(dbSession, COMPONENT_ID); + + assertNoFavorite(); + } + + @Test + public void put_existing_favorite() { + underTest.put(dbSession, COMPONENT_ID); + assertFavorite(); + + underTest.put(dbSession, COMPONENT_ID); + + assertFavorite(); + } + + private void assertFavorite() { + assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder() + .setUserId((int) USER_ID) + .setComponentId(COMPONENT_ID) + .build(), dbSession)).hasSize(1); + } + + private void assertNoFavorite() { + assertThat(dbClient.propertiesDao().selectByQuery(PropertyQuery.builder() + .setUserId((int) USER_ID) + .setComponentId(COMPONENT_ID) + .build(), dbSession)).isEmpty(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java index 7367d0d2d21..d8609659c74 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/ReportSubmitterTest.java @@ -36,6 +36,7 @@ import org.sonar.db.DbTester; import org.sonar.db.ce.CeTaskTypes; import org.sonar.db.component.ComponentDto; import org.sonar.server.component.ComponentService; +import org.sonar.server.component.FavoriteService; import org.sonar.server.component.NewComponent; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.permission.PermissionTemplateService; @@ -73,7 +74,9 @@ public class ReportSubmitterTest { private CeQueue queue = mock(CeQueueImpl.class); private ComponentService componentService = mock(ComponentService.class); private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class); - private ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentService, permissionTemplateService, db.getDbClient()); + private FavoriteService favoriteService = mock(FavoriteService.class); + + private ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentService, permissionTemplateService, db.getDbClient(), favoriteService); @Test public void submit_a_report_on_existing_project() { @@ -86,6 +89,7 @@ public class ReportSubmitterTest { verifyReportIsPersisted(TASK_UUID); verifyZeroInteractions(permissionTemplateService); + verifyZeroInteractions(favoriteService); verify(queue).submit(argThat(new TypeSafeMatcher() { @Override protected boolean matchesSafely(CeTaskSubmit submit) { @@ -105,7 +109,7 @@ public class ReportSubmitterTest { userSession.setGlobalPermissions(SCAN_EXECUTION, PROVISIONING); when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); - ComponentDto createdProject = new ComponentDto().setUuid(PROJECT_UUID).setKey(PROJECT_KEY); + ComponentDto createdProject = new ComponentDto().setId(23L).setUuid(PROJECT_UUID).setKey(PROJECT_KEY); when(componentService.create(any(DbSession.class), any(NewComponent.class))).thenReturn(createdProject); when(permissionTemplateService.wouldUserHavePermissionWithDefaultTemplate(any(DbSession.class), anyLong(), eq(SCAN_EXECUTION), anyString(), eq(PROJECT_KEY), eq(Qualifiers.PROJECT))) .thenReturn(true); @@ -114,6 +118,7 @@ public class ReportSubmitterTest { verifyReportIsPersisted(TASK_UUID); verify(permissionTemplateService).applyDefault(any(DbSession.class), eq(createdProject), anyLong()); + verify(favoriteService).put(any(DbSession.class), eq(createdProject.getId())); verify(queue).submit(argThat(new TypeSafeMatcher() { @Override protected boolean matchesSafely(CeTaskSubmit submit) { @@ -133,7 +138,7 @@ public class ReportSubmitterTest { userSession.setGlobalPermissions(SCAN_EXECUTION, PROVISIONING); when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID)); - when(componentService.create(any(DbSession.class), any(NewComponent.class))).thenReturn(new ComponentDto().setUuid(PROJECT_UUID).setKey(PROJECT_KEY)); + when(componentService.create(any(DbSession.class), any(NewComponent.class))).thenReturn(new ComponentDto().setId(23L).setUuid(PROJECT_UUID).setKey(PROJECT_KEY)); when(permissionTemplateService.wouldUserHavePermissionWithDefaultTemplate(any(DbSession.class), anyLong(), eq(SCAN_EXECUTION), anyString(), eq(PROJECT_KEY), eq(Qualifiers.PROJECT))) .thenReturn(true);