pico.addSingleton(HashAction.class);
pico.addSingleton(RawAction.class);
pico.addSingleton(IndexAction.class);
+ pico.addSingleton(ScmAction.class);
pico.addSingleton(SourceLineIndexDefinition.class);
pico.addSingleton(SourceLineIndex.class);
pico.addSingleton(SourceLineIndexer.class);
import com.google.common.io.Resources;
import org.apache.commons.io.Charsets;
import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.web.UserRole;
import java.io.OutputStreamWriter;
import java.io.Reader;
-public class HashAction implements RequestHandler {
+public class HashAction implements SourcesAction {
private final DbClient dbClient;
this.dbClient = dbClient;
}
- void define(WebService.NewController controller) {
+ @Override
+ public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction("hash")
.setDescription("Show line line hashes for a given file. Require See Source Code permission on file's project<br/>")
.setSince("5.0")
import com.google.common.io.Resources;
import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
import java.util.List;
-public class IndexAction implements RequestHandler {
+public class IndexAction implements SourcesAction {
private final DbClient dbClient;
private final SourceService sourceService;
this.sourceService = sourceService;
}
- void define(WebService.NewController controller) {
+ @Override
+ public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction("index")
.setDescription("Get source code as line number / text pairs. Require See Source Code permission on file")
.setSince("5.0")
import com.google.common.io.Resources;
import org.apache.commons.lang.ObjectUtils;
import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.DateUtils;
import java.util.Date;
import java.util.List;
-public class LinesAction implements RequestHandler {
+public class LinesAction implements SourcesAction {
private final SourceLineIndex sourceLineIndex;
private final HtmlSourceDecorator htmlSourceDecorator;
this.componentService = componentService;
}
- void define(WebService.NewController controller) {
+ @Override
+ public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction("lines")
.setDescription("Show source code with line oriented info. Require See Source Code permission on file's project<br/>" +
"Each element of the result array is an object which contains:" +
}
JsonWriter json = response.newJsonWriter().beginObject();
- writeSource(sourceLines, from, json);
+ writeSource(sourceLines, json);
json.endObject().close();
}
- private void writeSource(List<SourceLineDoc> lines, int from, JsonWriter json) {
+ private void writeSource(List<SourceLineDoc> lines, JsonWriter json) {
json.name("sources").beginArray();
for (SourceLineDoc line: lines) {
json.beginObject()
import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.web.UserRole;
import java.io.IOException;
import java.util.List;
-public class RawAction implements RequestHandler {
+public class RawAction implements SourcesAction {
private final DbClient dbClient;
private final SourceService sourceService;
this.sourceService = sourceService;
}
- void define(WebService.NewController controller) {
+ @Override
+ public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction("raw")
.setDescription("Get source code as plain text. Require See Source Code permission on file")
.setSince("5.0")
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.source.ws;
+
+import com.google.common.base.Strings;
+import com.google.common.io.Resources;
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
+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.DateUtils;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.source.index.SourceLineDoc;
+import org.sonar.server.source.index.SourceLineIndex;
+import org.sonar.server.user.UserSession;
+
+import java.util.Date;
+import java.util.List;
+
+public class ScmAction implements SourcesAction {
+
+ private final DbClient dbClient;
+ private final SourceLineIndex sourceLineIndex;
+
+ public ScmAction(DbClient dbClient, SourceLineIndex sourceLineIndex) {
+ this.dbClient = dbClient;
+ this.sourceLineIndex = sourceLineIndex;
+ }
+
+ @Override
+ public void define(WebService.NewController controller) {
+ WebService.NewAction action = controller.createAction("scm")
+ .setDescription("Get SCM information of source files. Require See Source Code permission on file's project<br/>" +
+ "Each element of the result array is composed of:" +
+ "<ol>" +
+ "<li>Line number</li>" +
+ "<li>Author of the commit</li>" +
+ "<li>Datetime of the commit (before 5.2 it was only the Date)</li>" +
+ "<li>Revision of the commit (added in 5.2)</li>" +
+ "</ol>")
+ .setSince("4.4")
+ .setResponseExample(Resources.getResource(getClass(), "example-scm.json"))
+ .setHandler(this);
+
+ action
+ .createParam("key")
+ .setRequired(true)
+ .setDescription("File key")
+ .setExampleValue("my_project:/src/foo/Bar.php");
+
+ action
+ .createParam("from")
+ .setDescription("First line to return. Starts at 1")
+ .setExampleValue("10")
+ .setDefaultValue("1");
+
+ action
+ .createParam("to")
+ .setDescription("Last line to return (inclusive)")
+ .setExampleValue("20");
+
+ action
+ .createParam("commits_by_line")
+ .setDescription("Group lines by SCM commit if value is false, else display commits for each line, even if two " +
+ "consecutive lines relate to the same commit.")
+ .setBooleanPossibleValues()
+ .setDefaultValue("false");
+ }
+
+ @Override
+ public void handle(Request request, Response response) {
+ String fileKey = request.mandatoryParam("key");
+ int from = Math.max(request.mandatoryParamAsInt("from"), 1);
+ int to = (Integer) ObjectUtils.defaultIfNull(request.paramAsInt("to"), Integer.MAX_VALUE);
+ boolean commitsByLine = request.mandatoryParamAsBoolean("commits_by_line");
+
+ DbSession session = dbClient.openSession(false);
+ try {
+ ComponentDto fileDto = dbClient.componentDao().getByKey(session, fileKey);
+ UserSession.get().checkProjectUuidPermission(UserRole.CODEVIEWER, fileDto.projectUuid());
+ List<SourceLineDoc> sourceLines = sourceLineIndex.getLines(fileDto.uuid(), from, to);
+ if (sourceLines.isEmpty()) {
+ throw new NotFoundException("File '" + fileKey + "' has no sources");
+ }
+
+ JsonWriter json = response.newJsonWriter().beginObject();
+ writeSource(sourceLines, commitsByLine, json);
+ json.endObject().close();
+ } finally {
+ session.close();
+ }
+ }
+
+ private static void writeSource(List<SourceLineDoc> lines, boolean showCommitsByLine, JsonWriter json) {
+ json.name("scm").beginArray();
+
+ SourceLineDoc previousLine = null;
+ boolean started = false;
+ for (SourceLineDoc lineDoc : lines) {
+ if (hasScm(lineDoc) && (!started || showCommitsByLine || !isSameCommit(previousLine, lineDoc))) {
+ json.beginArray()
+ .value(lineDoc.line())
+ .value(lineDoc.scmAuthor());
+ Date date = lineDoc.scmDate();
+ json.value(date == null ? null : DateUtils.formatDateTime(date));
+ json.value(lineDoc.scmRevision());
+ json.endArray();
+ started = true;
+ }
+ previousLine = lineDoc;
+ }
+ json.endArray();
+ }
+
+ private static boolean isSameCommit(SourceLineDoc previousLine, SourceLineDoc currentLine) {
+ return new EqualsBuilder()
+ .append(previousLine.scmAuthor(), currentLine.scmAuthor())
+ .append(previousLine.scmDate(), currentLine.scmDate())
+ .append(previousLine.scmRevision(), currentLine.scmRevision())
+ .isEquals();
+ }
+
+ private static boolean hasScm(SourceLineDoc line){
+ return !Strings.isNullOrEmpty(line.scmAuthor()) || line.scmDate() != null || !Strings.isNullOrEmpty(line.scmRevision());
+ }
+}
import com.google.common.io.Resources;
import org.apache.commons.lang.ObjectUtils;
import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
import java.util.List;
-public class ShowAction implements RequestHandler {
+public class ShowAction implements SourcesAction {
private final SourceService sourceService;
private final DbClient dbClient;
this.dbClient = dbClient;
}
- void define(WebService.NewController controller) {
+ @Override
+ public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction("show")
.setDescription("Get source code. Require See Source Code permission on file's project<br/>" +
"Each element of the result array is composed of:" +
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.source.ws;
+
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.WebService;
+
+public interface SourcesAction extends RequestHandler {
+
+ void define(WebService.NewController controller);
+
+}
public class SourcesWs implements WebService {
- private final ShowAction showAction;
- private final LinesAction linesAction;
- private final RawAction rawAction;
- private final HashAction hashAction;
- private final IndexAction indexAction;
+ private final SourcesAction[] actions;
- public SourcesWs(ShowAction showAction, RawAction rawAction, LinesAction linesAction, HashAction hashAction, IndexAction indexAction) {
- this.showAction = showAction;
- this.linesAction = linesAction;
- this.rawAction = rawAction;
- this.hashAction = hashAction;
- this.indexAction = indexAction;
+ public SourcesWs(SourcesAction... actions) {
+ this.actions = actions;
}
@Override
NewController controller = context.createController("api/sources")
.setSince("4.2")
.setDescription("Display sources information");
- showAction.define(controller);
- linesAction.define(controller);
- rawAction.define(controller);
- hashAction.define(controller);
- indexAction.define(controller);
+ for (SourcesAction action : actions) {
+ action.define(controller);
+ }
controller.done();
}
}
{
"scm": [
- [1, "julien", "2013-03-13"],
- [2, "julien", "2013-03-14"],
- [3, "simon", "2014-01-01"]
+ [1, "julien", "2013-03-13T12:34:56+0100", "a1e2b3e5d6f5"],
+ [2, "julien", "2013-03-14T13:17:22+0100", "b1e2b3e5d6f5"],
+ [3, "simon", "2014-01-01T15:35:36+0100", "c1e2b3e5d6f5"]
]
}
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
@RunWith(MockitoJUnitRunner.class)
@Category(DbTests.class)
DbClient dbClient = new DbClient(db.database(), db.myBatis(), new FileSourceDao(db.myBatis()), new ComponentDao());
- tester = new WsTester(
- new SourcesWs(
- mock(ShowAction.class),
- mock(RawAction.class),
- mock(LinesAction.class),
- new HashAction(dbClient),
- mock(IndexAction.class)
- )
- );
+ tester = new WsTester(new SourcesWs(new HashAction(dbClient)));
}
@After
import org.sonar.server.ws.WsTester;
import static com.google.common.collect.Lists.newArrayList;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public void setUp() throws Exception {
when(dbClient.componentDao()).thenReturn(componentDao);
when(dbClient.openSession(false)).thenReturn(session);
- tester = new WsTester(new SourcesWs(mock(ShowAction.class), mock(RawAction.class), mock(LinesAction.class),
- mock(HashAction.class), new IndexAction(dbClient, sourceService)));
+ tester = new WsTester(new SourcesWs(new IndexAction(dbClient, sourceService)));
}
@Test
import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Matchers.*;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
@Before
public void setUp() throws Exception {
- tester = new WsTester(
- new SourcesWs(
- mock(ShowAction.class),
- mock(RawAction.class),
- new LinesAction(sourceLineIndex, htmlSourceDecorator, componentService),
- mock(HashAction.class),
- mock(IndexAction.class)
- )
- );
+ tester = new WsTester(new SourcesWs(new LinesAction(sourceLineIndex, htmlSourceDecorator, componentService)));
when(htmlSourceDecorator.getDecoratedSourceAsHtml(anyString(), anyString(), anyString())).thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public void setUp() throws Exception {
when(dbClient.componentDao()).thenReturn(componentDao);
when(dbClient.openSession(false)).thenReturn(session);
- tester = new WsTester(new SourcesWs(mock(ShowAction.class), new RawAction(dbClient, sourceService), mock(LinesAction.class),
- mock(HashAction.class), mock(IndexAction.class)));
+ tester = new WsTester(new SourcesWs(new RawAction(dbClient, sourceService)));
}
@Test
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.source.ws;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.server.component.ComponentTesting;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.source.index.SourceLineDoc;
+import org.sonar.server.source.index.SourceLineIndex;
+import org.sonar.server.source.index.SourceLineIndexDefinition;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.ws.WsTester;
+
+import java.util.Date;
+
+public class ScmActionTest {
+
+ private static final String FILE_KEY = "FILE_KEY";
+ private static final String FILE_UUID = "FILE_A";
+ private static final String PROJECT_UUID = "PROJECT_A";
+
+ @ClassRule
+ public static DbTester dbTester = new DbTester();
+
+ @ClassRule
+ public static EsTester esTester = new EsTester().addDefinitions(new SourceLineIndexDefinition(new Settings()));
+
+ WsTester tester;
+
+ DbClient dbClient;
+
+ DbSession session;
+
+ @Before
+ public void setUp() throws Exception {
+ dbTester.truncateTables();
+ esTester.truncateIndices();
+ dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao());
+ session = dbClient.openSession(false);
+
+ tester = new WsTester(new SourcesWs(new ScmAction(dbClient, new SourceLineIndex(esTester.client()))));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ session.close();
+ }
+
+ @Test
+ public void show_scm() throws Exception {
+ initFile();
+ MockUserSession.set().addProjectUuidPermissions(UserRole.CODEVIEWER, PROJECT_UUID);
+
+ esTester.putDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE,
+ newSourceLine("julien", "123-456-789", DateUtils.parseDateTime("2015-03-30T12:34:56+0000"), 1)
+ );
+
+ WsTester.TestRequest request = tester.newGetRequest("api/sources", "scm").setParam("key", FILE_KEY);
+ request.execute().assertJson(getClass(), "show_scm.json");
+ }
+
+ @Test
+ public void show_scm_from_given_range_lines() throws Exception {
+ initFile();
+ MockUserSession.set().addProjectUuidPermissions(UserRole.CODEVIEWER, PROJECT_UUID);
+
+ esTester.putDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE,
+ newSourceLine("julien", "123-456-789", DateUtils.parseDateTime("2015-03-30T12:34:56+0000"), 1),
+ newSourceLine("julien", "123-456-789", DateUtils.parseDateTime("2015-03-30T12:34:56+0000"), 2),
+ newSourceLine("julien", "456-789-101", DateUtils.parseDateTime("2015-03-27T12:34:56+0000"), 3),
+ newSourceLine("simon", "789-101-112", DateUtils.parseDateTime("2015-03-31T12:34:56+0000"), 4)
+ );
+
+ WsTester.TestRequest request = tester.newGetRequest("api/sources", "scm").setParam("key", FILE_KEY).setParam("from", "2").setParam("to", "3");
+ request.execute().assertJson(getClass(), "show_scm_from_given_range_lines.json");
+ }
+
+ @Test
+ public void not_group_lines_by_commit() throws Exception {
+ initFile();
+ MockUserSession.set().addProjectUuidPermissions(UserRole.CODEVIEWER, PROJECT_UUID);
+
+ // lines 1 and 2 are the same commit, but not 3 (different date)
+ esTester.putDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE,
+ newSourceLine("julien", "123-456-789", DateUtils.parseDateTime("2015-03-30T12:34:56+0000"), 1),
+ newSourceLine("julien", "123-456-789", DateUtils.parseDateTime("2015-03-30T12:34:56+0000"), 2),
+ newSourceLine("julien", "456-789-101", DateUtils.parseDateTime("2015-03-27T12:34:56+0000"), 3),
+ newSourceLine("simon", "789-101-112", DateUtils.parseDateTime("2015-03-31T12:34:56+0000"), 4)
+ );
+
+ WsTester.TestRequest request = tester.newGetRequest("api/sources", "scm").setParam("key", FILE_KEY).setParam("commits_by_line", "true");
+ request.execute().assertJson(getClass(), "not_group_lines_by_commit.json");
+ }
+
+ @Test
+ public void group_lines_by_commit() throws Exception {
+ initFile();
+ MockUserSession.set().addProjectUuidPermissions(UserRole.CODEVIEWER, PROJECT_UUID);
+
+ // lines 1 and 2 are the same commit, but not 3 (different date)
+ esTester.putDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE,
+ newSourceLine("julien", "123-456-789", DateUtils.parseDateTime("2015-03-30T12:34:56+0000"), 1),
+ newSourceLine("julien", "123-456-789", DateUtils.parseDateTime("2015-03-30T12:34:56+0000"), 2),
+ newSourceLine("julien", "456-789-101", DateUtils.parseDateTime("2015-03-27T12:34:56+0000"), 3),
+ newSourceLine("simon", "789-101-112", DateUtils.parseDateTime("2015-03-31T12:34:56+0000"), 4)
+ );
+
+ WsTester.TestRequest request = tester.newGetRequest("api/sources", "scm").setParam("key", FILE_KEY).setParam("commits_by_line", "false");
+ request.execute().assertJson(getClass(), "group_lines_by_commit.json");
+ }
+
+ @Test
+ public void accept_negative_value_in_from_parameter() throws Exception {
+ initFile();
+ MockUserSession.set().addProjectUuidPermissions(UserRole.CODEVIEWER, PROJECT_UUID);
+
+ esTester.putDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE,
+ newSourceLine("julien", "123-456-789", DateUtils.parseDateTime("2015-03-30T12:34:56+0000"), 1),
+ newSourceLine("julien", "123-456-710", DateUtils.parseDateTime("2015-03-29T12:34:56+0000"), 2),
+ newSourceLine("julien", "456-789-101", DateUtils.parseDateTime("2015-03-27T12:34:56+0000"), 3),
+ newSourceLine("simon", "789-101-112", DateUtils.parseDateTime("2015-03-31T12:34:56+0000"), 4)
+ );
+
+ WsTester.TestRequest request = tester.newGetRequest("api/sources", "scm").setParam("key", FILE_KEY).setParam("from", "-2").setParam("to", "3");
+ request.execute().assertJson(getClass(), "accept_negative_value_in_from_parameter.json");
+ }
+
+ @Test
+ public void return_empty_value_when_no_scm() throws Exception {
+ initFile();
+ MockUserSession.set().addProjectUuidPermissions(UserRole.CODEVIEWER, PROJECT_UUID);
+
+ esTester.putDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE,
+ newSourceLine(null, null, null, 1)
+ );
+
+ WsTester.TestRequest request = tester.newGetRequest("api/sources", "scm").setParam("key", FILE_KEY);
+ request.execute().assertJson(getClass(), "return_empty_value_when_no_scm.json");
+ }
+
+ @Test(expected = ForbiddenException.class)
+ public void fail_without_code_viewer_permission() throws Exception {
+ initFile();
+ MockUserSession.set().addProjectUuidPermissions(UserRole.USER, PROJECT_UUID);
+
+ WsTester.TestRequest request = tester.newGetRequest("api/sources", "scm").setParam("key", FILE_KEY);
+ request.execute();
+ }
+
+ private void initFile() {
+ ComponentDto project = ComponentTesting.newProjectDto(PROJECT_UUID);
+ dbClient.componentDao().insert(session, project, ComponentTesting.newFileDto(project, FILE_UUID).setKey(FILE_KEY));
+ session.commit();
+ }
+
+ private SourceLineDoc newSourceLine(String author, String revision, Date date, int line) {
+ return new SourceLineDoc()
+ .setScmAuthor(author)
+ .setScmRevision(revision)
+ .setScmDate(date)
+ .setLine(line)
+ .setProjectUuid(PROJECT_UUID)
+ .setFileUuid(FILE_UUID);
+ }
+}
import static com.google.common.collect.Lists.newArrayList;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class ShowActionTest {
public void setUp() throws Exception {
when(dbClient.componentDao()).thenReturn(componentDao);
when(dbClient.openSession(false)).thenReturn(session);
- tester = new WsTester(new SourcesWs(new ShowAction(sourceService, dbClient), mock(RawAction.class),
- mock(LinesAction.class),
- mock(HashAction.class),
- mock(IndexAction.class)));
+ tester = new WsTester(new SourcesWs(new ShowAction(sourceService, dbClient)));
}
@Test
--- /dev/null
+{
+ "scm": [
+ [1, "julien", "2015-03-30T12:34:56+0000", "123-456-789"],
+ [2, "julien", "2015-03-29T12:34:56+0000", "123-456-710"],
+ [3, "julien", "2015-03-27T12:34:56+0000", "456-789-101"]
+ ]
+}
--- /dev/null
+{
+ "scm": [
+ [1, "julien", "2015-03-30T12:34:56+0000", "123-456-789"],
+ [3, "julien", "2015-03-27T12:34:56+0000", "456-789-101"],
+ [4, "simon", "2015-03-31T12:34:56+0000", "789-101-112"]
+ ]
+}
--- /dev/null
+{
+ "scm": [
+ [1, "julien", "2015-03-30T12:34:56+0000", "123-456-789"],
+ [2, "julien", "2015-03-30T12:34:56+0000", "123-456-789"],
+ [3, "julien", "2015-03-27T12:34:56+0000", "456-789-101"],
+ [4, "simon", "2015-03-31T12:34:56+0000", "789-101-112"]
+ ]
+}
--- /dev/null
+{
+ "scm": []
+}
--- /dev/null
+{
+ "scm": [
+ [1, "julien", "2015-03-30T12:34:56+0000", "123-456-789"]
+ ]
+}
--- /dev/null
+{
+ "scm": [
+ [2, "julien", "2015-03-30T12:34:56+0000", "123-456-789"],
+ [3, "julien", "2015-03-27T12:34:56+0000", "456-789-101"]
+ ]
+}