]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6455 Create WS /api/dependencies/show 268/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 30 Apr 2015 13:11:36 +0000 (15:11 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 30 Apr 2015 14:29:14 +0000 (16:29 +0200)
server/sonar-server/src/main/java/org/sonar/server/component/db/ComponentDao.java
server/sonar-server/src/main/java/org/sonar/server/design/ws/DependenciesWs.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/design/ws/ShowAction.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/design/ws/package-info.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
server/sonar-server/src/main/resources/org/sonar/server/design/ws/example-show.json [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/design/ws/DependenciesWsTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/design/ws/ShowActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/design/ws/ShowActionTest/return_file_dependencies.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/design/ws/ShowActionTest/return_nothing.json [new file with mode: 0644]

index 31f42a2fc0d957e5ddf5209bfb7774dd5ade0b05..6f41f9280ae159f1bda8a0f0ab5de8d9187fc222 100644 (file)
@@ -36,6 +36,7 @@ import org.sonar.server.db.BaseDao;
 import org.sonar.server.exceptions.NotFoundException;
 
 import javax.annotation.CheckForNull;
+
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -74,7 +75,7 @@ public class ComponentDao extends BaseDao<ComponentMapper, ComponentDto, String>
   public ComponentDto getByUuid(DbSession session, String uuid) {
     ComponentDto componentDto = getNullableByUuid(session, uuid);
     if (componentDto == null) {
-      throw new NotFoundException(String.format("Project with uuid '%s' not found", uuid));
+      throw new NotFoundException(String.format("Component with uuid '%s' not found", uuid));
     }
     return componentDto;
   }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/design/ws/DependenciesWs.java b/server/sonar-server/src/main/java/org/sonar/server/design/ws/DependenciesWs.java
new file mode 100644 (file)
index 0000000..e8425e4
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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.design.ws;
+
+import org.sonar.api.server.ws.WebService;
+
+public class DependenciesWs implements WebService {
+
+  private final ShowAction showAction;
+
+  public DependenciesWs(ShowAction showAction) {
+    this.showAction = showAction;
+  }
+
+  @Override
+  public void define(Context context) {
+    NewController controller = context.createController("api/dependencies")
+      .setSince("5.2");
+
+    showAction.define(controller);
+
+    controller.done();
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/design/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/design/ws/ShowAction.java
new file mode 100644 (file)
index 0000000..bf2882e
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * 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.design.ws;
+
+import com.google.common.io.Resources;
+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.text.JsonWriter;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.design.FileDependencyDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.user.UserSession;
+import org.sonar.server.user.ws.BaseUsersWsAction;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class ShowAction implements BaseUsersWsAction {
+
+  private static final String PARAM_FROM_PARENT_UUID = "fromParentUuid";
+  private static final String PARAM_TO_PARENT_UUID = "toParentUuid";
+
+  private final DbClient dbClient;
+
+  public ShowAction(DbClient dbClient) {
+    this.dbClient = dbClient;
+  }
+
+  @Override
+  public void define(WebService.NewController controller) {
+    WebService.NewAction action = controller.createAction("show")
+      .setDescription("Show file dependencies between two directories")
+      .setSince("5.2")
+      .setInternal(true)
+      .setHandler(this)
+      .setResponseExample(Resources.getResource(getClass(), "example-show.json"));
+
+    action.createParam(PARAM_FROM_PARENT_UUID)
+      .setDescription("First directory uuid")
+      .setRequired(true)
+      .setExampleValue("2312cd03-b514-4acc-94f4-5c5e8e0062b2");
+
+    action.createParam(PARAM_TO_PARENT_UUID)
+      .setDescription("Second directory uuid")
+      .setRequired(true)
+      .setExampleValue("d38641a2-3166-451d-a2db-ab3b82e2d3ca");
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    String fromParentUuid = request.mandatoryParam(PARAM_FROM_PARENT_UUID);
+    String toParentUuid = request.mandatoryParam(PARAM_TO_PARENT_UUID);
+
+    DbSession session = dbClient.openSession(false);
+    try {
+      ComponentDto fromParent = dbClient.componentDao().getByUuid(session, fromParentUuid);
+      ComponentDto project = dbClient.componentDao().getByUuid(session, fromParent.projectUuid());
+      UserSession.get().checkProjectUuidPermission(UserRole.USER, project.uuid());
+
+      List<FileDependencyDto> fileDependencies = dbClient.fileDependencyDao().selectFromParents(session, fromParentUuid, toParentUuid, project.getId());
+      writeResponse(response, fileDependencies, componentsByUuid(session, fileDependencies));
+    } finally {
+      session.close();
+    }
+  }
+
+  private void writeResponse(Response response, List<FileDependencyDto> fileDependencies, Map<String, ComponentDto> componentsByUuid) {
+    JsonWriter json = response.newJsonWriter().beginObject();
+    json.name("dependencies").beginArray();
+    for (FileDependencyDto fileDependencyDto : fileDependencies) {
+      ComponentDto fromComponent = getComponent(fileDependencyDto.getFromComponentUuid(), componentsByUuid);
+      ComponentDto toComponent = getComponent(fileDependencyDto.getToComponentUuid(), componentsByUuid);
+      json.beginObject()
+        .prop("fromUuid", fromComponent.uuid())
+        .prop("fromName", fromComponent.longName())
+        .prop("toUuid", toComponent.uuid())
+        .prop("toName", toComponent.longName())
+        .prop("weight", fileDependencyDto.getWeight())
+        .endObject();
+    }
+    json.endArray().endObject().close();
+  }
+
+  private Map<String, ComponentDto> componentsByUuid(DbSession session, List<FileDependencyDto> fileDependencies) {
+    Set<String> uuids = new HashSet<>();
+    for (FileDependencyDto fileDependency : fileDependencies) {
+      uuids.add(fileDependency.getFromComponentUuid());
+      uuids.add(fileDependency.getToComponentUuid());
+    }
+    Map<String, ComponentDto> componentsByUuid = new HashMap<>();
+    for (ComponentDto componentDto : dbClient.componentDao().getByUuids(session, uuids)) {
+      componentsByUuid.put(componentDto.uuid(), componentDto);
+    }
+    return componentsByUuid;
+  }
+
+  private static ComponentDto getComponent(String uuid, Map<String, ComponentDto> componentsByUuid) {
+    ComponentDto component = componentsByUuid.get(uuid);
+    if (component == null) {
+      throw new IllegalStateException(String.format("Component with uuid '%s' does not exists", uuid));
+    }
+    return component;
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/design/ws/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/design/ws/package-info.java
new file mode 100644 (file)
index 0000000..f871e44
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.server.design.ws;
+
+import javax.annotation.ParametersAreNonnullByDefault;
index 4f464e21c20cbf992756b53acd80b932f5856019..9f7bb52c222cbd39b6fcebedda9be2590bc9f1a0 100644 (file)
@@ -134,6 +134,8 @@ import org.sonar.server.debt.DebtModelService;
 import org.sonar.server.debt.DebtModelXMLExporter;
 import org.sonar.server.debt.DebtRulesXMLImporter;
 import org.sonar.server.design.FileDesignWidget;
+import org.sonar.server.design.db.FileDependencyDao;
+import org.sonar.server.design.ws.DependenciesWs;
 import org.sonar.server.duplication.ws.DuplicationsJsonWriter;
 import org.sonar.server.duplication.ws.DuplicationsParser;
 import org.sonar.server.duplication.ws.DuplicationsWs;
@@ -483,7 +485,8 @@ class ServerComponents {
       EventDao.class,
       ActivityDao.class,
       AnalysisReportDao.class,
-      FileSourceDao.class
+      FileSourceDao.class,
+      FileDependencyDao.class
       ));
     components.addAll(CorePropertyDefinitions.all());
     components.addAll(MigrationSteps.CLASSES);
@@ -878,6 +881,8 @@ class ServerComponents {
 
     // Design
     pico.addSingleton(FileDesignWidget.class);
+    pico.addSingleton(DependenciesWs.class);
+    pico.addSingleton(org.sonar.server.design.ws.ShowAction.class);
 
     // System
     pico.addSingletons(Arrays.asList(
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/design/ws/example-show.json b/server/sonar-server/src/main/resources/org/sonar/server/design/ws/example-show.json
new file mode 100644 (file)
index 0000000..979046c
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "dependencies":[
+    {
+      "fromUuid": "ae8ef766-269e-481e-b89e-0a3cf52f0feb",
+      "fromName": "src/main/java/org/sonar/core/issue/db/ActionPlanDao.java",
+      "toUuid": "5e96f736-1b2d-46d9-a071-b9a44e123438",
+      "toName": "src/main/java/org/sonar/core/persistence/DaoComponent.java",
+      "weight": 1
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/design/ws/DependenciesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/design/ws/DependenciesWsTest.java
new file mode 100644 (file)
index 0000000..0549e70
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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.design.ws;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.ws.WsTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+public class DependenciesWsTest {
+
+  WebService.Controller controller;
+
+  @Before
+  public void setUp() throws Exception {
+    WsTester tester = new WsTester(new DependenciesWs(new ShowAction(mock(DbClient.class))));
+    controller = tester.controller("api/dependencies");
+  }
+
+  @Test
+  public void define_controller() throws Exception {
+    assertThat(controller).isNotNull();
+    assertThat(controller.description()).isNull();
+    assertThat(controller.since()).isEqualTo("5.2");
+    assertThat(controller.actions()).hasSize(1);
+  }
+
+  @Test
+  public void define_search_action() throws Exception {
+    WebService.Action action = controller.action("show");
+    assertThat(action).isNotNull();
+    assertThat(action.isPost()).isFalse();
+    assertThat(action.responseExampleAsString()).isNotEmpty();
+    assertThat(action.isInternal()).isTrue();
+    assertThat(action.params()).hasSize(2);
+  }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/design/ws/ShowActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/design/ws/ShowActionTest.java
new file mode 100644 (file)
index 0000000..b541b99
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * 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.design.ws;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.component.SnapshotDto;
+import org.sonar.core.design.FileDependencyDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.persistence.DbTester;
+import org.sonar.server.component.ComponentTesting;
+import org.sonar.server.component.SnapshotTesting;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.component.db.SnapshotDao;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.design.db.FileDependencyDao;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.user.MockUserSession;
+import org.sonar.server.ws.WsTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
+
+public class ShowActionTest {
+
+  private static final String PROJECT_UUID = "PROJECT";
+  private static final String DIR1_UUID = "DIR1";
+  private static final String FILE1_UUID = "FILE1";
+  private static final String DIR2_UUID = "DIR2";
+  private static final String FILE2_UUID = "FILE2";
+  private static final String UNKNOWN_UUID = "UNKNOWN";
+
+  Long projectSnapshotId;
+
+  @ClassRule
+  public static DbTester dbTester = new DbTester();
+
+  DbClient dbClient;
+
+  DbSession session;
+
+  WebService.Controller controller;
+
+  WsTester tester;
+
+  @Before
+  public void setUp() throws Exception {
+    dbTester.truncateTables();
+    dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao(), new SnapshotDao(System2.INSTANCE), new FileDependencyDao());
+    session = dbClient.openSession(false);
+    tester = new WsTester(new DependenciesWs(new ShowAction(dbClient)));
+    controller = tester.controller("api/dependencies");
+
+    initComponents();
+  }
+
+  @After
+  public void after() {
+    session.close();
+  }
+
+  @Test
+  public void return_file_dependencies() throws Exception {
+    dbClient.fileDependencyDao().insert(session, new FileDependencyDto()
+      .setFromComponentUuid(FILE1_UUID)
+      .setToComponentUuid(FILE2_UUID)
+      .setFromParentUuid(DIR1_UUID)
+      .setToParentUuid(DIR2_UUID)
+      .setRootProjectSnapshotId(projectSnapshotId)
+      .setWeight(2)
+      .setCreatedAt(1000L));
+    session.commit();
+
+    MockUserSession.set().addProjectUuidPermissions(UserRole.USER, PROJECT_UUID);
+
+    tester.newGetRequest("api/dependencies", "show")
+      .setParam("fromParentUuid", DIR1_UUID)
+      .setParam("toParentUuid", DIR2_UUID)
+      .execute()
+      .assertJson(getClass(), "return_file_dependencies.json");
+  }
+
+  @Test
+  public void return_nothing() throws Exception {
+    MockUserSession.set().addProjectUuidPermissions(UserRole.USER, PROJECT_UUID);
+
+    tester.newGetRequest("api/dependencies", "show")
+      .setParam("fromParentUuid", DIR1_UUID)
+      .setParam("toParentUuid", DIR2_UUID)
+      .execute()
+      .assertJson(getClass(), "return_nothing.json");
+  }
+
+  @Test(expected = ForbiddenException.class)
+  public void fail_if_no_user_permission_on_project() throws Exception {
+    MockUserSession.set().addProjectUuidPermissions(UserRole.CODEVIEWER, PROJECT_UUID);
+
+    tester.newGetRequest("api/dependencies", "show")
+      .setParam("fromParentUuid", DIR1_UUID)
+      .setParam("toParentUuid", DIR2_UUID)
+      .execute()
+      .assertJson(getClass(), "return_nothing.json");
+  }
+
+  @Test
+  public void fail_if_from_parent_uuid_does_not_exists() throws Exception {
+    dbClient.fileDependencyDao().insert(session, new FileDependencyDto()
+      .setFromComponentUuid(FILE1_UUID)
+      .setToComponentUuid(FILE2_UUID)
+      .setFromParentUuid(DIR1_UUID)
+      .setToParentUuid(DIR2_UUID)
+      .setRootProjectSnapshotId(projectSnapshotId)
+      .setWeight(2)
+      .setCreatedAt(1000L));
+    session.commit();
+
+    MockUserSession.set().addProjectUuidPermissions(UserRole.USER, PROJECT_UUID);
+
+    try {
+      tester.newGetRequest("api/dependencies", "show")
+        .setParam("fromParentUuid", UNKNOWN_UUID)
+        .setParam("toParentUuid", DIR2_UUID)
+        .execute()
+        .assertJson(getClass(), "return_file_dependencies.json");
+      failBecauseExceptionWasNotThrown(NotFoundException.class);
+    } catch (NotFoundException e) {
+      assertThat(e).hasMessage("Component with uuid 'UNKNOWN' not found");
+    }
+  }
+
+  @Test
+  public void return_nothing_if_to_parent_uuid_does_not_exists() throws Exception {
+    dbClient.fileDependencyDao().insert(session, new FileDependencyDto()
+      .setFromComponentUuid(FILE1_UUID)
+      .setToComponentUuid(FILE2_UUID)
+      .setFromParentUuid(DIR1_UUID)
+      .setToParentUuid(DIR2_UUID)
+      .setRootProjectSnapshotId(projectSnapshotId)
+      .setWeight(2)
+      .setCreatedAt(1000L));
+    session.commit();
+
+    MockUserSession.set().addProjectUuidPermissions(UserRole.USER, PROJECT_UUID);
+
+    tester.newGetRequest("api/dependencies", "show")
+      .setParam("fromParentUuid", DIR1_UUID)
+      .setParam("toParentUuid", UNKNOWN_UUID)
+      .execute()
+      .assertJson(getClass(), "return_nothing.json");
+  }
+
+  @Test
+  public void fail_if_from_component_uuid_does_not_exists() throws Exception {
+    dbClient.fileDependencyDao().insert(session, new FileDependencyDto()
+      .setFromComponentUuid(UNKNOWN_UUID)
+      .setToComponentUuid(FILE2_UUID)
+      .setFromParentUuid(DIR1_UUID)
+      .setToParentUuid(DIR2_UUID)
+      .setRootProjectSnapshotId(projectSnapshotId)
+      .setWeight(2)
+      .setCreatedAt(1000L));
+    session.commit();
+
+    MockUserSession.set().addProjectUuidPermissions(UserRole.USER, PROJECT_UUID);
+
+    try {
+      tester.newGetRequest("api/dependencies", "show")
+        .setParam("fromParentUuid", DIR1_UUID)
+        .setParam("toParentUuid", DIR2_UUID)
+        .execute()
+        .assertJson(getClass(), "return_file_dependencies.json");
+      failBecauseExceptionWasNotThrown(IllegalStateException.class);
+    } catch (IllegalStateException e) {
+      assertThat(e).hasMessage("Component with uuid 'UNKNOWN' does not exists");
+    }
+  }
+
+  @Test
+  public void fail_if_to_component_uuid_does_not_exists() throws Exception {
+    dbClient.fileDependencyDao().insert(session, new FileDependencyDto()
+      .setFromComponentUuid(FILE1_UUID)
+      .setToComponentUuid(UNKNOWN_UUID)
+      .setFromParentUuid(DIR1_UUID)
+      .setToParentUuid(DIR2_UUID)
+      .setRootProjectSnapshotId(projectSnapshotId)
+      .setWeight(2)
+      .setCreatedAt(1000L));
+    session.commit();
+
+    MockUserSession.set().addProjectUuidPermissions(UserRole.USER, PROJECT_UUID);
+
+    try {
+      tester.newGetRequest("api/dependencies", "show")
+        .setParam("fromParentUuid",DIR1_UUID)
+        .setParam("toParentUuid", DIR2_UUID)
+        .execute()
+        .assertJson(getClass(), "return_file_dependencies.json");
+      failBecauseExceptionWasNotThrown(IllegalStateException.class);
+    } catch (IllegalStateException e) {
+      assertThat(e).hasMessage("Component with uuid 'UNKNOWN' does not exists");
+    }
+  }
+
+  private void initComponents(){
+    ComponentDto project = ComponentTesting.newProjectDto(PROJECT_UUID);
+    ComponentDto directory1 = ComponentTesting.newDirectory(project, "/src/main/java/dir1").setUuid(DIR1_UUID);
+    ComponentDto file1 = ComponentTesting.newFileDto(directory1, FILE1_UUID).setLongName("src/main/java/dir1/File1.java");
+    ComponentDto directory2 = ComponentTesting.newDirectory(project, "/src/main/java/dir2").setUuid(DIR2_UUID);
+    ComponentDto file2 = ComponentTesting.newFileDto(directory1, FILE2_UUID).setLongName("src/main/java/dir2/File2.java");
+    dbClient.componentDao().insert(session, project, directory1, directory2, file1, file2);
+
+    SnapshotDto projectSnapshot = SnapshotTesting.createForProject(project);
+    dbClient.snapshotDao().insert(session, projectSnapshot);
+
+    session.commit();
+
+    projectSnapshotId = projectSnapshot.getId();
+  }
+
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/design/ws/ShowActionTest/return_file_dependencies.json b/server/sonar-server/src/test/resources/org/sonar/server/design/ws/ShowActionTest/return_file_dependencies.json
new file mode 100644 (file)
index 0000000..122c0e6
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "dependencies":[
+    {
+      "fromUuid": "FILE1",
+      "fromName": "src/main/java/dir1/File1.java",
+      "toUuid": "FILE2",
+      "toName": "src/main/java/dir2/File2.java",
+      "weight": 2
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/design/ws/ShowActionTest/return_nothing.json b/server/sonar-server/src/test/resources/org/sonar/server/design/ws/ShowActionTest/return_nothing.json
new file mode 100644 (file)
index 0000000..45f00a3
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "dependencies":[]
+}