]> source.dussan.org Git - sonarqube.git/commitdiff
Improve /api/sources/show
authorSimon Brandhof <simon.brandhof@gmail.com>
Tue, 29 Apr 2014 09:39:55 +0000 (11:39 +0200)
committerSimon Brandhof <simon.brandhof@gmail.com>
Tue, 29 Apr 2014 09:39:55 +0000 (11:39 +0200)
21 files changed:
sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
sonar-server/src/main/java/org/sonar/server/source/SourceService.java
sonar-server/src/main/java/org/sonar/server/source/ws/ShowAction.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/source/ws/SourcesShowWsHandler.java [deleted file]
sonar-server/src/main/java/org/sonar/server/source/ws/SourcesWs.java
sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java
sonar-server/src/test/java/org/sonar/server/source/ws/ShowActionTest.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/source/ws/SourcesShowWsHandlerTest.java [deleted file]
sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java
sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source.json [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_params_from_and_to.json [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm.json [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm_with_from_and_to_params.json [new file with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/source/ws/ShowActionTest/show_source_with_scm_without_repeating_same_lines.json [new file with mode: 0644]
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 with mode: 0644]
sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source.json [deleted file]
sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_params_from_and_to.json [deleted file]
sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm.json [deleted file]
sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm_with_from_and_to_params.json [deleted file]
sonar-server/src/test/resources/org/sonar/server/source/ws/SourcesShowWsHandlerTest/show_source_with_scm_without_repeating_same_lines.json [deleted file]
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]

index 65c0a5c1aa5ca058db52641dd5075aa88b4fad13..472498ba7fb6ffaf638510ba1e146758b828d295 100644 (file)
@@ -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);
index 1db10c1b1017376e91806abf23488c62da236740..07ac61c839ab9c60a891e820677489c564045815 100644 (file)
@@ -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<String> getSourcesForComponent(String componentKey) {
-    return getSourcesByComponent(componentKey, null, null);
+  public List<String> getLinesAsHtml(String fileKey) {
+    return getLinesAsHtml(fileKey, null, null);
   }
 
-  public List<String> getSourcesByComponent(String componentKey, @Nullable Integer from, @Nullable Integer to) {
-    ResourceDto project = resourceDao.getRootProjectByComponentKey(componentKey);
+  public List<String> 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<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml(componentKey, from, to);
+    List<String> 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 (file)
index 0000000..9c919ed
--- /dev/null
@@ -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<String> 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<String> 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<String> authors = splitLine(authorData);
+      List<String> 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<String> 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 (file)
index 27d13cc..0000000
+++ /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<String> 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<String> 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<String> authors = splitLine(authorData);
-      List<String> 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<String> splitLine(String line) {
-    return newArrayList(Splitter.on(";").omitEmptyStrings().split(line));
-  }
-
-  private String[] splitColumn(String column) {
-    return column.split("=");
-  }
-
-}
index 0530f6f588ce96aa615fff4252c00cde07c09b15..c1bc2c2cea58b09e3aa28ecb85a00eb71b25d151 100644 (file)
@@ -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();
   }
 }
