aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2016-12-01 19:09:12 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2016-12-05 18:10:31 +0100
commite1d60fa822a6591e9303497cc36f467465f2bcc8 (patch)
treef4731d33bb05c55bef8e8fad019843539756ccbb /server/sonar-server
parent74c5ca3839bc61535a68d8eb7f89015c6f653b43 (diff)
downloadsonarqube-e1d60fa822a6591e9303497cc36f467465f2bcc8.tar.gz
sonarqube-e1d60fa822a6591e9303497cc36f467465f2bcc8.zip
SONAR-8450 Cleanup ComponentNavigationActionTest
Diffstat (limited to 'server/sonar-server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentNavigationAction.java39
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/ui/ws/example-component.json1
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentNavigationActionTest.java318
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/ui/ws/GlobalNavigationActionTest.java6
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/on_module.json32
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/quality_profile_admin.json26
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_bread_crumbs_on_several_levels.json (renamed from server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/breadcrumbs.json)0
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_breadcrumbs_on_module.json14
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_component_info_when_anonymous_no_snapshot.json (renamed from server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/no_snapshot.json)0
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_component_info_when_snapshot.json (renamed from server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_snapshot_and_connected_user.json)2
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_component_info_with_favourite.json (renamed from server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/no_snapshot_user_favourite.json)0
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_configuration_for_admin.json (renamed from server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_admin_rights.json)16
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_configuration_for_quality_profile_admin.json12
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_configuration_with_all_properties.json (renamed from server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_all_properties.json)16
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_extensions.json12
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_extensions_for_admin.json (renamed from server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/admin_with_extensions.json)13
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_dashboards.json20
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_default_dashboards.json20
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_extensions.json25
19 files changed, 192 insertions, 380 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentNavigationAction.java b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentNavigationAction.java
index 4d824d7806e..5499d5f9a4c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentNavigationAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/ComponentNavigationAction.java
@@ -25,7 +25,6 @@ import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
-import java.util.Locale;
import java.util.Optional;
import javax.annotation.Nullable;
import org.sonar.api.i18n.I18n;
@@ -40,8 +39,6 @@ import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.api.web.NavigationSection;
import org.sonar.api.web.Page;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
@@ -55,6 +52,10 @@ import org.sonar.server.ui.ViewProxy;
import org.sonar.server.ui.Views;
import org.sonar.server.user.UserSession;
+import static java.util.Locale.ENGLISH;
+import static org.sonar.api.web.UserRole.ADMIN;
+import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.core.permission.GlobalPermissions.QUALITY_PROFILE_ADMIN;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
public class ComponentNavigationAction implements NavigationWsAction {
@@ -102,36 +103,25 @@ public class ComponentNavigationAction implements NavigationWsAction {
@Override
public void handle(Request request, Response response) throws Exception {
String componentKey = request.mandatoryParam(PARAM_COMPONENT_KEY);
-
- DbSession session = dbClient.openSession(false);
-
- try {
+ try (DbSession session = dbClient.openSession(false)) {
ComponentDto component = componentFinder.getByKey(session, componentKey);
-
- if (!(userSession.hasComponentUuidPermission(UserRole.USER, component.projectUuid()) || userSession.hasComponentUuidPermission(UserRole.ADMIN, component.projectUuid()))) {
+ if (!(userSession.hasComponentUuidPermission(USER, component.projectUuid()) || userSession.hasComponentUuidPermission(ADMIN, component.projectUuid()))) {
throw new ForbiddenException("Insufficient privileges");
}
-
Optional<SnapshotDto> analysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(session, component.projectUuid());
JsonWriter json = response.newJsonWriter();
json.beginObject();
writeComponent(json, session, component, analysis.orElse(null), userSession);
-
- if (userSession.hasComponentUuidPermission(UserRole.ADMIN, component.projectUuid()) || userSession.hasPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN)) {
+ if (userSession.hasComponentUuidPermission(ADMIN, component.projectUuid()) || userSession.hasPermission(QUALITY_PROFILE_ADMIN)) {
writeConfiguration(json, component, userSession);
}
-
writeBreadCrumbs(json, session, component);
json.endObject().close();
-
- } finally {
- session.close();
}
}
private void writeComponent(JsonWriter json, DbSession session, ComponentDto component, @Nullable SnapshotDto analysis, UserSession userSession) {
-
json.prop("key", component.key())
.prop("uuid", component.uuid())
.prop("name", component.name())
@@ -143,7 +133,7 @@ public class ComponentNavigationAction implements NavigationWsAction {
json.prop("version", analysis.getVersion())
.prop("snapshotDate", DateUtils.formatDateTime(new Date(analysis.getCreatedAt())));
List<ViewProxy<Page>> pages = views.getPages(NavigationSection.RESOURCE, component.scope(), component.qualifier(), component.language());
- writeExtensions(json, component, pages, userSession.locale());
+ writeExtensions(json, component, pages);
}
}
@@ -157,11 +147,11 @@ public class ComponentNavigationAction implements NavigationWsAction {
return componentFavourites.size() == 1;
}
- private void writeExtensions(JsonWriter json, ComponentDto component, List<ViewProxy<Page>> pages, Locale locale) {
+ private void writeExtensions(JsonWriter json, ComponentDto component, List<ViewProxy<Page>> pages) {
json.name("extensions").beginArray();
for (ViewProxy<Page> page : pages) {
if (page.isUserAuthorized(component)) {
- writePage(json, getPageUrl(page, component), i18n.message(locale, page.getId() + ".page", page.getTitle()));
+ writePage(json, getPageUrl(page, component), i18n.message(ENGLISH, page.getId() + ".page", page.getTitle()));
}
}
json.endArray();
@@ -189,8 +179,7 @@ public class ComponentNavigationAction implements NavigationWsAction {
}
private void writeConfiguration(JsonWriter json, ComponentDto component, UserSession userSession) {
- boolean isAdmin = userSession.hasComponentUuidPermission(UserRole.ADMIN, component.projectUuid());
- Locale locale = userSession.locale();
+ boolean isAdmin = userSession.hasComponentUuidPermission(ADMIN, component.projectUuid());
json.name("configuration").beginObject();
writeConfigPageAccess(json, isAdmin, component);
@@ -199,7 +188,7 @@ public class ComponentNavigationAction implements NavigationWsAction {
json.name("extensions").beginArray();
List<ViewProxy<Page>> configPages = views.getPages(NavigationSection.RESOURCE_CONFIGURATION, component.scope(), component.qualifier(), component.language());
for (ViewProxy<Page> page : configPages) {
- writePage(json, getPageUrl(page, component), i18n.message(locale, page.getId() + ".page", page.getTitle()));
+ writePage(json, getPageUrl(page, component), i18n.message(ENGLISH, page.getId() + ".page", page.getTitle()));
}
json.endArray();
}
@@ -214,8 +203,6 @@ public class ComponentNavigationAction implements NavigationWsAction {
json.prop("showQualityProfiles", isProject);
json.prop("showQualityGates", isProject);
json.prop("showManualMeasures", showManualMeasures);
- // TODO delete showActionPlans when UI is updated
- json.prop("showActionPlans", false);
json.prop("showLinks", isAdmin && isProject);
json.prop("showPermissions", isAdmin && componentTypeHasProperty(component, PROPERTY_HAS_ROLE_POLICY));
json.prop("showHistory", isAdmin && componentTypeHasProperty(component, PROPERTY_MODIFIABLE_HISTORY));
@@ -228,7 +215,7 @@ public class ComponentNavigationAction implements NavigationWsAction {
return resourceType != null && resourceType.getBooleanProperty(resourceTypeProperty);
}
- private void writePage(JsonWriter json, String url, String name) {
+ private static void writePage(JsonWriter json, String url, String name) {
json.beginObject()
.prop("url", url)
.prop("name", name)
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/ui/ws/example-component.json b/server/sonar-server/src/main/resources/org/sonar/server/ui/ws/example-component.json
index 8357f139f90..43a34ed87ce 100644
--- a/server/sonar-server/src/main/resources/org/sonar/server/ui/ws/example-component.json
+++ b/server/sonar-server/src/main/resources/org/sonar/server/ui/ws/example-component.json
@@ -18,7 +18,6 @@
"showQualityProfiles": true,
"showQualityGates": true,
"showManualMeasures": true,
- "showActionPlans": true,
"showLinks": true,
"showPermissions": true,
"showHistory": true,
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentNavigationActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentNavigationActionTest.java
index a30fe1ea202..9dffcf84359 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentNavigationActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/ComponentNavigationActionTest.java
@@ -19,13 +19,10 @@
*/
package org.sonar.server.ui.ws;
-import java.util.Date;
-import java.util.Locale;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
+import org.junit.rules.ExpectedException;
import org.sonar.api.i18n.I18n;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.ResourceType;
@@ -40,171 +37,156 @@ import org.sonar.api.web.ResourceQualifier;
import org.sonar.api.web.ResourceScope;
import org.sonar.api.web.UserRole;
import org.sonar.api.web.View;
-import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.component.SnapshotDto;
-import org.sonar.db.component.SnapshotTesting;
+import org.sonar.db.property.PropertyDbTester;
import org.sonar.db.property.PropertyDto;
+import org.sonar.db.user.UserDbTester;
+import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ui.Views;
-import org.sonar.server.ws.WsTester;
+import org.sonar.server.ws.WsActionTester;
+import static java.util.Locale.ENGLISH;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import static org.sonar.core.permission.GlobalPermissions.QUALITY_PROFILE_ADMIN;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+import static org.sonar.db.component.ComponentTesting.newDirectory;
+import static org.sonar.db.component.ComponentTesting.newFileDto;
+import static org.sonar.db.component.ComponentTesting.newModuleDto;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonar.db.component.SnapshotTesting.newAnalysis;
+import static org.sonar.test.JsonAssert.assertJson;
public class ComponentNavigationActionTest {
- System2 system = mock(System2.class);
+ private static final String PROJECT_KEY = "polop";
+ private static final ComponentDto PROJECT = newProjectDto("abcd").setKey(PROJECT_KEY).setName("Polop").setLanguage("xoo");
@Rule
- public DbTester dbTester = DbTester.create(system);
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public DbTester dbTester = DbTester.create(System2.INSTANCE);
@Rule
public UserSessionRule userSessionRule = UserSessionRule.standalone();
+ private ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
+ private UserDbTester userDbTester = new UserDbTester(dbTester);
+ private PropertyDbTester propertyDbTester = new PropertyDbTester(dbTester);
private DbClient dbClient = dbTester.getDbClient();
- private I18n i18n;
+ private I18n i18n = mock(I18n.class);
+
+ private ResourceTypes resourceTypes = mock(ResourceTypes.class);
- private ResourceTypes resourceTypes;
+ private WsActionTester ws;
@Before
public void before() {
- i18n = mock(I18n.class);
- when(i18n.message(any(Locale.class), any(String.class), any(String.class)))
- .thenAnswer(new Answer<String>() {
- @Override
- public String answer(InvocationOnMock invocation) throws Throwable {
- return invocation.getArgumentAt(2, String.class);
- }
- });
-
- resourceTypes = mock(ResourceTypes.class);
+ when(i18n.message(eq(ENGLISH), any(String.class), any(String.class)))
+ .thenAnswer(invocation -> invocation.getArgumentAt(2, String.class));
}
- @Test(expected = IllegalArgumentException.class)
+ @Test
public void fail_on_missing_parameters() throws Exception {
- WsTester wsTester = newdWsTester();
- wsTester.newGetRequest("api/navigation", "component").execute();
+ init();
+
+ expectedException.expect(IllegalArgumentException.class);
+ ws.newRequest().execute();
}
- @Test(expected = NotFoundException.class)
- public void fail_on_unexistent_key() throws Exception {
- WsTester wsTester = newdWsTester();
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "polop").execute();
+ @Test
+ public void fail_on_unknown_component_key() throws Exception {
+ init();
+
+ expectedException.expect(NotFoundException.class);
+ execute(PROJECT.key());
}
- @Test(expected = ForbiddenException.class)
+ @Test
public void fail_on_missing_permission() throws Exception {
- dbClient.componentDao().insert(dbTester.getSession(), ComponentTesting.newProjectDto("abcd").setKey("polop"));
- dbTester.getSession().commit();
+ init();
+ componentDbTester.insertComponent(PROJECT);
- WsTester wsTester = newdWsTester();
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "polop").execute();
+ expectedException.expect(ForbiddenException.class);
+ execute(PROJECT.key());
}
@Test
- public void no_snapshot_anonymous() throws Exception {
- dbClient.componentDao().insert(dbTester.getSession(), ComponentTesting.newProjectDto("abcd")
- .setKey("polop").setName("Polop"));
- dbTester.getSession().commit();
+ public void return_component_info_when_anonymous_no_snapshot() throws Exception {
+ init();
+ componentDbTester.insertComponent(PROJECT);
+ userSessionRule.addProjectUuidPermissions(UserRole.USER, PROJECT.uuid());
- userSessionRule.addProjectUuidPermissions(UserRole.USER, "abcd");
-
- WsTester wsTester = newdWsTester();
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "polop").execute().assertJson(getClass(), "no_snapshot.json");
+ executeAndVerify(PROJECT.key(), "return_component_info_when_anonymous_no_snapshot.json");
}
@Test
- public void no_snapshot_connected_user_and_favorite() throws Exception {
- int userId = 42;
- ComponentDto project = ComponentTesting.newProjectDto("abcd")
- .setKey("polop").setName("Polop");
- dbClient.componentDao().insert(dbTester.getSession(), project);
- dbClient.propertiesDao().saveProperty(dbTester.getSession(), new PropertyDto().setKey("favourite").setResourceId(project.getId()).setUserId((long) userId));
- dbTester.getSession().commit();
-
- userSessionRule.login("obiwan").setUserId(userId).addProjectUuidPermissions(UserRole.USER, "abcd");
-
- WsTester wsTester = newdWsTester();
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "polop").execute().assertJson(getClass(), "no_snapshot_user_favourite.json");
+ public void return_component_info_with_favourite() throws Exception {
+ init();
+ UserDto user = userDbTester.insertUser("obiwan");
+ componentDbTester.insertComponent(PROJECT);
+ propertyDbTester.insertProperty(new PropertyDto().setKey("favourite").setResourceId(PROJECT.getId()).setUserId(user.getId()));
+ userSessionRule.login(user).addProjectUuidPermissions(UserRole.USER, PROJECT.uuid());
+
+ executeAndVerify(PROJECT.key(), "return_component_info_with_favourite.json");
}
@Test
- public void with_snapshot_and_connected_user() throws Exception {
- Date snapshotDate = DateUtils.parseDateTime("2015-04-22T11:44:00+0200");
-
- int userId = 42;
- ComponentDto project = ComponentTesting.newProjectDto("abcd")
- .setKey("polop").setName("Polop");
- dbClient.componentDao().insert(dbTester.getSession(), project);
- dbClient.snapshotDao().insert(dbTester.getSession(), new SnapshotDto()
- .setUuid("u1")
- .setCreatedAt(snapshotDate.getTime())
+ public void return_component_info_when_snapshot() throws Exception {
+ init();
+ componentDbTester.insertComponent(PROJECT);
+ componentDbTester.insertSnapshot(newAnalysis(PROJECT)
+ .setCreatedAt(DateUtils.parseDateTime("2015-04-22T11:44:00+0200").getTime())
.setVersion("3.14")
- .setLast(true)
- .setComponentUuid(project.uuid()));
- dbTester.getSession().commit();
-
- userSessionRule.login("obiwan").setUserId(userId).addProjectUuidPermissions(UserRole.USER, "abcd");
+ .setLast(true));
+ userSessionRule.addProjectUuidPermissions(UserRole.USER, PROJECT.uuid());
- WsTester wsTester = newdWsTester();
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "polop").execute().assertJson(getClass(), "with_snapshot_and_connected_user.json");
+ executeAndVerify(PROJECT.key(), "return_component_info_when_snapshot.json");
}
@Test
- public void with_extensions() throws Exception {
- ComponentDto project = ComponentTesting.newProjectDto("abcd")
- .setKey("polop").setName("Polop").setLanguage("xoo");
- dbClient.componentDao().insert(dbTester.getSession(), project);
- dbClient.snapshotDao().insert(dbTester.getSession(), SnapshotTesting.newAnalysis(project));
- dbTester.getSession().commit();
+ public void return_extensions() throws Exception {
+ init(createViews());
+ componentDbTester.insertProjectAndSnapshot(PROJECT);
+ userSessionRule.anonymous().addProjectUuidPermissions(UserRole.USER, PROJECT.uuid());
- userSessionRule.addProjectUuidPermissions(UserRole.USER, "abcd");
-
- WsTester wsTester = newdWsTester(createViews());
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "polop").execute().assertJson(getClass(), "with_extensions.json");
+ executeAndVerify(PROJECT.key(), "return_extensions.json");
}
@Test
- public void admin_with_extensions() throws Exception {
- ComponentDto project = ComponentTesting.newProjectDto("abcd")
- .setKey("polop").setName("Polop").setLanguage("xoo");
- dbClient.componentDao().insert(dbTester.getSession(), project);
- dbClient.snapshotDao().insert(dbTester.getSession(), SnapshotTesting.newAnalysis(project));
- dbTester.getSession().commit();
-
- userSessionRule
- .addProjectUuidPermissions(UserRole.USER, "abcd")
- .addProjectUuidPermissions(UserRole.ADMIN, "abcd");
-
- WsTester wsTester = newdWsTester(createViews());
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "polop").execute().assertJson(getClass(), "admin_with_extensions.json");
+ public void return_extensions_for_admin() throws Exception {
+ init(createViews());
+ componentDbTester.insertProjectAndSnapshot(PROJECT);
+ userSessionRule.anonymous()
+ .addProjectUuidPermissions(UserRole.USER, PROJECT.uuid())
+ .addProjectUuidPermissions(UserRole.ADMIN, PROJECT.uuid());
+
+ executeAndVerify(PROJECT.key(), "return_extensions_for_admin.json");
}
@Test
- public void with_admin_rights() throws Exception {
- final String language = "xoo";
- int userId = 42;
- dbClient.componentDao().insert(dbTester.getSession(), ComponentTesting.newProjectDto("abcd")
- .setKey("polop").setName("Polop").setLanguage(language));
- dbTester.getSession().commit();
-
- userSessionRule.login("obiwan").setUserId(userId)
+ public void return_configuration_for_admin() throws Exception {
+ UserDto user = userDbTester.insertUser();
+ componentDbTester.insertComponent(PROJECT);
+ userSessionRule.login(user)
.addProjectUuidPermissions(UserRole.USER, "abcd")
.addProjectUuidPermissions(UserRole.ADMIN, "abcd");
@NavigationSection(NavigationSection.RESOURCE_CONFIGURATION)
@ResourceScope(Scopes.PROJECT)
@ResourceQualifier(Qualifiers.PROJECT)
- @ResourceLanguage(language)
+ @ResourceLanguage("xoo")
class FirstPage implements Page {
@Override
public String getTitle() {
@@ -216,12 +198,11 @@ public class ComponentNavigationActionTest {
return "first_page";
}
}
- Page page1 = new FirstPage();
@NavigationSection(NavigationSection.RESOURCE_CONFIGURATION)
@ResourceScope(Scopes.PROJECT)
@ResourceQualifier(Qualifiers.PROJECT)
- @ResourceLanguage(language)
+ @ResourceLanguage("xoo")
class SecondPage implements Page {
@Override
public String getTitle() {
@@ -233,25 +214,20 @@ public class ComponentNavigationActionTest {
return "/second/page";
}
}
- Page page2 = new SecondPage();
- WsTester wsTester = newdWsTester(new Page[]{page1, page2});
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "polop").execute().assertJson(getClass(), "with_admin_rights.json");
+ init(new Page[] {new FirstPage(), new SecondPage()});
+ executeAndVerify(PROJECT.key(), "return_configuration_for_admin.json");
}
@Test
- public void with_component_which_has_all_properties() throws Exception {
- int userId = 42;
- ComponentDto project = ComponentTesting.newProjectDto("abcd")
- .setKey("polop").setName("Polop");
- dbClient.componentDao().insert(dbTester.getSession(), project);
- dbTester.getSession().commit();
-
- userSessionRule.login("obiwan").setUserId(userId)
+ public void return_configuration_with_all_properties() throws Exception {
+ init();
+ componentDbTester.insertComponent(PROJECT);
+ userSessionRule.anonymous()
.addProjectUuidPermissions(UserRole.USER, "abcd")
.addProjectUuidPermissions(UserRole.ADMIN, "abcd");
- ResourceType projectResourceType = ResourceType.builder(project.qualifier())
+ ResourceType projectResourceType = ResourceType.builder(PROJECT.qualifier())
.setProperty("comparable", true)
.setProperty("configurable", true)
.setProperty("hasRolePolicy", true)
@@ -259,96 +235,72 @@ public class ComponentNavigationActionTest {
.setProperty("updatable_key", true)
.setProperty("deletable", true)
.build();
- when(resourceTypes.get(project.qualifier()))
+ when(resourceTypes.get(PROJECT.qualifier()))
.thenReturn(projectResourceType);
- WsTester wsTester = newdWsTester();
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "polop").execute().assertJson(getClass(), "with_all_properties.json");
+ executeAndVerify(PROJECT.key(), "return_configuration_with_all_properties.json");
}
@Test
- public void on_module() throws Exception {
- int userId = 42;
- ComponentDto project = ComponentTesting.newProjectDto("abcd")
- .setKey("polop").setName("Polop");
- ComponentDto module = ComponentTesting.newModuleDto("bcde", project)
- .setKey("palap").setName("Palap");
- dbClient.componentDao().insert(dbTester.getSession(), project, module);
- dbTester.getSession().commit();
-
- userSessionRule.login("obiwan").setUserId(userId)
+ public void return_breadcrumbs_on_module() throws Exception {
+ init();
+ ComponentDto project = componentDbTester.insertComponent(PROJECT);
+ ComponentDto module = componentDbTester.insertComponent(newModuleDto("bcde", project).setKey("palap").setName("Palap"));
+ userSessionRule.anonymous()
.addProjectUuidPermissions(UserRole.USER, "abcd")
.addProjectUuidPermissions(UserRole.ADMIN, "abcd");
- WsTester wsTester = newdWsTester();
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "palap").execute().assertJson(getClass(), "on_module.json");
+ executeAndVerify(module.key(), "return_breadcrumbs_on_module.json");
}
@Test
- public void with_quality_profile_admin_rights() throws Exception {
- final String language = "xoo";
- int userId = 42;
- dbClient.componentDao().insert(dbTester.getSession(), ComponentTesting.newProjectDto("abcd")
- .setKey("polop").setName("Polop").setLanguage(language));
- dbTester.getSession().commit();
-
- userSessionRule.login("obiwan").setUserId(userId)
+ public void return_configuration_for_quality_profile_admin() throws Exception {
+ init();
+ componentDbTester.insertComponent(PROJECT);
+ userSessionRule.anonymous()
.addProjectUuidPermissions(UserRole.USER, "abcd")
- .setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
+ .setGlobalPermissions(QUALITY_PROFILE_ADMIN);
- @NavigationSection(NavigationSection.RESOURCE_CONFIGURATION)
- class FirstPage implements Page {
- @Override
- public String getTitle() {
- return "First Page";
- }
-
- @Override
- public String getId() {
- return "first_page";
- }
- }
- WsTester wsTester = newdWsTester(new FirstPage());
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "polop").execute().assertJson(getClass(), "quality_profile_admin.json");
+ executeAndVerify(PROJECT.key(), "return_configuration_for_quality_profile_admin.json");
}
@Test
- public void bread_crumbs_on_several_levels() throws Exception {
- ComponentDto project = ComponentTesting.newProjectDto("abcd")
- .setKey("polop").setName("Polop");
- ComponentDto module = ComponentTesting.newModuleDto("bcde", project)
- .setKey("palap").setName("Palap");
- ComponentDto directory = ComponentTesting.newDirectory(module, "src/main/xoo");
- ComponentDto file = ComponentTesting.newFileDto(directory, directory, "cdef").setName("Source.xoo")
+ public void return_bread_crumbs_on_several_levels() throws Exception {
+ init();
+ ComponentDto project = componentDbTester.insertComponent(PROJECT);
+ ComponentDto module = componentDbTester.insertComponent(newModuleDto("bcde", project).setKey("palap").setName("Palap"));
+ ComponentDto directory = componentDbTester.insertComponent(newDirectory(module, "src/main/xoo"));
+ ComponentDto file = componentDbTester.insertComponent(newFileDto(directory, directory, "cdef").setName("Source.xoo")
.setKey("palap:src/main/xoo/Source.xoo")
- .setPath(directory.path());
- dbClient.componentDao().insert(dbTester.getSession(), project, module, directory, file);
-
- dbTester.getSession().commit();
+ .setPath(directory.path()));
+ userSessionRule.addProjectUuidPermissions(UserRole.USER, project.uuid());
- userSessionRule.addProjectUuidPermissions(UserRole.USER, "abcd");
-
- WsTester wsTester = newdWsTester();
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "palap:src/main/xoo/Source.xoo").execute().assertJson(getClass(), "breadcrumbs.json");
+ executeAndVerify(file.key(), "return_bread_crumbs_on_several_levels.json");
}
@Test
public void work_with_only_system_admin() throws Exception {
- ComponentDto project = ComponentTesting.newProjectDto("abcd")
- .setKey("polop").setName("Polop").setLanguage("xoo");
- dbClient.componentDao().insert(dbTester.getSession(), project);
- dbClient.snapshotDao().insert(dbTester.getSession(), SnapshotTesting.newAnalysis(project));
- dbTester.getSession().commit();
+ init(createViews());
+ componentDbTester.insertProjectAndSnapshot(PROJECT);
+ userSessionRule.setGlobalPermissions(SYSTEM_ADMIN);
- userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
+ execute(PROJECT.key());
+ }
+
+ private void init(View... views) {
+ ws = new WsActionTester(new ComponentNavigationAction(dbClient, new Views(userSessionRule, views), i18n, resourceTypes, userSessionRule, new ComponentFinder(dbClient)));
+ }
+
+ private String execute(String componentKey) {
+ return ws.newRequest().setParam("componentKey", componentKey).execute().getInput();
+ }
- WsTester wsTester = newdWsTester(createViews());
- wsTester.newGetRequest("api/navigation", "component").setParam("componentKey", "polop").execute();
+ private void verify(String json, String expectedJson) {
+ assertJson(json).isSimilarTo(getClass().getResource(ComponentNavigationActionTest.class.getSimpleName() + "/" + expectedJson));
}
- private WsTester newdWsTester(View... views) {
- return new WsTester(new NavigationWs(new ComponentNavigationAction(dbClient, new Views(userSessionRule, views), i18n, resourceTypes, userSessionRule,
- new ComponentFinder(dbClient))));
+ private void executeAndVerify(String componentKey, String expectedJson) {
+ verify(execute(componentKey), expectedJson);
}
private View[] createViews() {
@@ -403,6 +355,6 @@ public class ComponentNavigationActionTest {
}
}
Page adminPage = new AdminPage();
- return new Page[]{page1, page2, adminPage};
+ return new Page[] {page1, page2, adminPage};
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/GlobalNavigationActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/GlobalNavigationActionTest.java
index 4419611cbfb..58db73feb9e 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/GlobalNavigationActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/GlobalNavigationActionTest.java
@@ -38,10 +38,10 @@ import org.sonar.db.dialect.MySql;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ui.Views;
import org.sonar.server.ws.WsActionTester;
-import org.sonar.test.JsonAssert;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import static org.sonar.test.JsonAssert.assertJson;
public class GlobalNavigationActionTest {
@@ -171,7 +171,7 @@ public class GlobalNavigationActionTest {
when(database.getDialect()).thenReturn(new MySql());
String result = ws.newRequest().execute().getInput();
- JsonAssert.assertJson(ws.getDef().responseExampleAsString()).isSimilarTo(result);
+ assertJson(ws.getDef().responseExampleAsString()).isSimilarTo(result);
}
private void init() {
@@ -184,7 +184,7 @@ public class GlobalNavigationActionTest {
}
private void executeAndVerify(String json) {
- JsonAssert.assertJson(ws.newRequest().execute().getInput()).isSimilarTo(getClass().getResource(GlobalNavigationActionTest.class.getSimpleName() + "/" + json));
+ assertJson(ws.newRequest().execute().getInput()).isSimilarTo(getClass().getResource(GlobalNavigationActionTest.class.getSimpleName() + "/" + json));
}
private View[] createViews() {
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/on_module.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/on_module.json
deleted file mode 100644
index 51e9d413003..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/on_module.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- "key": "palap",
- "uuid": "bcde",
- "name": "Palap",
- "isComparable": false,
- "canBeFavorite": true,
- "isFavorite": false,
- "configuration": {
- "showSettings": false,
- "showQualityProfiles": false,
- "showQualityGates": false,
- "showManualMeasures": true,
- "showActionPlans": false,
- "showLinks": false,
- "showPermissions": false,
- "showHistory": false,
- "showUpdateKey": false,
- "extensions": []
- },
- "breadcrumbs": [
- {
- "key": "polop",
- "name": "Polop",
- "qualifier": "TRK"
- },
- {
- "key": "palap",
- "name": "Palap",
- "qualifier": "BRC"
- }
- ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/quality_profile_admin.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/quality_profile_admin.json
deleted file mode 100644
index 594a12562e6..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/quality_profile_admin.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "key": "polop",
- "uuid": "abcd",
- "name": "Polop",
- "isComparable": false,
- "canBeFavorite": true,
- "isFavorite": false,
- "configuration": {
- "showSettings": false,
- "showQualityProfiles": true,
- "showQualityGates": true,
- "showManualMeasures": false,
- "showActionPlans": false,
- "showLinks": false,
- "showPermissions": false,
- "showHistory": false,
- "showUpdateKey": false
- },
- "breadcrumbs": [
- {
- "key": "polop",
- "name": "Polop",
- "qualifier": "TRK"
- }
- ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/breadcrumbs.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_bread_crumbs_on_several_levels.json
index c0b1fa23a6e..c0b1fa23a6e 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/breadcrumbs.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_bread_crumbs_on_several_levels.json
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_breadcrumbs_on_module.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_breadcrumbs_on_module.json
new file mode 100644
index 00000000000..5054f144064
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_breadcrumbs_on_module.json
@@ -0,0 +1,14 @@
+{
+ "breadcrumbs": [
+ {
+ "key": "polop",
+ "name": "Polop",
+ "qualifier": "TRK"
+ },
+ {
+ "key": "palap",
+ "name": "Palap",
+ "qualifier": "BRC"
+ }
+ ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/no_snapshot.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_component_info_when_anonymous_no_snapshot.json
index 897600a6b5c..897600a6b5c 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/no_snapshot.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_component_info_when_anonymous_no_snapshot.json
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_snapshot_and_connected_user.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_component_info_when_snapshot.json
index 7af8830a799..1ca93830a06 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_snapshot_and_connected_user.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_component_info_when_snapshot.json
@@ -3,7 +3,7 @@
"uuid": "abcd",
"name": "Polop",
"isComparable": false,
- "canBeFavorite": true,
+ "canBeFavorite": false,
"isFavorite": false,
"snapshotDate": "2015-04-22T11:44:00+0200",
"version": "3.14",
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/no_snapshot_user_favourite.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_component_info_with_favourite.json
index 119f86af877..119f86af877 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/no_snapshot_user_favourite.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_component_info_with_favourite.json
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_admin_rights.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_configuration_for_admin.json
index c213ac06368..f2961819391 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_admin_rights.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_configuration_for_admin.json
@@ -1,16 +1,9 @@
{
- "key": "polop",
- "uuid": "abcd",
- "name": "Polop",
- "isComparable": false,
- "canBeFavorite": true,
- "isFavorite": false,
"configuration": {
"showSettings": false,
"showQualityProfiles": true,
"showQualityGates": true,
"showManualMeasures": true,
- "showActionPlans": false,
"showLinks": true,
"showPermissions": false,
"showHistory": false,
@@ -25,12 +18,5 @@
"url": "/second/page?id=polop"
}
]
- },
- "breadcrumbs": [
- {
- "key": "polop",
- "name": "Polop",
- "qualifier": "TRK"
- }
- ]
+ }
}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_configuration_for_quality_profile_admin.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_configuration_for_quality_profile_admin.json
new file mode 100644
index 00000000000..0b8a1b3a05d
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_configuration_for_quality_profile_admin.json
@@ -0,0 +1,12 @@
+{
+ "configuration": {
+ "showSettings": false,
+ "showQualityProfiles": true,
+ "showQualityGates": true,
+ "showManualMeasures": false,
+ "showLinks": false,
+ "showPermissions": false,
+ "showHistory": false,
+ "showUpdateKey": false
+ }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_all_properties.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_configuration_with_all_properties.json
index 930df6729ef..3384808676b 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_all_properties.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_configuration_with_all_properties.json
@@ -1,27 +1,13 @@
{
- "key": "polop",
- "uuid": "abcd",
- "name": "Polop",
- "isComparable": true,
- "canBeFavorite": true,
- "isFavorite": false,
"configuration": {
"showSettings": true,
"showQualityProfiles": true,
"showQualityGates": true,
"showManualMeasures": true,
- "showActionPlans": false,
"showLinks": true,
"showPermissions": true,
"showHistory": true,
"showUpdateKey": true,
"extensions": []
- },
- "breadcrumbs": [
- {
- "key": "polop",
- "name": "Polop",
- "qualifier": "TRK"
- }
- ]
+ }
}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_extensions.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_extensions.json
new file mode 100644
index 00000000000..6a5c706a339
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_extensions.json
@@ -0,0 +1,12 @@
+{
+ "extensions": [
+ {
+ "name": "First Page",
+ "url": "/plugins/resource/polop?page=first_page"
+ },
+ {
+ "name": "Second Page",
+ "url": "/second/page?id=polop"
+ }
+ ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/admin_with_extensions.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_extensions_for_admin.json
index 329c923f30c..b4f36e8b2e6 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/admin_with_extensions.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/return_extensions_for_admin.json
@@ -1,10 +1,4 @@
{
- "key": "polop",
- "uuid": "abcd",
- "name": "Polop",
- "isComparable": false,
- "canBeFavorite": false,
- "isFavorite": false,
"extensions": [
{
"name": "First Page",
@@ -18,12 +12,5 @@
"name": "Admin Page",
"url": "/admin/page?id=polop"
}
- ],
- "breadcrumbs": [
- {
- "key": "polop",
- "name": "Polop",
- "qualifier": "TRK"
- }
]
}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_dashboards.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_dashboards.json
deleted file mode 100644
index a582f0f6ddd..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_dashboards.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "key": "polop",
- "uuid": "abcd",
- "name": "Polop",
- "isComparable": false,
- "canBeFavorite": false,
- "isFavorite": false,
- "dashboardws": [
- {
- "name": "Anon Dashboard"
- }
- ],
- "breadcrumbs": [
- {
- "key": "polop",
- "name": "Polop",
- "qualifier": "TRK"
- }
- ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_default_dashboards.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_default_dashboards.json
deleted file mode 100644
index c24d40abcf9..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_default_dashboards.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "key": "polop",
- "uuid": "abcd",
- "name": "Polop",
- "isComparable": false,
- "canBeFavorite": true,
- "isFavorite": false,
- "dashboards": [
- {
- "name": "Anon Dashboard"
- }
- ],
- "breadcrumbs": [
- {
- "key": "polop",
- "name": "Polop",
- "qualifier": "TRK"
- }
- ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_extensions.json b/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_extensions.json
deleted file mode 100644
index b28f5586817..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/ui/ws/ComponentNavigationActionTest/with_extensions.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "key": "polop",
- "uuid": "abcd",
- "name": "Polop",
- "isComparable": false,
- "canBeFavorite": false,
- "isFavorite": false,
- "extensions": [
- {
- "name": "First Page",
- "url": "/plugins/resource/polop?page=first_page"
- },
- {
- "name": "Second Page",
- "url": "/second/page?id=polop"
- }
- ],
- "breadcrumbs": [
- {
- "key": "polop",
- "name": "Polop",
- "qualifier": "TRK"
- }
- ]
-}