import org.sonar.server.test.index.TestDoc;
import org.sonar.server.test.index.TestIndex;
import org.sonar.server.user.UserSession;
+import org.sonar.server.ws.KeyExamples;
import org.sonar.server.ws.WsUtils;
import org.sonarqube.ws.Common;
import org.sonarqube.ws.WsTests;
public static final String TEST_FILE_ID = "testFileId";
public static final String TEST_FILE_KEY = "testFileKey";
public static final String SOURCE_FILE_ID = "sourceFileId";
+ public static final String SOURCE_FILE_KEY = "sourceFileKey";
public static final String SOURCE_FILE_LINE_NUMBER = "sourceFileLineNumber";
private final DbClient dbClient;
"<li>" + TEST_FILE_ID + "</li>" +
"<li>" + TEST_ID + "</li>" +
"<li>" + SOURCE_FILE_ID + " and " + SOURCE_FILE_LINE_NUMBER + "</li>" +
+ "<li>" + SOURCE_FILE_KEY + "and" + SOURCE_FILE_LINE_NUMBER + "</li>" +
"</ul>")
.setSince("5.2")
.setResponseExample(Resources.getResource(getClass(), "tests-example-list.json"))
action
.createParam(SOURCE_FILE_ID)
- .setDescription("IF of source file. Must be provided with the source file line number.")
+ .setDescription("ID of source file. Must be provided with the source file line number.")
.setExampleValue(Uuids.UUID_EXAMPLE_03);
+ action
+ .createParam(SOURCE_FILE_KEY)
+ .setSince("5.4")
+ .setDescription("Key of source file. Must be provided with the source file line number.")
+ .setExampleValue(KeyExamples.KEY_FILE_EXAMPLE_001);
+
action
.createParam(SOURCE_FILE_LINE_NUMBER)
- .setDescription("Source file line number. Must be provided with the source file ID.")
+ .setDescription("Source file line number. Must be provided with the source file ID or key.")
.setExampleValue("10");
}
String testFileUuid = request.param(TEST_FILE_ID);
String testFileKey = request.param(TEST_FILE_KEY);
String sourceFileUuid = request.param(SOURCE_FILE_ID);
+ String sourceFileKey = request.param(SOURCE_FILE_KEY);
Integer sourceFileLineNumber = request.paramAsInt(SOURCE_FILE_LINE_NUMBER);
SearchOptions searchOptions = new SearchOptions().setPage(
request.mandatoryParamAsInt(WebService.Param.PAGE),
- request.mandatoryParamAsInt(WebService.Param.PAGE_SIZE)
- );
+ request.mandatoryParamAsInt(WebService.Param.PAGE_SIZE));
DbSession dbSession = dbClient.openSession(false);
SearchResult<TestDoc> tests;
Map<String, ComponentDto> componentsByTestFileUuid;
try {
- tests = searchTests(dbSession, testUuid, testFileUuid, testFileKey, sourceFileUuid, sourceFileLineNumber, searchOptions);
+ tests = searchTests(dbSession, testUuid, testFileUuid, testFileKey, sourceFileUuid, sourceFileKey, sourceFileLineNumber, searchOptions);
componentsByTestFileUuid = buildComponentsByTestFileUuid(dbSession, tests.getDocs());
} finally {
MyBatis.closeQuietly(dbSession);
return Maps.uniqueIndex(components, ComponentDtoFunctions.toUuid());
}
- private static class TestToFileUuidFunction implements Function<TestDoc, String> {
- @Override
- public String apply(@Nonnull TestDoc testDoc) {
- return testDoc.fileUuid();
- }
- }
-
private SearchResult<TestDoc> searchTests(DbSession dbSession, @Nullable String testUuid, @Nullable String testFileUuid, @Nullable String testFileKey,
- @Nullable String sourceFileUuid, @Nullable Integer sourceFileLineNumber, SearchOptions searchOptions) {
+ @Nullable String sourceFileUuid, @Nullable String sourceFileKey, @Nullable Integer sourceFileLineNumber, SearchOptions searchOptions) {
if (testUuid != null) {
return searchTestsByTestUuid(dbSession, testUuid, searchOptions);
}
if (sourceFileUuid != null && sourceFileLineNumber != null) {
return searchTestsBySourceFileUuidAndLineNumber(dbSession, sourceFileUuid, sourceFileLineNumber, searchOptions);
}
+ if (sourceFileKey != null && sourceFileLineNumber != null) {
+ ComponentDto component = componentFinder.getByKey(dbSession, sourceFileKey);
+ return searchTestsBySourceFileUuidAndLineNumber(dbSession, component.uuid(), sourceFileLineNumber, searchOptions);
+ }
throw new IllegalArgumentException(
"One (and only one) of the following combination of parameters must be provided: 1) test UUID. 2) test file UUID. " +
- "3) test file key. 4) source file UUID and source file line number.");
+ "3) test file key. 4) source file ID or key with a source file line number.");
}
private SearchResult<TestDoc> searchTestsBySourceFileUuidAndLineNumber(DbSession dbSession, String sourceFileUuid, Integer sourceFileLineNumber, SearchOptions searchOptions) {
ComponentDto component = dbClient.componentDao().selectOrFailByUuid(dbSession, componentUuid);
userSession.checkComponentUuidPermission(UserRole.CODEVIEWER, component.projectUuid());
}
+
+ private static class TestToFileUuidFunction implements Function<TestDoc, String> {
+ @Override
+ public String apply(@Nonnull TestDoc testDoc) {
+ return testDoc.fileUuid();
+ }
+ }
}
}
@Test
- public void list_based_on_main_file_and_line_number() throws Exception {
+ public void list_based_on_source_file_uuid_and_line_number() throws Exception {
String mainFileUuid = "MAIN-FILE-UUID";
userSessionRule.addProjectUuidPermissions(UserRole.CODEVIEWER, TestFile1.PROJECT_UUID);
dbClient.componentDao().insert(db.getSession(),
request.execute().assertJson(getClass(), "list-main-file.json");
}
+ @Test
+ public void list_based_on_source_file_key_and_line_number() throws Exception {
+ String sourceFileUuid = "MAIN-FILE-UUID";
+ String sourceFileKey = "MAIN-FILE-KEY";
+ userSessionRule.addProjectUuidPermissions(UserRole.CODEVIEWER, TestFile1.PROJECT_UUID);
+ dbClient.componentDao().insert(db.getSession(),
+ new ComponentDto()
+ .setUuid(TestFile1.FILE_UUID)
+ .setLongName(TestFile1.LONG_NAME)
+ .setKey(TestFile1.KEY)
+ .setProjectUuid(TestFile1.PROJECT_UUID),
+ new ComponentDto()
+ .setUuid(TestFile2.FILE_UUID)
+ .setLongName(TestFile2.LONG_NAME)
+ .setProjectUuid(TestFile2.PROJECT_UUID)
+ .setKey(TestFile2.KEY),
+ new ComponentDto()
+ .setUuid(sourceFileUuid)
+ .setKey(sourceFileKey)
+ .setProjectUuid(TestFile1.PROJECT_UUID)
+ );
+ db.getSession().commit();
+
+ es.putDocuments(TestIndexDefinition.INDEX, TestIndexDefinition.TYPE,
+ new TestDoc()
+ .setUuid(TestFile1.UUID)
+ .setProjectUuid(TestFile1.PROJECT_UUID)
+ .setName(TestFile1.NAME)
+ .setFileUuid(TestFile1.FILE_UUID)
+ .setDurationInMs(TestFile1.DURATION_IN_MS)
+ .setStatus(TestFile1.STATUS)
+ .setMessage(TestFile1.MESSAGE)
+ .setCoveredFiles(TestFile1.COVERED_FILES)
+ .setStackTrace(TestFile1.STACKTRACE),
+ new TestDoc()
+ .setUuid(TestFile2.UUID)
+ .setProjectUuid(TestFile2.PROJECT_UUID)
+ .setName(TestFile2.NAME)
+ .setFileUuid(TestFile2.FILE_UUID)
+ .setDurationInMs(TestFile2.DURATION_IN_MS)
+ .setStatus(TestFile2.STATUS)
+ .setStackTrace(TestFile2.STATUS)
+ .setMessage(TestFile2.MESSAGE)
+ .setCoveredFiles(TestFile2.COVERED_FILES)
+ .setStackTrace(TestFile2.STACKTRACE));
+
+ WsTester.TestRequest request = ws.newGetRequest("api/tests", "list")
+ .setParam(ListAction.SOURCE_FILE_KEY, sourceFileKey)
+ .setParam(ListAction.SOURCE_FILE_LINE_NUMBER, "10");
+
+ request.execute().assertJson(getClass(), "list-main-file.json");
+ }
+
@Test(expected = IllegalArgumentException.class)
public void fail_when_no_argument() throws Exception {
ws.newGetRequest("api/tests", "list").execute();