Przeglądaj źródła

SONAR-8117 Extract creation of quality gate into QualityGateUpdater

tags/6.2-RC1
Julien Lancelot 7 lat temu
rodzic
commit
7b348e0ba5
19 zmienionych plików z 375 dodań i 82 usunięć
  1. 1
    0
      server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateModule.java
  2. 65
    0
      server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateUpdater.java
  3. 2
    9
      server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java
  4. 4
    2
      server/sonar-server/src/main/java/org/sonar/server/qualitygate/RegisterQualityGates.java
  5. 21
    11
      server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java
  6. 2
    1
      server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java
  7. 2
    1
      server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java
  8. 3
    1
      server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java
  9. 2
    1
      server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java
  10. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java
  11. 75
    0
      server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateUpdaterTest.java
  12. 0
    19
      server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java
  13. 18
    10
      server/sonar-server/src/test/java/org/sonar/server/qualitygate/RegisterQualityGatesTest.java
  14. 113
    0
      server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateActionTest.java
  15. 1
    21
      server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java
  16. 15
    3
      sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesService.java
  17. 8
    0
      sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesWsParameters.java
  18. 8
    0
      sonar-ws/src/main/protobuf/ws-qualitygates.proto
  19. 34
    2
      sonar-ws/src/test/java/org/sonarqube/ws/client/qualitygate/QualityGatesServiceTest.java

+ 1
- 0
server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateModule.java Wyświetl plik

