import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
import org.apache.commons.lang.StringUtils;
+import org.apache.ibatis.session.SqlSession;
import org.elasticsearch.common.collect.Lists;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.core.component.ComponentQuery;
import org.sonar.core.component.db.ComponentDao;
import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.persistence.MyBatis;
import org.sonar.core.properties.PropertiesDao;
import org.sonar.core.properties.PropertyDto;
import org.sonar.core.qualitygate.db.QualityGateConditionDao;
private final ComponentDao componentDao;
- public QualityGates(QualityGateDao dao, QualityGateConditionDao conditionDao, MetricFinder metricFinder, PropertiesDao propertiesDao, ComponentDao componentDao) {
+ private final MyBatis myBatis;
+
+ public QualityGates(QualityGateDao dao, QualityGateConditionDao conditionDao, MetricFinder metricFinder, PropertiesDao propertiesDao, ComponentDao componentDao,
+ MyBatis myBatis) {
this.dao = dao;
this.conditionDao = conditionDao;
this.metricFinder = metricFinder;
this.propertiesDao = propertiesDao;
this.componentDao = componentDao;
+ this.myBatis = myBatis;
}
public QualityGateDto create(String name) {
return toRename;
}
+ public QualityGateDto copy(long sourceId, String destinationName) {
+ checkPermission(UserSession.get());
+ getNonNullQgate(sourceId);
+ validateQualityGate(null, destinationName);
+ QualityGateDto destinationGate = new QualityGateDto().setName(destinationName);
+ SqlSession session = myBatis.openSession();
+ try {
+ dao.insert(destinationGate, session);
+ for(QualityGateConditionDto sourceCondition: conditionDao.selectForQualityGate(sourceId, session)) {
+ conditionDao.insert(new QualityGateConditionDto().setQualityGateId(destinationGate.getId())
+ .setMetricId(sourceCondition.getMetricId()).setOperator(sourceCondition.getOperator())
+ .setWarningThreshold(sourceCondition.getWarningThreshold()).setErrorThreshold(sourceCondition.getErrorThreshold()).setPeriod(sourceCondition.getPeriod()),
+ session);
+ }
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ return destinationGate;
+ }
+
+
public Collection<QualityGateDto> list() {
return dao.selectAll();
}
createCondition(request, response);
}
});
- createCondition.newParam(PARAM_GATE_ID).setDescription("The numerical ID of the quality gate.");
+ createCondition.newParam(PARAM_GATE_ID).setDescription("The numerical ID of the quality gate for which the condition will be created.");
addConditionParams(createCondition);
NewAction updateCondition = controller.newAction("update_condition")
}
}).newParam(PARAM_NAME).setDescription("The name of the quality gate to create.");
+ NewAction copy = controller.newAction("copy")
+ .setDescription("Copy a quality gate, given its ID and the name for the new quality gate.")
+ .setPost(true)
+ .setHandler(new RequestHandler() {
+ @Override
+ public void handle(Request request, Response response) {
+ copy(request, response);
+ }
+ });
+ copy.newParam(PARAM_ID).setDescription("The ID of the source quality gate.");
+ copy.newParam(PARAM_NAME).setDescription("The name of the destination quality gate.");
+
controller.newAction("set_as_default")
.setDescription("Select the default quality gate.")
.setPost(true)
search(request, response);
}
});
- search.newParam(PARAM_GATE_ID).setDescription("The numerical ID of the quality gate.");
+ search.newParam(PARAM_GATE_ID).setDescription("The numerical ID of the quality gate considered for association.");
search.newParam(PARAM_SELECTED).setDescription("Optionally, to search for projects associated (selected=selected) or not (selected=deselected).");
search.newParam(PARAM_QUERY).setDescription("Optionally, part of the name of the projects to search for.");
search.newParam(PARAM_PAGE);
deselect.newParam(PARAM_PROJECT_ID);
}
+ protected void copy(Request request, Response response) {
+ QualityGateDto newQualityGate = qualityGates.copy(parseId(request, PARAM_ID), request.requiredParam(PARAM_NAME));
+ JsonWriter writer = response.newJsonWriter();
+ writeQualityGate(newQualityGate, writer).close();
+ }
+
protected void listMetrics(Request request, Response response) {
JsonWriter writer = response.newJsonWriter().beginObject().name("metrics").beginArray();
for (Metric metric: qualityGates.gateMetrics()) {
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
+import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.Metric.ValueType;
import org.sonar.core.component.ComponentQuery;
import org.sonar.core.component.db.ComponentDao;
import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.persistence.MyBatis;
import org.sonar.core.properties.PropertiesDao;
import org.sonar.core.properties.PropertyDto;
import org.sonar.core.qualitygate.db.QualityGateConditionDao;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@Mock
private ComponentDao componentDao;
+ @Mock
+ private MyBatis myBatis;
+
private QualityGates qGates;
UserSession authorizedUserSession = MockUserSession.create().setLogin("gaudol").setName("Olivier").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
@Before
public void initialize() {
- qGates = new QualityGates(dao, conditionDao, metricFinder, propertiesDao, componentDao);
+ qGates = new QualityGates(dao, conditionDao, metricFinder, propertiesDao, componentDao, myBatis);
UserSessionTestUtils.setUserSession(authorizedUserSession);
}
verify(propertiesDao).deleteProjectProperty("sonar.qualitygate", projectId);
}
+ @Test
+ public void should_copy_qgate() throws Exception {
+ String name = "Atlantis";
+ long sourceId = 42L;
+ final long destId = 43L;
+ long metric1Id = 1L;
+ long metric2Id = 2L;
+ QualityGateConditionDto cond1 = new QualityGateConditionDto().setMetricId(metric1Id);
+ QualityGateConditionDto cond2 = new QualityGateConditionDto().setMetricId(metric2Id);
+ Collection<QualityGateConditionDto> conditions = ImmutableList.of(cond1, cond2);
+
+ when(dao.selectById(sourceId)).thenReturn(new QualityGateDto().setId(sourceId).setName("SG-1"));
+ SqlSession session = mock(SqlSession.class);
+ when(myBatis.openSession()).thenReturn(session);
+ Mockito.doAnswer(new Answer<Object>() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ ((QualityGateDto) invocation.getArguments()[0]).setId(destId);
+ return null;
+ }
+ }).when(dao).insert(any(QualityGateDto.class), eq(session));
+ when(conditionDao.selectForQualityGate(anyLong(), eq(session))).thenReturn(conditions);
+ QualityGateDto atlantis = qGates.copy(sourceId, name);
+ assertThat(atlantis.getName()).isEqualTo(name);
+ verify(dao).selectByName(name);
+ verify(dao).insert(atlantis, session);
+ verify(conditionDao).selectForQualityGate(anyLong(), eq(session));
+ verify(conditionDao, times(conditions.size())).insert(any(QualityGateConditionDto.class), eq(session));
+ }
+
}
assertThat(controller).isNotNull();
assertThat(controller.path()).isEqualTo("api/qualitygates");
assertThat(controller.description()).isNotEmpty();
- assertThat(controller.actions()).hasSize(14);
+ assertThat(controller.actions()).hasSize(15);
WebService.Action list = controller.action("list");
assertThat(list).isNotNull();
assertThat(create.param("name")).isNotNull();
assertThat(create.isPrivate()).isFalse();
+ WebService.Action copy = controller.action("copy");
+ assertThat(copy).isNotNull();
+ assertThat(copy.handler()).isNotNull();
+ assertThat(copy.since()).isEqualTo("4.3");
+ assertThat(copy.isPost()).isTrue();
+ assertThat(copy.param("id")).isNotNull();
+ assertThat(copy.param("name")).isNotNull();
+ assertThat(copy.isPrivate()).isFalse();
+
WebService.Action destroy = controller.action("destroy");
assertThat(destroy).isNotNull();
assertThat(destroy.handler()).isNotNull();