3 * Copyright (C) 2009-2020 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.measure.custom.ws;
22 import org.junit.Rule;
23 import org.junit.Test;
24 import org.junit.rules.ExpectedException;
25 import org.sonar.api.measures.Metric;
26 import org.sonar.api.server.ws.Change;
27 import org.sonar.api.server.ws.WebService.Action;
28 import org.sonar.api.utils.System2;
29 import org.sonar.db.DbTester;
30 import org.sonar.db.component.ComponentDto;
31 import org.sonar.db.component.ComponentTesting;
32 import org.sonar.db.measure.custom.CustomMeasureDto;
33 import org.sonar.db.metric.MetricDto;
34 import org.sonar.db.organization.OrganizationDto;
35 import org.sonar.db.user.UserDto;
36 import org.sonar.server.component.TestComponentFinder;
37 import org.sonar.server.es.EsTester;
38 import org.sonar.server.exceptions.BadRequestException;
39 import org.sonar.server.exceptions.ForbiddenException;
40 import org.sonar.server.exceptions.NotFoundException;
41 import org.sonar.server.tester.UserSessionRule;
42 import org.sonar.server.user.ws.UserJsonWriter;
43 import org.sonar.server.ws.WsActionTester;
45 import static java.lang.String.format;
46 import static org.assertj.core.api.Assertions.assertThat;
47 import static org.assertj.core.api.Assertions.tuple;
48 import static org.sonar.api.measures.Metric.ValueType.BOOL;
49 import static org.sonar.api.measures.Metric.ValueType.FLOAT;
50 import static org.sonar.api.measures.Metric.ValueType.INT;
51 import static org.sonar.api.measures.Metric.ValueType.LEVEL;
52 import static org.sonar.api.measures.Metric.ValueType.STRING;
53 import static org.sonar.api.measures.Metric.ValueType.WORK_DUR;
54 import static org.sonar.api.web.UserRole.ADMIN;
55 import static org.sonar.db.component.ComponentTesting.newModuleDto;
56 import static org.sonar.server.util.TypeValidationsTesting.newFullTypeValidations;
57 import static org.sonar.test.JsonAssert.assertJson;
59 public class CreateActionTest {
62 public UserSessionRule userSession = UserSessionRule.standalone();
64 public ExpectedException expectedException = ExpectedException.none();
66 public DbTester db = DbTester.create(System2.INSTANCE);
68 public EsTester es = EsTester.create();
70 private final WsActionTester ws = new WsActionTester(
71 new CreateAction(db.getDbClient(), userSession, System2.INSTANCE, new CustomMeasureValidator(newFullTypeValidations()),
72 new CustomMeasureJsonWriter(new UserJsonWriter(userSession)), TestComponentFinder.from(db)));
75 public void verify_definition() {
76 Action wsDef = ws.getDef();
78 assertThat(wsDef.deprecatedSince()).isEqualTo("7.4");
79 assertThat(wsDef.isInternal()).isFalse();
80 assertThat(wsDef.since()).isEqualTo("5.2");
81 assertThat(wsDef.isPost()).isTrue();
82 assertThat(wsDef.changelog()).extracting(Change::getVersion, Change::getDescription).containsOnly(
83 tuple("8.4", "Param 'metricId' data type changes from integer to string."));
87 public void create_boolean_custom_measure_in_db() {
88 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
89 ComponentDto project = db.components().insertPrivateProject();
90 UserDto user = db.users().insertUser();
91 userSession.logIn(user).addProjectPermission(ADMIN, project);
94 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
95 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
96 .setParam(CreateAction.PARAM_DESCRIPTION, "custom-measure-description")
97 .setParam(CreateAction.PARAM_VALUE, "true")
100 assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
101 .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
102 .containsExactlyInAnyOrder(tuple("custom-measure-description", null, 1d, project.uuid()));
106 public void create_int_custom_measure_in_db() {
107 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(INT.name()));
108 ComponentDto project = db.components().insertPrivateProject();
109 UserDto user = db.users().insertUser();
110 userSession.logIn(user).addProjectPermission(ADMIN, project);
113 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
114 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
115 .setParam(CreateAction.PARAM_VALUE, "42")
118 assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
119 .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
120 .containsExactlyInAnyOrder(tuple(null, null, 42d, project.uuid()));
124 public void create_text_custom_measure_in_db() {
125 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
126 ComponentDto project = db.components().insertPrivateProject();
127 UserDto user = db.users().insertUser();
128 userSession.logIn(user).addProjectPermission(ADMIN, project);
131 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
132 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
133 .setParam(CreateAction.PARAM_VALUE, "custom-measure-free-text")
136 assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
137 .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
138 .containsExactlyInAnyOrder(tuple(null, "custom-measure-free-text", 0d, project.uuid()));
142 public void create_text_custom_measure_with_metric_key() {
143 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
144 ComponentDto project = db.components().insertPrivateProject();
145 UserDto user = db.users().insertUser();
146 userSession.logIn(user).addProjectPermission(ADMIN, project);
149 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
150 .setParam(CreateAction.PARAM_METRIC_KEY, metric.getKey())
151 .setParam(CreateAction.PARAM_VALUE, "whatever-value")
154 assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
155 .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
156 .containsExactlyInAnyOrder(tuple(null, "whatever-value", 0d, project.uuid()));
160 public void create_text_custom_measure_with_project_key() {
161 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
162 ComponentDto project = db.components().insertPrivateProject();
163 UserDto user = db.users().insertUser();
164 userSession.logIn(user).addProjectPermission(ADMIN, project);
167 .setParam(CreateAction.PARAM_PROJECT_KEY, project.getKey())
168 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
169 .setParam(CreateAction.PARAM_VALUE, "whatever-value")
172 assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
173 .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
174 .containsExactlyInAnyOrder(tuple(null, "whatever-value", 0d, project.uuid()));
178 public void create_float_custom_measure_in_db() {
179 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(FLOAT.name()));
180 ComponentDto project = db.components().insertPrivateProject();
181 UserDto user = db.users().insertUser();
182 userSession.logIn(user).addProjectPermission(ADMIN, project);
185 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
186 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
187 .setParam(CreateAction.PARAM_VALUE, "4.2")
190 assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
191 .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
192 .containsExactlyInAnyOrder(tuple(null, null, 4.2d, project.uuid()));
196 public void create_work_duration_custom_measure_in_db() {
197 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(WORK_DUR.name()));
198 ComponentDto project = db.components().insertPrivateProject();
199 UserDto user = db.users().insertUser();
200 userSession.logIn(user).addProjectPermission(ADMIN, project);
203 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
204 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
205 .setParam(CreateAction.PARAM_VALUE, "253")
208 assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
209 .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
210 .containsExactlyInAnyOrder(tuple(null, null, 253d, project.uuid()));
214 public void create_level_type_custom_measure_in_db() {
215 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(LEVEL.name()));
216 ComponentDto project = db.components().insertPrivateProject();
217 UserDto user = db.users().insertUser();
218 userSession.logIn(user).addProjectPermission(ADMIN, project);
221 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
222 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
223 .setParam(CreateAction.PARAM_VALUE, Metric.Level.ERROR.name())
226 assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
227 .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
228 .containsExactlyInAnyOrder(tuple(null, Metric.Level.ERROR.name(), 0d, project.uuid()));
232 public void response_with_object_and_id() {
233 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
234 ComponentDto project = db.components().insertPrivateProject();
235 UserDto user = db.users().insertUser();
236 userSession.logIn(user).addProjectPermission(ADMIN, project);
238 String response = ws.newRequest()
239 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
240 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
241 .setParam(CreateAction.PARAM_DESCRIPTION, "custom-measure-description")
242 .setParam(CreateAction.PARAM_VALUE, "custom-measure-free-text")
246 CustomMeasureDto customMeasure = db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()).get(0);
247 assertJson(response).isSimilarTo("{\n" +
248 " \"id\": \"" + customMeasure.getUuid() + "\",\n" +
249 " \"value\": \"custom-measure-free-text\",\n" +
250 " \"description\": \"custom-measure-description\",\n" +
252 " \"id\": \"" + metric.getUuid() + "\",\n" +
253 " \"key\": \"" + metric.getKey() + "\",\n" +
254 " \"type\": \"" + metric.getValueType() + "\",\n" +
255 " \"name\": \"" + metric.getShortName() + "\",\n" +
256 " \"domain\": \"" + metric.getDomain() + "\"\n" +
258 " \"projectId\": \"" + project.uuid() + "\",\n" +
259 " \"projectKey\": \"" + project.getKey() + "\",\n" +
260 " \"pending\": true\n" +
265 public void create_custom_measure_on_module() {
266 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
267 ComponentDto project = db.components().insertPrivateProject();
268 ComponentDto module = db.components().insertComponent(newModuleDto(project));
269 UserDto user = db.users().insertUser();
270 userSession.logIn(user).addProjectPermission(ADMIN, project);
273 .setParam(CreateAction.PARAM_PROJECT_ID, module.uuid())
274 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
275 .setParam(CreateAction.PARAM_DESCRIPTION, "custom-measure-description")
276 .setParam(CreateAction.PARAM_VALUE, "true")
279 assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
280 .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
281 .containsExactlyInAnyOrder(tuple("custom-measure-description", null, 1d, module.uuid()));
285 public void create_custom_measure_on_a_view() {
286 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
287 OrganizationDto organization = db.organizations().insert();
288 ComponentDto view = db.components().insertPrivatePortfolio(organization);
289 UserDto user = db.users().insertUser();
290 userSession.logIn(user).addProjectPermission(ADMIN, view);
293 .setParam(CreateAction.PARAM_PROJECT_ID, view.uuid())
294 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
295 .setParam(CreateAction.PARAM_DESCRIPTION, "custom-measure-description")
296 .setParam(CreateAction.PARAM_VALUE, "true")
299 assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
300 .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
301 .containsExactlyInAnyOrder(tuple("custom-measure-description", null, 1d, view.uuid()));
305 public void create_custom_measure_on_a_sub_view() {
306 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
307 OrganizationDto organization = db.organizations().insert();
308 ComponentDto view = db.components().insertPrivatePortfolio(organization);
309 ComponentDto subView = db.components().insertSubView(view);
310 UserDto user = db.users().insertUser();
311 userSession.logIn(user).addProjectPermission(ADMIN, view);
314 .setParam(CreateAction.PARAM_PROJECT_ID, subView.uuid())
315 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
316 .setParam(CreateAction.PARAM_DESCRIPTION, "custom-measure-description")
317 .setParam(CreateAction.PARAM_VALUE, "true")
320 assertThat(db.getDbClient().customMeasureDao().selectByMetricUuid(db.getSession(), metric.getUuid()))
321 .extracting(CustomMeasureDto::getDescription, CustomMeasureDto::getTextValue, CustomMeasureDto::getValue, CustomMeasureDto::getComponentUuid)
322 .containsExactlyInAnyOrder(tuple("custom-measure-description", null, 1d, subView.uuid()));
326 public void fail_when_project_id_nor_project_key_provided() {
327 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
328 ComponentDto project = db.components().insertPrivateProject();
329 UserDto user = db.users().insertUser();
330 userSession.logIn(user).addProjectPermission(ADMIN, project);
332 expectedException.expect(IllegalArgumentException.class);
333 expectedException.expectMessage("Either 'projectId' or 'projectKey' must be provided");
336 .setParam(CreateAction.PARAM_METRIC_ID, "whatever-id")
337 .setParam(CreateAction.PARAM_VALUE, metric.getUuid())
342 public void fail_when_project_id_and_project_key_are_provided() {
343 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
344 ComponentDto project = db.components().insertPrivateProject();
345 UserDto user = db.users().insertUser();
346 userSession.logIn(user).addProjectPermission(ADMIN, project);
348 expectedException.expect(IllegalArgumentException.class);
349 expectedException.expectMessage("Either 'projectId' or 'projectKey' must be provided");
352 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
353 .setParam(CreateAction.PARAM_PROJECT_KEY, project.getKey())
354 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
355 .setParam(CreateAction.PARAM_VALUE, "whatever-value")
360 public void fail_when_project_key_does_not_exist_in_db() {
361 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
362 ComponentDto project = db.components().insertPrivateProject();
363 UserDto user = db.users().insertUser();
364 userSession.logIn(user).addProjectPermission(ADMIN, project);
366 expectedException.expect(NotFoundException.class);
367 expectedException.expectMessage("Component key 'another-project-key' not found");
370 .setParam(CreateAction.PARAM_PROJECT_KEY, "another-project-key")
371 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
372 .setParam(CreateAction.PARAM_VALUE, "whatever-value")
377 public void fail_when_project_id_does_not_exist_in_db() {
378 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
379 ComponentDto project = db.components().insertPrivateProject();
380 UserDto user = db.users().insertUser();
381 userSession.logIn(user).addProjectPermission(ADMIN, project);
383 expectedException.expect(NotFoundException.class);
384 expectedException.expectMessage("Component id 'another-project-uuid' not found");
387 .setParam(CreateAction.PARAM_PROJECT_ID, "another-project-uuid")
388 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
389 .setParam(CreateAction.PARAM_VALUE, "whatever-value")
394 public void fail_when_metric_uuid_nor_metric_key_is_provided() {
395 ComponentDto project = db.components().insertPrivateProject();
396 UserDto user = db.users().insertUser();
397 userSession.logIn(user).addProjectPermission(ADMIN, project);
399 expectedException.expect(IllegalArgumentException.class);
400 expectedException.expectMessage("Either the metric uuid or the metric key must be provided");
403 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
404 .setParam(CreateAction.PARAM_VALUE, "whatever-value")
409 public void fail_when_metric_uuid_and_metric_key_are_provided() {
410 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
411 ComponentDto project = db.components().insertPrivateProject();
412 UserDto user = db.users().insertUser();
413 userSession.logIn(user).addProjectPermission(ADMIN, project);
415 expectedException.expect(IllegalArgumentException.class);
416 expectedException.expectMessage("Either the metric uuid or the metric key must be provided");
419 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
420 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
421 .setParam(CreateAction.PARAM_METRIC_KEY, metric.getKey())
422 .setParam(CreateAction.PARAM_VALUE, "whatever-value")
427 public void fail_when_metric_key_is_not_found_in_db() {
428 ComponentDto project = db.components().insertPrivateProject();
429 UserDto user = db.users().insertUser();
430 userSession.logIn(user).addProjectPermission(ADMIN, project);
432 expectedException.expect(IllegalArgumentException.class);
433 expectedException.expectMessage("Metric with key 'unknown' does not exist");
436 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
437 .setParam(CreateAction.PARAM_METRIC_KEY, "unknown")
438 .setParam(CreateAction.PARAM_VALUE, "whatever-value")
443 public void fail_when_metric_uuid_is_not_found_in_db() {
444 ComponentDto project = db.components().insertPrivateProject();
445 UserDto user = db.users().insertUser();
446 userSession.logIn(user).addProjectPermission(ADMIN, project);
448 expectedException.expect(IllegalArgumentException.class);
449 expectedException.expectMessage("Metric with uuid '42' does not exist");
452 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
453 .setParam(CreateAction.PARAM_METRIC_ID, "42")
454 .setParam(CreateAction.PARAM_VALUE, "whatever-value")
459 public void fail_when_measure_already_exists_on_same_project_and_same_metric() {
460 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(STRING.name()));
461 ComponentDto project = db.components().insertPrivateProject();
462 UserDto userMeasureCreator = db.users().insertUser();
463 db.measures().insertCustomMeasure(userMeasureCreator, project, metric);
464 UserDto userAuthenticated = db.users().insertUser();
465 userSession.logIn(userAuthenticated).addProjectPermission(ADMIN, project);
467 expectedException.expect(BadRequestException.class);
468 expectedException.expectMessage(format("A measure already exists for project '%s' and metric '%s'", project.getKey(), metric.getKey()));
471 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
472 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
473 .setParam(CreateAction.PARAM_VALUE, "whatever-value")
478 public void fail_when_value_is_not_well_formatted() {
479 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
480 ComponentDto project = db.components().insertPrivateProject();
481 UserDto user = db.users().insertUser();
482 userSession.logIn(user).addProjectPermission(ADMIN, project);
484 expectedException.expect(BadRequestException.class);
485 expectedException.expectMessage("Value 'non-correct-boolean-value' must be one of \"true\" or \"false\"");
488 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
489 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
490 .setParam(CreateAction.PARAM_VALUE, "non-correct-boolean-value")
495 public void fail_when_system_administrator() {
496 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
497 ComponentDto project = db.components().insertPrivateProject();
498 UserDto user = db.users().insertUser();
499 userSession.logIn(user).setSystemAdministrator();
501 expectedException.expect(ForbiddenException.class);
504 .setParam(CreateAction.PARAM_PROJECT_ID, project.uuid())
505 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
506 .setParam(CreateAction.PARAM_VALUE, "whatever-value")
511 public void fail_when_not_a_project() {
512 MetricDto metric = db.measures().insertMetric(m -> m.setUserManaged(true).setValueType(BOOL.name()));
513 ComponentDto project = db.components().insertPrivateProject();
514 ComponentDto directory = db.components().insertComponent(ComponentTesting.newDirectory(project, "dir"));
515 UserDto user = db.users().insertUser();
516 userSession.logIn(user).addProjectPermission(ADMIN, project);
518 expectedException.expect(BadRequestException.class);
519 expectedException.expectMessage(format("Component '%s' must be a project or a module.", directory.getKey()));
522 .setParam(CreateAction.PARAM_PROJECT_ID, directory.uuid())
523 .setParam(CreateAction.PARAM_METRIC_ID, metric.getUuid())
524 .setParam(CreateAction.PARAM_VALUE, "whatever-value")