@@ -45,6 +45,7 @@ public class QualityGateModule extends Module {
protected void configureModule() {
add(
QualityGates.class,
QualityGateUpdater.class,
QgateProjectFinder.class,
// WS
QualityGatesWs.class,

+ 65
- 0
server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateUpdater.java Wyświetl plik

@@ -0,0 +1,65 @@
/*
* 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.qualitygate;

import javax.annotation.Nullable;
import org.sonar.db.DbClient;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.Errors;
import org.sonar.server.exceptions.Message;
import org.sonar.server.util.Validation;

import static com.google.common.base.Strings.isNullOrEmpty;

public class QualityGateUpdater {

private final DbClient dbClient;

public QualityGateUpdater(DbClient dbClient) {
this.dbClient = dbClient;
}

public QualityGateDto create(String name) {
validateQualityGate(null, name);
QualityGateDto newQualityGate = new QualityGateDto().setName(name);
dbClient.qualityGateDao().insert(newQualityGate);
return newQualityGate;
}

private void validateQualityGate(@Nullable Long qGateId, @Nullable String name) {
Errors errors = new Errors();
if (isNullOrEmpty(name)) {
errors.add(Message.of(Validation.CANT_BE_EMPTY_MESSAGE, "Name"));
} else {
checkQualityGateDoesNotAlreadyExist(qGateId, name, errors);
}
if (!errors.isEmpty()) {
throw new BadRequestException(errors);
}
}

private void checkQualityGateDoesNotAlreadyExist(@Nullable Long qGateId, String name, Errors errors) {
QualityGateDto existingQgate = dbClient.qualityGateDao().selectByName(name);
boolean isModifyingCurrentQgate = qGateId != null && existingQgate != null && existingQgate.getId().equals(qGateId);
errors.check(isModifyingCurrentQgate || existingQgate == null, Validation.IS_ALREADY_USED_MESSAGE, "Name");
}
}

+ 2
- 9
server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java Wyświetl plik

@@ -57,7 +57,8 @@ import org.sonar.server.util.Validation;
import static java.lang.String.format;

/**
* @since 4.3
* Methods from this class should be moved to {@link QualityGateUpdater} and to new classes QualityGateFinder / QualityGateConditionsUpdater / etc.
* in order to have classes with clearer responsibilities and more easily testable (without having to use too much mocks)
*/
public class QualityGates {

@@ -81,14 +82,6 @@ public class QualityGates {
this.userSession = userSession;
}

public QualityGateDto create(String name) {
checkPermission();
validateQualityGate(null, name);
QualityGateDto newQualityGate = new QualityGateDto().setName(name);
dao.insert(newQualityGate);
return newQualityGate;
}

public QualityGateDto get(Long qGateId) {
return getNonNullQgate(qGateId);
}

+ 4
- 2
server/sonar-server/src/main/java/org/sonar/server/qualitygate/RegisterQualityGates.java Wyświetl plik

@@ -41,10 +41,12 @@ public class RegisterQualityGates implements Startable {
private static final String NEW_COVERAGE_ERROR_THRESHOLD = "80";

private final QualityGates qualityGates;
private final QualityGateUpdater qualityGateUpdater;
private final LoadedTemplateDao loadedTemplateDao;

public RegisterQualityGates(QualityGates qualityGates, LoadedTemplateDao loadedTemplateDao) {
public RegisterQualityGates(QualityGates qualityGates, QualityGateUpdater qualityGateUpdater, LoadedTemplateDao loadedTemplateDao) {
this.qualityGates = qualityGates;
this.qualityGateUpdater = qualityGateUpdater;
this.loadedTemplateDao = loadedTemplateDao;
}

@@ -66,7 +68,7 @@ public class RegisterQualityGates implements Startable {
}

private void createBuiltinQualityGate() {
QualityGateDto builtin = qualityGates.create(BUILTIN_QUALITY_GATE);
QualityGateDto builtin = qualityGateUpdater.create(BUILTIN_QUALITY_GATE);
qualityGates.createCondition(builtin.getId(), NEW_VULNERABILITIES_KEY, OPERATOR_GREATER_THAN, null, NEW_VULNERABILITIES_ERROR_THRESHOLD, LEAK_PERIOD);
qualityGates.createCondition(builtin.getId(), NEW_BUGS_KEY, OPERATOR_GREATER_THAN, null, NEW_BUGS_ERROR_THRESHOLD, LEAK_PERIOD);
qualityGates.createCondition(builtin.getId(), NEW_SQALE_DEBT_RATIO_KEY, OPERATOR_GREATER_THAN, null, DEBT_ON_NEW_CODE_ERROR_THRESHOLD, LEAK_PERIOD);

+ 21
- 11
server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/CreateAction.java Wyświetl plik

@@ -22,28 +22,35 @@ package org.sonar.server.qualitygate.ws;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.qualitygate.QualityGates;
import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;
import org.sonar.server.qualitygate.QualityGateUpdater;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.WsQualityGates.CreateWsResponse;

import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.ACTION_CREATE;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_NAME;

public class CreateAction implements QualityGatesWsAction {

private final QualityGates qualityGates;
private final UserSession userSession;
private final QualityGateUpdater qualityGateUpdater;

public CreateAction(QualityGates qualityGates) {
this.qualityGates = qualityGates;
public CreateAction(UserSession userSession, QualityGateUpdater qualityGateUpdater) {
this.userSession = userSession;
this.qualityGateUpdater = qualityGateUpdater;
}

@Override
public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction("create")
WebService.NewAction action = controller.createAction(ACTION_CREATE)
.setDescription("Create a Quality Gate. Require Administer Quality Gates permission")
.setSince("4.3")
.setPost(true)
.setHandler(this);

action.createParam(QualityGatesWsParameters.PARAM_NAME)
action.createParam(PARAM_NAME)
.setDescription("The name of the quality gate to create")
.setRequired(true)
.setExampleValue("My Quality Gate");
@@ -51,9 +58,12 @@ public class CreateAction implements QualityGatesWsAction {

@Override
public void handle(Request request, Response response) {
QualityGateDto newQualityGate = qualityGates.create(request.mandatoryParam(QualityGatesWsParameters.PARAM_NAME));
JsonWriter writer = response.newJsonWriter();
QualityGatesWs.writeQualityGate(newQualityGate, writer).close();
userSession.checkPermission(GlobalPermissions.QUALITY_GATE_ADMIN);
QualityGateDto newQualityGate = qualityGateUpdater.create(request.mandatoryParam(PARAM_NAME));
CreateWsResponse.Builder createWsResponse = CreateWsResponse.newBuilder()
.setId(newQualityGate.getId())
.setName(newQualityGate.getName());
writeProtobuf(createWsResponse.build(), request, response);
}

}

+ 2
- 1
server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java Wyświetl plik

@@ -39,6 +39,7 @@ import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.ACTION_GET_BY_PROJECT;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY;

@@ -57,7 +58,7 @@ public class GetByProjectAction implements QualityGatesWsAction {

@Override
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction("get_by_project")
WebService.NewAction action = context.createAction(ACTION_GET_BY_PROJECT)
.setInternal(true)
.setSince("6.1")
.setDescription("Get the quality gate of a project.<br> " +

+ 2
- 1
server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java Wyświetl plik

@@ -52,6 +52,7 @@ import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesEx
import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.ACTION_PROJECT_STATUS;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_ANALYSIS_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY;
@@ -80,7 +81,7 @@ public class ProjectStatusAction implements QualityGatesWsAction {

@Override
public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction("project_status")
WebService.NewAction action = controller.createAction(ACTION_PROJECT_STATUS)
.setDescription(String.format("Get the quality gate status of a project or a Compute Engine task.<br />" +
MSG_ONE_PARAMETER_ONLY + "<br />" +
"The different statuses returned are: %s. The %s status is returned when there is no quality gate associated with the analysis.<br />" +

+ 3
- 1
server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QualityGatesWs.java Wyświetl plik

@@ -27,6 +27,8 @@ import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters;

import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.CONTROLLER_QUALITY_GATES;

public class QualityGatesWs implements WebService {
private final QualityGatesWsAction[] actions;

@@ -36,7 +38,7 @@ public class QualityGatesWs implements WebService {

@Override
public void define(Context context) {
NewController controller = context.createController("api/qualitygates")
NewController controller = context.createController(CONTROLLER_QUALITY_GATES)
.setSince("4.3")
.setDescription("Manage quality gates, including conditions and project association.");


+ 2
- 1
server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/SelectAction.java Wyświetl plik

@@ -40,6 +40,7 @@ import static org.sonar.server.qualitygate.QualityGates.SONAR_QUALITYGATE_PROPER
import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.WsUtils.checkFound;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.ACTION_SELECT;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_GATE_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY;
@@ -57,7 +58,7 @@ public class SelectAction implements QualityGatesWsAction {

@Override
public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction("select")
WebService.NewAction action = controller.createAction(ACTION_SELECT)
.setDescription("Associate a project to a quality gate.<br>" +
"The '%s' or '%s' must be provided.<br>" +
"Project id as a numeric value is deprecated since 6.1. Please use the id similar to '%s'.<br>" +

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateModuleTest.java Wyświetl plik

@@ -30,6 +30,6 @@ public class QualityGateModuleTest {
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new QualityGateModule().configure(container);
assertThat(container.size()).isEqualTo(20 + 2);
assertThat(container.size()).isEqualTo(21 + 2);
}
}

+ 75
- 0
server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGateUpdaterTest.java Wyświetl plik

@@ -0,0 +1,75 @@
/*
* 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.qualitygate;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.exceptions.BadRequestException;

import static java.lang.String.format;
import static org.assertj.core.api.Java6Assertions.assertThat;

public class QualityGateUpdaterTest {

static final String QGATE_NAME = "Default";

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Rule
public DbTester db = DbTester.create(System2.INSTANCE);

DbClient dbClient = db.getDbClient();

QualityGateUpdater underTest = new QualityGateUpdater(dbClient);

@Test
public void create_quality_gate() throws Exception {
QualityGateDto result = underTest.create(QGATE_NAME);

assertThat(result).isNotNull();
assertThat(result.getName()).isEqualTo(QGATE_NAME);
assertThat(result.getCreatedAt()).isNotNull();
QualityGateDto reloaded = dbClient.qualityGateDao().selectByName(QGATE_NAME);
assertThat(reloaded).isNotNull();
}

@Test
public void fail_to_create_when_name_is_empty() throws Exception {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage(format("errors.cant_be_empty", "Name"));
underTest.create("");
}

@Test
public void fail_to_create_when_name_already_exists() throws Exception {
dbClient.qualityGateDao().insert(new QualityGateDto().setName(QGATE_NAME));

expectedException.expect(BadRequestException.class);
expectedException.expectMessage("errors.is_already_used");
underTest.create(QGATE_NAME);
}
}

+ 0
- 19
server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java Wyświetl plik

@@ -51,7 +51,6 @@ import org.sonar.db.qualitygate.QualityGateConditionDto;
import org.sonar.db.qualitygate.QualityGateDao;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.tester.AnonymousMockUserSession;
import org.sonar.server.tester.MockUserSession;
@@ -122,24 +121,6 @@ public class QualityGatesTest {
assertThat(underTest.list()).isEqualTo(allQgates);
}

@Test(expected = ForbiddenException.class)
public void should_fail_create_on_missing_permission() {
userSessionRule.set(unauthorizedUserSession);
underTest.create("polop");
}

@Test(expected = BadRequestException.class)
public void should_fail_create_on_empty_name() {
underTest.create("");
}

@Test(expected = BadRequestException.class)
public void should_fail_create_on_duplicate_name() {
String name = "SG-1";
when(dao.selectByName(name)).thenReturn(new QualityGateDto().setName(name).setId(QUALITY_GATE_ID));
underTest.create(name);
}

@Test
public void should_get_qgate_by_id() {
long id = QUALITY_GATE_ID;

+ 18
- 10
server/sonar-server/src/test/java/org/sonar/server/qualitygate/RegisterQualityGatesTest.java Wyświetl plik

@@ -19,13 +19,18 @@
*/
package org.sonar.server.qualitygate;

import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.loadedtemplate.LoadedTemplateDao;
import org.sonar.db.loadedtemplate.LoadedTemplateDto;
import org.sonar.db.qualitygate.QualityGateDto;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -41,28 +46,31 @@ import static org.sonar.db.qualitygate.QualityGateConditionDto.OPERATOR_LESS_THA

public class RegisterQualityGatesTest {

static long QGATE_ID = 42L;
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);

DbClient dbClient = db.getDbClient();

QualityGates qualityGates = mock(QualityGates.class);
LoadedTemplateDao templateDao = mock(LoadedTemplateDao.class);
RegisterQualityGates task = new RegisterQualityGates(qualityGates, templateDao);
RegisterQualityGates task = new RegisterQualityGates(qualityGates, new QualityGateUpdater(dbClient), templateDao);

@Test
public void register_default_gate() {
String templateType = "QUALITY_GATE";
String templateName = "SonarQube way";
when(templateDao.countByTypeAndKey(templateType, templateName)).thenReturn(0);
when(qualityGates.create(templateName)).thenReturn(new QualityGateDto().setId(QGATE_ID));

task.start();

verify(templateDao).countByTypeAndKey(templateType, templateName);
verify(qualityGates).create(templateName);
verify(qualityGates).createCondition(eq(QGATE_ID), eq(NEW_BUGS_KEY), eq(OPERATOR_GREATER_THAN), eq((String) null), eq("0"), eq(1));
verify(qualityGates).createCondition(eq(QGATE_ID), eq(NEW_VULNERABILITIES_KEY), eq(OPERATOR_GREATER_THAN), eq((String) null), eq("0"), eq(1));
verify(qualityGates).createCondition(eq(QGATE_ID), eq(NEW_SQALE_DEBT_RATIO_KEY), eq(OPERATOR_GREATER_THAN), eq((String) null), eq("5"), eq(1));
verify(qualityGates).createCondition(eq(QGATE_ID), eq(NEW_COVERAGE_KEY), eq(OPERATOR_LESS_THAN), eq((String) null), eq("80"), eq(1));
verify(qualityGates).setDefault(eq(QGATE_ID));
verify(qualityGates).createCondition(anyInt(), eq(NEW_BUGS_KEY), eq(OPERATOR_GREATER_THAN), eq((String) null), eq("0"), eq(1));
verify(qualityGates).createCondition(anyInt(), eq(NEW_VULNERABILITIES_KEY), eq(OPERATOR_GREATER_THAN), eq((String) null), eq("0"), eq(1));
verify(qualityGates).createCondition(anyInt(), eq(NEW_SQALE_DEBT_RATIO_KEY), eq(OPERATOR_GREATER_THAN), eq((String) null), eq("5"), eq(1));
verify(qualityGates).createCondition(anyInt(), eq(NEW_COVERAGE_KEY), eq(OPERATOR_LESS_THAN), eq((String) null), eq("80"), eq(1));
verify(qualityGates).setDefault(anyLong());

assertThat(dbClient.qualityGateDao().selectByName(templateName)).isNotNull();

ArgumentCaptor<LoadedTemplateDto> templateArg = ArgumentCaptor.forClass(LoadedTemplateDto.class);
verify(templateDao).insert(templateArg.capture());

+ 113
- 0
server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/CreateActionTest.java Wyświetl plik

@@ -0,0 +1,113 @@
/*
* 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.qualitygate.ws;

import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.server.ws.WebService;
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.qualitygate.QualityGateDto;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.qualitygate.QualityGateUpdater;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.MediaTypes;
import org.sonarqube.ws.WsQualityGates.CreateWsResponse;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;

public class CreateActionTest {

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Rule
public UserSessionRule userSession = UserSessionRule.standalone();

@Rule
public DbTester db = DbTester.create(System2.INSTANCE);

DbClient dbClient = db.getDbClient();
DbSession dbSession = db.getSession();

CreateAction underTest = new CreateAction(userSession, new QualityGateUpdater(dbClient));

WsActionTester ws = new WsActionTester(underTest);

@Test
public void create_quality_gate() throws Exception {
setUserAsQualityGateAdmin();

CreateWsResponse response = executeRequest("Default");

assertThat(response.getName()).isEqualTo("Default");
assertThat(response.getId()).isNotNull();
dbSession.commit();
QualityGateDto qualityGateDto = dbClient.qualityGateDao().selectByName("Default");
assertThat(qualityGateDto).isNotNull();
}

@Test
public void fail_when_not_quality_gate_admin() throws Exception {
setUserAsNotQualityGateAdmin();

expectedException.expect(ForbiddenException.class);
executeRequest("Default");
}

@Test
public void test_ws_definition() {
WebService.Action action = ws.getDef();
assertThat(action).isNotNull();
assertThat(action.isInternal()).isFalse();
assertThat(action.isPost()).isTrue();
assertThat(action.responseExampleAsString()).isNull();
assertThat(action.params()).hasSize(1);
}

private CreateWsResponse executeRequest(String name) {
TestRequest request = ws.newRequest()
.setMediaType(MediaTypes.PROTOBUF)
.setParam("name", name);
try {
return CreateWsResponse.parseFrom(request.execute().getInputStream());
} catch (IOException e) {
throw new IllegalStateException(e);
}
}

private void setUserAsQualityGateAdmin() {
userSession.login("project-admin").setGlobalPermissions(QUALITY_GATE_ADMIN);
}

private void setUserAsNotQualityGateAdmin() {
userSession.login("not-admin").setGlobalPermissions(SCAN_EXECUTION);
}

}

+ 1
- 21
server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java Wyświetl plik

@@ -70,7 +70,7 @@ public class QualityGatesWsTest {

tester = new WsTester(new QualityGatesWs(
new ListAction(qGates), new ShowAction(qGates), new SearchAction(projectFinder),
new CreateAction(qGates), new CopyAction(qGates), new DestroyAction(qGates), new RenameAction(qGates),
new CreateAction(null, null), new CopyAction(qGates), new DestroyAction(qGates), new RenameAction(qGates),
new SetAsDefaultAction(qGates), new UnsetDefaultAction(qGates),
new CreateConditionAction(qGates), new UpdateConditionAction(qGates), new DeleteConditionAction(qGates),
selectAction, new DeselectAction(qGates, mock(DbClient.class), mock(ComponentFinder.class)), new AppAction(null, null)));
@@ -186,14 +186,6 @@ public class QualityGatesWsTest {
assertThat(appInit.isInternal()).isTrue();
}

@Test
public void create_nominal() throws Exception {
String name = "New QG";
when(qGates.create(name)).thenReturn(new QualityGateDto().setId(42L).setName(name));
tester.newPostRequest("api/qualitygates", "create").setParam("name", name).execute()
.assertJson("{\"id\":42,\"name\":\"New QG\"}");
}

@Test
public void copy_nominal() throws Exception {
String name = "Copied QG";
@@ -202,18 +194,6 @@ public class QualityGatesWsTest {
.assertJson("{\"id\":42,\"name\":\"Copied QG\"}");
}

@Test(expected = IllegalArgumentException.class)
public void create_with_missing_name() throws Exception {
tester.newPostRequest("api/qualitygates", "create").execute();
}

@Test(expected = BadRequestException.class)
public void create_with_duplicate_name() throws Exception {
String name = "New QG";
when(qGates.create(name)).thenThrow(new BadRequestException("Name is already used"));
tester.newPostRequest("api/qualitygates", "create").setParam("name", name).execute();
}

@Test
public void rename_nominal() throws Exception {
Long id = 42L;

+ 15
- 3
sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesService.java Wyświetl plik

@@ -19,25 +19,31 @@
*/
package org.sonarqube.ws.client.qualitygate;

import org.sonarqube.ws.WsQualityGates.CreateWsResponse;
import org.sonarqube.ws.WsQualityGates.ProjectStatusWsResponse;
import org.sonarqube.ws.client.BaseService;
import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.WsConnector;

import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.ACTION_CREATE;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.ACTION_PROJECT_STATUS;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.ACTION_SELECT;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.CONTROLLER_QUALITY_GATES;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_ANALYSIS_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_GATE_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_NAME;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY;

public class QualityGatesService extends BaseService {

public QualityGatesService(WsConnector wsConnector) {
super(wsConnector, "api/qualitygates");
super(wsConnector, CONTROLLER_QUALITY_GATES);
}

public ProjectStatusWsResponse projectStatus(ProjectStatusWsRequest request) {
return call(new GetRequest(path("project_status"))
return call(new GetRequest(path(ACTION_PROJECT_STATUS))
.setParam(PARAM_ANALYSIS_ID, request.getAnalysisId())
.setParam(PARAM_PROJECT_ID, request.getProjectId())
.setParam(PARAM_PROJECT_KEY, request.getProjectKey()),
@@ -45,9 +51,15 @@ public class QualityGatesService extends BaseService {
}

public void associateProject(SelectWsRequest request) {
call(new PostRequest(path("select"))
call(new PostRequest(path(ACTION_SELECT))
.setParam(PARAM_GATE_ID, request.getGateId())
.setParam(PARAM_PROJECT_ID, request.getProjectId())
.setParam(PARAM_PROJECT_KEY, request.getProjectKey()));
}

public CreateWsResponse create(String name) {
return call(new PostRequest(path(ACTION_CREATE))
.setParam(PARAM_NAME, name),
CreateWsResponse.parser());
}
}

+ 8
- 0
sonar-ws/src/main/java/org/sonarqube/ws/client/qualitygate/QualityGatesWsParameters.java Wyświetl plik

@@ -21,6 +21,14 @@
package org.sonarqube.ws.client.qualitygate;

public class QualityGatesWsParameters {

public static final String CONTROLLER_QUALITY_GATES = "api/qualitygates";

public static final String ACTION_PROJECT_STATUS = "project_status";
public static final String ACTION_GET_BY_PROJECT = "get_by_project";
public static final String ACTION_SELECT = "select";
public static final String ACTION_CREATE = "create";

public static final String PARAM_ANALYSIS_ID = "analysisId";
public static final String PARAM_PROJECT_ID = "projectId";
public static final String PARAM_PROJECT_KEY = "projectKey";

+ 8
- 0
sonar-ws/src/main/protobuf/ws-qualitygates.proto Wyświetl plik

@@ -91,3 +91,11 @@ message AppWsResponse {
}
}

// POST api/qualitygates/create
message CreateWsResponse {
optional int64 id = 1;
optional string name = 2;
}




+ 34
- 2
sonar-ws/src/test/java/org/sonarqube/ws/client/qualitygate/QualityGatesServiceTest.java Wyświetl plik

@@ -22,15 +22,20 @@ package org.sonarqube.ws.client.qualitygate;

import org.junit.Rule;
import org.junit.Test;
import org.sonarqube.ws.WsQualityGates.CreateWsResponse;
import org.sonarqube.ws.WsQualityGates.ProjectStatusWsResponse;
import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.ServiceTester;
import org.sonarqube.ws.client.WsConnector;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_ANALYSIS_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_GATE_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_NAME;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY;
import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_GATE_ID;

public class QualityGatesServiceTest {
private static final String PROJECT_ID_VALUE = "195";
@@ -43,7 +48,7 @@ public class QualityGatesServiceTest {
private QualityGatesService underTest = serviceTester.getInstanceUnderTest();

@Test
public void associate_project_does_POST_request() {
public void associate_project() {
underTest.associateProject(new SelectWsRequest()
.setGateId(GATE_ID_VALUE)
.setProjectId(PROJECT_ID_VALUE)
@@ -60,4 +65,31 @@ public class QualityGatesServiceTest {
.hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
.andNoOtherParam();
}

@Test
public void project_status() {
underTest.projectStatus(new ProjectStatusWsRequest()
.setAnalysisId("analysisId")
.setProjectId("projectId")
.setProjectKey("projectKey"));
GetRequest getRequest = serviceTester.getGetRequest();

assertThat(serviceTester.getGetParser()).isSameAs(ProjectStatusWsResponse.parser());
serviceTester.assertThat(getRequest)
.hasParam(PARAM_ANALYSIS_ID, "analysisId")
.hasParam(PARAM_PROJECT_ID, "projectId")
.hasParam(PARAM_PROJECT_KEY, "projectKey")
.andNoOtherParam();
}

@Test
public void create() {
underTest.create("Default");
PostRequest request = serviceTester.getPostRequest();

assertThat(serviceTester.getPostParser()).isSameAs(CreateWsResponse.parser());
serviceTester.assertThat(request)
.hasParam(PARAM_NAME, "Default")
.andNoOtherParam();
}
}

Ładowanie…
Anuluj
Zapisz