diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2016-09-19 18:07:47 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2016-09-22 14:10:30 +0200 |
commit | 1d8455866b14fc692bfebe2de64e4437438a5ce8 (patch) | |
tree | 7622a2d48dbdee11b2ac5924f56917a1740e041a | |
parent | fe748d13bd9ecd4b24e1a4c088a51ee362b6a61f (diff) | |
download | sonarqube-1d8455866b14fc692bfebe2de64e4437438a5ce8.tar.gz sonarqube-1d8455866b14fc692bfebe2de64e4437438a5ce8.zip |
SONAR-8116 Return rating metrics in api/qualitygates/app
8 files changed, 273 insertions, 222 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java index a82529336e8..70b462cd45e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java @@ -51,7 +51,6 @@ import org.sonar.server.exceptions.Errors; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.Message; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.exceptions.ServerException; import org.sonar.server.user.UserSession; import org.sonar.server.util.Validation; @@ -242,23 +241,6 @@ public class QualityGates { } } - public Collection<Metric> gateMetrics() { - return metricFinder.findAll().stream() - .filter(QualityGates::isAvailableForInit) - .collect(Collectors.toList()); - } - - public boolean currentUserHasWritePermission() { - boolean hasWritePermission = false; - try { - checkPermission(); - hasWritePermission = true; - } catch (ServerException unallowed) { - // Ignored - } - return hasWritePermission; - } - private Collection<QualityGateConditionDto> getConditions(long qGateId, @Nullable Long conditionId) { Collection<QualityGateConditionDto> conditions = conditionDao.selectForQualityGate(qGateId); if (conditionId == null) { @@ -315,14 +297,14 @@ public class QualityGates { errors.check(isAlertable(metric), format("Metric '%s' cannot be used to define a condition.", metric.getKey())); } - private static boolean isAvailableForInit(Metric metric) { - return !metric.isDataType() && !CoreMetrics.ALERT_STATUS.equals(metric) && ValueType.RATING != metric.getType(); - } - private static boolean isAlertable(Metric metric) { return isAvailableForInit(metric) && BooleanUtils.isFalse(metric.isHidden()); } + private static boolean isAvailableForInit(Metric metric) { + return !metric.isDataType() && !CoreMetrics.ALERT_STATUS.equals(metric) && ValueType.RATING != metric.getType(); + } + private boolean isDefault(QualityGateDto qGate) { return qGate.getId().equals(getDefaultId()); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/AppAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/AppAction.java index 90aa2d27707..e72c78d87a8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/AppAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/AppAction.java @@ -19,20 +19,32 @@ */ package org.sonar.server.qualitygate.ws; -import org.apache.commons.lang.BooleanUtils; -import org.sonar.api.measures.Metric; +import java.util.Collection; +import java.util.stream.Collectors; 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.server.qualitygate.QualityGates; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.metric.MetricDto; +import org.sonar.server.user.UserSession; +import org.sonarqube.ws.WsQualityGates.AppWsResponse.Metric; + +import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY; +import static org.sonar.api.measures.Metric.ValueType.DATA; +import static org.sonar.api.measures.Metric.ValueType.DISTRIB; +import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN; +import static org.sonar.server.ws.WsUtils.writeProtobuf; +import static org.sonarqube.ws.WsQualityGates.AppWsResponse; public class AppAction implements QualityGatesWsAction { - private final QualityGates qualityGates; + private final UserSession userSession; + private final DbClient dbClient; - public AppAction(QualityGates qualityGates) { - this.qualityGates = qualityGates; + public AppAction(UserSession userSession, DbClient dbClient) { + this.userSession = userSession; + this.dbClient = dbClient; } @Override @@ -47,39 +59,42 @@ public class AppAction implements QualityGatesWsAction { @Override public void handle(Request request, Response response) { - JsonWriter writer = response.newJsonWriter().beginObject(); - addPermissions(writer); - addPeriods(writer); - addMetrics(writer); - writer.endObject().close(); + writeProtobuf(AppWsResponse.newBuilder() + .setEdit(userSession.hasPermission(QUALITY_GATE_ADMIN)) + .addAllMetrics(loadMetrics() + .stream() + .map(AppAction::toMetric) + .collect(Collectors.toList())) + .build(), + request, response); } - private void addPermissions(JsonWriter writer) { - writer.prop("edit", qualityGates.currentUserHasWritePermission()); + private static Metric toMetric(MetricDto metricDto) { + String domain = metricDto.getDomain(); + Metric.Builder metricBuilder = Metric.newBuilder() + .setKey(metricDto.getKey()) + .setName(metricDto.getShortName()) + .setType(metricDto.getValueType()) + .setHidden(metricDto.isHidden()); + if (domain != null) { + metricBuilder.setDomain(domain); + } + return metricBuilder.build(); } - private static void addPeriods(JsonWriter writer) { - writer.name("periods").beginArray(); - writer.beginObject() - .prop("key", 1L) - .prop("text", "Leak") - .endObject(); - writer.endArray(); + private Collection<MetricDto> loadMetrics() { + DbSession dbSession = dbClient.openSession(false); + try { + return dbClient.metricDao().selectEnabled(dbSession).stream() + .filter(metric -> !isDataType(metric) && !ALERT_STATUS_KEY.equals(metric.getKey())) + .collect(Collectors.toList()); + } finally { + dbClient.closeSession(dbSession); + } } - private void addMetrics(JsonWriter writer) { - writer.name("metrics").beginArray(); - for (Metric metric : qualityGates.gateMetrics()) { - writer.beginObject() - .prop("id", metric.getId()) - .prop("key", metric.getKey()) - .prop("name", metric.getName()) - .prop("type", metric.getType().toString()) - .prop("domain", metric.getDomain()) - .prop("hidden", BooleanUtils.isNotFalse(metric.isHidden())) - .endObject(); - } - writer.endArray(); + private static boolean isDataType(MetricDto metric) { + return DATA.name().equals(metric.getValueType()) || DISTRIB.name().equals(metric.getValueType()); } } diff --git a/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/app-example.json b/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/app-example.json index e1449fef2dd..96acddbf206 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/app-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/qualitygate/ws/app-example.json @@ -1,30 +1,7 @@ { "edit": false, - "periods": [ - { - "key": 1, - "text": "since previous analysis" - }, - { - "key": 2, - "text": "over 365 days" - }, - { - "key": 3, - "text": "since previous version" - }, - { - "key": 4, - "text": "over period 4 - defined at project level" - }, - { - "key": 5, - "text": "over period 5 - defined at project level" - } - ], "metrics": [ { - "id": 10, "key": "accessors", "name": "Accessors", "type": "INT", @@ -32,52 +9,11 @@ "hidden": true }, { - "id": 111, - "key": "clirr_api_behavior_changes", - "name": "API behavior changes", - "type": "INT", - "domain": "API compatibility", - "hidden": false - }, - { - "id": 110, - "key": "clirr_api_breaks", - "name": "API breaks", - "type": "INT", - "domain": "API compatibility", - "hidden": false - }, - { - "id": 62, - "key": "blocker_violations", - "name": "Blocker issues", - "type": "INT", - "domain": "Issues", - "hidden": false - }, - { - "id": 138, "key": "blocker_remediation_cost", "name": "Blocker Technical Debt", "type": "WORK_DUR", "domain": "SQALE", "hidden": false - }, - { - "id": 45, - "key": "conditions_to_cover", - "name": "Branches to cover", - "type": "INT", - "domain": "Tests", - "hidden": true - }, - { - "id": 131, - "key": "new_it_conditions_to_cover", - "name": "Branches to cover by IT on new code", - "type": "INT", - "domain": "Tests (Integration)", - "hidden": true } ] } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java index 61f22762d9a..be41b48e548 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java @@ -122,23 +122,6 @@ public class QualityGatesTest { assertThat(underTest.list()).isEqualTo(allQgates); } - @Test - public void should_create_qgate() { - String name = "SG-1"; - QualityGateDto sg1 = underTest.create(name); - assertThat(sg1.getName()).isEqualTo(name); - verify(dao).selectByName(name); - verify(dao).insert(sg1); - assertThat(underTest.currentUserHasWritePermission()).isTrue(); - } - - @Test(expected = ForbiddenException.class) - public void should_fail_create_on_anonymous() { - userSessionRule.set(unauthenticatedUserSession); - assertThat(underTest.currentUserHasWritePermission()).isFalse(); - underTest.create("polop"); - } - @Test(expected = ForbiddenException.class) public void should_fail_create_on_missing_permission() { userSessionRule.set(unauthorizedUserSession); @@ -637,7 +620,6 @@ public class QualityGatesTest { when(classicMetric.getType()).thenReturn(ValueType.BOOL); when(metricFinder.findAll()).thenReturn(ImmutableList.of( dataMetric, hiddenMetric, nullHiddenMetric, alertMetric, ratingMetric, classicMetric)); - assertThat(underTest.gateMetrics()).hasSize(3).containsOnly(classicMetric, hiddenMetric, nullHiddenMetric); } private Metric addMetric(String metricKey, String metricName) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java index 7e942c4be87..993810ecb84 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/AppActionTest.java @@ -19,85 +19,213 @@ */ package org.sonar.server.qualitygate.ws; -import com.google.common.collect.ImmutableList; -import java.util.Collection; -import java.util.Locale; -import java.util.Map; -import org.json.simple.JSONValue; -import org.junit.Before; +import java.io.IOException; +import java.util.List; +import org.junit.Rule; import org.junit.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.sonar.api.i18n.I18n; -import org.sonar.api.measures.Metric; -import org.sonar.api.measures.Metric.ValueType; -import org.sonar.core.timemachine.Periods; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.System2; import org.sonar.db.DbClient; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.qualitygate.QgateProjectFinder; -import org.sonar.server.qualitygate.QualityGates; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsTester; +import org.sonar.server.ws.WsActionTester; +import org.sonarqube.ws.MediaTypes; +import org.sonarqube.ws.WsQualityGates.AppWsResponse; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.sonar.api.measures.Metric.ValueType.BOOL; +import static org.sonar.api.measures.Metric.ValueType.DATA; +import static org.sonar.api.measures.Metric.ValueType.DISTRIB; +import static org.sonar.api.measures.Metric.ValueType.INT; +import static org.sonar.api.measures.Metric.ValueType.RATING; +import static org.sonar.api.measures.Metric.ValueType.WORK_DUR; +import static org.sonar.core.permission.GlobalPermissions.DASHBOARD_SHARING; +import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN; +import static org.sonar.db.metric.MetricTesting.newMetricDto; +import static org.sonar.test.JsonAssert.assertJson; +import static org.sonarqube.ws.MediaTypes.JSON; public class AppActionTest { - private QualityGates qGates = mock(QualityGates.class); - private Periods periods = mock(Periods.class); - private I18n i18n = mock(I18n.class); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); - WsTester ws; + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); - @Before - public void setUp() { - SelectAction selectAction = new SelectAction(mock(DbClient.class), mock(UserSessionRule.class), mock(ComponentFinder.class)); + DbClient dbClient = db.getDbClient(); + DbSession dbSession = db.getSession(); - ws = new WsTester(new QualityGatesWs( - new ListAction(qGates), new ShowAction(qGates), new SearchAction(mock(QgateProjectFinder.class)), - new CreateAction(qGates), 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(qGates))); + AppAction underTest = new AppAction(userSession, dbClient); + WsActionTester ws = new WsActionTester(underTest); + + @Test + public void return_metrics() throws Exception { + dbClient.metricDao().insert(dbSession, newMetricDto() + .setKey("metric") + .setShortName("Metric") + .setDomain("General") + .setValueType(BOOL.name()) + .setHidden(true)); + dbSession.commit(); + + AppWsResponse response = executeRequest(); + + List<AppWsResponse.Metric> metrics = response.getMetricsList(); + assertThat(metrics).hasSize(1); + AppWsResponse.Metric metric = metrics.get(0); + assertThat(metric.getKey()).isEqualTo("metric"); + assertThat(metric.getName()).isEqualTo("Metric"); + assertThat(metric.getDomain()).isEqualTo("General"); + assertThat(metric.getType()).isEqualTo(BOOL.name()); + assertThat(metric.getHidden()).isTrue(); + } + + @Test + public void return_metric_without_domain() throws Exception { + dbClient.metricDao().insert(dbSession, newMetricDto() + .setKey("metric") + .setShortName("Metric") + .setDomain(null) + .setValueType(BOOL.name()) + .setHidden(true)); + dbSession.commit(); + + AppWsResponse response = executeRequest(); + + List<AppWsResponse.Metric> metrics = response.getMetricsList(); + assertThat(metrics).hasSize(1); + AppWsResponse.Metric metric = metrics.get(0); + assertThat(metric.getKey()).isEqualTo("metric"); + assertThat(metric.hasDomain()).isFalse(); } @Test - @SuppressWarnings({"unchecked", "rawtypes"}) - public void should_initialize_app() throws Exception { - doAnswer(new Answer<String>() { - @Override - public String answer(InvocationOnMock invocation) throws Throwable { - return (String) invocation.getArguments()[1]; - } - }).when(i18n).message(any(Locale.class), any(String.class), any(String.class)); - - Metric metric = mock(Metric.class); - when(metric.getId()).thenReturn(42); - when(metric.getKey()).thenReturn("metric"); - when(metric.getName()).thenReturn("Metric"); - when(metric.getType()).thenReturn(ValueType.BOOL); - when(metric.getDomain()).thenReturn("General"); - when(metric.isHidden()).thenReturn(false); - when(qGates.gateMetrics()).thenReturn(ImmutableList.of(metric)); - - String json = ws.newGetRequest("api/qualitygates", "app").execute().outputAsString(); - - Map responseJson = (Map) JSONValue.parse(json); - assertThat((Boolean) responseJson.get("edit")).isFalse(); - Collection<Map> periods = (Collection<Map>) responseJson.get("periods"); - assertThat(periods).hasSize(1); - Collection<Map> metrics = (Collection<Map>) responseJson.get("metrics"); + public void return_rating_metrics() throws Exception { + dbClient.metricDao().insert(dbSession, newMetricDto() + .setKey("reliability_rating") + .setShortName("Reliability Rating") + .setDomain("Reliability") + .setValueType(RATING.name()) + .setHidden(false)); + dbSession.commit(); + + AppWsResponse response = executeRequest(); + + List<AppWsResponse.Metric> metrics = response.getMetricsList(); assertThat(metrics).hasSize(1); - Map metricMap = metrics.iterator().next(); - assertThat(metricMap.get("id").toString()).isEqualTo("42"); - assertThat(metricMap.get("key")).isEqualTo("metric"); - assertThat(metricMap.get("name")).isEqualTo("Metric"); - assertThat(metricMap.get("type")).isEqualTo("BOOL"); - assertThat(metricMap.get("domain")).isEqualTo("General"); - assertThat(metricMap.get("hidden")).isEqualTo(false); + AppWsResponse.Metric metric = metrics.get(0); + assertThat(metric.getKey()).isEqualTo("reliability_rating"); + assertThat(metric.getName()).isEqualTo("Reliability Rating"); + assertThat(metric.getDomain()).isEqualTo("Reliability"); + assertThat(metric.getType()).isEqualTo(RATING.name()); + assertThat(metric.getHidden()).isFalse(); + } + + @Test + public void does_not_return_DISTRIB_metric() throws Exception { + dbClient.metricDao().insert(dbSession, newMetricDto() + .setKey("function_complexity_distribution") + .setShortName("Function Distribution / Complexity") + .setDomain("Complexity") + .setValueType(DISTRIB.name()) + .setHidden(false)); + dbSession.commit(); + + AppWsResponse response = executeRequest(); + + assertThat(response.getMetricsList()).isEmpty(); + } + + @Test + public void does_not_return_DATA_metric() throws Exception { + dbClient.metricDao().insert(dbSession, newMetricDto() + .setKey("ncloc_language_distribution") + .setShortName("Lines of Code Per Language") + .setDomain("Size") + .setValueType(DATA.name()) + .setHidden(false)); + dbSession.commit(); + + AppWsResponse response = executeRequest(); + + assertThat(response.getMetricsList()).isEmpty(); + } + + @Test + public void does_not_return_quality_gate_metric() throws Exception { + dbClient.metricDao().insert(dbSession, newMetricDto() + .setKey("alert_status") + .setShortName("Quality Gate Status") + .setDomain("Releasability") + .setValueType(INT.name()) + .setHidden(false)); + dbSession.commit(); + + AppWsResponse response = executeRequest(); + + assertThat(response.getMetricsList()).isEmpty(); + } + + @Test + public void return_edit_to_false_when_not_quality_gate_permission() throws Exception { + userSession.login("not-admin").setGlobalPermissions(DASHBOARD_SHARING); + + AppWsResponse response = executeRequest(); + + assertThat(response.getEdit()).isFalse(); + } + + @Test + public void return_edit_to_true_when_quality_gate_permission() throws Exception { + userSession.login("admin").setGlobalPermissions(QUALITY_GATE_ADMIN); + + AppWsResponse response = executeRequest(); + + assertThat(response.getEdit()).isTrue(); + } + + @Test + public void test_example_json_response() { + dbClient.metricDao().insert(dbSession, + newMetricDto() + .setKey("accessors") + .setShortName("Accessors") + .setDomain("Size") + .setValueType(INT.name()) + .setHidden(true), + newMetricDto() + .setKey("blocker_remediation_cost") + .setShortName("Blocker Technical Debt") + .setDomain("SQALE") + .setValueType(WORK_DUR.name()) + .setHidden(false)); + dbSession.commit(); + + String result = ws.newRequest() + .setMediaType(JSON) + .execute() + .getInput(); + + assertJson(ws.getDef().responseExampleAsString()).isSimilarTo(result); + } + + @Test + public void test_ws_definition() { + WebService.Action action = ws.getDef(); + assertThat(action).isNotNull(); + assertThat(action.isInternal()).isTrue(); + assertThat(action.isPost()).isFalse(); + assertThat(action.responseExampleAsString()).isNotEmpty(); + assertThat(action.params()).isEmpty(); + } + + private AppWsResponse executeRequest() { + try { + return AppWsResponse.parseFrom(ws.newRequest().setMediaType(MediaTypes.PROTOBUF).execute().getInputStream()); + } catch (IOException e) { + throw new IllegalStateException(e); + } } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java index 58916a1ab78..1f711722b8b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/QualityGatesWsTest.java @@ -73,7 +73,7 @@ public class QualityGatesWsTest { new CreateAction(qGates), 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(qGates))); + selectAction, new DeselectAction(qGates, mock(DbClient.class), mock(ComponentFinder.class)), new AppAction(null, null))); } @Test @@ -261,9 +261,7 @@ public class QualityGatesWsTest { when(qGates.list()).thenReturn(Lists.newArrayList( new QualityGateDto().setId(42L).setName("Golden"), new QualityGateDto().setId(43L).setName("Star"), - new QualityGateDto().setId(666L).setName("Ninth") - )); - when(qGates.currentUserHasWritePermission()).thenReturn(false); + new QualityGateDto().setId(666L).setName("Ninth"))); tester.newGetRequest("api/qualitygates", "list").execute().assertJson( "{\"qualitygates\":[{\"id\":42,\"name\":\"Golden\"},{\"id\":43,\"name\":\"Star\"},{\"id\":666,\"name\":\"Ninth\"}]}"); } @@ -274,8 +272,7 @@ public class QualityGatesWsTest { when(qGates.list()).thenReturn(Lists.newArrayList( defaultQgate, new QualityGateDto().setId(43L).setName("Star"), - new QualityGateDto().setId(666L).setName("Ninth") - )); + new QualityGateDto().setId(666L).setName("Ninth"))); when(qGates.getDefault()).thenReturn(defaultQgate); tester.newGetRequest("api/qualitygates", "list").execute().assertJson( "{\"qualitygates\":[{\"id\":42,\"name\":\"Golden\"},{\"id\":43,\"name\":\"Star\"},{\"id\":666,\"name\":\"Ninth\"}],\"default\":42}"); @@ -295,14 +292,12 @@ public class QualityGatesWsTest { when(qGates.get(gateId)).thenReturn(new QualityGateDto().setId(gateId).setName("Golden")); when(qGates.listConditions(gateId)).thenReturn(ImmutableList.of( new QualityGateConditionDto().setId(1L).setMetricKey("ncloc").setOperator("GT").setErrorThreshold("10000"), - new QualityGateConditionDto().setId(2L).setMetricKey("new_coverage").setOperator("LT").setWarningThreshold("90").setPeriod(3) - )); + new QualityGateConditionDto().setId(2L).setMetricKey("new_coverage").setOperator("LT").setWarningThreshold("90").setPeriod(3))); tester.newGetRequest("api/qualitygates", "show").setParam("id", Long.toString(gateId)).execute().assertJson( "{\"id\":12345,\"name\":\"Golden\",\"conditions\":[" + "{\"id\":1,\"metric\":\"ncloc\",\"op\":\"GT\",\"error\":\"10000\"}," + "{\"id\":2,\"metric\":\"new_coverage\",\"op\":\"LT\",\"warning\":\"90\",\"period\":3}" - + "]}" - ); + + "]}"); } @Test @@ -312,14 +307,12 @@ public class QualityGatesWsTest { when(qGates.get(gateName)).thenReturn(new QualityGateDto().setId(qGateId).setName(gateName)); when(qGates.listConditions(qGateId)).thenReturn(ImmutableList.of( new QualityGateConditionDto().setId(1L).setMetricKey("ncloc").setOperator("GT").setErrorThreshold("10000"), - new QualityGateConditionDto().setId(2L).setMetricKey("new_coverage").setOperator("LT").setWarningThreshold("90").setPeriod(3) - )); + new QualityGateConditionDto().setId(2L).setMetricKey("new_coverage").setOperator("LT").setWarningThreshold("90").setPeriod(3))); tester.newGetRequest("api/qualitygates", "show").setParam("name", gateName).execute().assertJson( "{\"id\":12345,\"name\":\"Golden\",\"conditions\":[" + "{\"id\":1,\"metric\":\"ncloc\",\"op\":\"GT\",\"error\":\"10000\"}," + "{\"id\":2,\"metric\":\"new_coverage\",\"op\":\"LT\",\"warning\":\"90\",\"period\":3}" - + "]}" - ); + + "]}"); } @Test(expected = BadRequestException.class) @@ -388,8 +381,7 @@ public class QualityGatesWsTest { when(assoc.hasMoreResults()).thenReturn(true); List<ProjectQgateAssociation> projects = ImmutableList.of( new ProjectQgateAssociation().setId(42L).setName("Project One").setMember(false), - new ProjectQgateAssociation().setId(24L).setName("Project Two").setMember(true) - ); + new ProjectQgateAssociation().setId(24L).setName("Project Two").setMember(true)); when(assoc.projects()).thenReturn(projects); when(projectFinder.find(any(ProjectQgateAssociationQuery.class))).thenReturn(assoc); @@ -413,8 +405,7 @@ public class QualityGatesWsTest { Association assoc = mock(Association.class); when(assoc.hasMoreResults()).thenReturn(true); List<ProjectQgateAssociation> projects = ImmutableList.of( - new ProjectQgateAssociation().setId(24L).setName("Project Two").setMember(true) - ); + new ProjectQgateAssociation().setId(24L).setName("Project Two").setMember(true)); when(assoc.projects()).thenReturn(projects); when(projectFinder.find(any(ProjectQgateAssociationQuery.class))).thenReturn(assoc); diff --git a/sonar-db/src/main/java/org/sonar/db/metric/MetricDto.java b/sonar-db/src/main/java/org/sonar/db/metric/MetricDto.java index 09b07c9ff21..5a3ebb8fe17 100644 --- a/sonar-db/src/main/java/org/sonar/db/metric/MetricDto.java +++ b/sonar-db/src/main/java/org/sonar/db/metric/MetricDto.java @@ -105,11 +105,12 @@ public class MetricDto { return this; } + @CheckForNull public String getDomain() { return domain; } - public MetricDto setDomain(String domain) { + public MetricDto setDomain(@Nullable String domain) { this.domain = domain; return this; } @@ -206,4 +207,5 @@ public class MetricDto { this.decimalScale = i; return this; } + } diff --git a/sonar-ws/src/main/protobuf/ws-qualitygates.proto b/sonar-ws/src/main/protobuf/ws-qualitygates.proto index 514a5341a37..a8b26096d13 100644 --- a/sonar-ws/src/main/protobuf/ws-qualitygates.proto +++ b/sonar-ws/src/main/protobuf/ws-qualitygates.proto @@ -76,3 +76,18 @@ message QualityGate { optional string name = 2; optional bool default = 3; } + +// GET api/qualitygates/app +message AppWsResponse { + optional bool edit = 1; + repeated Metric metrics = 3; + + message Metric { + optional string key = 1; + optional string name = 2; + optional string type = 3; + optional string domain = 4; + optional bool hidden = 5; + } +} + |