QProfileCopier.class,
QProfileBackuper.class,
QProfileReset.class,
- RubyQProfileActivityService.class,
+ QProfilesWsModule.class,
// rule
RuleIndexDefinition.class,
--- /dev/null
-import org.sonar.server.component.ws.LanguageParamUtils;
+ /*
+ * 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.qualityprofile.ws;
+
+ import org.sonar.api.resources.Languages;
+ import org.sonar.api.server.ws.WebService;
++import org.sonar.server.util.LanguageParamUtils;
+
+ import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
+ import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
+ import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROFILE_KEY;
+ import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROFILE_NAME;
+ import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROJECT_KEY;
+ import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROJECT_UUID;
+
+ public class ProjectAssociationParameters {
+
+ private final Languages languages;
+
+ public ProjectAssociationParameters(Languages languages) {
+ this.languages = languages;
+ }
+
+ void addParameters(WebService.NewAction action) {
+ action.setPost(true);
+ action.createParam(PARAM_PROJECT_UUID)
+ .setDescription("A project UUID. Either this parameter, or projectKey must be set.")
+ .setExampleValue("69e57151-be0d-4157-adff-c06741d88879");
+ action.createParam(PARAM_PROJECT_KEY)
+ .setDescription("A project key. Either this parameter, or projectUuid must be set.")
+ .setExampleValue(KEY_PROJECT_EXAMPLE_001);
+ action.createParam(PARAM_PROFILE_KEY)
+ .setDescription("A quality profile key. Either this parameter, or a combination of profileName + language must be set.")
+ .setExampleValue("sonar-way-java-12345");
+ action.createParam(PARAM_PROFILE_NAME)
+ .setDescription("A quality profile name. If this parameter is set, profileKey must not be set and language must be set to disambiguate.")
+ .setExampleValue("Soanr way");
+ action.createParam(PARAM_LANGUAGE)
+ .setDescription("A quality profile language. If this parameter is set, profileKey must not be set and profileName must be set to disambiguate.")
+ .setPossibleValues(LanguageParamUtils.getLanguageKeys(languages))
+ .setExampleValue("js");
+ }
+
+ }
--- /dev/null
+ /*
+ * 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.qualityprofile.ws;
+
+ import org.sonar.core.platform.Module;
+
+ public class QProfilesWsModule extends Module {
+ @Override
+ protected void configureModule() {
+ add(
+ AddProjectAction.class,
+ BackupAction.class,
+ BulkRuleActivationActions.class,
+ CompareAction.class,
+ CopyAction.class,
+ ChangelogAction.class,
++ ChangelogLoader.class,
+ ChangeParentAction.class,
+ CreateAction.class,
+ DeleteAction.class,
+ ExportAction.class,
+ ExportersAction.class,
+ ImportersAction.class,
+ InheritanceAction.class,
+ QProfilesWs.class,
+ ProjectAssociationFinder.class,
+ ProjectAssociationParameters.class,
+ ProjectsAction.class,
+ RenameAction.class,
+ RemoveProjectAction.class,
+ RestoreAction.class,
+ RestoreBuiltInAction.class,
+ RuleActivationActions.class,
+ SearchAction.class,
+ SetDefaultAction.class
+ );
+ }
+ }
import org.sonarqube.ws.QualityProfiles.SearchWsResponse.QualityProfile;
import org.sonarqube.ws.client.qualityprofile.SearchWsRequest;
-import static com.google.common.collect.Maps.uniqueIndex;
import static java.lang.String.format;
+import static java.util.function.Function.identity;
+import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_SEARCH;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_DEFAULTS;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROFILE_NAME;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROJECT_KEY;
++import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.*;
public class SearchAction implements QProfileWsAction {
action
.createParam(PARAM_DEFAULTS)
.setDescription(format("Return the quality profile marked as default for each language. " +
-- "If provided, then the parameters '%s', '%s' must not be set.",
++ "If provided, then the parameters '%s', '%s' must not be set.",
PARAM_LANGUAGE, PARAM_PROJECT_KEY))
.setDefaultValue(false)
.setBooleanPossibleValues();
@RunWith(MockitoJUnitRunner.class)
public class BackupActionTest {
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
+ private static final String SOME_PROFILE_KEY = "polop-palap-xoo-12345";
- // TODO Replace with proper DbTester + EsTester medium test once DaoV2 is removed
- @Mock
- private QProfileBackuper backuper;
-
- private WsTester tester;
-
- @Before
- public void setUp() {
- DbClient dbClient = new DbClient(db.database(), db.myBatis());
-
- tester = new WsTester(new QProfilesWs(
- mock(RuleActivationActions.class),
- mock(BulkRuleActivationActions.class),
- new BackupAction(backuper, dbClient, new QProfileFactory(dbClient), LanguageTesting.newLanguages("xoo"))));
- }
+ private QProfileBackuper backuper = mock(QProfileBackuper.class);
+ private QProfileFactory profileFactory = mock(QProfileFactory.class);
+ private WsTester tester = new WsTester(new QProfilesWs(
+ mock(RuleActivationActions.class),
+ mock(BulkRuleActivationActions.class),
- mock(ProjectAssociationActions.class),
+ new BackupAction(mock(DbClient.class), backuper, profileFactory, LanguageTesting.newLanguages("xoo"))));
@Test
public void backup_profile() throws Exception {
@Before
public void before() {
- wsTester = new WsTester(new QProfilesWs(mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class), mock(ProjectAssociationActions.class),
- dbTester.truncateTables();
- esTester.truncateIndices();
-
- System2 system = mock(System2.class);
-
- // create pre-defined rules
- RuleDto xooRule1 = RuleTesting.newXooX1().setSeverity("MINOR");
- db.ruleDao().insert(dbSession, xooRule1);
-
- // create pre-defined profiles P1 and P2
- db.qualityProfileDao().insert(dbSession, QProfileTesting.newXooP1(), QProfileTesting.newXooP2());
-
- login = "david";
- UserDto user = new UserDto().setLogin(login).setName("David").setEmail("dav@id.com").setCreatedAt(System.currentTimeMillis()).setUpdatedAt(System.currentTimeMillis());
- db.userDao().insert(dbSession, user);
-
- dbSession.commit();
- dbSession.clearCache();
-
+ wsTester = new WsTester(new QProfilesWs(mock(RuleActivationActions.class), mock(BulkRuleActivationActions.class),
- new ChangelogAction(db, new ActivityIndex(esTester.client()), new QProfileFactory(db), LanguageTesting.newLanguages("xoo"))));
+ new ChangelogAction(changelogLoader, profileFactory, new Languages(), dbTester.getDbClient())));
}
@Test
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
- import org.sonar.db.component.ComponentDao;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
- import org.sonar.db.qualityprofile.QualityProfileDao;
import org.sonar.db.qualityprofile.QualityProfileDto;
- import org.sonar.db.user.AuthorizationDao;
import org.sonar.db.user.GroupRoleDto;
import org.sonar.db.user.RoleDao;
- import org.sonar.db.user.UserDao;
import org.sonar.db.user.UserDto;
-import org.sonar.db.user.UserRoleDto;
+import org.sonar.db.user.UserPermissionDto;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.qualityprofile.QProfileTesting;
import org.sonar.server.tester.UserSessionRule;
--- /dev/null
- assertThat(container.size()).isEqualTo(24 + 2);
+ /*
+ * 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.qualityprofile.ws;
+
+ import org.junit.Test;
+ import org.sonar.core.platform.ComponentContainer;
+
+ import static org.assertj.core.api.Assertions.assertThat;
+
+ public class QProfilesWsModuleTest {
+ @Test
+ public void verify_count_of_added_components() {
+ ComponentContainer container = new ComponentContainer();
+ new QProfilesWsModule().configure(container);
++ assertThat(container.size()).isEqualTo(25 + 2);
+ }
+ }
public void setUp() {
QProfileService profileService = mock(QProfileService.class);
I18n i18n = mock(I18n.class);
+ DbClient dbClient = mock(DbClient.class);
Languages languages = LanguageTesting.newLanguages(xoo1Key, xoo2Key);
+ ProjectAssociationParameters projectAssociationParameters = new ProjectAssociationParameters(languages);
ProfileImporter[] importers = createImporters(languages);
controller = new WsTester(new QProfilesWs(
new RuleActivationActions(profileService),
new BulkRuleActivationActions(profileService, null, i18n, userSessionRule),
- new ProjectAssociationActions(null, null, null, languages, userSessionRule),
+ new AddProjectAction(projectAssociationParameters, null, null, null),
+ new RemoveProjectAction(projectAssociationParameters, null, null, null),
new CreateAction(null, null, null, languages, importers, userSessionRule),
new ImportersAction(importers),
- new RestoreBuiltInAction(null),
+ new RestoreBuiltInAction(null, languages),
new SearchAction(null, languages),
new SetDefaultAction(languages, null, null, userSessionRule),
new ProjectsAction(null, userSessionRule),
private DbSession session;
-
@Before
public void setUp() {
- dbTester.truncateTables();
qualityProfileDao = new QualityProfileDao(dbTester.myBatis(), mock(System2.class));
dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), qualityProfileDao);
session = dbClient.openSession(false);
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.language.LanguageTesting;
import org.sonar.server.qualityprofile.QProfileFactory;
-import org.sonar.server.qualityprofile.QProfileLoader;
import org.sonar.server.qualityprofile.QProfileLookup;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
+import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.MediaTypes;
+import org.sonarqube.ws.QualityProfiles.SearchWsResponse;
+import org.sonarqube.ws.QualityProfiles.SearchWsResponse.QualityProfile;
+import static com.google.common.base.Throwables.propagate;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import static org.sonar.api.utils.DateUtils.formatDateTime;
+import static org.sonar.api.utils.DateUtils.parseDateTime;
import static org.sonar.db.component.ComponentTesting.newProjectDto;
- import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_DEFAULTS;
- import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_PROFILE_NAME;
- import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_PROJECT_KEY;
+import static org.sonar.db.qualityprofile.QualityProfileTesting.newQualityProfileDto;
import static org.sonar.test.JsonAssert.assertJson;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_DEFAULTS;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROFILE_NAME;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROJECT_KEY;
++import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.*;
public class SearchActionTest {
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
+ import org.sonar.db.component.ComponentTesting;
import static com.google.common.collect.ImmutableList.of;
+import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.sonar.db.qualityprofile.QualityProfileDto.createFor;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonar.db.qualityprofile.QualityProfileTesting.newQualityProfileDto;
public class QualityProfileDaoTest {
assertThat(underTest.selectByProjectAndLanguages(dbTester.getSession(), "unknown", singletonList("java"))).isEmpty();
}
- ComponentDto project = componentDb.insertComponent(ComponentTesting.newProjectDto());
+ @Test
+ public void selectByKeys() {
+ qualityProfileDb.insertQualityProfiles(newQualityProfileDto().setKey("qp-key-1"), newQualityProfileDto().setKee("qp-key-2"), newQualityProfileDto().setKee("qp-key-3"));
+
+ assertThat(underTest.selectOrFailByKey(dbSession, "qp-key-1")).isNotNull();
+ assertThat(underTest.selectByKey(dbSession, "qp-key-1")).isNotNull();
+ assertThat(underTest.selectByKey(dbSession, "qp-key-42")).isNull();
+ assertThat(underTest.selectByKeys(dbSession, newArrayList("qp-key-1", "qp-key-3", "qp-key-42")))
+ .hasSize(2)
+ .extracting(QualityProfileDto::getKey).containsOnlyOnce("qp-key-1", "qp-key-3");
+ assertThat(underTest.selectByKeys(dbSession, emptyList())).isEmpty();
+ }
+
+ @Test
+ public void select_selected_projects() throws Exception {
+ ComponentDto project1 = componentDbTester.insertComponent(newProjectDto().setName("Project1 name"));
+ ComponentDto project2 = componentDbTester.insertComponent(newProjectDto().setName("Project2 name"));
+ ComponentDto project3 = componentDbTester.insertComponent(newProjectDto().setName("Project3 name"));
+
+ QualityProfileDto profile1 = newQualityProfileDto();
+ qualityProfileDb.insertQualityProfiles(profile1);
+ qualityProfileDb.associateProjectWithQualityProfile(project1, profile1);
+ qualityProfileDb.associateProjectWithQualityProfile(project2, profile1);
+
+ QualityProfileDto profile2 = newQualityProfileDto();
+ qualityProfileDb.insertQualityProfiles(profile2);
+ qualityProfileDb.associateProjectWithQualityProfile(project3, profile2);
+
+ assertThat(underTest.selectSelectedProjects(profile1.getKey(), null, dbSession))
+ .extracting("projectId", "projectUuid", "projectKey", "projectName", "profileKey")
+ .containsOnly(
+ tuple(project1.getId(), project1.uuid(), project1.key(), project1.name(), profile1.getKey()),
+ tuple(project2.getId(), project2.uuid(), project2.key(), project2.name(), profile1.getKey())
+ );
+
+ assertThat(underTest.selectSelectedProjects(profile1.getKey(), "ect1", dbSession)).hasSize(1);
+ assertThat(underTest.selectSelectedProjects("unknown", null, dbSession)).isEmpty();
+ }
+
+ @Test
+ public void select_deselected_projects() throws Exception {
+ ComponentDto project1 = componentDbTester.insertComponent(newProjectDto().setName("Project1 name"));
+ ComponentDto project2 = componentDbTester.insertComponent(newProjectDto().setName("Project2 name"));
+ ComponentDto project3 = componentDbTester.insertComponent(newProjectDto().setName("Project3 name"));
+
+ QualityProfileDto profile1 = newQualityProfileDto();
+ qualityProfileDb.insertQualityProfiles(profile1);
+ qualityProfileDb.associateProjectWithQualityProfile(project1, profile1);
+
+ QualityProfileDto profile2 = newQualityProfileDto();
+ qualityProfileDb.insertQualityProfiles(profile2);
+ qualityProfileDb.associateProjectWithQualityProfile(project2, profile2);
+
+ assertThat(underTest.selectDeselectedProjects(profile1.getKey(), null, dbSession))
+ .extracting("projectId", "projectUuid", "projectKey", "projectName", "profileKey")
+ .containsOnly(
+ tuple(project2.getId(), project2.uuid(), project2.key(), project2.name(), null),
+ tuple(project3.getId(), project3.uuid(), project3.key(), project3.name(), null)
+ );
+
+ assertThat(underTest.selectDeselectedProjects(profile1.getKey(), "ect2", dbSession)).hasSize(1);
+ assertThat(underTest.selectDeselectedProjects("unknown", null, dbSession)).hasSize(3);
+ }
+
+ @Test
+ public void select_project_associations() throws Exception {
+ ComponentDto project1 = componentDbTester.insertComponent(newProjectDto().setName("Project1 name"));
+ ComponentDto project2 = componentDbTester.insertComponent(newProjectDto().setName("Project2 name"));
+ ComponentDto project3 = componentDbTester.insertComponent(newProjectDto().setName("Project3 name"));
+
+ QualityProfileDto profile1 = newQualityProfileDto();
+ qualityProfileDb.insertQualityProfiles(profile1);
+ qualityProfileDb.associateProjectWithQualityProfile(project1, profile1);
+
+ QualityProfileDto profile2 = newQualityProfileDto();
+ qualityProfileDb.insertQualityProfiles(profile2);
+ qualityProfileDb.associateProjectWithQualityProfile(project2, profile2);
+
+ assertThat(underTest.selectProjectAssociations(profile1.getKey(), null, dbSession))
+ .extracting("projectId", "projectUuid", "projectKey", "projectName", "profileKey")
+ .containsOnly(
+ tuple(project1.getId(), project1.uuid(), project1.key(), project1.name(), profile1.getKey()),
+ tuple(project2.getId(), project2.uuid(), project2.key(), project2.name(), null),
+ tuple(project3.getId(), project3.uuid(), project3.key(), project3.name(), null)
+ );
+
+ assertThat(underTest.selectProjectAssociations(profile1.getKey(), "ect2", dbSession)).hasSize(1);
+ assertThat(underTest.selectProjectAssociations("unknown", null, dbSession)).hasSize(3);
+ }
+
+ @Test
+ public void update_project_profile_association() {
- qualityProfileDbTester.associateProjectWithQualityProfile(project, profile1Language1, profile2Language2);
++ ComponentDto project = componentDbTester.insertComponent(ComponentTesting.newProjectDto());
+ QualityProfileDto profile1Language1 = insertQualityProfileDto("profile1", "Profile 1", "xoo");
+ QualityProfileDto profile2Language2 = insertQualityProfileDto("profile2", "Profile 2", "xoo2");
+ QualityProfileDto profile3Language1 = insertQualityProfileDto("profile3", "Profile 3", "xoo");
++ qualityProfileDb.associateProjectWithQualityProfile(project, profile1Language1, profile2Language2);
+
+ underTest.updateProjectProfileAssociation(project.uuid(), profile3Language1.getKey(), profile1Language1.getKey(), dbSession);
+
+ assertThat(underTest.selectByProjectAndLanguage(dbSession, project.getKey(), "xoo").getKey()).isEqualTo(profile3Language1.getKey());
+ assertThat(underTest.selectByProjectAndLanguage(dbSession, project.getKey(), "xoo2").getKey()).isEqualTo(profile2Language2.getKey());
+ }
+
+ private QualityProfileDto insertQualityProfileDto(String key, String name, String language) {
+ QualityProfileDto dto = QualityProfileDto.createFor(key).setName(name).setLanguage(language);
+ underTest.insert(dbSession, dto);
+ return dto;
+ }
++
}
public void insertQualityProfiles(QualityProfileDto qualityProfile, QualityProfileDto... qualityProfiles) {
dbClient.qualityProfileDao().insert(dbSession, qualityProfile, qualityProfiles);
+ dbSession.commit();
}
+ public QualityProfileDto insertQualityProfile(QualityProfileDto qualityProfile) {
+ dbClient.qualityProfileDao().insert(dbSession, qualityProfile);
+ return qualityProfile;
+ }
+
public void insertProjectWithQualityProfileAssociations(ComponentDto project, QualityProfileDto... qualityProfiles) {
dbClient.componentDao().insert(dbSession, project);
for (QualityProfileDto qualityProfile : qualityProfiles) {