From: Simon Brandhof Date: Tue, 29 Apr 2014 09:39:55 +0000 (+0200) Subject: Improve /api/sources/show X-Git-Tag: 4.4-RC1~1355 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=28ad609e158204a4645092f3699fad9c1479e3d9;p=sonarqube.git Improve /api/sources/show --- diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index 65c0a5c1aa5..472498ba7fb 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -116,7 +116,7 @@ import org.sonar.server.source.CodeColorizers; import org.sonar.server.source.DeprecatedSourceDecorator; import org.sonar.server.source.HtmlSourceDecorator; import org.sonar.server.source.SourceService; -import org.sonar.server.source.ws.SourcesShowWsHandler; +import org.sonar.server.source.ws.ShowAction; import org.sonar.server.source.ws.SourcesWs; import org.sonar.server.startup.*; import org.sonar.server.text.MacroInterpreter; @@ -382,7 +382,7 @@ class ServerComponents { pico.addSingleton(DeprecatedSourceDecorator.class); pico.addSingleton(SourceService.class); pico.addSingleton(SourcesWs.class); - pico.addSingleton(SourcesShowWsHandler.class); + pico.addSingleton(ShowAction.class); // text pico.addSingleton(MacroInterpreter.class); diff --git a/sonar-server/src/main/java/org/sonar/server/source/SourceService.java b/sonar-server/src/main/java/org/sonar/server/source/SourceService.java index 1db10c1b101..07ac61c839a 100644 --- a/sonar-server/src/main/java/org/sonar/server/source/SourceService.java +++ b/sonar-server/src/main/java/org/sonar/server/source/SourceService.java @@ -32,7 +32,6 @@ import org.sonar.server.user.UserSession; import javax.annotation.CheckForNull; import javax.annotation.Nullable; - import java.util.List; public class SourceService implements ServerComponent { @@ -54,38 +53,37 @@ public class SourceService implements ServerComponent { this.measureDataDao = measureDataDao; } - public List getSourcesForComponent(String componentKey) { - return getSourcesByComponent(componentKey, null, null); + public List getLinesAsHtml(String fileKey) { + return getLinesAsHtml(fileKey, null, null); } - public List getSourcesByComponent(String componentKey, @Nullable Integer from, @Nullable Integer to) { - ResourceDto project = resourceDao.getRootProjectByComponentKey(componentKey); + public List getLinesAsHtml(String fileKey, @Nullable Integer from, @Nullable Integer to) { + ResourceDto project = resourceDao.getRootProjectByComponentKey(fileKey); if (project == null) { - throw new NotFoundException("This component does not exists."); + throw new NotFoundException("File does not exist"); } UserSession.get().checkProjectPermission(UserRole.CODEVIEWER, project.getKey()); - List decoratedSource = sourceDecorator.getDecoratedSourceAsHtml(componentKey, from, to); + List decoratedSource = sourceDecorator.getDecoratedSourceAsHtml(fileKey, from, to); if (!decoratedSource.isEmpty()) { return decoratedSource; - } else { - return deprecatedSourceDecorator.getSourceAsHtml(componentKey, from, to); } + return deprecatedSourceDecorator.getSourceAsHtml(fileKey, from, to); } @CheckForNull - public String getScmAuthorData(String componentKey) { - return findDataFromComponent(componentKey, CoreMetrics.SCM_AUTHORS_BY_LINE_KEY); + public String getScmAuthorData(String fileKey) { + return findDataFromComponent(fileKey, CoreMetrics.SCM_AUTHORS_BY_LINE_KEY); } @CheckForNull - public String getScmDateData(String componentKey) { - return findDataFromComponent(componentKey, CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY); + public String getScmDateData(String fileKey) { + return findDataFromComponent(fileKey, CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE_KEY); } @CheckForNull - private String findDataFromComponent(String componentKey, String metricKey) { - MeasureDataDto data = measureDataDao.findByComponentKeyAndMetricKey(componentKey, metricKey); + private String findDataFromComponent(String fileKey, String metricKey) { + MeasureDataDto data = measureDataDao.findByComponentKeyAndMetricKey(fileKey, metricKey); if (data != null) { return data.getText(); } diff --git a/sonar-server/src/main/java/org/sonar/server/source/ws/ShowAction.java b/sonar-server/src/main/java/org/sonar/server/source/ws/ShowAction.java new file mode 100644 index 00000000000..9c919ed5afa --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/source/ws/ShowAction.java @@ -0,0 +1,156 @@ +/* + * 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.Splitter; +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 org.sonar.api.utils.text.JsonWriter; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.source.SourceService; + +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; + +public class ShowAction implements RequestHandler { + + private final SourceService sourceService; + + public ShowAction(SourceService sourceService) { + this.sourceService = sourceService; + } + + void define(WebService.NewController controller) { + WebService.NewAction action = controller.createAction("show") + .setDescription("Get source code. Parameter 'output' with value 'raw' is missing before being marked as a public WS.") + .setSince("4.2") + .setInternal(true) + .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("scm") + .setDescription("Enable loading of SCM information per line") + .setPossibleValues("true", "false") + .setDefaultValue("false"); + } + + @Override + public void handle(Request request, Response response) { + String fileKey = request.mandatoryParam("key"); + int from = Math.max(request.paramAsInt("from", 1), 1); + + Integer toParam = request.paramAsInt("to"); + + List sourceHtml = sourceService.getLinesAsHtml(fileKey, from, toParam); + if (sourceHtml.isEmpty()) { + throw new NotFoundException("File '" + fileKey + "' has no sources"); + } + + int to = toParam != null ? toParam : sourceHtml.size() + from; + JsonWriter json = response.newJsonWriter().beginObject(); + writeSource(sourceHtml, from, json); + + if (request.paramAsBoolean("scm", false)) { + String scmAuthorData = sourceService.getScmAuthorData(fileKey); + String scmDataData = sourceService.getScmDateData(fileKey); + writeScm(scmAuthorData, scmDataData, from, to, json); + } + json.endObject().close(); + } + + private void writeSource(List lines, int from, JsonWriter json) { + json.name("source").beginObject(); + for (int i = 0; i < lines.size(); i++) { + String line = lines.get(i); + json.prop(Integer.toString(i + from), line); + } + json.endObject(); + } + + private void writeScm(@Nullable String authorData, @Nullable String scmDateData, int from, int to, JsonWriter json) { + if (authorData != null) { + json.name("scm").beginObject(); + List authors = splitLine(authorData); + List dates = splitLine(scmDateData); + + String previousAuthor = null; + String previousDate = null; + boolean scmDataAdded = false; + for (int i = 0; i < authors.size(); i++) { + String[] authorWithLine = splitColumn(authors.get(i)); + Integer line = Integer.parseInt(authorWithLine[0]); + String author = authorWithLine[1]; + + String[] dateWithLine = splitColumn(dates.get(i)); + String date = dateWithLine[1]; + String formattedDate = DateUtils.formatDate(DateUtils.parseDateTime(date)); + if (line >= from && line <= to && (!isSameCommit(date, previousDate, author, previousAuthor) || !scmDataAdded)) { + json.name(Integer.toString(line)).beginArray(); + json.value(author); + json.value(formattedDate); + json.endArray(); + scmDataAdded = true; + } + previousAuthor = author; + previousDate = date; + } + json.endObject(); + } + } + + private boolean isSameCommit(String date, String previousDate, String author, String previousAuthor) { + return author.equals(previousAuthor) && date.equals(previousDate); + } + + private List splitLine(@Nullable String line) { + if (line == null) { + return Collections.emptyList(); + } + return newArrayList(Splitter.on(";").omitEmptyStrings().split(line)); + } + + private String[] splitColumn(String column) { + return column.split("="); + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/source/ws/SourcesShowWsHandler.java b/sonar-server/src/main/java/org/sonar/server/source/ws/SourcesShowWsHandler.java deleted file mode 100644 index 27d13cc58bc..00000000000 --- a/sonar-server/src/main/java/org/sonar/server/source/ws/SourcesShowWsHandler.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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.Splitter; -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.utils.DateUtils; -import org.sonar.api.utils.text.JsonWriter; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.source.SourceService; - -import java.util.List; - -import static com.google.common.collect.Lists.newArrayList; - -public class SourcesShowWsHandler implements RequestHandler { - - private final SourceService sourceService; - - public SourcesShowWsHandler(SourceService sourceService) { - this.sourceService = sourceService; - } - - @Override - public void handle(Request request, Response response) { - String componentKey = request.mandatoryParam("key"); - Integer fromParam = request.paramAsInt("from"); - Integer toParam = request.paramAsInt("to"); - int from = (fromParam != null && fromParam > 0) ? fromParam : 1; - List sourceHtml = sourceService.getSourcesByComponent(componentKey, from, toParam); - if (sourceHtml.isEmpty()) { - throw new NotFoundException("Component : " + componentKey + " has no source."); - } - - String scmAuthorData = sourceService.getScmAuthorData(componentKey); - String scmDataData = sourceService.getScmDateData(componentKey); - - int to = toParam != null ? toParam : sourceHtml.size() + from; - JsonWriter json = response.newJsonWriter(); - json.beginObject(); - writeSource(sourceHtml, from, json); - writeScm(scmAuthorData, scmDataData, from, to, json); - json.endObject().close(); - } - - private void writeSource(List source, int from, JsonWriter json) { - json.name("source").beginObject(); - for (int i = 0; i < source.size(); i++) { - String line = source.get(i); - json.prop(Integer.toString(i + from), line); - } - json.endObject(); - } - - private void writeScm(String authorData, String scmDateData, int from, int to, JsonWriter json) { - if (authorData != null) { - json.name("scm").beginObject(); - List authors = splitLine(authorData); - List dates = splitLine(scmDateData); - - String previousAuthor = null; - String previousDate = null; - boolean scmDataAdded = false; - for (int i = 0; i < authors.size(); i++) { - String[] authorWithLine = splitColumn(authors.get(i)); - Integer line = Integer.parseInt(authorWithLine[0]); - String author = authorWithLine[1]; - - String[] dateWithLine = splitColumn(dates.get(i)); - String date = dateWithLine[1]; - String formattedDate = DateUtils.formatDate(DateUtils.parseDateTime(date)); - if (line >= from && line <= to && (!isSameCommit(date, previousDate, author, previousAuthor) || !scmDataAdded)) { - json.name(Integer.toString(line)).beginArray(); - json.value(author); - json.value(formattedDate); - json.endArray(); - scmDataAdded = true; - } - previousAuthor = author; - previousDate = date; - } - json.endObject(); - } - } - - private boolean isSameCommit(String date, String previousDate, String author, String previousAuthor) { - return author.equals(previousAuthor) && date.equals(previousDate); - } - - private List splitLine(String line) { - return newArrayList(Splitter.on(";").omitEmptyStrings().split(line)); - } - - private String[] splitColumn(String column) { - return column.split("="); - } - -} diff --git a/sonar-server/src/main/java/org/sonar/server/source/ws/SourcesWs.java b/sonar-server/src/main/java/org/sonar/server/source/ws/SourcesWs.java index 0530f6f588c..c1bc2c2cea5 100644 --- a/sonar-server/src/main/java/org/sonar/server/source/ws/SourcesWs.java +++ b/sonar-server/src/main/java/org/sonar/server/source/ws/SourcesWs.java @@ -24,23 +24,16 @@ import org.sonar.api.server.ws.WebService; public class SourcesWs implements WebService { - private final SourcesShowWsHandler showHandler; + private final ShowAction showAction; - public SourcesWs(SourcesShowWsHandler showHandler) { - this.showHandler = showHandler; + public SourcesWs(ShowAction showAction) { + this.showAction = showAction; } @Override public void define(Context context) { NewController controller = context.createController("api/sources"); - - controller.createAction("show") - .setDescription("Show source of a component") - .setSince("4.2") - .setInternal(true) - .setHandler(showHandler) - .createParam("key", "Component key"); - + showAction.define(controller); controller.done(); } } diff --git a/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java b/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java index 7dea0debe40..e21d3e43990 100644 --- a/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java +++ b/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java @@ -62,26 +62,26 @@ public class SourceServiceTest { } @Test - public void get_sources_by_component() throws Exception { + public void get_lines() throws Exception { String projectKey = "org.sonar.sample"; String componentKey = "org.sonar.sample:Sample"; MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, projectKey); when(resourceDao.getRootProjectByComponentKey(componentKey)).thenReturn(new ResourceDto().setKey(projectKey)); - service.getSourcesForComponent(componentKey); + service.getLinesAsHtml(componentKey); verify(sourceDecorator).getDecoratedSourceAsHtml(componentKey, null, null); } @Test - public void fail_to_get_sources_by_component_if_component_not_found() throws Exception { + public void fail_to_get_lines_if_file_not_found() throws Exception { String projectKey = "org.sonar.sample"; String componentKey = "org.sonar.sample:Sample"; MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, projectKey); when(resourceDao.getRootProjectByComponentKey(componentKey)).thenReturn(null); try { - service.getSourcesForComponent(componentKey); + service.getLinesAsHtml(componentKey); fail(); } catch (Exception e) { assertThat(e).isInstanceOf(NotFoundException.class); @@ -91,26 +91,26 @@ public class SourceServiceTest { } @Test - public void get_sources_by_component_with_only_given_lines() throws Exception { + public void get_block_of_lines() throws Exception { String projectKey = "org.sonar.sample"; String componentKey = "org.sonar.sample:Sample"; MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, projectKey); when(resourceDao.getRootProjectByComponentKey(componentKey)).thenReturn(new ResourceDto().setKey(projectKey)); - service.getSourcesByComponent(componentKey, 1, 2); + service.getLinesAsHtml(componentKey, 1, 2); verify(sourceDecorator).getDecoratedSourceAsHtml(componentKey, 1, 2); } @Test - public void get_sources_by_component_from_deprecated_source_decorator_when_no_data_from_new_decorator() throws Exception { + public void get_lines_from_deprecated_source_decorator_when_no_data_from_new_decorator() throws Exception { String projectKey = "org.sonar.sample"; String componentKey = "org.sonar.sample:Sample"; MockUserSession.set().addProjectPermissions(UserRole.CODEVIEWER, projectKey); when(resourceDao.getRootProjectByComponentKey(componentKey)).thenReturn(new ResourceDto().setKey(projectKey)); when(sourceDecorator.getDecoratedSourceAsHtml(eq(componentKey), anyInt(), anyInt())).thenReturn(Collections.emptyList()); - service.getSourcesByComponent(componentKey, 1, 2); + service.getLinesAsHtml(componentKey, 1, 2); verify(deprecatedSourceDecorator).getSourceAsHtml(componentKey, 1, 2); } diff --git a/sonar-server/src/test/java/org/sonar/server/source/ws/ShowActionTest.java b/sonar-server/src/test/java/org/sonar/server/source/ws/ShowActionTest.java new file mode 100644 index 00000000000..d723c113d07 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/source/ws/ShowActionTest.java @@ -0,0 +1,183 @@ +/* + * 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.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.server.ws.WsTester; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.source.SourceService; + +import java.util.Collections; + +import static com.google.common.collect.Lists.newArrayList; +import static org.fest.assertions.Assertions.assertThat; +import static org.fest.assertions.Fail.fail; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class ShowActionTest { + + @Mock + SourceService sourceService; + + WsTester tester; + + @Before + public void setUp() throws Exception { + tester = new WsTester(new SourcesWs(new ShowAction(sourceService))); + } + + @Test + public void show_source() throws Exception { + String componentKey = "src/Foo.java"; + when(sourceService.getLinesAsHtml(eq(componentKey), anyInt(), anyInt())).thenReturn(newArrayList( + "/*", + " * Header", + " */", + "", + "public class HelloWorld {", + "}" + )); + + WsTester.TestRequest request = tester.newRequest("show").setParam("key", componentKey); + request.execute().assertJson(getClass(), "show_source.json"); + } + + @Test + public void fail_to_show_source_if_no_source_found() throws Exception { + String componentKey = "src/Foo.java"; + when(sourceService.getLinesAsHtml(anyString(), anyInt(), anyInt())).thenReturn(Collections.emptyList()); + + try { + WsTester.TestRequest request = tester.newRequest("show").setParam("key", componentKey); + request.execute(); + fail(); + } catch (Exception e) { + assertThat(e).isInstanceOf(NotFoundException.class); + } + } + + @Test + public void show_source_with_from_and_to_params() throws Exception { + String componentKey = "src/Foo.java"; + when(sourceService.getLinesAsHtml(componentKey, 3, 5)).thenReturn(newArrayList( + " */", + "", + "public class HelloWorld {" + )); + WsTester.TestRequest request = tester.newRequest("show").setParam("key", componentKey).setParam("from", "3").setParam("to", "5"); + request.execute().assertJson(getClass(), "show_source_with_params_from_and_to.json"); + } + + @Test + public void show_source_accept_from_less_than_one() throws Exception { + String fileKey = "src/Foo.java"; + when(sourceService.getLinesAsHtml(fileKey, 1, 5)).thenReturn(newArrayList( + " */", + "", + "public class HelloWorld {" + )); + WsTester.TestRequest request = tester.newRequest("show").setParam("key", fileKey).setParam("from", "0").setParam("to", "5"); + request.execute(); + verify(sourceService).getLinesAsHtml(fileKey, 1, 5); + } + + @Test + public void show_source_with_scm() throws Exception { + String fileKey = "src/Foo.java"; + when(sourceService.getLinesAsHtml(eq(fileKey), anyInt(), anyInt())).thenReturn(newArrayList( + "public class HelloWorld {}" + )); + + when(sourceService.getScmAuthorData(fileKey)).thenReturn("1=julien;"); + when(sourceService.getScmDateData(fileKey)).thenReturn("1=2013-03-13T16:22:31+0100;"); + + WsTester.TestRequest request = tester.newRequest("show").setParam("key", fileKey).setParam("scm", "true"); + request.execute().assertJson(getClass(), "show_source_with_scm.json"); + } + + @Test + public void show_source_with_scm_with_from_and_to_params() throws Exception { + String fileKey = "src/Foo.java"; + when(sourceService.getLinesAsHtml(fileKey, 3, 5)).thenReturn(newArrayList( + " */", + "", + "public class HelloWorld {" + )); + when(sourceService.getScmAuthorData(fileKey)) + .thenReturn("1=julien;2=simon;3=julien;4=simon;5=jean;6=julien"); + when(sourceService.getScmDateData(fileKey)) + .thenReturn("1=2013-03-13T16:22:31+0100;2=2013-03-14T16:22:31+0100;3=2013-03-13T16:22:31+0100;4=2013-03-14T16:22:31+0100;5=2013-03-15T16:22:31+0100;6=2013-03-13T16:22:31+0100;"); + + WsTester.TestRequest request = tester.newRequest("show") + .setParam("key", fileKey) + .setParam("from", "3") + .setParam("to", "5") + .setParam("scm", "true"); + request.execute().assertJson(getClass(), "show_source_with_scm_with_from_and_to_params.json"); + } + + @Test + public void show_source_with_scm_without_repeating_same_lines() throws Exception { + String fileKey = "src/Foo.java"; + when(sourceService.getLinesAsHtml(eq(fileKey), anyInt(), anyInt())).thenReturn(newArrayList( + " */", + "", + "public class HelloWorld {" + )); + when(sourceService.getScmAuthorData(fileKey)) + .thenReturn("1=julien;2=julien;3=simon"); + when(sourceService.getScmDateData(fileKey)) + .thenReturn("1=2013-03-13T16:22:31+0100;2=2013-03-13T16:22:31+0100;3=2013-03-14T16:22:31+0100;"); + WsTester.TestRequest request = tester.newRequest("show") + .setParam("key", fileKey) + .setParam("scm", "true"); + request.execute().assertJson(getClass(), "show_source_with_scm_without_repeating_same_lines.json"); + } + + @Test + public void show_source_with_scm_when_from_is_after_same_commit() throws Exception { + String fileKey = "src/Foo.java"; + when(sourceService.getLinesAsHtml(fileKey, 3, 5)).thenReturn(newArrayList( + " */", + "", + "public class HelloWorld {" + )); + + // Since line 2, it's the same commit + when(sourceService.getScmAuthorData(fileKey)) + .thenReturn("1=julien;2=simon;3=simon;4=simon;5=simon;6=simon"); + when(sourceService.getScmDateData(fileKey)) + .thenReturn("1=2013-03-13T16:22:31+0100;2=2013-03-14T16:22:31+0100;3=2013-03-14T16:22:31+0100;4=2013-03-14T16:22:31+0100;5=2013-03-14T16:22:31+0100;6=2013-03-14T16:22:31+0100;"); + WsTester.TestRequest request = tester.newRequest("show") + .setParam("key", fileKey) + .setParam("from", "3") + .setParam("to", "5") + .setParam("scm", "true"); + request.execute().assertJson(getClass(), "show_source_with_scm_without_repeating_same_lines_and_with_from_param_after_repetition.json"); + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesShowWsHandlerTest.java b/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesShowWsHandlerTest.java deleted file mode 100644 index 537e1403974..00000000000 --- a/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesShowWsHandlerTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.sonar.server.ws.WsTester; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.source.SourceService; - -import java.util.Collections; - -import static com.google.common.collect.Lists.newArrayList; -import static org.fest.assertions.Assertions.assertThat; -import static org.fest.assertions.Fail.fail; -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class SourcesShowWsHandlerTest { - - @Mock - SourceService sourceService; - - WsTester tester; - - @Before - public void setUp() throws Exception { - tester = new WsTester(new SourcesWs(new SourcesShowWsHandler(sourceService))); - } - - @Test - public void show_source() throws Exception { - String componentKey = "org.apache.struts:struts:Dispatcher"; - when(sourceService.getSourcesByComponent(eq(componentKey), anyInt(), anyInt())).thenReturn(newArrayList( - "/*", - " * Header", - " */", - "", - "public class HelloWorld {", - "}" - )); - - WsTester.TestRequest request = tester.newRequest("show").setParam("key", componentKey); - request.execute().assertJson(getClass(), "show_source.json"); - } - - @Test - public void fail_to_show_source_if_no_source_found() throws Exception { - String componentKey = "org.apache.struts:struts:Dispatcher"; - when(sourceService.getSourcesByComponent(anyString(), anyInt(), anyInt())).thenReturn(Collections.emptyList()); - - try { - WsTester.TestRequest request = tester.newRequest("show").setParam("key", componentKey); - request.execute(); - fail(); - } catch (Exception e) { - assertThat(e).isInstanceOf(NotFoundException.class); - } - } - - @Test - public void show_source_with_from_and_to_params() throws Exception { - String componentKey = "org.apache.struts:struts:Dispatcher"; - when(sourceService.getSourcesByComponent(componentKey, 3, 5)).thenReturn(newArrayList( - " */", - "", - "public class HelloWorld {" - )); - WsTester.TestRequest request = tester.newRequest("show").setParam("key", componentKey).setParam("from", "3").setParam("to", "5"); - request.execute().assertJson(getClass(), "show_source_with_params_from_and_to.json"); - } - - @Test - public void show_source_always_should_not_begin_with_from_0() throws Exception { - String componentKey = "org.apache.struts:struts:Dispatcher"; - when(sourceService.getSourcesByComponent(componentKey, 1, 5)).thenReturn(newArrayList( - " */", - "", - "public class HelloWorld {" - )); - WsTester.TestRequest request = tester.newRequest("show").setParam("key", componentKey).setParam("from", "0").setParam("to", "5"); - request.execute(); - verify(sourceService).getSourcesByComponent(componentKey, 1, 5); - } - - @Test - public void show_source_with_scm() throws Exception { - String componentKey = "org.apache.struts:struts:Dispatcher"; - when(sourceService.getSourcesByComponent(eq(componentKey), anyInt(), anyInt())).thenReturn(newArrayList( - "public class HelloWorld {}" - )); - - when(sourceService.getScmAuthorData(componentKey)).thenReturn("1=julien;"); - when(sourceService.getScmDateData(componentKey)).thenReturn("1=2013-03-13T16:22:31+0100;"); - - WsTester.TestRequest request = tester.newRequest("show").setParam("key", componentKey); - request.execute().assertJson(getClass(), "show_source_with_scm.json"); - } - - @Test - public void show_source_with_scm_with_from_and_to_params() throws Exception { - String componentKey = "org.apache.struts:struts:Dispatcher"; - when(sourceService.getSourcesByComponent(componentKey, 3, 5)).thenReturn(newArrayList( - " */", - "", - "public class HelloWorld {" - )); - when(sourceService.getScmAuthorData(componentKey)) - .thenReturn("1=julien;2=simon;3=julien;4=simon;5=jean;6=julien"); - when(sourceService.getScmDateData(componentKey)) - .thenReturn("1=2013-03-13T16:22:31+0100;2=2013-03-14T16:22:31+0100;3=2013-03-13T16:22:31+0100;4=2013-03-14T16:22:31+0100;5=2013-03-15T16:22:31+0100;6=2013-03-13T16:22:31+0100;"); - - WsTester.TestRequest request = tester.newRequest("show").setParam("key", componentKey).setParam("from", "3").setParam("to", "5"); - request.execute().assertJson(getClass(), "show_source_with_scm_with_from_and_to_params.json"); - } - - @Test - public void show_source_with_scm_without_repeating_same_lines() throws Exception { - String componentKey = "org.apache.struts:struts:Dispatcher"; - when(sourceService.getSourcesByComponent(eq(componentKey), anyInt(), anyInt())).thenReturn(newArrayList( - " */", - "", - "public class HelloWorld {" - )); - when(sourceService.getScmAuthorData(componentKey)) - .thenReturn("1=julien;2=julien;3=simon"); - when(sourceService.getScmDateData(componentKey)) - .thenReturn("1=2013-03-13T16:22:31+0100;2=2013-03-13T16:22:31+0100;3=2013-03-14T16:22:31+0100;"); - WsTester.TestRequest request = tester.newRequest("show").setParam("key", componentKey); - request.execute().assertJson(getClass(), "show_source_with_scm_without_repeating_same_lines.json"); - } - - @Test - public void show_source_with_scm_when_from_is_after_same_commit() throws Exception { - String componentKey = "org.apache.struts:struts:Dispatcher"; - when(sourceService.getSourcesByComponent(componentKey, 3, 5)).thenReturn(newArrayList( - " */", - "", - "public class HelloWorld {" - )); - - // Since line 2, it's the same commit - when(sourceService.getScmAuthorData(componentKey)) - .thenReturn("1=julien;2=simon;3=simon;4=simon;5=simon;6=simon"); - when(sourceService.getScmDateData(componentKey)) - .thenReturn("1=2013-03-13T16:22:31+0100;2=2013-03-14T16:22:31+0100;3=2013-03-14T16:22:31+0100;4=2013-03-14T16:22:31+0100;5=2013-03-14T16:22:31+0100;6=2013-03-14T16:22:31+0100;"); - WsTester.TestRequest request = tester.newRequest("show").setParam("key", componentKey).setParam("from", "3").setParam("to", "5"); - request.execute().assertJson(getClass(), "show_source_with_scm_without_repeating_same_lines_and_with_from_param_after_repetition.json"); - } -} diff --git a/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java b/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java index b24da55479b..f7a37a78a46 100644 --- a/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java @@ -22,6 +22,7 @@ package org.sonar.server.source.ws; import org.junit.Test; import org.sonar.api.server.ws.WebService; +import org.sonar.server.source.SourceService; import org.sonar.server.ws.WsTester; import static org.fest.assertions.Assertions.assertThat; @@ -29,8 +30,8 @@ import static org.mockito.Mockito.mock; public class SourcesWsTest { - SourcesShowWsHandler showHandler = mock(SourcesShowWsHandler.class); - WsTester tester = new WsTester(new SourcesWs(showHandler)); + ShowAction showAction = new ShowAction(mock(SourceService.class)); + WsTester tester = new WsTester(new SourcesWs(showAction)); @Test public void define_ws() throws Exception { @@ -43,7 +44,6 @@ public class SourcesWsTest { assertThat(show.handler()).isNotNull(); assertThat(show.since()).isEqualTo("4.2"); assertThat(show.isPost()).isFalse(); - assertThat(show.isInternal()).isTrue(); - assertThat(show.handler()).isSameAs(showHandler); + assertThat(show.handler()).isSameAs(showAction); } } diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source.json new file mode 100644 index 00000000000..f31010c347c --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source.json @@ -0,0 +1,18 @@ +{ + "source": { + "1": "/*", + "2": " * Header", + "3": " */", + "4": "", + "5": "public class HelloWorld {", + "6": "}" + } +} + + + + + + + + diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_params_from_and_to.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_params_from_and_to.json new file mode 100644 index 00000000000..f345655217c --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_params_from_and_to.json @@ -0,0 +1,15 @@ +{ + "source": { + "3": " */", + "4": "", + "5": "public class HelloWorld {" + } +} + + + + + + + + diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm.json new file mode 100644 index 00000000000..6e753092de6 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm.json @@ -0,0 +1,16 @@ +{ + "source": { + "1": "public class HelloWorld {}" + }, + "scm": { + "1": ["julien", "2013-03-13"] + } +} + + + + + + + + diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm_with_from_and_to_params.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm_with_from_and_to_params.json new file mode 100644 index 00000000000..a4540521bdc --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm_with_from_and_to_params.json @@ -0,0 +1,20 @@ +{ + "source": { + "3": " */", + "4": "", + "5": "public class HelloWorld {" + }, + "scm": { + "3": ["julien", "2013-03-13"], + "4": ["simon", "2013-03-14"], + "5": ["jean", "2013-03-15"] + } +} + + + + + + + + diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm_without_repeating_same_lines.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm_without_repeating_same_lines.json new file mode 100644 index 00000000000..ae74340195c --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm_without_repeating_same_lines.json @@ -0,0 +1,19 @@ +{ + "source": { + "1": " */", + "2": "", + "3": "public class HelloWorld {" + }, + "scm": { + "1": ["julien", "2013-03-13"], + "3": ["simon", "2013-03-14"] + } +} + + + + + + + + diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm_without_repeating_same_lines_and_with_from_param_after_repetition.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm_without_repeating_same_lines_and_with_from_param_after_repetition.json new file mode 100644 index 00000000000..1f852be106e --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm_without_repeating_same_lines_and_with_from_param_after_repetition.json @@ -0,0 +1,18 @@ +{ + "source": { + "3": " */", + "4": "", + "5": "public class HelloWorld {" + }, + "scm": { + "3": ["simon", "2013-03-14"] + } +} + + + + + + + + diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source.json deleted file mode 100644 index f31010c347c..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "source": { - "1": "/*", - "2": " * Header", - "3": " */", - "4": "", - "5": "public class HelloWorld {", - "6": "}" - } -} - - - - - - - - diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_params_from_and_to.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_params_from_and_to.json deleted file mode 100644 index f345655217c..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_params_from_and_to.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "source": { - "3": " */", - "4": "", - "5": "public class HelloWorld {" - } -} - - - - - - - - diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm.json deleted file mode 100644 index 6e753092de6..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "source": { - "1": "public class HelloWorld {}" - }, - "scm": { - "1": ["julien", "2013-03-13"] - } -} - - - - - - - - diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm_with_from_and_to_params.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm_with_from_and_to_params.json deleted file mode 100644 index a4540521bdc..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm_with_from_and_to_params.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "source": { - "3": " */", - "4": "", - "5": "public class HelloWorld {" - }, - "scm": { - "3": ["julien", "2013-03-13"], - "4": ["simon", "2013-03-14"], - "5": ["jean", "2013-03-15"] - } -} - - - - - - - - diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm_without_repeating_same_lines.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm_without_repeating_same_lines.json deleted file mode 100644 index ae74340195c..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm_without_repeating_same_lines.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "source": { - "1": " */", - "2": "", - "3": "public class HelloWorld {" - }, - "scm": { - "1": ["julien", "2013-03-13"], - "3": ["simon", "2013-03-14"] - } -} - - - - - - - - diff --git a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm_without_repeating_same_lines_and_with_from_param_after_repetition.json b/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm_without_repeating_same_lines_and_with_from_param_after_repetition.json deleted file mode 100644 index 1f852be106e..00000000000 --- a/sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm_without_repeating_same_lines_and_with_from_param_after_repetition.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "source": { - "3": " */", - "4": "", - "5": "public class HelloWorld {" - }, - "scm": { - "3": ["simon", "2013-03-14"] - } -} - - - - - - - -