index 7dea0debe4070df1cf2596f79db5d8d7abea6c77..e21d3e4399072fe0e1330df41927c652e396be12 100644 (file)
@@ -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.<String>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 (file)
index 0000000..d723c11
--- /dev/null
@@ -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 <span class=\"sym-31 sym\">HelloWorld</span> {",
+      "}"
+    ));
+
+    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.<String>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 <span class=\"sym-31 sym\">HelloWorld</span> {"
+    ));
+    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 <span class=\"sym-31 sym\">HelloWorld</span> {"
+    ));
+    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 <span class=\"sym-31 sym\">HelloWorld</span> {}"
+    ));
+
+    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 <span class=\"sym-31 sym\">HelloWorld</span> {"
+    ));
+    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 <span class=\"sym-31 sym\">HelloWorld</span> {"
+    ));
+    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 <span class=\"sym-31 sym\">HelloWorld</span> {"
+    ));
+
+    // 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 (file)
index 537e140..0000000
+++ /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 <span class=\"sym-31 sym\">HelloWorld</span> {",
-      "}"
-    ));
-
-    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.<String>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 <span class=\"sym-31 sym\">HelloWorld</span> {"
-    ));
-    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 <span class=\"sym-31 sym\">HelloWorld</span> {"
-    ));
-    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 <span class=\"sym-31 sym\">HelloWorld</span> {}"
-    ));
-
-    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 <span class=\"sym-31 sym\">HelloWorld</span> {"
-    ));
-    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 <span class=\"sym-31 sym\">HelloWorld</span> {"
-    ));
-    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 <span class=\"sym-31 sym\">HelloWorld</span> {"
-    ));
-
-    // 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");
-  }
-}
index b24da55479b4829a022f5ce953dcd9d69fdcf499..f7a37a78a46e6c386aa2212cc081cd1b0d35efda 100644 (file)
@@ -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 (file)
index 0000000..f31010c
--- /dev/null
@@ -0,0 +1,18 @@
+{
+  "source": {
+    "1": "/*",
+    "2": " * Header",
+    "3": " */",
+    "4": "",
+    "5": "public class <span class=\"sym-31 sym\">HelloWorld</span> {",
+    "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 (file)
index 0000000..f345655
--- /dev/null
@@ -0,0 +1,15 @@
+{
+  "source": {
+    "3": " */",
+    "4": "",
+    "5": "public class <span class=\"sym-31 sym\">HelloWorld</span> {"
+  }
+}
+
+
+
+
+
+
+
+
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 (file)
index 0000000..6e75309
--- /dev/null
@@ -0,0 +1,16 @@
+{
+  "source": {
+    "1": "public class <span class=\"sym-31 sym\">HelloWorld</span> {}"
+  },
+  "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 (file)
index 0000000..a454052
--- /dev/null
@@ -0,0 +1,20 @@
+{
+  "source": {
+    "3": " */",
+    "4": "",
+    "5": "public class <span class=\"sym-31 sym\">HelloWorld</span> {"
+  },
+  "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 (file)
index 0000000..ae74340
--- /dev/null
@@ -0,0 +1,19 @@
+{
+  "source": {
+    "1": " */",
+    "2": "",
+    "3": "public class <span class=\"sym-31 sym\">HelloWorld</span> {"
+  },
+  "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 (file)
index 0000000..1f852be
--- /dev/null
@@ -0,0 +1,18 @@
+{
+  "source": {
+    "3": " */",
+    "4": "",
+    "5": "public class <span class=\"sym-31 sym\">HelloWorld</span> {"
+  },
+  "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 (file)
index f31010c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "source": {
-    "1": "/*",
-    "2": " * Header",
-    "3": " */",
-    "4": "",
-    "5": "public class <span class=\"sym-31 sym\">HelloWorld</span> {",
-    "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 (file)
index f345655..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "source": {
-    "3": " */",
-    "4": "",
-    "5": "public class <span class=\"sym-31 sym\">HelloWorld</span> {"
-  }
-}
-
-
-
-
-
-
-
-
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 (file)
index 6e75309..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "source": {
-    "1": "public class <span class=\"sym-31 sym\">HelloWorld</span> {}"
-  },
-  "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 (file)
index a454052..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "source": {
-    "3": " */",
-    "4": "",
-    "5": "public class <span class=\"sym-31 sym\">HelloWorld</span> {"
-  },
-  "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 (file)
index ae74340..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "source": {
-    "1": " */",
-    "2": "",
-    "3": "public class <span class=\"sym-31 sym\">HelloWorld</span> {"
-  },
-  "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 (file)
index 1f852be..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "source": {
-    "3": " */",
-    "4": "",
-    "5": "public class <span class=\"sym-31 sym\">HelloWorld</span> {"
-  },
-  "scm": {
-    "3": ["simon", "2013-03-14"]
-  }
-}
-
-
-
-
-
-
-
-